I.MX6ULL 的 pinctrl 子系统驱动之PIN配置信息

发布时间:2024年01月22日

一.? 简介

上一篇文章简介了解了Linux内核存在 pinctrl子系统,以及其作用。

本文了解 I.MX6ULL芯片的(Linux内核中的) pinctrl子系统。具体了解 以设备树文件中某个设备节点为例,了解 pinctrl子系统会使用到 设备节点中的PIN 配置信息。
注意:这里以 正点原子的 EMMC版ALPHA开发板的 设备树文件为例(即imx6ull-alientek-emmc.dts,内容与设备树文件 imx6ull-14x14-evk.dts中代码相同)进行学习。

二.? PIN 配置信息详解

1.? iomuxc节点

要使用 pinctrl 子系统,我们需要在设备树里面设置 PIN 的配置信息,毕竟 pinctrl 子系统要根据你提供的信息来配置 PIN 功能,一般会在设备树里面创建一个节点来描述 PIN 的配置信 息。
打开 imx6ull.dtsi 文件,找到一个叫做 iomuxc 的节点,如下所示:
			iomuxc: iomuxc@020e0000 {
				compatible = "fsl,imx6ul-iomuxc";
				reg = <0x020e0000 0x4000>;
			};
iomuxc 节点就是 I.MX6ULL IOMUXC 外设对应的节点,看起来内容很少,没看出什么 PIN 的配置有关的内容啊。
打开 imx6ull-alientek-emmc.dts,也有 iomuxc 节点的信息 ,如下所示内容:
 &iomuxc {
     pinctrl-names = "default";
     pinctrl-0 = <&pinctrl_hog_1>;
     imx6ul-evk {
     pinctrl_hog_1: hoggrp-1 {
     fsl,pins = <
         MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
         MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059
         MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059
         MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058
     >;
 };
......
     pinctrl_flexcan1: flexcan1grp{
     fsl,pins = <
         MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x1b020
         MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x1b020
     >;
 };
......
    pinctrl_wdog: wdoggrp {
    fsl,pins = <
         MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x30b0
        >;
     };
   };
};

上面的代码就是向 iomuxc 节点追加数据,不同的外设使用的 PIN 不同、其配置也不 同,因此,一个萝卜一个坑,将某个外设所使用的所有 PIN 都组织在一个子节点里面。
imx6ull-alientek-emmc.dts设备树文件中,pinctrl_hog_1 子节点就是和热插拔有关的 PIN 集合,比如 USB OTG ID 引脚。
pinctrl_flexcan1 子节点是 flexcan1 这个外设所使用的 PIN pinctrl_wdog 子节点是 wdog 外设所 使用的 PIN 。如果需要在 iomuxc 中添加我们自定义外设的 PIN ,那么需要新建一个子节点,然 后将这个自定义外设的所有 PIN 配置信息都放到这个子节点中。

将 以上两个部分的 iomuxc节点信息结合到一起,就可以得到完整的 iomuxc 节点,如下所示:

iomuxc: iomuxc@020e0000 {
	compatible = "fsl,imx6ul-iomuxc";
	reg = <0x020e0000 0x4000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_hog_1>;
    imx6ul-evk {
    pinctrl_hog_1: hoggrp-1 {
    fsl,pins = <
        MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
        MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059
        MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059
        MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x13058
      >;
......
    };
  };
};
2 行, compatible 属性值为“ fsl,imx6ul-iomuxc ”,前面讲解设备树的时候说过, Linux 核会根据 compatbile 属性值来查找对应的驱动文件,所以,我们在 Linux 内核源码中全局搜索字 符串 “ fsl,imx6ul-iomuxc ” 就会找到 I.MX6ULL 这颗 SOC pinctrl 驱动文件。
9~12 行, pinctrl_hog_1 子节点所使用的 PIN 配置信息。

2.? UART1_RTS_B 这个 PIN

我们就以第 9 行的 UART1_RTS_B 这个 PIN 为例,讲解一下如何添加 PIN 的配置信息, UART1_RTS_B 的配置信息如下:
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059
首先说明一下, UART1_RTS_B 这个 PIN 是作为 SD 卡的检测引脚,也就是通过此 PIN 就可 以 检 测 到 SD 卡 是 否 有 插 入 。 UART1_RTS_B 的 配 置 信 息 分 为 两 部 分 :
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059

我们重点来看一下这两部分是什么含义

首先来看一下 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19,这是一个宏定义,定义在文件

arch/arm/boot/dts/imx6ul-pinfunc.h 中, imx6ull.dtsi 会引用 imx6ull-pinfunc.h 这个头文件,而
imx6ull-pinfunc.h 又会引用 imx6ul-pinfunc.h 这个头文件。 从这里可以看出,可以在 设备树中引用 C 语言中 .h 文件中的内容。
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 的宏定 义内容如下:
#define MX6UL_PAD_UART1_RTS_B__UART1_DCE_RTS                      0x0090 0x031C 0x0620 0x0 0x3
#define MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS                      0x0090 0x031C 0x0000 0x0 0x0
#define MX6UL_PAD_UART1_RTS_B__ENET1_TX_ER                        0x0090 0x031C 0x0000 0x1 0x0
#define MX6UL_PAD_UART1_RTS_B__USDHC1_CD_B                        0x0090 0x031C 0x0668 0x2 0x1
#define MX6UL_PAD_UART1_RTS_B__CSI_DATA05                         0x0090 0x031C 0x04CC 0x3 0x1
#define MX6UL_PAD_UART1_RTS_B__ENET2_1588_EVENT1_OUT              0x0090 0x031C 0x0000 0x4 0x0
#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19                         0x0090 0x031C 0x0000 0x5 0x0
#define MX6UL_PAD_UART1_RTS_B__USDHC2_CD_B                        0x0090 0x031C 0x0674 0x8 0x2
上面代码中,可以看出一共有 8 个以“ MX6UL_PAD_UART1_RTS_B ”开头的宏定义,大家 仔细观察应该就能发现,这 8 个宏定义分别对应 UART1_RTS_B 这个 PIN 8 个复用 IO
阅《 I.MX6ULL 参考手册》可以知 UART1_RTS_B 的可选复用 IO 如图 所示:

以上的宏 定 义 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 表示将 UART1_RTS_B 这个 IO 复用为 GPIO1_IO19 。此宏定义后面跟着 5 个数字,也就是这个宏定义 的具体值,如下所示:
0x0090 0x031C 0x0000 0x5 0x0
5 个值的含义如下所示:
<mux_reg conf_reg input_reg mux_mode input_val>

综上所述可知:
0x0090 mux_reg 寄存器偏移地址,设备树中的 iomuxc 节点就是 IOMUXC 外设对应的节点 , 根 据 其 reg 属 性 可 知 IOMUXC 外 设 寄 存 器 起 始 地 址 为 0x020e0000 。 因 此,
0x020e0000+0x0090=0x020e0090 IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B 寄存器地址 正 好 是 0x020e0090
大 家 可 以 在 《 IMX6ULL 参 考 手 册 》 中 找 到 IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B 这个寄存器的位域图,如下图 所示:

因此可知:
0x020e0000+mux_reg 就是 PIN 的复用寄存器地址。
0x031C conf_reg 寄存器偏移地址,和 mux_reg 一样, 0x020e0000+0x031c=0x020e031c
这个就是寄存器 IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B 的地址。
0x0000 input_reg 寄存器偏移地址,有些外设有 input_reg 寄存器,有 input_reg 寄存器的 外设需要配置 input_reg 寄存器。没有的话就不需要设置, UART1_RTS_B 这个 PIN 在做 GPIO1_IO19 的时候是没有 input_reg 寄存器,因此,这里 intput_reg 是无效的。
mux_mode 即配置复用的值,也就是所要设置的 muc_reg寄存器的值。
mux_reg
寄 存 器 值 , 在 这 里 就 相 当 于 设 置
IOMUXC_SW_MUX_CTL_PAD_UART1_RTS_B 寄存器为 0x5 ,也即是设置 UART1_RTS_B
PIN 复用为 GPIO1_IO19
0x0 input_reg 寄存器值,在这里无效。
这就是宏 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 的含义,看的比较仔细的同学应该 会发现并没有 conf_reg 寄存器的值, config_reg 寄存器是设置一个 PIN 的电气特性的
回到以下代码 中,如下所示:
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 我们上面已经分析了,就剩下了一个 0x17059
0x17059 就是 conf_reg 寄存器值!此值由用户自行设置,通 过此值来设置一个 IO 的上 / 下拉、驱动能力和速度等。在这里就相当于设置寄存器 IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B 的值为 0x17059

文章来源:https://blog.csdn.net/wojiaxiaohuang2014/article/details/135738102
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。