嵌入式开发记录-day43 设备树-pinctrl子系统框架

1、在pinctrl子系统出现之前,管理设备树都是在platform下管理的,在该平台下管理设备封装了一套API就是GPIO子系统接口gpiolib;很繁杂;

  为了节省代码,方便管理设备,引入了设备树后,管理物理引脚,在管脚封装得基础上,对外提供简洁的API接口;该接口直接定义物理管脚,

  对上给GPIO子系统调用;因此,在物理硬件与GPIO子系统之间,搭起了一个桥梁;该桥梁就是pinctrl子系统;

  因此,在引入设备树之后,GPIO子系统是通过pinctrl子系统来实现的,这一点要牢记。

2、gpio子系统与pinctrl子系统对比

  1、pinctrl子系统和GPIO子系统的结构和功能类似,内部结构有所差异

  2、在引入设备树之后,GPIO子系统是通过pinctrl子系统来实现的,这一点要牢记。

  3、pinctrl子系统相比gpio子系统,增加了引脚复用和pin脚状态设置这两个功能。

1、GPIO子系统系统结构--参考图1
    通过GPIO子系统功能:
    引脚功能的配置(设置为GPIO,特殊功能,GPIO的方向,设置为中断等等);
    实现软硬件的分离(分离出硬件差异,有厂商提供底层支持;软件分层,驱动只需要调用接口API即可操作GPIO);
    iommu内存管理(直接调用宏即可操作GPIO)。
    GPIO子系统提供一系列的API对外调用,
2、pinctrl子系统内部结构--参考图4
    pinctrl的内部主要分为两部分功能:pin config管脚配置和pin mux管脚复用 
    驱动调用pin脚(不仅指GPIO,例如uart也需要用到pin脚),那么需要用到两部分硬件的功能:
    A: 设置引脚功能的复用;
    B:配置pin脚的状态。

在以前驱动移植中,经常会遇到,调试很久的驱动,发现管脚的初始化出了问题(这是经常会遇到的问题)。
    传统模式中,管脚初始化在uboot中或者在内核中增加额外的初始化代码(不同的平台版本有区别),也有可能在驱动中额外增加初始化代码。
    
在驱动中,可以直接而通用的实现管脚功能复用和配置,这样驱动的移植工作会更加简单。

3、驱动为什么要移植,而不能直接使用?

  一方面是:上层应用接口的变化,不过这种情况很少;
  另外一方面:主要是因为硬件差异,现在更多的硬件管脚差异--pinctrl的初始化和配置放到了设备树中
  (不仅仅是pin这部分硬件差异在设备树中),所以很多移植只需要修改下设备树文件即可。

4、pinctrl子系统

  pinctrl的内部主要分为两部分功能:pin config管脚配置和pin mux管脚复用

    驱动调用pin脚(不仅指GPIO,例如uart也需要用到pin脚),那么需要用到两部分硬件的功能:

    A: 设置引脚功能的复用;
    B:配置pin脚的状态。
  pinctrl子系统相比gpio子系统,增加了引脚复用和pin脚状态设置这两个功能。管脚更容易配置、以及初始化
  传统模式中,使用GPIO子系统配置管脚,管脚初始化在uboot中或者在内核中增加额外的初始化代码(不同的平台版本有区别),也有可能在驱动中额外增加初始化代码。
  pinctrl子系统引入了设置引脚功能复用和配置pin脚,这个功能需要和设备树文件结合使用。
  在驱动中,可以直接而通用的实现管脚功能复用和配置,这样驱动的移植工作会更加简单。

3、pinctrl参考文档

  1、设备树文件:arch/arm/boot/dts/exynos4412-pinctrl.dtsi

  参考文档:Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

cd Documentation
find ./ -name "pinctrl"  显示./devicetree/bindings/pinctrl/
cd /devicetree/bindings/pinctrl/
vim samsung-pinctrl.txt
View Code

  为什么肯定会存在这样的文档:三星给设备树中添加属性节点,必须要添加相关的说明文档,否则
Linux官方肯定不允许三星给设备树添加设备节点。这样的规范是Linux官方提出的;

4、pinctrl的属性

  1、compatible:compatible: should be one of the following. 三星提供了一系列支持的节点名称

  2、reg:reg: Base address of the pin controller hardware module and length of the address space it occupies;包含有基地址和偏移地址;

  3、Pin banks 它是pinctrl的子节点,Pin banks子节点必须要有的属性:

-- gpio-controller: identifies the node as a gpio controller and pin bank
  -- #gpio-cells: number of cells in GPIO specifier.  // 引用时候必须要有的参数
  例子:
  Eg: <&gpx2 6 0>
        <[phandle of the gpio controller node]
        [pin number within the gpio controller]
        [flags]>

        Values for gpio specifier:
        - Pin number: is a value between 0 to 7.
        - Flags: 0 - Active High
                 1 - Active Low
 前面gpio的例程,设备树中增加如下:    
 gpl2: gpl2 {
            gpio-controller;
            #gpio-cells = <2>;

            interrupt-controller;
            #interrupt-cells = <2>;   // 有两个参数可以选择
                };
 
  leds_test_node:leds_test_node {           // 加个冒号表示可以被引用
                compatible = "leds_test";
                status = "disabled";
                gpios1 = <&gpl2 0 GPIO_ACTIVE_HIGH>; --gpl2引用的pinctrl文件下的gpl2,
                gpios2 = <&gpk1 1 GPIO_ACTIVE_HIGH>;
        };
View Code

  4、Pin mux/config groups ,它是pinctrl的子节点,Pin banks子节点实现的功能: The pin mux (selecting pin function mode) and pin config (pull up/down, driver strength) settings are represented as child nodes of the pin-controller node. 

 子节点的要求和语法:
  The child node should contain a list of pin(s) on which a particular pin
  function selection or pin configuration (or both) have to applied.
  list of pins的写法:
  A the property name "samsung,pins"
  B 引用管脚using pin names:"[pin bank name]-[pin number within the bank]"。eg:"gpa0-0", "gpa0-1", "gpa0-2" and so on
  C 功能复用属性:"samsung,pin-function"
    The pin function selection that should be applied on the pins listed in the
  child node is specified using the "samsung,pin-function" property.
  D 配置属性:
  - samsung,pin-val: Initial value of pin output buffer.
  - samsung,pin-pud: Pull up/down configuration.
  - samsung,pin-drv: Drive strength configuration.
  - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
  - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
  语法还要遵守"pinctrl-bindings.txt"文件的规则
  其中中断部分,后续介绍,这部分只是以GPIO功能为例
View Code

5、设备树文档中的例程

例子1:为什么function是1,val是1...
  #include <dt-bindings/pinctrl/samsung.h>
  leds_gpios1:leds-gpios1{  // 有冒号 代表这个节点可以被引用
            samsung,pins = "gpl2-0" ;
            samsung,pin-function = <1>;   
            samsung,pin-val = <1>;
            samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
    };
        
  例子2:以下代码添加到arch/arm/boot/dts/exynos4412-pinctrl.dtsi        
    leds_gpios1{
        leds_gpios1_on:leds_gpios1-on {
            samsung,pins = "gpl2-0" ;
                        samsung,pin-function = <1>;   // <1>里面的1 表示,引用的时候必须要有一个参数; 这个参数就是,配置该管脚为输出
                        samsung,pin-val = <1>;
                        samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
        };
        leds_gpios1_off:leds_gpios1-off {
            samsung,pins = "gpl2-0" ;
                            samsung,pin-function = <1>;
                            samsung,pin-val = <0>;
                            samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
        };
    };
View Code

 

posted @ 2020-09-13 10:15  笑不出花的旦旦  阅读(428)  评论(0)    收藏  举报