前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >04_Pinctrl子系统主要数据结构

04_Pinctrl子系统主要数据结构

作者头像
韦东山
发布2021-12-08 11:04:12
6660
发布2021-12-08 11:04:12
举报
文章被收录于专栏:韦东山嵌入式韦东山嵌入式

资料下载

coding无法使用浏览器打开,必须用git工具下载:

代码语言:javascript
复制
git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git

视频观看

百问网驱动大全

Pinctrl子系统主要数据结构

参考资料:

  • Linux 5.x内核
    • Documentation\devicetree\bindings\pinctrl\pinctrl-bindings.txt
    • arch/arm/boot/dts/stm32mp151.dtsi
    • arch/arm/boot/dts/stm32mp157-100ask-pinctrl.dtsi
    • arch/arm/boot/dts/stm32mp15xx-100ask.dtsi
    • drivers\pinctrl\stm32\pinctrl-stm32mp157.c
    • drivers\pinctrl\stm32\pinctrl-stm32.c
  • Linux 4.x内核文档
    • Documentation\pinctrl.txt
    • Documentation\devicetree\bindings\pinctrl\pinctrl-bindings.txt
    • arch/arm/boot/dts/imx6ull-14x14-evk.dts
    • arch/arm/boot/dts/100ask_imx6ull-14x14.dts
    • drivers\pinctrl\freescale\pinctrl-imx6ul.c
    • drivers\pinctrl\freescale\pinctrl-imx.c

1. 设备树

1.1 理想模型
在这里插入图片描述
在这里插入图片描述
1.2 实际的例子
  • IMX6ULL
在这里插入图片描述
在这里插入图片描述
  • STM32MP157
在这里插入图片描述
在这里插入图片描述

2. pincontroller的数据结构

记住pinctrl的三大作用,有助于理解所涉及的数据结构:

  • 引脚枚举与命名(Enumerating and naming)
  • 引脚复用(Multiplexing):比如用作GPIO、I2C或其他功能
  • 引脚配置(Configuration):比如上拉、下来、open drain、驱动强度等
2.1 pinctrl_desc和pinctrl_dev
1. 结构体引入

pincontroller虽然是一个软件的概念,但是它背后是有硬件支持的,所以可以使用一个结构体来表示它:pinctrl_dev。

怎么构造出pinctrl_dev?我们只需要描述它:提供一个pinctrl_desc,然后调用pinctrl_register就可以:

代码语言:javascript
复制
struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
				    struct device *dev, void *driver_data);

怎么使用pinctrl_desc、pinctrl_dev来描述一个pin controller?这两个结构体定义如下:

在这里插入图片描述
在这里插入图片描述

pinctrl_desc示例如下:

在这里插入图片描述
在这里插入图片描述
2. 作用1:描述、获得引脚

使用结构体pinctrl_pin_desc来描述一个引脚,一个pin controller有多个引脚:

在这里插入图片描述
在这里插入图片描述

使用pinctrl_ops来操作引脚,主要功能有二:

  • 来取出某组的引脚:get_groups_count、get_group_pins
  • 处理设备树中pin controller中的某个节点:dt_node_to_map,把device_node转换为一系列的pinctrl_map
在这里插入图片描述
在这里插入图片描述
3. 作用2:引脚复用
在这里插入图片描述
在这里插入图片描述
4. 作用3:引脚配置
在这里插入图片描述
在这里插入图片描述
5. 使用pinctrl_desc注册得到pinctrl_dev

调用devm_pinctrl_register或pinctrl_register,就可以根据pinctrl_desc构造出pinctrl_dev,并且把pinctrl_dev放入链表:

代码语言:javascript
复制
devm_pinctrl_register
    pinctrl_register
    	struct pinctrl_dev *pctldev;
		pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL);

		pctldev->owner = pctldesc->owner;
		pctldev->desc = pctldesc;
		pctldev->driver_data = driver_data;

		/* check core ops for sanity */
		ret = pinctrl_check_ops(pctldev);

		/* If we're implementing pinmuxing, check the ops for sanity */
		ret = pinmux_check_ops(pctldev);

		/* If we're implementing pinconfig, check the ops for sanity */
		ret = pinconf_check_ops(pctldev);

		/* Register all the pins */
		ret = pinctrl_register_pins(pctldev, pctldesc->pins, pctldesc->npins);

		list_add_tail(&pctldev->node, &pinctrldev_list);

3. client的数据结构

在设备树中,使用pinctrl时格式如下:

代码语言:javascript
复制
/* For a client device requiring named states */
device {
    pinctrl-names = "active", "idle";
    pinctrl-0 = <&state_0_node_a>;
    pinctrl-1 = <&state_1_node_a &state_1_node_b>;
};

设备节点要么被转换为platform_device,或者其他结构体(比如i2c_client),但是里面都会有一个device结构体,比如:

在这里插入图片描述
在这里插入图片描述
3.1 dev_pin_info

每个device结构体里都有一个dev_pin_info结构体,用来保存设备的pinctrl信息:

在这里插入图片描述
在这里插入图片描述
3.2 pinctrl

假设芯片上有多个pin controller,那么这个设备使用哪个pin controller?

这需要通过设备树来确定:

  • 分析设备树,找到pin controller
  • 对于每个状态,比如default、init,去分析pin controller中的设备树节点
    • 使用pin controller的pinctrl_ops.dt_node_to_map来处理设备树的pinctrl节点信息,得到一系列的pinctrl_map
    • 这些pinctrl_map放在pinctrl.dt_maps链表中
    • 每个pinctrl_map都被转换为pinctrl_setting,放在对应的pinctrl_state.settings链表中
在这里插入图片描述
在这里插入图片描述
3.3 pinctrl_map和pinctrl_setting

设备引用pin controller中的某个节点时,这个节点会被转换为一些列的pinctrl_map:

  • 转换为多少个pinctrl_map,完全由具体的驱动决定
  • 每个pinctrl_map,又被转换为一个pinctrl_setting
  • 举例,设备节点里有:pinctrl-0 = <&state_0_node_a>
    • pinctrl-0对应一个状态,会得到一个pinctrl_state
    • state_0_node_a节点被解析为一系列的pinctrl_map
    • 这一系列的pinctrl_map被转换为一系列的pinctrl_setting
    • 这些pinctrl_setting被放入pinctrl_state的settings链表
在这里插入图片描述
在这里插入图片描述

4. 使用pinctrl_setting

调用过程:

代码语言:javascript
复制
really_probe
	pinctrl_bind_pins
		pinctrl_select_state
			/* Apply all the settings for the new state */
			list_for_each_entry(setting, &state->settings, node) {
				switch (setting->type) {
				case PIN_MAP_TYPE_MUX_GROUP:
					ret = pinmux_enable_setting(setting);
							ret = ops->set_mux(...);
				break;
				case PIN_MAP_TYPE_CONFIGS_PIN:
				case PIN_MAP_TYPE_CONFIGS_GROUP:
					ret = pinconf_apply_setting(setting);
							ret = ops->pin_config_group_set(...);
					break;
				default:
					ret = -EINVAL;
				break;
			}		
代码语言:javascript
复制
		case PIN_MAP_TYPE_CONFIGS_GROUP:
				ret = pinconf_apply_setting(setting);
						ret = ops->pin_config_group_set(...);
				break;
			default:
				ret = -EINVAL;
			break;
		}		
代码语言:javascript
复制
![在这里插入图片描述](https://img-blog.csdnimg.cn/94254633e52d4b7e8e664ca77a4e158d.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3RoaXN3YXlfZGl5,size_16,color_FFFFFF,t_70)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-08-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资料下载
  • 视频观看
  • Pinctrl子系统主要数据结构
    • 1. 设备树
      • 1.1 理想模型
      • 1.2 实际的例子
    • 2. pincontroller的数据结构
      • 2.1 pinctrl_desc和pinctrl_dev
    • 3. client的数据结构
      • 3.1 dev_pin_info
      • 3.2 pinctrl
      • 3.3 pinctrl_map和pinctrl_setting
    • 4. 使用pinctrl_setting
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档