GPIO子系统有新旧两种:总结的是新版的GPIO子系统。
新版GPIO子系统是基于描述符来实现的。
一,描述符(gpio_desc结构体)
/*
* 内核源码目录下的“drivers/gpio/gpiolib.h”文件中
* 作用:GPIOX的描述符,用于操作API
*/
struct gpio_desc{
struct gpio_device gdev; //GPIO设备结构体
unsigned long flags; //标志位,用于表示不同的属性
/*标志位符号对应的位号*/
#defineFLAG_REQUESTED0 //GPIO已请求
#defineFLAG_IS_OUT1 //GPIO用作输出
#defineFLAG_EXPORT2 //受sysfs_lock保护的导出标志
#defineFLAG_SYSFS3 //通过/sys/class/gpio/control导出的标志
#defineFLAG_ACTIVE_LOW6 //GPIO值为低电平时激活
#defineFLAG_OPEN_DRAIN7 //GPIO为开漏类型
#defineFLAG_OPEN_SOURCE8 //GPIO为开源类型
#defineFLAG_USED_AS_IRQ9 //GPIO连接到中断请求(IRQ)
#defineFLAG_IS_HOGGED11 //GPIO被独占占用
#defineFLAG_TRANSITORY12 //GPIO在休眠或复位时可能失去值
/*连接标签*/
const char*label; //GPIO的名称
const char*name; //GPIO的名称
};
--->>>
/*
* 内核源码目录下的“drivers/gpio/gpiolib.h”文件中
* 作用:描述GPIO设备
*/
struct gpio_device {
int id; // GPIO 设备ID
struct device *dev; // 对应的设备结构体指针
struct cdev chrdev; // 字符设备结构体
struct device *mockdev; // 模拟设备结构体指针
struct module *owner; // 拥有该GPIO设备的内核模块指针
struct gpio_chip *chip; // 对应的GPIO芯片结构体指针
struct gpio_desc *descs;// GPIO 描述符数组指针
int base; // GPIO 编号的起始值
u16 ngpio; // GPIO 的数量
const char *label; // GPIO 设备的标签
void *data; // 与GPIO 设备相关的数据指针
struct list_head list; // 用于将GPIO设备结构体连接到链表中
#ifdef CONFIG_PINCTRL
/*
* 如果启用了CONFIG_PINCTRL选项,GPIO控制器可以选择描述它们在SoC中服务的实际引脚范围。
* 此信息将由pinctrl子系统用于配置相应的GPIO引脚。
*/
struct list_head pin_ranges; // 描述GPIO控制器引脚范围的链表
#endif
};
--->>>
/*
* 内核源码目录下的“include/linux/gpio/driver.h”文件中
* 作用:描述GPIO芯片的属性和操作函数
*/
struct gpio_chip {
..........
};
二,相关API函数
2.1 获取GPIO描述符
struct gpio_desc *gpiod_get(struct device *dev,const char *con_id,
enumgpiod_flags flags);
struct gpio_desc *gpiod_get_index(struct device *dev, const char *con_id,
unsigned int idx, enum gpiod_flags flags);
struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id,
enum gpiod_flags flags);
struct gpio_desc *gpiod_get_index_optional(struct device *dev,
const char *con_id,unsigned int index,enum gpiod_flags flags);
1,dev:指向设备结构体的指针,表示与GPIO相关联的设备
2,con_id:连接标识符(connection identifier),用于标识所需的GPIO连接。通常由设备树(Devic eTree)或其他设备描述信息定义
3,flags:GPIO描述符的选项标志,用于指定GPIO的属性和操作模式: enum gpiod_flags
4,index:表示GPIO的索引值,当设备树的GPIO属性值包含多个GPIO引脚描述时,使用 index 来表示每个GPIO引脚的唯一标识
5,带optional后缀的函数与不带optional后缀的函数在功能上是相同
2.2 释放GPIO描述符
void gpiod_put(struct gpio_desc *desc);
2.3 GPIO操作函数
struct gpio_desc *mygpio1; // GPIO描述符指针
int dir,value,irq; // 方向 值 中断号
//将GPIO设置为输出模式并设置初始值为低电平
gpiod_direction_output(mygpio1,0);
//将GPIO设置为输入模式
int gpiod_direction_input(struct gpio_desc *desc);
//设置GPIO为高电平
gpiod_set_value(mygpio1,1);
//获取GPIO的方向
dir = gpiod_get_direction(mygpio1);
//获取GPIO的值
value = gpiod_get_value(mygpio1);
//将GPIO转换为中断号
irq = gpiod_to_irq(mygpio1);
三,三级节点操作函数
略
四,动态切换引脚复用功能
设备树:pinctrl-names = "mygpio_func1", "mygpio_func2";
4.1GPIO子系统与pinctrl子系统相结合
设备树:pinctrl-names = "myled1";
猜测:如果 pinctrl-names != "default"; 就要调用函数来配设。
4.2 切换方式
设备树:
my_gpio:gpio1_a0 {
compatible = "mygpio";
my-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
pinctrl-names = "mygpio_func1", "mygpio_func2";
pinctrl-0 = <&mygpio_ctrl>;
pinctrl-1 = <&i2c3_sda>;
};
略: