Pinctrl 与 GPIO 子系统
从 IOMUXC 引脚复用到 pinctrl/gpio 子系统,掌握 Linux 引脚管理的标准方式
版本说明
本教程基于以下内核版本:
- linux-imx 6.12.49 推荐
- mainline 7.1.0 进阶
学习路径
本教程从 i.MX6ULL 的 IOMUXC 硬件原理讲起,逐步拆解 pinctrl(引脚复用/电气配置)和 gpio(电平读写)两大子系统,最后落到驱动实现与 imx/mainline 双轨对比。
🎯 推荐学习路径
阶段一:硬件基础
- 01_introduction - 为什么需要 pinctrl/gpio 子系统
- 02_hardware_foundation - IOMUXC 与引脚复用原理
阶段二:pinctrl 子系统
- 03_pinctrl_subsystem_arch - pinctrl 子系统架构
- 04_pinctrl_device_tree - pinctrl 设备树绑定
阶段三:gpio 子系统
- 05_gpio_subsystem_arch - gpio 子系统架构
- 06_gpio_device_tree - gpio 设备树绑定
阶段四:驱动实战
- 07_driver_implementation - 驱动实现
- 08_build_and_test - 编译测试与验证
- 09_kernel_comparison - imx 与 mainline 对比
章节目录
学习目标
理解 pinctrl 与 gpio 两大子系统的分工:pinctrl 负责引脚复用与电气配置(IOMUXC),gpio 负责电平读写与中断。学会用设备树描述引脚(pinctrl 节点 + gpio 属性),用 gpiod_get() / gpiod_direction_output() 等 Descriptor API 操作硬件,告别直接读写寄存器。
前置知识
- 字符设备驱动基础
- 设备树基本语法(见 01_device_tree_base)
- i.MX6ULL 内存映射 IO 概念
延伸阅读
- Pinctrl 子系统文档
- GPIO Descriptor API
- i.MX6ULL IOMUXC 寄存器见 参考资源索引
常见问题
Q: pinctrl 和 gpio 子系统什么关系?
A: 分工不同。pinctrl 管引脚"干什么用"——复用成 GPIO / I2C / UART 还是其他功能,以及上下拉、驱动强度等电气配置;gpio 管引脚"作为 GPIO 时"的电平读写和中断。一个引脚先经 pinctrl 配成 GPIO 功能,再由 gpio 子系统操作。
Q: mainline 为什么删了 of_gpio.h 旧 API?
A: 主线推动 GPIO Descriptor API(gpiod_*),旧的 of_get_gpio() 返回全局 GPIO 号的 number-based API 被废弃。imx 内核还保留旧头文件,所以同一份驱动在 imx 能编、mainline 编不过。本项目已统一迁移到 gpiod API,详见 09_kernel_comparison。
Q: MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 这个宏是什么?
A: 它展开成 5 个整数:mux_reg conf_reg input_reg mux_val input_val,告诉 pinctrl 把某个 PAD 的复用寄存器和配置寄存器写成特定值。由内核 arch/arm/boot/dts/nxp/imx/imx6ul-pinfunc.h 定义。