1.先举个例子
1 、添加 pinctrl 节点
iomuxc 节点就是 I.MX6ULL 的 IOMUXC 外设对应的节点
imx6ull.dtsi
iomuxc: iomuxc@020e0000 {
compatible = "fsl,imx6ul-iomuxc";
reg = <0x020e0000 0x4000>;
}
imx6ull.dts 根节点下
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-names = "default";
imx6ul-evk {
pinctrl_led: ledgrp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0 /* LED0 */
>;
};
....
}
arch/arm/boot/dts/imx6ul-pinfunc.h文件
#define MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x0068 0x02F4 0x05A8 0x0 0x1
#define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3 0x0068 0x02F4 0x0000 0x1 0x0
#define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC 0x0068 0x02F4 0x0660 0x2 0x0
#define MX6UL_PAD_GPIO1_IO03__REF_CLK_32K 0x0068 0x02F4 0x0000 0x3 0x0
#define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B 0x0068 0x02F4 0x0668 0x4 0x0
#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x0068 0x02F4 0x0000 0x5 0x0
#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_EXT_CLK 0x0068 0x02F4 0x0000 0x6 0x0
#define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK 0x0068 0x02F4 0x0000 0x7 0x0
#define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX 0x0068 0x02F4 0x0624 0x8 0x1
#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX 0x0068 0x02F4 0x0000 0x8 0x0
IOMUX概念引出
1.IOMUX概念
IOMUX概念的引出:SOC厂商为了推出功能丰富的核心板,以应对不同市场不同用户的需求,引入了引脚复用-IOMUXC架构。
IOMUX架构:输入输出多路复用器(Input/Output Multiplexer ),说白了就是用有限的引脚资源实现尽可能多的功能,每个引脚最多可复用好几种功能,每个功能又可以出现在不同的引脚上。
2.IOMUX引脚功能配置方法
IOMUX引脚功能配置,主要是对SOC芯片中IOMUXC控制器中的各寄存器作相应参数配置。
控制器中的寄存器主要分为三大类:
IOMUXC_SW_PAD_CTRL_X - 管脚控制寄存器
IOMUXC_SW_MUX_CTL_PAD_X - 输出路由寄存器
IOMUXC_X_SELECT_INPUT - 输入路由寄存器
在Linux内核中,我们定义引脚时,会用到以下6个参数,分别是:
_pad_ctrl_ofs - 控制寄存器的偏移地址(16进制)
_mux_ctrl_ofs - MUX控制寄存器的偏移地址(16进制),用于选择引脚的功能
_mux_mode - MUX模式,bit03,范围07
_select_input_ofs - SELECT_INPUT寄存器偏移地址(16进制)
_select_input - Daisy Chain模式,bit01,范围03
_pad_ctrl - 引脚控制寄存器
关于前5个参数的配置方法,网上有很多文档讲的很好,很细致。而且在Linux内核的dtb目录中,SOC厂商已经把各功能引脚的这五个参数的值写到了相应的宏定义头文件(xxx-pinfunc.h)中,直接查看即可,无需更改。
对应关系,如下例所示:
0x0068 | 0x02F4 | 0x5 | 0x0000 | 0x0 |
---|---|---|---|---|
mux_ctrl_ofs | pad_ctrl_ofs | sel_input_ofs | mux_mode | sel_input |
此图包含了 _pad_ctrl_ofs 和 _pad_ctrl_ofs 的值_select_input_ofs
这里主要讲最后一个参数如何确定,因为最后一个参数往往需要我们自己在设备树-dtb中添加或修改。
_PAD_CTRL的确定:
首先,要有soc芯片厂商提供的芯片使用手册。
0x10B0 就是 conf_reg 寄存器值!此值由用户自行设置,通
过此值来设置一个 IO 的上/下拉、驱动能力和速度等。在这里就相当于设置寄存器
IOMUXC_SW_PAD_CTL_PAD_UART1_RTS_B 的值为 0x10B0 。
其次,翻阅到IOMUXC章节,找到对应引脚功能的MUX_PAD_CTRL寄存器,根据手册说明确定其值即可。
比如,我在xxx-pinfunc.h头文件中,查到A引脚可做GPIO1_IO01使用,那么我就在IOMUXC章节中搜索包括GPIO1_IO01和PAD_CTRL的寄存器即可。
若搜索不到,可以在External Signals and Pin Multiplexing章节搜索GPIO1_IO01,看看他被哪个功能名称所替代,然后再用那个功能名称去IOMUXC章节搜索即可。
最后,在设备树的dtb中的iomux部分,添加该功能引脚定义即可。
IOMUX的寄存器配置是通过物理地址->总线地址一
一映射到复用控制器上的,将物理地址的参数值传递给挂载在总线的IOMUXC控制寄存器上,也就是引脚功能配置最终是靠IOMUXC控制器来完成。
引脚配置完成后,还需要配置具体功能的控制器里寄存器参数,这样才能共同完成引脚的功能确定。IOMUX只起了一个功能切换的作用。
Pinctrl是一种硬件抽象层,它允许驱动程序通过配置引脚的电平、输入/输出、时钟等属性来控制硬件设备的行为。