第二十节、pinctl和gpio子系统
本节用于介绍pinctl和gpio子系统
1、什么是pinctrl和gpio子系统?
2、Linux Pinctrl子系统提供的功能是什么?
(1)管理系统中所有的可以控制的pin,在系统初始化的时候,枚举所有可以控制的pin,并标识这些pin。
(2)管理这些pin的复用(Multiplexing)。对于SOC而言,其引脚除了配置成普通的GPIO之外,若干个引脚还可以组成一个pin group,形成特定的功能。
(3)配置这些pin的特性。例如使能或关闭引脚上的pull-up、pull-down电阻,配置引脚的driver strength。
3、不同soc厂家的pin controller的节点这些节点里都是把某些引脚复用成某些功能。
4.不同soc厂家的pin controller的节点里面的属性都是什么意思?
可以通过Linux 源码目录Documentation/devicetree/bindings下的txt文档查看。
如在文件
Documentation/devicetree/bindings/pinctrl/fsl\,imx6q-pinctrl.txt
有对imx6q的pinctrl的使用说明,详细说明了fsl,pins =
5.怎么在代码里面使用pin controller里面定义好的节点?
例1:
pinctrl-names = "default";
//设备的状态,可以有多个状态,default为状态0
pinctrl-0 = <&pinctrl_audmux_1>;
//第0个状态所对应的引脚配置,也就是default状态对应的引脚在pin controller里面定义好的节点pinctrl_audmux_1里面的管脚配置
例2:
pinctrl-names = "default", "wake up";
//设备的状态,可以有多个状态,default为状态0
pinctrl-0 = <&pinctrl_audmux_1>;
//第0个状态所对应的引脚配置,也就是default状态对应的引脚在pin controller里面定义好的节点pinctrl_audmux_1里面的管脚配置
pinctrl-1 = <&pinctrl_audmux_2>;
//第1个状态所对应的引脚配置,也就是default状态对应的引脚在pin controller里面定义好的节点pinctrl_audmux_2里面的管脚配置
例3:
pinctrl-names = "default";
//设备的状态,可以有多个状态,default为状态0
pinctrl-0 = <&pinctrl_audmux_1
&pinctrl_audmux_2>;
//第0个状态所对应的引脚配置,也就是default状态对应的引脚在pin controller里面定义好的节点pinctrl_audmux_1和pinctrl_audmux_2里面的管脚配置
Linux内核提供了pinctrl 子系统和gpio子系统用于GPIO驱动,当然pinctrl子系统负责的就不仅仅是GPIO的驱动了而是所有pin脚的配置。pinctrl子系统是随着设备树的加入而加入的,依赖于设备树。GPIO子系统在之前的内核中也是存在的,但是pinctrl子系统的加入GPIO子系统也是有很大的改变。
在以前的内核版本中,如果要配置GPIO的话一般要使用SOC厂家实现的配置函数,例如三星的配置函s3c_gpio_cfgpin等,这样带来的问题就是各家有各家的接口函数与实现方式,不但内核的代码复用率低而且开发者很难记住这么多的函数,如果要使用多种平台的话背函数都是很麻烦的,所以在引入设备树后对GPIO子系统进行了大的改造,使用设备树来实现并提供统一的接口。通过GPIO子系统功能主要实现引脚功能的配置,如设置为GPlO,特殊功能,GPIO的方向,设置为中断等。
那么我们先来看一下怎么在设备树中pinctrl和gpio子系统描述一个gpio。
<1>设备树使用pinctrl和gpio子系统描述一个gpio
test_key {
#address-cells = <1>;
#size-cells = <1>;
status = "okay";
compatible = "keys";
pinctrl-name = "default";
pinctrl-0 = <&pinctrl_key>;
gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
};
<2>常用gpio子系统提供的api函数
1、gpio_request 函数
作用:gpio_request 函数用于申请一个GPIO管脚
函数原型:
文件位置路径:include/linux/gpio.h
static inline 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函数进行释放。
函数原型:
文件位置路径:include/linux/gpio.h
static inline void gpio_free(unsigned gpio)
//参数
//gpio:要释放的gpio标号
3、gpio_direction_input 函数
作用:此函数用于设置某个GPIO为输入
函数原型:
文件位置路径:include/linux/gpio.h
static inline int gpio_direction_input(unsigned gpio)
//参数
//gpio:要设置为输入的GPIO标号。
//返回值
//成功,返回0
//失败,返回负值
4、gpio_direction_output 函数
作用:此函数用于设置某个GPIO为输出
函数原型:
文件位置路径:include/linux/gpio.h
static inline int gpio_direction_output(unsigned gpio, int value)
//参数
//gpio:要设置为输入的GPIO标号。
//value:GPIO默认输出值
//返回值
//成功,返回0
//失败,返回负值
5、gpio_get_value 函数
作用:此函数用于获取某个GPIO的值(0或1)
函数原型:
文件位置路径:include/linux/gpio.h
static inline int gpio_get_value(unsigned gpio)
//参数
//gpio:要获取的GPIO标号
//返回值
//成功,GPIO的值
//失败,返回负值
6、gpio_set_value 函数
作用:此函数用于设置某个GPIO的值(0或1)
函数原型:
文件位置路径:include/linux/gpio.h
static inline void gpio_set_value(unsigned gpio, int value)
//参数
//gpio:要设置的GPIO标号
//value:要设置的值