i.MX6ULL(十九) linux gpio子系统

一 简介

pinctrl 子系统重点是设置 PIN( 有的 SOC 叫做 PAD) 的复用 和电气属性,
如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话,那么接下来就要用到 gpio 子系 统了。gpio 子系统顾名思义,就是用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO
为输入输出,读取 GPIO 的值等。 gpio 子系统的主要目的就是方便驱动开发者使用 gpio ,驱动
开发者在设备树中添加 gpio 相关信息,然后就可以在驱动程序中使用 gpio 子系统提供的 API
函数来操作 GPIO Linux 内核向驱动开发者屏蔽掉了 GPIO 的设置过程,极大的方便了驱动开
发者使用 GPIO

1.1、设备树中的 gpio 信息

一种设备的节点属性设置都会有一些套路,查询内核中的文档,比如Documentation/devicetree/bindings/i2c/i2c-imx.txt就描述了imx平台的i2c属性设置方法
I.MX6ULL-ALPHA 开发板上的 UART1_RTS_B 做为 SD 卡的检测引脚, UART1_RTS_B
用为 GPIO1_IO19 ,通过读取这个 GPIO 的高低电平就可以知道 SD 卡有没有插入。 首先肯定是
UART1_RTS_B 这个 PIN 复用为 GPIO1_IO19 ,并且设置电气属性,也就是上一小节讲的
pinctrl 节点。打开 imx6ull-alientek-emmc.dts UART1_RTS_B 这个 PIN pincrtl 设置如下:

示例代码 45.2.2.1 SD 卡 CD 引脚 PIN 配置参数
316 pinctrl_hog_1: hoggrp-1 {
317 fsl,pins = <
318 MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
......
322 >;
323 };
pinctrl 配置好以后就是设置 gpio 了, SD 卡驱动程序通过读取 GPIO1_IO19 的值来判断 SD
卡有没有插入,但是 SD 卡驱动程序怎么知道 CD 引脚连接的 GPIO1_IO19 呢?肯定是需要设
备树告诉驱动啊!在设备树中 SD 卡节点下添加一个属性来描述 SD 卡的 CD 引脚就行了
 
示例代码 45.2.2.2 设备树中 SD 卡节点
760 &usdhc1 {
761 pinctrl-names = "default", "state_100mhz", "state_200mhz";
762 pinctrl-0 = <&pinctrl_usdhc1>;
763 pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
764 pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
765 /* pinctrl-3 = <&pinctrl_hog_1>; */
766 cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
767 keep-power-in-suspend;
768 enable-sdio-wakeup;
769 vmmc-supply = <®_sd1_vmmc>;
770 status = "okay";
771 };
cd - gpios = <& gpio1 19 GPIO_ACTIVE_LOW >;
属性“ cd-gpios ”描述了 SD 卡的 CD 引脚使用的哪个 IO 。属性值一共有三个,
我们来看一下这三个属性值的含义,“ &gpio1 ”表示 CD 引脚所使用的 IO 属于 GPIO1 组,“ 19
表示 GPIO1 组的第 19 IO ,通过这两个值 SD 卡驱动程序就知道 CD 引脚使用了 GPIO1_IO19
GPIO 。“ GPIO_ACTIVE_LOW ”表示低电平  1   有效,如果改为“ GPIO_ACTIVE_HIGH ”就表
示高电平 0 有效。

示例代码 45.2.2.2 gpio1 节点
504 gpio1 : gpio@0209c000 {
505 compatible = "fsl,imx6ul-gpio" , "fsl,imx35-gpio" ;
506 reg = < 0x0209c000 0x4000 >;
507 interrupts = < GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH >,
508 < GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH >;
509 gpio - controller ;
510 #gpio - cells = < 2 >;
511 interrupt - controller ;
512 #interrupt - cells = < 2 >;
513 };
gpio1 节点信息描述了 GPIO1 控制器的所有信息,重点就是 GPIO1 外设寄存器基地址以及
兼 容 属 性 。 关 于 I.MX 系 列 SOC GPIO 控 制 器 绑 定 信 息 请 查 看 文 档
Documentation/devicetree/bindings/gpio/ fsl-imx-gpio.txt
505 行,设置 gpio1 节点的 compatible 属性有两个,分别为“ fsl,imx6ul-gpio ”和“ fsl,imx35-
gpio ”,在 Linux 内核中搜索这两个字符串就可以找到 I.MX6UL GPIO 驱动程序。
506 行, reg 属性设置了 GPIO1 控制器的寄存器基地址为 0X0209C000,
509 行,“ gpio-controller ”表示 gpio1 节点是个 GPIO 控制器。
510 行,“ #gpio-cells ”属性和“ #address-cells ”类似, #gpio-cells 应该为 2 ,表示一共有
两个 cell ,第一个 cell GPIO 编号 ,比如“ &gpio1 3 ”就表示 GPIO1_IO03 。第二个 cell 表示
GPIO 极 性  .

1.2 添加gpio节点到设备树 

在根节点“/”下创建 test 设备子节点:

添加 pinctrl 信息 

 添加 GPIO 属性信息 

test {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_test>;
    gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
}

 二  GPIO 驱动程序简介

下图是gpio和pinctrl子系统架构图 

image-20230415163259138

2.1 如何从设备树中获取gpio信息

linux设备树中读取gpio信息 通过操作gpiolib库实现 该库是linux 设备管理 分层思想中 驱动。

  1.  首先获取gpio所处的设备节点 of_find_node_by_path
  2.  获取gpio编号 of_get_named_gpio 
  3.  请求此编号的gpio gpio_request函数
  4.  设置gpio输入输出 gpio_direction_input 或 gpio_direction_outout
  5.  gpio 输入输出值设置  gpio_get_value /gpio_set_value

2.2 gpio api

gpio 子系统提供的常用的 API 函数有下面 几个:
1 gpio_request 函数
gpio_request 函数用于申请一个 GPIO 管脚,在使用一个 GPIO 之前一定要使用 gpio_request
进行申请,函数原型如下:
int gpio_request(unsigned gpio, const char *label)
函数参数和返回值含义如下:
gpio :要申请的 gpio 标号,使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信
息,此函数会返回这个 GPIO 的标号。
label :给 gpio 设置个名字。
返回值: 0 ,申请成功;其他值,申请失败。
2 gpio_free 函数
如果不使用某个 GPIO 了,那么就可以调用 gpio_free 函数进行释放。函数原型如下:
void gpio_free(unsigned gpio)
函数参数和返回值含义如下:
gpio :要释放的 gpio 标号。
返回值: 无。
3 gpio_direction_input 函数
此函数用于设置某个 GPIO 为输入,函数原型如下所示:
int gpio_direction_input(unsigned gpio)
函数参数和返回值含义如下:
gpio :要设置为输入的 GPIO 标号。
返回值: 0 ,设置成功;负值,设置失败。
4 gpio_direction_output 函数
此函数用于设置某个 GPIO 为输出,并且设置默认输出值,函数原型如下:
int gpio_direction_output(unsigned gpio, int value)
函数参数和返回值含义如下:
gpio :要设置为输出的 GPIO 标号。
value GPIO 默认输出值。
返回值: 0 ,设置成功;负值,设置失败。
5 gpio_get_value 函数
此函数用于获取某个 GPIO 的值 (0 1) ,此函数是个宏,定义所示:
#define gpio_get_value __gpio_get_value
int __gpio_get_value(unsigned gpio)
函数参数和返回值含义如下:
gpio :要获取的 GPIO 标号。
返回值: 非负值,得到的 GPIO 值;负值,获取失败。
6 gpio_set_value 函数
此函数用于设置某个 GPIO 的值,此函数是个宏,定义如下
#define gpio_set_value __gpio_set_value
void __gpio_set_value(unsigned gpio, int value)
函数参数和返回值含义如下:
gpio :要设置的 GPIO 标号。
value 要设置的值。
返回值:
关于 gpio 子系统常用的 API 函数就讲这些,这些是我们用的最多的。

对gpio操作实例 将在platform中讲解

你可能感兴趣的:(重学嵌入式,linux,运维,服务器)