Linux驱动开发pinctrl子系统和gpio子系统
Posted XXX_UUU_XXX
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux驱动开发pinctrl子系统和gpio子系统相关的知识,希望对你有一定的参考价值。
Linux驱动分离与分层的产物:pinctrl子系统和gpio子系统
pinctrl子系统
设置pin引脚的复用和电气属性
主要工作内容:
- 获取设备树中 pin 信息
- 根据获取到的 pin 信息来设置 pin 的复用功能
- 根据获取到的 pin 信息来设置 pin 的电气特性,比如上/下拉、速度、驱动能力等
pinctrl设备树绑定信息可以参考Linux内核路径/Documentation/devicetree/bindings/pinctrl/xxx-pinctrl.txt
设备树中添加pinctrl节点
在设备中检查PIN是否被多个外设使用。
- 检查pinctrl的设置
- 如果PIN被设置为GPIO,检查gpio是否被别的外设使用
示例:I.MX SOC,在iomuxc节点下,
节点前缀一定要为pinctrl_
// 创建节点
pinctrl_test: testgrp
// 创建属性
fsl,pins = <
// MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0X17059 复用功能 电气特性
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0X17059
>;
;
MX6UL_PAD_UART1_RTS_B__GPIO1_IO19,UART1_RTS_B 做为 SD 卡的检测引脚,UART1_RTS_B 复用为 GPIO1_IO19。查看芯片手册可知。
# define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031C 0x0000 0x5 0x0
<mux_reg conf_reg input_reg mux_mode input_val>
0x0090 0x031C 0x0000 0x5 0x0
- 和根据芯片手册中数据对应
- mux_reg 寄存器偏移地址,iomuxc节点首地址0x020e0000,因此UART1_RTS_B这个PIN的mux寄存器地址 就是:0x020e0000+0x0090=0x020e 0090
- conf_reg 寄存器偏移地址,0x020e0000+0x031c=0x020e031c,这个寄存器就是UART1_RTS_B的电气属性配置寄存器。0x17059:为电气属性配置寄存器的值
- input_reg 寄存器偏移地址,有些外设有 input_reg 寄存器,有 input_reg 寄存器的 外设需要配置 input_reg 寄存器。没有的话就不需要设置
- mux_mode 复用值,寄存器值,0x5表示复用为GPIO1_IO19,将其写入0x020e 0090
- input_reg 寄存器值,在这里无效,为0
gpio子系统
pinctrl子系统将一个PIN复用为GPIO后,需要使用gpio子系统。gpio子系统主要用来初始化GPIO并提供响应的API函数。设置GPIO输入输出、读取GPIO值等。
pinctrl设备树绑定信息可以参考Linux内核路径/Documentation/devicetree/bindings/gpio/xxx-gpio.txt
使用函数of_find_node_by_path获取GPIO所处设备节点,使用函数of_get_named_gpio获取GPIO编号,使用API函数gpio_request请求编号对应的GPIO,设置GPIO的输入gpio_direction_input或输出gpio_direction_output,如果GPIO为输入,使用gpio_get_vaule读取GPIO值,如果GPIO为输出,使用gpio_set_value设置GPIO值,不使用GPIO时,使用gpio_free释放。
OF函数
of_gpio_named_count
- 获取设备树某个属性里面定义了几个 GPIO 信息,空的GPIO信息也会获取到
- int of_gpio_named_count(struct device_node *np, const char *propname)
- np:设备节点。 propname:GPIO 属性
- 返回值:正值,GPIO 数量;负值,失败
of_gpio_count
获取gpios属性的GPIO数量,而 of_gpio_named_count 函数可以获取任意属性的GPIO信息
- int of_gpio_count(struct device_node *np)
- np:设备节点
- 返回值:正值,GPIO数量;负值,失败
of_get_named_gpio
获取GPIO编号,将设备树中<&gpio1 19 GPIO_ACTIVE_LOW>的属性信息转换为对应的GPIO编 号。of_get_named_gpio函数在驱动中使用频繁。
- int of_get_named_gpio(struct device_node *np, const char *propname, int index)
- np:设备节点。 propname:包含要获取GPIO信息的属性名
- index:GPIO索引,一个属性里面可能包含多个 GPIO,此参数指定要获取哪个GPIO的编号,如果只有一个 GPIO 信息的话此参数为 0。
- 返回值:正值,获取到的 GPIO 编号;负值,失败。
API函数
gpio_request
用于申请一个 GPIO 管脚,在使用一个 GPIO 之前一定要使用 gpio_request 进行申请。
申请GPIO可以检测是否被其他设备使用,如果IO被分配给了其他设备,申请失败,需要重新分配IO。申请IO失败,通常是该IO被其他外设占用,需要检查设备树文件中使用相同IO的设备,修改(注释)pinctrl和gpio节点中相同的IO设置,重新编译设备树。
- int gpio_request(unsigned gpio, const char *label)
- gpio:要申请的 gpio 标号,使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信 息,会返回这个 GPIO 的标号。 label:给 gpio 设置个名字。
- 返回值:0,申请成功;其他值,申请失败。
gpio_free
如果不使用某个 GPIO ,进行释放
- void gpio_free(unsigned gpio)
- gpio:要释放的 gpio 标号。
- 返回值:无。
gpio_direction_input
用于设置某个 GPIO 为输入
- int gpio_direction_input(unsigned gpio)
- gpio:要设置为输入的 GPIO 标号。
- 返回值:0,设置成功;负值,设置失败。
gpio_direction_output
函数用于设置某个 GPIO 为输出,并且设置默认输出值
- int gpio_direction_output(unsigned gpio, int value)
- gpio:要设置为输出的 GPIO 标号。 value:GPIO 默认输出值
gpio_get_value
用于获取某个 GPIO 的值(0 或 1),此函数是个宏
- #define gpio_get_value __gpio_get_value
- int __gpio_get_value(unsigned gpio)
- gpio:要获取的 GPIO 标号
- 返回值:非负值,得到的 GPIO 值;负值,获取失败
gpio_set_value
用于设置某个 GPIO 的值,此函数是个宏
- #define gpio_set_value __gpio_set_value
- void __gpio_set_value(unsigned gpio, int value)
- gpio:要设置的 GPIO 标号。 value:要设置的值
- 返回值:无
设备树中添加gpio节点
test
pinctrl-names = "default"; // pinctrl-names属性
pinctrl-0 = <&pinctrl_test>; // pinctrl-0节点,引用pinctrl_test节点
gpio = <&gpio1 19 GPIO_ACTIVE_LOW>; // GPIO属性,test节点使用GPIO1_IO19,低电平有效
以上是关于Linux驱动开发pinctrl子系统和gpio子系统的主要内容,如果未能解决你的问题,请参考以下文章
使用pinctrl和gpio子系统开发GPIO驱动正点原子IMX6ULL阿尔法板的LED灯
Linux——Linux驱动之设备树中pinctrl和gpio子系统应用实践(如何使用其在设备树中配置GPIO,驱动中如何调用?)
Linux——Linux驱动之设备树中pinctrl和gpio子系统应用实践(如何使用其在设备树中配置GPIO,驱动中如何调用?)