DTS中如何配置设备相关的pinctrl

进行嵌入式Linux驱动开发时,不可避免的会涉及到DTS相关的编写工作,而其中,最为重要的一项工作就是pinctrl相关的配置,这包括pins的功能选择(作为普通IO,还是作为外围控制器的pins)以及pins的配置(pull-up/pull-down、驱动能力、三态等)。
内核中的pinctrl子系统抽象了不同SoC中关于pins的管理方式,Linux内核之pinctrl子系统对于pinctrl子系统进行了简要的概述,如果想要了解pinctrl子系统,可以参考这篇博文。

本文主要讲解对于一个具体的设备驱动,如何在DTS中基于pinctrl实现关于pins的管理,这包括:

  • 如何定义pin功能
  • 驱动程序如何引用pin

如何定义pin功能

利用内核文档

市面上存在很多的SoC,一般情况下,不同的SoC在DTS中关于pin的管理方式会有一些不同。SoC厂商在发布时,会编写相关的pinctrl驱动程序,同时,会在内核目录Documentation/devicetree/bindings/pinctrl下,编写相关的配置说明,比如,fsl,imx-pinctrl.txt
里面说明了 Freescale IOMUX Controller (IOMUXC) for I.MX相关的配置说明;rockchipi, pinctrl.txt里面说面了Rockchip Pinmux Controller相关的配置说明。

所以,当我们拿到一块电路板时,首先,需要确定其使用的SoC,然后,去Documentation/devicetree/bindings/pinctrl目录下,找到关于该款SoC相关的pinctrl的配置说明。这里需要注意的时,某个厂商的SoC一般遵循相同的pinctrl配置方式,所以,在未找到具体SoC的
pinctrl使用说明时,可以直接查看这个SoC厂商的说明文档,比如,我们如果使用的是s3c6410,可以看到该目录下,没有s3c6410相关的说明,但是,我们可以找到samsung-pinctrl.txt,参照这个文档,同样可以在DTS中配置pinctrl。

pin配置举例

下面拿一个例子,说明一下如何在DTS中定义pin的功能。

Freescale IOMUX

关于Freescale SoC的pinctrl配置,主要完成一下两项内容:

  • 确定SoC的pinctrl控制器的兼容性: compatible: “fsl,-iomuxc”,关于SoC的IOMUX的兼容性,需要到fsl,-pinctrl.txt中获得。
  • 配置具体的pins: fsl,pins/</>,该字段定义了pin的功能,其一般定义一组pins的功能,这一组pins服务于同一function,比如spi控制器。每个配置项包括6字段分别是:前5个字段分别是<mux_reg conf_reg input_reg mux_val input_val>,可以到/arch/arm/boot/dts的imx*-pinfunc.h中找到他们的定义,
    比如,imx6ul-pinfunc.h定义imx6ul这款SoC的所有pins。6个字段是pin的配置参数,比如:pull-up/pull-down等。

下面是sd卡所用到的pin的功能配置定义:

usdhc@219c000 { /* uSDHC4 */
    non-removable;
    vmmc-supply = <&reg_3p3v>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_usdhc4_1>;
};         
           
iomuxc@20e0000 {
    compatible = "fsl,imx6q-iomuxc";
    reg = <0x020e0000 0x4000>;
           
    /* shared pinctrl settings */
    usdhc4 {
        pinctrl_usdhc4_1: usdhc4grp-1 {
            fsl,pins = <
                MX6QDL_PAD_SD4_CMD__SD4_CMD    0x17059
                MX6QDL_PAD_SD4_CLK__SD4_CLK    0x10059
                MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
                MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
                MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
                MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
                MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059                                                                                                                                                                                                                                    
                MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
                MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
                MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
            >;
    };  
    ....
};       
  • iomuxc的兼容性为"fsl,imx6q-iomuxc";
  • 节点pinctrl_usdhc4_1定义了设备uSDHC4所使用的pins功能。

驱动程序如何使用pins

对于普通的设备,如何定义其使用到的pin呢?上面关于Freescale IOMUX的举例,说明了uSDHC4这个设备如何定义pins的功能。文档pinctrl-bindings.txt中说明了一般情况下如何在DTS中定义一个设备驱动的pins功能。

如果一个设备使用到某些pins,那么,在其DTS节点中至少包含下面两项内容:

  • pinctrl-names:定义设备不同的工作状态,一般包括下面几个:default、init、sleep、idle。其中,sleep、idle用于系统的电源管理,以达到控制系统功耗的目的。
  • pinctrl-0:定义了一个phandles的列表,每个phandle指向一个pinctrl的节点。该配置项定义了该设备的一种工作状态,其对应于pinctrl-names中首个工作状态。

下面举例说明一下:
deviceA {
pinctrl-names = “defalut”, “idle”;
pinctrl-0 = <&state_0_node_a>;
pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};

deviceA节点,定义了"default","idle"两种工作状态,所以,下面依次定义了pinctrl-0和pinctrl-1两个pins列表,分别对应于上面两个状态。

上面内容,说明了一个设备如何在DTS中配置其所用到的pins,后面文章还具体分析pinctrl子系统在DTS中的配置方式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章