目录
2.2.7. 可选的电源管理状态(sleep 和 idle)
阅读引言:
pinctrl子系统顾名思义就是引脚控制的意思, 如下图一个Soc芯片有很多的引脚, 那大家有没有想过,我们在写驱动的时候, 是直接调用的一些接口比如设置gpio的电气属性,使用i2c总线就行数据的发送和接收等,这个时候,其实有些引脚是有复用关系的。那么linux是什么时候将我们需要使用的引脚设置为gpio功能, i2c功能的呢? 这个问题就是本文需要解决的疑问。
一、PinCtrl子系统的定义
PinCtrl子系统(Pin Controller子系统)是Linux内核中的一个重要组件,用于管理和配置芯片引脚的功能和电气特性。其主要功能和作用包括以下几个方面。
-
引脚枚举与命名:在系统初始化时,PinCtrl子系统会枚举所有可以控制的引脚,并为每个引脚分配一个唯一的编号。
-
引脚复用管理:PinCtrl子系统允许将引脚配置为不同的功能,例如GPIO、I2C、SPI、UART等。一个引脚可以根据需要在不同功能之间切换。
-
电气特性配置:PinCtrl子系统可以配置引脚的电气特性,例如上拉/下拉电阻、驱动能力、开漏等。
-
引脚状态管理:PinCtrl子系统通过“引脚状态”(Pin State)的概念,管理设备在不同工作状态下的引脚配置。例如,设备在默认状态、睡眠状态或空闲状态下可以有不同的引脚配置。
-
设备树支持:PinCtrl子系统通过设备树(Device Tree)获取引脚配置信息,从而实现硬件与软件的解耦。设备驱动可以通过设备树声明所需的引脚配置,PinCtrl子系统负责解析并应用这些配置。
-
与GPIO子系统的协同:PinCtrl子系统与GPIO子系统紧密协作,负责引脚的功能复用和电气配置,而GPIO子系统则专注于GPIO的输入输出控制。
PinCtrl子系统的设计目标是提供一个统一的框架,让不同SoC平台的引脚管理更加灵活和高效,同时减少硬件平台之间的差异。
二、明确PinCtrl子系统和我们编写驱动的关系
PinCtrl子系统实现了Soc芯片引脚的管理、命名、编号, 以及各种配置的实现,配置引脚的复用功能, 设置引脚的电气属性等。这些内容都是芯片厂家的BSP驱动工程师实现好的,我们作为二级驱动开发人员, 只需要知道如何在设备树中指定和配置我们需要的功能。
pinctrl-0
pinctrl-names
设置这些节点主要使用和设备树中的这两个属性。比如这里的这个键盘的写法
在这个键盘的设备树节点中就指定了使用的状态, 和具体的哪一个配置。以上便是这个子系统的使用, 使用非常的简单, 我们只需要在设备树中添加子节点, 加上我们需要的引脚配置信息就能使用起来, 接下来我们将具体的分析PinCtrl子系统是如何设置引脚的具体功能的。
三、pinctrl_desc结构体引入
linux源码路径include\linux\pinctrl\pinctrl.h
其实, 各家厂商实现PInCtrl子系统就是在实现这个结构体, 然后注册, 后面我们会在分析,现在先说一说这个结构体的成员, 以及含义。
name: 引脚控制器的名字
pins: 具体某一个引脚的描述结构体指针, 到最后这儿其实指向一个描述整个芯片引脚的数组
pctlops: 操作引脚组的方法结构体指针
pmxops: 设置引脚复用功能的结构体指针
confops: 配置引脚电气属性的结构体指针
owner: 模块归属
struct pinctrl_pin_desc const *pins, 这个成员的原型如下:
const struct pinctrl_ops *pctlops成员的原型如下:
const struct pinmux_ops *pmxops成员的原型如下:
const struct pinconf_ops *confops成员结构体原型:
芯片厂家的BSP工程师其实在适配PinCtrl子系统的时候, 其实就是在实现这个结构体中的方法,以及结合自家的设备树的写法, 需要自己的编写从设备树中获得配置信息, 以便在驱动中使用。这个结构体就先介绍到这里, 大家对这个都系先有个印象。
四、PinCtrl子系统驱动实现分析
1.芯片厂家是如何实现PinCtrl子系统的
这里我们以瑞芯微3588为例,来大致看一下设置引脚复用的驱动是如何实现的。这是文件路径:linux-6.6.55\drivers\pinctrl\pinctrl-rockchip.c