04、pinctrl 结构体
主要包含
struct dev_pin_info
//各个驱动模块来填充
pinctrl_dev
(给控制器使用)struct pinctrl_desc
//pinctrl 来填充(给控制器使用)struct pinctrl
//一个GPIO 复用的实例化(给客户端使用)struct pinctrl_state
//不同状态记录struct pinctrl_setting
//
一、dev_pin_info结构体
当系统启用 CONFIG_PINCTRL
配置时,设备结构体(struct device
)会包含一个 struct dev_pin_info
来管理引脚信息。以下是这个结构体各成员的简要说明:
struct dev_pin_info {
struct pinctrl *p; // 引脚控制器指针
struct pinctrl_state *default_state; // 默认状态
struct pinctrl_state *init_state; // 初始化状态
#ifdef CONFIG_PM
struct pinctrl_state *sleep_state; // 睡眠状态(仅支持电源管理时可用)
struct pinctrl_state *idle_state; // 空闲状态(仅支持电源管理时可用)
#endif
};
2
3
4
5
6
7
8
9
成员解释
struct pinctrl *p
指向设备使用的 引脚控制器对象,用于控制和配置设备的引脚。struct pinctrl_state *default_state
设备 正常工作时 的引脚配置状态(默认设置)。struct pinctrl_state *init_state
设备 初始化阶段 使用的引脚配置状态。struct pinctrl_state *sleep_state
设备 进入睡眠状态时 的引脚配置(仅当系统支持电源管理时可用)。struct pinctrl_state *idle_state
设备 空闲时 的引脚配置(仅当系统支持电源管理时可用)。
::: 总结:
核心功能:管理设备在不同状态下的引脚配置(如默认、初始化、睡眠、空闲)。
依赖条件:
sleep_state
和 idle_state
仅在启用 CONFIG_PM
(电源管理)时有效。
作用:通过不同状态的引脚配置,优化设备在不同场景下的性能和功耗。 :::
二、pinctrl_desc
pinctrl_desc 结构体定义在内核源码目录的“/include/linux/pinctrl/pinctrl.h” 文件中 :
struct pinctrl_desc {
const char *name; // 引脚控制器的名称
const struct pinctrl_pin_desc *pins; // 引脚描述符数组
unsigned int npins; // 引脚描述符数组的大小
const struct pinctrl_ops *pctlops; // 引脚控制操作函数指针
const struct pinmux_ops *pmxops; // 引脚复用操作函数指针
const struct pinconf_ops *confops; // 引脚配置操作函数指针
struct module *owner; // 拥有该结构体的模块
#ifdef CONFIG_GENERIC_PINCONF
unsigned int num_custom_params; // 自定义参数数量
const struct pinconf_generic_params *custom_params; // 自定义参数数组
const struct pin_config_item *custom_conf_items; // 自定义配置项数组
#endif
};
2
3
4
5
6
7
8
9
10
11
12
13
14
pinctrl_desc结构体用于描述硬件中的引脚控制器信息,帮助软件管理芯片引脚的功能。以下是各部分的简单说明:
名称(name) 字符串名称,用来标识这个引脚控制器,比如"gpio-controller-1"
引脚信息数组(pins) 存储所有引脚的详细信息列表,每个条目包含:
- 引脚编号(如GPIO1_3)
- 对应的物理管脚功能(如USB数据线或LED控制)
引脚数量(npins) 上面数组里包含的引脚总数,告诉系统有多少个引脚需要管理
基础操作接口(pctlops) 这个函数指针集合包含:
- 引脚基本操作(如初始化/复位)
- 控制引脚开关状态
- 管理引脚组的通用功能
复用功能接口(pmxops) 管理引脚多路复用功能的函数集合,比如:
- 将某个引脚从普通GPIO切换为SPI总线使用
- 设置引脚的工作模式(输入/输出/中断等)
配置接口(confops) 处理引脚详细配置的函数,例如:
- 设置上拉/下拉电阻
- 调整驱动强度(信号强度)
- 配置引脚电平翻转等特性
模块归属(owner) 标记这个结构体属于哪个内核模块,防止不同模块间冲突
(当支持自定义配置时) 8. 自定义参数(custom_params) 存储厂商特定的特殊配置项,比如:
- 特殊的信号边沿检测模式
- 高级电源管理设置
::: 这个结构体就像芯片引脚的"使用说明书",把硬件能做什么、怎么操作都告诉操作系统,让软件可以安全地控制每个引脚的功能。 :::
三、pinctrl_dev
struct pinctrl_dev {
struct list_head node;
struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree;
#ifdef CONFIG_GENERIC_PINCTRL_GROUPS
struct radix_tree_root pin_group_tree;
unsigned int num_groups;
#endif
#ifdef CONFIG_GENERIC_PINMUX_FUNCTIONS
struct radix_tree_root pin_function_tree;
unsigned int num_functions;
#endif
struct list_head gpio_ranges;
struct device *dev;
struct module *owner;
void *driver_data;
struct pinctrl *p;
struct pinctrl_state *hog_default;
struct pinctrl_state *hog_sleep;
struct mutex mutex;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
四、pinctrl
core.h
/**
* struct pinctrl - per-device pin control state holder
* @node: global list node
* @dev: the device using this pin control handle
* @states: a list of states for this device
* @state: the current state
* @dt_maps: the mapping table chunks dynamically parsed from device tree for
* this device, if any
* @users: reference count
*/
struct pinctrl {
struct list_head node;
struct device *dev;
struct list_head states;
struct pinctrl_state *state;
struct list_head dt_maps;
struct kref users;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
五、pinctrl_state
/**
* struct pinctrl_state - a pinctrl state for a device
* @node: list node for struct pinctrl's @states field
* @name: the name of this state
* @settings: a list of settings for this state
*/
struct pinctrl_state {
struct list_head node;
const char *name; // default、sleep、自定义
struct list_head settings;
};
2
3
4
5
6
7
8
9
10
11
六、pinctrl_setting
struct pinctrl_dev *pctldev; 会在probe中填充
/**
* struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP
* @group: the group selector to program
* @func: the function selector to program
*/
struct pinctrl_setting_mux {
unsigned group;
unsigned func;
};
/**
* struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_*
* @group_or_pin: the group selector or pin ID to program
* @configs: a pointer to an array of config parameters/values to program into
* hardware. Each individual pin controller defines the format and meaning
* of config parameters.
* @num_configs: the number of entries in array @configs
*/
struct pinctrl_setting_configs {
unsigned group_or_pin;
unsigned long *configs;
unsigned num_configs;
};
/**
* struct pinctrl_setting - an individual mux or config setting
* @node: list node for struct pinctrl_settings's @settings field
* @type: the type of setting
* @pctldev: pin control device handling to be programmed. Not used for
* PIN_MAP_TYPE_DUMMY_STATE.
* @dev_name: the name of the device using this state
* @data: Data specific to the setting type
*/
struct pinctrl_setting {
struct list_head node;
enum pinctrl_map_type type;
struct pinctrl_dev *pctldev;
const char *dev_name;
union {
struct pinctrl_setting_mux mux;
struct pinctrl_setting_configs configs;
} data;
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45