参考资料:
芯片内部有很多控制器 gpio i2c uart 然后他们都需要有引脚才能与外部交流,而芯片也有很多引脚 pin,然后这些 pin 是独立的,这些 pin连接到哪一个控制器(外设)上,就需要中间有一个 pin controller 子系统来管理,而这个 pin controller 子系统 这是软件上抽象的一个概念,其主要功能在下面介绍。
Pinctrl:Pin Controller,顾名思义,就是用来控制引脚的:
Pinctrl驱动由芯片厂家的BSP工程师提供,一般的驱动工程师只需要在设备树里:
在一般的设备驱动程序里,甚至可以没有pinctrl的代码。
对于一般的驱动工程师,只需要知道“怎么使用pinctrl”即可。
基于使用的角度驱动工程师要掌握的Pinctrl重要概念
Pinctrl子系统使用示例
主要数据结构与调试方法
pincontroller的数据结构构造过程情景分析(会拆分为很多节)
client端的数据结构构造过程情景分析(会拆分为很多节)
编写一个虚拟的pincontroller驱动程序
这是透明的,我们的驱动基本不用管。当设备切换状态时,对应的pinctrl就会被调用。
比如在platform_device和platform_driver的枚举过程中,流程如下:
当系统休眠时,也会去设置该设备sleep状态对应的引脚,不需要我们自己去调用代码。
非要自己调用,也有函数:
devm_pinctrl_get_select_default(struct device *dev); // 使用"default"状态的引脚
pinctrl_get_select(struct device *dev, const char *name); // 根据name选择某种状态的引脚
pinctrl_put(struct pinctrl *p); // 不再使用, 退出时调用
参考资料:
以I2C为例:
生成pincontroller设备树信息,有3中方法:
对于IMX6ULL,有引脚配置工具/设备树生成工具:
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&BOARD_InitPins>;
imx6ull-board {
i2c1_pins: i2c1_pins { /*!< Function assigned for the core: Cortex-A7[ca7] */
fsl,pins = <
MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x000018B0
MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x000018B0
>;
};
};
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
status = "okay";
};
这是透明的,我们的驱动基本不用管。当设备切换状态时,对应的pinctrl就会被调用。
比如在platform_device和platform_driver的枚举过程中,流程如下: