一文搞懂 | Linux pinctrl/gpio子系统

💡 原文中文,约12600字,阅读约需30分钟。
📝

内容提要

本文介绍了pinctrl子系统和gpio子系统在内核中的应用,包括引脚控制器的抽象、pin groups的功能实现、pin configuration的配置、pin mux的操作、pinctrl driver的信息收集,以及gpio子系统的GPIO控制器和引脚表示、设备树中的配置、gpio ranges的转换和pinctrl core的接口申请。

🔎

延伸解读

pinctrl与gpio的层次关系

文章指出,pinctrl子系统管理所有管脚,而GPIO只是管脚的一种用途。因此,GPIO子系统在申请管脚时,需要向pinctrl子系统请求,并将管脚配置为GPIO功能。这种设计意味着GPIO驱动不能绕过pinctrl直接操作硬件,必须通过pinctrl core提供的接口(如pinctrl_request_gpio)进行协调。理解这一点有助于在驱动开发中正确处理资源申请和功能复用。

设备树中的状态与映射机制

在设备树中,pinctrl驱动为每个设备定义多种pin state(如default、sleep),consumer驱动通过pinctrl-names和pinctrl-x引用这些状态。pinctrl core在初始化时解析设备树,将状态信息转换为pin map,供驱动调用pinctrl_select_state时使用。这种机制将硬件配置与驱动逻辑分离,使得同一驱动可以适配不同板级的引脚配置,提高了代码的可移植性。

GPIO子系统的两套接口与资源管理

GPIO子系统提供基于描述符(gpiod_前缀)和老式(gpio_前缀)两套接口。文章建议使用devm_版本的函数,因为其自动释放资源的机制可以简化错误处理。例如,在申请GPIO后若后续内存申请失败,使用devm函数可以避免手动释放GPIO,减少资源泄漏风险。这反映了内核驱动开发中资源管理的最佳实践。

gpio ranges的转换作用

pinctrl子系统维护gpio number到pin number的映射(gpio ranges)。当GPIO驱动调用pinctrl_request_gpio时,pinctrl core会查找gpio ranges链表,将GPIO编号转换为对应的pin编号,然后调用pinmux_ops中的回调函数(如gpio_request_enable)来申请管脚。这一转换机制确保了GPIO子系统与pinctrl子系统之间的正确对接,是两者耦合的关键环节。

❓

Q&A

pinctrl子系统的主要功能是什么?

pinctrl子系统主要用于管理引脚控制器,提供引脚的抽象、配置和复用功能。

GPIO子系统如何表示和控制引脚?

GPIO子系统通过gpio_device和gpio_chip结构体来表示和控制GPIO引脚。

如何在设备树中配置GPIO控制器?

在设备树中,GPIO控制器通过节点定义,使用属性引用特定引脚,并指定GPIO组和引脚的有效电平。

pinctrl driver在初始化时需要注册哪些操作函数?

pinctrl driver在初始化时需要注册三类操作函数:pctlops、pmxops和confops。

pin mux的作用是什么?

pin mux允许引脚配置为不同功能,以适应不同的应用场景,如将引脚配置为GPIO或I2C功能。

如何使用GPIO子系统的devm版本函数?

建议使用devm版本的函数以自动管理资源,确保在设备销毁时自动释放已申请的GPIO资源。

🏷️

标签

➡️

继续阅读