一、pinctrl子系统
借助pinctrl子系统来设置一个引脚的复用功能和属性。
pinctrl子系统的主要工作内容:
- 获取设备树中pin的信息
- 根据获取到的pin信息来设置pin的复用功能
- 根据获取到的pin信息设置pin的电气特性,比如上拉下拉、速度、驱动能力等
对于使用者来说,只需要在设备树里面设置好某个pin的相关属性即可,其余的初始化工作均由pinctrl子系统来完成,pinctrl子系统源码目录为:drivers/pinctrl。
二、设备树如何描述pin配置信息
pinctrl子系统根据设备树中的描述信息来设置pin功能。
1. iomuxc设备树节点
在imx6ull的设备树中,iomucx节点就是imx6ull iomuxc外设对应的节点,用来设置引脚复用。
(1)iomuxc子节点在arch/arm/boot/dts/imx6ul.dtsi
文件中的描述。
iomuxc: iomuxc@020e0000 {
compatible = "fsl,imx6ul-iomuxc";
reg = <0x020e0000 0x4000>;
};
iomucx外设的兼容性为"fsl,imx6ul-iomuxc",寄存器起始地址为0x020e0000、大小为0x4000。
(2)iomucx子节点在arch/arm/boot/dts/imx6ull-atk-emmc.dts
文件中的补充描述(节选部分代码)。
&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 /* SD1 CD */
MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */
>;
};
};
};
其中MX6UL_PAD_UART1_RTS_B__GPIO1_IO19
表示MX6UL_PAD_UART1_RTS_B引脚作为GPIO1_IO19使用。
2. 节点描述值的意义
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19
这些宏在arch/arm/boot/dts/imx6ull-pinfunc.h
和arch/arm/boot/dts/imx6ul-pinfunc.h
文件中定义,比如MX6UL_PAD_UART1_CTS_B引脚所有可复用的引脚宏定义如下:
宏定义所给出的5个值的意义为:
<mux_reg conf_reg input_reg mux_mode input_val>
- mux_reg:引脚复用寄存器
- conf_reg:引脚电气属性寄存器
- input_reg:输入寄存器,偏移为0表示没有
- mux_mode:引脚复用模式
- input_val:输入寄存器的值
引脚电气属性寄存器的值在宏定义之后,比如 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 的电气属性配置为0x17059。
三、pinctrl驱动大概实现框架
1. 如何找到imx6ull对应的pinctrl子系统驱动
驱动是根据设备树节点的兼容性(compatible)来匹配驱动。
imx6ull.dtsi描述文件中,iomucx的兼容性如图:
在内核源码中全局搜索该兼容性字符串,寻找对应驱动:
找到驱动文件为:drivers/pinctrl/freescale/pinctrl-imx6ul.c。
2. 驱动模块的加载与卸载
该驱动模块的加载与卸载函数如下:
3. 平台驱动结构体
在驱动模块入口中,调用platform_driver_register
API来注册一个平台设备驱动,注册的驱动结构体如下:
4. 驱动probe挂载函数
驱动probe挂载函数实现如下:
底层再调用imx的pinctrl probe函数,该函数实现在drivers/pinctrl/freescale/pinctrl-imx.c
文件中,其中会设置这样一组ops操作函数:
操作函数的定义如下:
其中 imx_pinconf_set 函数就会去操作底层寄存器完成引脚复用功能设置和电气属性设置:
5. 驱动remove移除函数
驱动remove卸载函数如下: