6.3在设备树中pinctrl的简单使用

 

文档:
内核 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

几个概念:

Bank: 以引脚名为依据, 这些引脚分为若干组, 每组称为一个Bank
      比如s3c2440里有GPA、GPB、GPC等Bank,
      每个Bank中有若干个引脚, 比如GPA0,GPA1, ..., GPC0, GPC1,...等引脚

Group: 以功能为依据, 具有相同功能的引脚称为一个Group
       比如s3c2440中串口0的TxD、RxD引脚使用 GPH2,GPH3, 那这2个引脚可以列为一组
       比如s3c2440中串口0的流量控制引脚使用 GPH0,GPH1, 那这2个引脚也可以列为一组

State: 设备的某种状态, 比如内核自己定义的"default","init","idel","sleep"状态;
       也可以是其他自己定义的状态, 比如串口的"flow_ctrl"状态(使用流量控制)
       
       设备处于某种状态时, 它可以使用若干个Group引脚a. 设备树中pinctrl节点:
a.1 它定义了各种 pin bank, 比如s3c2440有GPA,GPB,GPC,...,GPB各种BANK, 每个BANK中有若干引脚:
    

pinctrl_0: pinctrl@56000000 {
        reg = <0x56000000 0x1000>;

        gpa: gpa {
            gpio-controller;
            #gpio-cells = <2>;  /* 以后想使用gpa bank中的引脚时, 需要2个u32来指定引脚 */
        };

        gpb: gpb {
            gpio-controller;
            #gpio-cells = <2>;
        };

        gpc: gpc {
            gpio-controller;
            #gpio-cells = <2>;
        };

        gpd: gpd {
            gpio-controller;
            #gpio-cells = <2>;
        };
    };

a.2 它还定义了各种group(组合), 某种功能所涉及的引脚称为group,
    比如串口0要用到2个引脚: gph0, gph1:

    

uart0_data: uart0-data {
        samsung,pins = "gph-0", "gph-0";
        samsung,pin-function = <2>;   /* 在GPHCON寄存器中gph0,gph1可以设置以下值:
                                             0 --- 输入功能
                                             1 --- 输出功能
                                             2 --- 串口功能
                                          我们要使用串口功能,  
                                          samsung,pin-function 设置为2
                                       */
    };
 uart0_sleep: uart0_sleep {
        samsung,pins = "gph-0", "gph-1";
        samsung,pin-function = <0>;   /* 在GPHCON寄存器中gph0,gph1可以设置以下值:
                                             0 --- 输入功能
                                             1 --- 输出功能
                                             2 --- 串口功能
                                          我们要使用输入功能,  
                                          samsung,pin-function 设置为0
                                       */
    };

    

  
b. 设备节点中要使用某一个 pin group:
    

serial@50000000 {
        ......
        pinctrl-names = "default", "sleep";  /* 既是名字, 也称为state(状态) */
        pinctrl-0 = <&uart0_data>;
        pinctrl-1 = <&uart0_sleep>;
    };


    
    pinctrl-names中定义了2种state: default 和 sleep,
    default 对应的引脚是: pinctrl-0, 它指定了使用哪些pin group: uart0_data
    sleep   对应的引脚是: pinctrl-1, 它指定了使用哪些pin group: uart0_sleep

c. platform_device, platform_driver匹配时:

"第3课第06节_platform_device跟platform_driver的匹配" 中讲解了platform_device和platform_driver的匹配过程,
最终都会调用到 really_probe (drivers/base/dd.c)

really_probe:
    /* If using pinctrl, bind pins now before probing */
    ret = pinctrl_bind_pins(dev);
                dev->pins->default_state = pinctrl_lookup_state(dev->pins->p,
                                PINCTRL_STATE_DEFAULT);  /* 获得"default"状态的pinctrl */
                dev->pins->init_state = pinctrl_lookup_state(dev->pins->p,
                                PINCTRL_STATE_INIT);    /* 获得"init"状态的pinctrl */

                ret = pinctrl_select_state(dev->pins->p, dev->pins->init_state);    /* 优先设置"init"状态的引脚 */
                ret = pinctrl_select_state(dev->pins->p, dev->pins->default_state); /* 如果没有init状态, 则设置"default"状态的引脚 */
                                
    ......
    ret = drv->probe(dev);

所以: 如果设备节点中指定了pinctrl, 在对应的probe函数被调用之前, 先"bind pins", 即先绑定、设置引脚

d. 驱动中想选择、设置某个状态的引脚:
   

devm_pinctrl_get_select_default(struct device *dev);      // 使用"default"状态的引脚
   pinctrl_get_select(struct device *dev, const char *name); // 根据name选择某种状态的引脚
   
   pinctrl_put(struct pinctrl *p);   // 不再使用, 退出时调用


        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值