设备树和pinctrl粗解

上次文章中 我以DS18b20为例,在设备树中定义了ds18b20的资源(device),当时是依葫芦画瓢,没有深入探究,本文主要探讨下pin在设备树中的描述

参考文章:Linux内核中的GPIO系统之(3):pin controller driver代码分析 、fsl,imx6q-pinctrl.txt、fsl,imx-pinctrl.txt

先看我上一篇文章对ds18b20的描述

    my-ds18b20 {

        compatible = "ds18b20";
        gpios = <&gpio2 3 1>;   //有更改,以这里为准

        };

其实这是不完整的描述,因为我们仅仅指定了哪个引脚,而作为GPIO是这个引脚的功能之一,也许他还可以作为UART1_TX_DATA等等。那为何我们这个驱动可以成功呢?因为这个引脚在其他地方进行了初始化配置为了普通GPIO。

所以完整的描述应该这样:

        //myimx6ek314-iomux.dtsi
        pinctrl_nandf_pad: nandfpadgrp {
            fsl,pins = <
                /* All in U14 */
                MX6QDL_PAD_NANDF_CS0__GPIO6_IO11    0x80000000
                MX6QDL_PAD_NANDF_CS3__GPIO6_IO16    0x80000000
                MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09   0x80000000
                MX6QDL_PAD_NANDF_D0__GPIO2_IO00     0x80000000
                MX6QDL_PAD_NANDF_D2__GPIO2_IO02     0x80000000
                MX6QDL_PAD_NANDF_D3__GPIO2_IO03     0x40000000
                MX6QDL_PAD_NANDF_D4__GPIO2_IO04     0x80000000
                MX6QDL_PAD_NANDF_D5__GPIO2_IO05     0x80000000
                MX6QDL_PAD_NANDF_D6__GPIO2_IO06     0x80000000
                MX6QDL_PAD_NANDF_D7__GPIO2_IO07     0x80000000
            >;
        };

        //myimx6ek314.dtsi
        my-ds18b20 {

            compatible = "ds18b20"; 
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_nandf_pad>;

            gpios = <&gpio2 3 1>;  
            status = "okay";

        };

gpios = <&gpio2 3 1>; 对应了MX6QDL_PAD_NANDF_D3__GPIO2_IO03 (宏定义) 的pin configuration,我们具体来看看这个宏定arch\arm\boot\dts\imx6dl-pinfunc.h

                                          //<mux_reg  conf_reg input_reg mux_mode input_val>
#define MX6QDL_PAD_NANDF_D3__GPIO2_IO03       0x290   0x678    0x000     0x5       0x0

这个宏定义由5个数组成,我们主要关心第四个,mux_mode 0x5,这决定了这个引脚配置为什么功能,我们现在查询下芯片手册,在芯片手册中搜索关键词“GPIO2_IO03”
这里写图片描述
我们配置他为GPIO模式,不开启SION,那么后应该配置为0101 = 0x5,与我们宏定义相对应,其实从从这个宏定义的名字我们也能看出来他配置为了GPIO模式,MX6QDL_PAD_NANDF_D3__GPIO2_IO03 这个引脚原本功能为nand的data3引脚,我们复用为了GPIO2_3,我们在看看这个宏定义的源文件
这里写图片描述
这里可以看出,NANDF_D3 还可以复用为SD1_DATA7、NAND_DATA3。

我们再来说说pinctrl-names 和pinctrl-x。(以下两段摘自WOWO科技)

(1)pinctrl-names定义了一个state列表。那么什么是state呢?具体说应该是pin state,对于一个client device,它使用了一组pin,这一组pin应该同时处于某种状态,毕竟这些pin是属于一个具体的设备功能。state的定义和电源管理关系比较紧密,例如当设备active的时候,我们需要pin controller将相关的一组pin设定为具体的设备功能,而当设备进入sleep状态的时候,需要pin controller将相关的一组pin设定为普通GPIO,并精确的控制GPIO状态以便节省系统的功耗。state有两种,标识,一种就是pinctrl-names定义的字符串列表,另外一种就是ID。ID从0开始,依次加一。根据例子中的定义,state ID等于0(名字是active)的state对应pinctrl-0属性,state ID等于1(名字是idle)的state对应pinctrl-1属性。具体设备state的定义和各个设备相关,具体参考在自己的device bind。

(2)pinctrl-x的定义。pinctrl-x是一个句柄(phandle)列表,每个句柄指向一个pin configuration。有时候,一个state对应多个pin configure。例如在active的时候,I2C功能有两种配置,一种是从pin ID{7,8}引出,另外一个是从pin ID{69,103}引出。

下面我再给一段,供大家分析练手

             //myimx6ek314-iomux.dtsi   
                 pinctrl_nandf_keys: nandfkeysgrp {
            fsl,pins = <
                MX6QDL_PAD_NANDF_CS2__GPIO6_IO15    0x80000000  /* KEY_VOLUMEUP */
                MX6QDL_PAD_NANDF_RB0__GPIO6_IO10    0x80000000  /* KEY_VOLUMEDOWN */
            >;
        };  

        pinctrl_gpio_keys: gpiokeysgrp {
            fsl,pins = <
                MX6QDL_PAD_GPIO_4__GPIO1_IO04       0x80000000  /* KEY_POWER */
            >;
        };

    //myimx6ek314.dtsi
    gpio-keys {
        compatible = "gpio-keys";
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_nandf_keys &pinctrl_gpio_keys>;    //配置pin 为gpio

        power {
            label = "Power Button";
            gpios = <&gpio1 4 1>;
            gpio-key,wakeup;
            linux,code = <KEY_POWER>;
        };

        volume-up {
            label = "Volume Up";
            gpios = <&gpio6 15 1>;
            gpio-key,wakeup;
            linux,code = <KEY_VOLUMEUP>;
        };

        volume-down {
            label = "Volume Down";
            gpios = <&gpio6 10 1>;
            gpio-key,wakeup;
            linux,code = <KEY_VOLUMEDOWN>;
        };
    };

2017-11-09

猜你喜欢

转载自blog.csdn.net/a1171936767/article/details/80917350
今日推荐