前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >09_GPIO子系统与Pinctrl子系统的交互

09_GPIO子系统与Pinctrl子系统的交互

作者头像
韦东山
发布2021-12-08 10:09:35
8660
发布2021-12-08 10:09:35
举报
文章被收录于专栏:韦东山嵌入式

资料下载

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

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

视频观看

百问网驱动大全

GPIO子系统与Pinctrl子系统的交互

参考资料:

  • Linux 5.x内核文档
    • Linux-5.4\Documentation\driver-api
    • Linux-5.4\Documentation\devicetree\bindings\gpio\gpio.txt
    • Linux-5.4\drivers\gpio\gpio-74x164.c
  • Linux 4.x内核文档
    • Linux-4.9.88\Documentation\gpio
    • Linux-4.9.88\Documentation\devicetree\bindings\gpio\gpio.txt
    • Linux-4.9.88\drivers\gpio\gpio-74x164.c

1. 使用GPIO前应该设置Pinctrl

假设使用这个虚拟的GPIO Controller的pinA来控制LED:

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

要使用pinA来控制LED,首先要通过Pinctrl子系统把它设置为GPIO功能,然后才能设置它为输出引脚、设置它的输出值。

所以在设备树文件里,应该添加Pinctrl的内容:

代码语言:javascript
复制
virtual_pincontroller {
	compatible = "100ask,virtual_pinctrl";
	myled_pin: myled_pin {
			functions = "gpio";
			groups = "pin0";
			configs = <0x11223344>;
	};
};

gpio_virt: virtual_gpiocontroller {
	compatible = "100ask,virtual_gpio";
    gpio-controller;
    #gpio-cells = <2>;
    ngpios = <4>;
};

myled {
	compatible = "100ask,leddrv";
	led-gpios = <&gpio_virt 0 GPIO_ACTIVE_LOW>;
	pinctrl-names = "default";
	pinctrl-0 = <&myled_pin>;	
};

但是很多芯片,并不要求在设备树中把把引脚复用为GPIO功能。

比如STM32MP157,在它的设备树工具STM32CubeMX即使把引脚配置为GPIO功能,它也不会在设备树中出现。

原因在于:GPIO走了后门。

现实的芯片中,并没有Pinctrl这样的硬件,它的功能大部分是在GPIO模块中实现的。

Pinctrl是一个软件虚拟处理的概念,它的实现本来就跟GPIO密切相关。

甚至一些引脚默认就是GPIO功能。

按理说:

一个引脚可能被用作GPIO,也可能被用作I2C,GPIO和I2C这些功能时相同低位的。

要用作GPIO,需要先通过Pinctrl把引脚复用为GPIO功能。

但是Pinctrl和GPIO关系密切,当你使用gpiod_get获得GPIO引脚时,它就偷偷地通过Pinctrl把引脚复用为GPIO功能了。

2. GPIO和Pinctrl的映射关系

2.1 示例
在这里插入图片描述
在这里插入图片描述

从上图可知:

  • 左边的Pinctrl支持8个引脚,在Pinctrl的内部编号为0~7
  • 图中有2个GPIO控制器
    • GPIO0内部引脚编号为03,假设在GPIO子系统中全局编号为100103
    • GPIO1内部引脚编号为03,假设在GPIO子系统中全局编号为104107
  • 假设我们要使用pin1_1,应该这样做:
    • 根据GPIO1的内部编号1,可以换算为Pinctrl子系统中的编号5
    • 使用Pinctrl的函数,把第5个引脚配置为GPIO功能
2.2 数据结构
在这里插入图片描述
在这里插入图片描述

3. GPIO调用Pinctrl的过程

GPIO子系统中的request函数,用来申请某个GPIO引脚,

它会导致Pinctrl子系统中的这2个函数之一被调用:pmxops->gpio_request_enablepmxops->request

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

调用关系如下:

代码语言:javascript
复制
gpiod_get
    gpiod_get_index
    	desc = of_find_gpio(dev, con_id, idx, &lookupflags);
		ret = gpiod_request(desc, con_id ? con_id : devname);
					ret = gpiod_request_commit(desc, label);
								if (chip->request) {
                                    ret = chip->request(chip, offset);
                                }

我们编写GPIO驱动程序时,所设置chip->request函数,一般直接调用gpiochip_generic_request,它导致Pinctrl把引脚复用为GPIO功能。

代码语言:javascript
复制
gpiochip_generic_request(struct gpio_chip *chip, unsigned offset)
    pinctrl_request_gpio(chip->gpiodev->base + offset)
		ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); // gpio是引脚的全局编号

		/* Convert to the pin controllers number space */
		pin = gpio_to_pin(range, gpio);
    	
		ret = pinmux_request_gpio(pctldev, range, pin, gpio);
					ret = pin_request(pctldev, pin, owner, range);

Pinctrl子系统中的pin_request函数就会把引脚配置为GPIO功能:

代码语言:javascript
复制
static int pin_request(struct pinctrl_dev *pctldev,
		       int pin, const char *owner,
		       struct pinctrl_gpio_range *gpio_range)
{
    const struct pinmux_ops *ops = pctldev->desc->pmxops;
    
	/*
	 * If there is no kind of request function for the pin we just assume
	 * we got it by default and proceed.
	 */
	if (gpio_range && ops->gpio_request_enable)
		/* This requests and enables a single GPIO pin */
		status = ops->gpio_request_enable(pctldev, gpio_range, pin);
	else if (ops->request)
		status = ops->request(pctldev, pin);
	else
		status = 0;
}

3. 我们要做什么

如果不想在使用GPIO引脚时,在设备树中设置Pinctrl信息,

如果想让GPIO和Pinctrl之间建立联系,

我们需要做这些事情:

3.1 表明GPIO和Pinctrl间的联系

在GPIO设备树中使用gpio-ranges来描述它们之间的联系:

3.2 解析这些联系

在GPIO驱动程序中,解析跟Pinctrl之间的联系:处理gpio-ranges:

3.3 编程
3.3 编程
  • 在GPIO驱动程序中,提供gpio_chip->request
  • 在Pinctrl驱动程序中,提供pmxops->gpio_request_enablepmxops->request
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/08/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 资料下载
  • 视频观看
  • GPIO子系统与Pinctrl子系统的交互
    • 1. 使用GPIO前应该设置Pinctrl
      • 2. GPIO和Pinctrl的映射关系
        • 2.1 示例
        • 2.2 数据结构
      • 3. GPIO调用Pinctrl的过程
        • 3. 我们要做什么
          • 3.1 表明GPIO和Pinctrl间的联系
          • 3.2 解析这些联系
          • 3.3 编程
          • 3.3 编程
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档