Linux内核的 pinctrl 和 gpio 子系统

IMX6ULL的pinctrl子系统驱动

在 imx6ull.dtsi 文件中,有如下一个子节点,这个节点是在 根-> soc->aips1->iomuxc,用于IO复用功能。
在这里插入图片描述
但是该节点的内容主要是追加在 imx6ull-alientek-emmc.dts 文件中,因为不同IO不同需求配置不同,所以就追加在 .dts 文件里。以下就是部分追加内容。
Linux内核的 pinctrl 和 gpio 子系统_第1张图片
而在 fsl,pins = < > 里的内容,就是具体的每一个IO复用功能的配置。MX6UL_PAD_XXX__XXX_XXX 都是宏定义,这些宏定义在文件 arch/arm/boot/dts/imx6ul-pinfun.h 中。以下是部分代码。
Linux内核的 pinctrl 和 gpio 子系统_第2张图片

举例

MX6UL_PAD_UART1_TX_DATA__CSI_DATA02:含义就是将 UART1_TX_DATA 引脚复用为 CSI_DATA02 模式,

后面的5组字符则是对应寄存器地址或向寄存器地址填入的值。含义如下:

<mux_reg conf_reg input_reg mux_mode input_val>

mux_reg:	复用功能寄存器的偏移地址
conf_reg:	IO属性控制寄存器的偏移地址
input_reg:	输入寄存器的偏移地址
mux_mode:	是向 mux_reg 寄存器内写入的值
input_val:	是向 input_reg 寄存器内写入的值

如图所示寄存器:
Linux内核的 pinctrl 和 gpio 子系统_第3张图片

注意

需要注意的是:conf_reg寄存器的值并不是在 arch/arm/boot/dts/imx6ul-pinfun.h 这个文件中被写入,因为这是需要我们自己配置的,所以这个也在 imx6ull-alientek-emmc.dts 文件中。
Linux内核的 pinctrl 和 gpio 子系统_第4张图片
综上所述,如果我们要追加某一个IO的复用功能,就可以直接在 .dts文件中找到对应的追加信息即 &iomuxc,创建一个新的属性并写入要用的IO和电气属性即可,属性格式如下:

pinctrl_xxx: xxxgrp {
    fsl,pins = <
        		........
        >;
};

IMX6ULL的gpio子系统

gpio子系统是用于初始化GPIO并提供对应的操作GPIO的API函数。

GPIO信息:

以SD卡的CD引脚为例
IO复用控制设备节点:
Linux内核的 pinctrl 和 gpio 子系统_第5张图片
SD卡设备节点:
Linux内核的 pinctrl 和 gpio 子系统_第6张图片
GPIO1控制器的信息:
Linux内核的 pinctrl 和 gpio 子系统_第7张图片

  1. compatible 属性有两个,分别为“fsl,imx6ul-gpio”和“fsl,imx35-gpio”

  2. reg 属性设置了 GPIO1 控制器的寄存器基地址为 0X0209C000

  3. “gpio-controller”表示 gpio1 节点是个 GPIO 控制器。

  4. “#gpio-cells” 属性和 “#address-cells” 类似,#gpio-cells 为 2,表示一共有两个 cell,第一个 cell 为 GPIO 编号,比如 “&gpio1 3” 就表示 GPIO1_IO03。第二个 cell 表示 GPIO 极性 , 如果为 0 (GPIO_ACTIVE_HIGH) 的 话表示高电平有效,如果为1 (GPIO_ACTIVE_LOW) 的话表示低电平有效。

利用pinctrl 和 gpio 子系统编写 LED设备驱动

一、添加 pinctrl 节点

打开文件 /arch/arm/boot/dts/imx6ull-alientek-emmc.dts ,在 iomuxc 节点下的 imx6ul-evk 子节点下加入 自定义的 led 子节点。节点内描述信息为:将GPIO1_IO03 这个 PIN 复用为 GPIO1_IO03,电气属性值为 0X10B0。

 pinctrl_led: ledgrp {
                        fsl,pins = <
                                MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0x10B0
                        >;
                };

二、添加 LED 设备节点

同样在该文件内找到根节点,在根节点下创建 LED 设备节点,内容如下:

gpioled {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "atkalpha-gpioled";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_led>;
                led-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>;
                status = "okay";
                };

三、给 iomuxc 节点添加信息

(在后来实验中发现,这一步是非必要的)
pinctrl-0 属性设置了节点设备所使用的 PIN 对应的 pinctrl 节点,由于我们在 iomucx 节点下新建了一个 ledgrp 节点,所以要在 iomuxc 节点的 pinctrl-0 属性中添加参数。如下:

Linux内核的 pinctrl 和 gpio 子系统_第8张图片
该参数在添加 LED 设备节点时被定义。

四、检查 PIN 是否被其它外设使用

这里用到的引脚是 GPIO1_IO03,直接搜索这个引脚,如果被使用了就先屏蔽。

用 vim 编辑器在命令行模式下输入 “/GPIO1_IO03” 就是搜索GPIO1_IO03。

五、重新编译设备树文件

回到内核根目录,输入如下命令:

make dtbs

编译完成后复制到自己的 tftpboot 目录下,输入如下命令:

cp imx6ull-alientek-emmc.dtb /home/swiler/tftpboot

开发板进入uboot,重新下载zImage和imxull-alientek-emmc.dtb 文件,然后启动内核,从网络加载根文件系统,检查 gpioled 节点是否存在。

输入如下命令:

cd /proc/device-tree/
ls -l

设备节点如下图所示,存在gpioled,说明节点存在,接下来编写驱动检测节点是否能成功使用。
Linux内核的 pinctrl 和 gpio 子系统_第9张图片

你可能感兴趣的:(Linux基础,linux,驱动开发,单片机,物联网)