本节演示,如何使用Pinctrl子系统配置I2C通信所使用的引脚,以IMX6ULL为例。
如下图所示,在芯片内部,有I2C模块。
怎么配置I2C模块?
答:
- 首先,要知道I2C模块会使用哪些引脚,这可以通过看原理图确定。
- 确定使用哪些引脚之后(假设使用pinA,pinB), 就可以配置IOMUX,选择引脚的功能了。
- 最后,就是配置(config)引脚了。
其中,第二步、第三步的配置,会作为一个类似下图的节点保存在设备树中。
然后,就可以通过类似下图所示的节点,来选择使用上图所示的节点,而不需要写额外的代码。
如下图所示,右边的节点由于格式是统一的,所以很容易构造,难点在于左边的节点,它没有统一的格式,往往不同平台之间的格式就大不相同。
如何构造Pinctrl节点?
那么,如何构造左边的节点呢?
答:可以通过以下三种方法:
- 工具(tool),对于一些芯片厂商,有提供对应的工具,用于生成这些引脚;
- 文档,或设备树示例;
- 源码(较困难);
对于imx6ull,他有提供一个工具(i.MX Pins Tool v6),可以生成对应的引脚配置信息。
使用方法也很简单,选中想要配置的引脚,然后选择要配置成哪种功能,然后点击完成,就会生成对应的配置信息。
开始配置I2C模块
看原理图获取引脚
首先,根据底板原理图获取使用到的引脚信息。
使用的是64,65号引脚。
然后,找到对应的管脚号是G16,G17。
选择引脚功能
然后,可以在工具上选择引脚的功能。
生成的设备树配置信息如下:
配置引脚
引脚功能选择完毕后,还可以配置引脚。
配置引脚后,可以看到节点配置信息也产生了变化。
可以推测,前面的宏是选择引脚的功能,后面的值则是引脚的配置值。
配置Client节点
此时,我们生成了Pinctrl节点,但是要怎么选择使用它呢?
&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
>;
};
};
};
参考内核设备树文件,内核的配置和使用如下:
所以,可以这样使用pinctrl:
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
status = "okay";
};
i2c1节点会转换成一个平台设备,通过i2c1节点的compatible属性,与对应的平台驱动进行匹配,匹配成功后会调用default的pinctrl,对引脚进行配置。