一 简介
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子系统架构图
2.1 如何从设备树中获取gpio信息
linux设备树中读取gpio信息 通过操作gpiolib库实现 该库是linux 设备管理 分层思想中 驱动。
- 首先获取gpio所处的设备节点 of_find_node_by_path
- 获取gpio编号 of_get_named_gpio
- 请求此编号的gpio gpio_request函数
- 设置gpio输入输出 gpio_direction_input 或 gpio_direction_outout
- 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中讲解