07 pinctrl子系统
pinctrl子系统
pinctrl子系统的作用
- 获取设备树中 pin 的信息
- 设置 pin 的复用功能(在6ULL由IOUMXC寄存器控制)
- 设置 pin 的电气特性,比如上/下拉、速度、驱动能力等 (在6ULL由PAD寄存器控制)
相关寄存器
对于引脚的配置,不同平台通常不一样:

IMX6ULL使用IOMUXC(Input/Output Muliplexing Controller),和IOMUXC-SNVS寄存器实现引脚复用功能的设置、使用每个GPIO的PAD寄存器进行引脚电气属性的设置
- IOMUXC和IOMUXC-SNVS的区别主要在于配置的引脚所属的电源域,前者控制主电源域的引脚,而后者控制SNVS这个独立的电源域的引脚(该电源域用于在系统休眠时维持部分功能)
- 同一个引脚只能由一个引脚配置模块来配置
使用方法
pinctrl子系统的使用通常遵循以下步骤:
1.定义引脚控制组:节点的名字一般以grp结尾
1 | &iomuxc { |
pinctrl节点需要写在对应的引脚控制器(iomux)节点下LED的
MX6UL_PAD_GPIO1_IO03__GPIO1_IO03表示复用为GPIO1,实际是设置了GPIO的SW_MUX_CTL寄存器的值- 芯片的各种复用信息定义在Linux内核源码的
"arch/arm/boot/dts/imx6ull-pinfunc.h"中
- 芯片的各种复用信息定义在Linux内核源码的
0x10B0表示该pin的电气属性,实际是控制GPIO的SW_PAD_CTL寄存器- 具体是什么意思看I.MX6ULL的参考手册


| 位域 | 字段名 | 功能 | 选项值 |
|---|---|---|---|
| 16 | HYS |
施密特触发使能 | 0: 禁用,1: 使能(增强抗噪) |
| 15-14 | PUS |
上下拉电阻配置 | 00: 100K下拉,01: 47K上拉,10: 100K上拉,11: 22K上拉 |
| 13 | PUE |
上下拉/保持器选择 | 0: Keeper功能,1: 上下拉功能 |
| 12 | PKE |
上下拉/保持器使能 | 0: 禁用,1: 使能 |
| 11 | ODE |
开漏输出使能 | 0: 推挽输出,1: 开漏输出 |
| 10-8 | 保留 | 未使用 | - |
| 7-6 | SPEED |
信号带宽 | 00: 50MHz,01/10: 100MHz,11: 200MHz |
| 5-3 | DSE |
驱动强度 | 000: 禁用,001: R0(260Ω@3.3V),010: R0/2,… 111: R0/7 |
| 2-1 | 保留 | 未使用 | - |
| 0 | SRE |
压摆率控制 | 0: 慢压摆率(低EMI),1: 快压摆率(高速信号 |
设备树里的pinctrl写的都是16进制,要先转成2进制再分析
PAD寄存器不能设置输出还是输入,得在驱动代码里通过GPIOx_GDIR寄存器设置
PUS、PUE、PKE这三个选项确实存在明确的依赖关系:
根据文档内容,PUS、PUE、PKE这三个选项确实存在明确的依赖关系,它们共同构成了上拉/下拉电阻的配置逻辑:
- PKE(Pull/Keeper Enable)- 使能控制(位12)
- 首要开关:必须先将PKE设置为”1”(Enabled),PUS和PUE的配置才会生效
- 禁用状态:当PKE=”0”时,无论PUS和PUE设置什么值,上拉/下拉功能都会被禁用
- PUE(Pull Up/Down Select)- 模式选择(位13)
- 功能选择:在PKE=”1”的前提下,PUE决定使用哪种模式:
- PUE=0:Keeper模式(保持器功能)
- PUE=1:Pull模式(上拉/下拉电阻功能)
- PUS(Pull Up Select)- 电阻值选择(位15-14)
- 仅在Pull模式下有效:只有当PKE=”1”且PUE=”1”时,PUS的配置才有意义
- 只有输入模式才需要配置上下拉,输出模式不需要!输出模式得在驱动通过
gpio_set_value设置电平- pinctrl里本质是修改PAD_CTRL和IOMUCX_CTRL这2个寄存器,而GPIO的输入输出由GPIO_CTRL寄存器控制,也就是说设备树里通过pinctrl没法直接控制输入/输出以及高低电平
- 设备树里可以通过中断或者
gpio-hog机制间接控制输入/输出以及高低电平
2.在设备节点中引用引脚控制组:通过pinctrl-names 和 pinctrl-* 关联引脚组:
1 | &usdhc2 { |
pinctrl-names的长度需要和和pinctrl-*一致pinctrl-*并不代表该设备用到了几个不同的引脚,而是该设备用到的引脚可以配置成几种不同的状态。比如上面这个例子,usb可以配置成3个速度,所以为这3个状态各创建了一个pinctrl节点- 驱动层有API可以根据
pinctrl-names切换引脚到不同的状态(pinctrl-*)
注意事项
1.如果一个设备确实用到了多个不同的引脚,要么把这些引脚全部写在一个引脚控制组里面,比如这样
1 | pinctrl_uart1_sleep: uart1_sleep_grp { |
要么就写多个引脚控制组,但在使用的时候,写到设备节点的一个pinctrl-*里面
1 | &my_device { |
2.写完设备树后要进行冲突检查:
- 同一个引脚不能同时配置成多个状态
- 多个设备不能同时使用一个引脚,需要分时复用(设置
status属性)
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.



