gpio子系统与pinctrl子系统通用API

此篇不涉及gpio子系统和pinctrl原理解释,只列举相关操作函数:
 

通用的GPIO操作:

1. gpio_request(unsigned gpio, const char *label):向内核申请指定gpio,所申请的IO口会被内核记录
参数:gpio:申请IO口编号 ,label:申请者的名字,随便。
返回:int值,成功:0;失败:负数
注:在使用gpio口之前,应先用gpio_request()申请gpio口。
若申请成功,则说明该gpio口未被使用。
若申请失败,则说明该gpio口不存在或未被释放。
 
2. gpio_set_value(unsigned gpio, int value):设置gpio口的值
参数:gpio:要设置的IO口编号 ,value:要设置的值(0或1)
返回:无
 
3. gpio_get_value(unsigned gpio):获取gpio口的值
参数:gpio:要获取的IO口编号
返回:int值,IO口状态
 
4. gpio_direction_input(unsigned gpio):设置gpio为输入功能
参数:gpio:要设置的IO口编号
返回:int值
 
5. gpio_direction_output(unsigned gpio, int value):设置gpio为输出功能,同时设置gpio输出的值
参数:gpio:要设置的IO口编号 ,value:要设置的值(0或1)
返回:int值
注:一般来说,设置一个GPIO口为输出,先执行一次gpio_direction_output,然后接下来只需执行gpio_set_value就行了。
 
6. gpio_free(unsigned gpio):释放gpio口,释放的IO口会在内核记录消除
注:在使用完gpio口之后,应及时释放gpio口。释放的io,可以再次被申请。
 
与gpio子系统相关的of函数:
7、of_gpio_named_count 函数
of_gpio_named_count 函数用于获取设备树某个属性里面定义了几个 GPIO 信息,要注意的是空的 GPIO 信息也会被统计到,比如:
gpios = <0
     &gpio1 1 2
     0
     &gpio2 3 4>;
上述代码的“gpios”节点一共定义了 4 个 GPIO,但是有 2 个是空的,没有实际的含义。通过 of_gpio_named_count 函数统计出来的 GPIO 数量就是 4 个
int of_gpio_named_count(struct device_node *np, const char *propname)

// 参数说明
np:设备节点。
propname:要统计的 GPIO 属性。
返回值:正值,统计到的 GPIO 数量;负值,失败。
 
8、of_gpio_count 函数
和 of_gpio_named_count 函数一样,但是不同的地方在于,此函数统计的是“gpios”这个属性的 GPIO 数量,而 of_gpio_named_count 函数可以统计任意属性的 GPIO 信息,函数原型如下所示:
int of_gpio_count(struct device_node *np)

// 参数说明
np:设备节点。
返回值:正值,统计到的 GPIO 数量;负值,失败。

 

9、of_get_named_gpio 函数
此函数获取 GPIO 编号,因为 Linux 内核中关于 GPIO 的 API 函数都要使用 GPIO 编号,此函数会将设备树中类似<&gpio5 7 GPIO_ACTIVE_LOW>的属性信息转换为对应的 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 编号;负值,失败。
 

通用PINCTRL操作:

重要结构体:
struct pinctrl {
    struct device *dev;                    // 指向拥有该 pinctrl 结构体的设备的设备结构体指针。
    const char *name;                      // pinctrl 的名称,用于标识该 pinctrl 结构体所管理的设备引脚配置
    struct module *owner;                  // 指向拥有该 pinctrl 结构体的模块的模块结构体指针
    struct list_head pin_ctrls;            // 用于存储与该 pinctrl 相关的 pin control 结构体的链表头
    const struct pinctrl_ops *ops;         // 指向 pinctrl 操作函数的指针,包含了对该 pinctrl 结构体进行操作的函数指针
};

struct pinctrl_state {
    struct list_head node;                // 用于将 struct pinctrl_state 结构体链接到状态列表中的节点
    const char *name;                     // 状态的名称,用于标识不同的状态
    unsigned long *pins;                  // 一个无符号长整型数组,存储了设备需要配置的引脚号
    unsigned int num_pins;                // 表示 pins 数组中引脚的数量
    struct pinctrl *p;                    // 指向该状态所属的 pinctrl 句柄的指针。
};
相关函数:
1、struct pinctrl *devm_pinctrl_get(struct device *dev):从设备树中获取指定设备的 pinctrl 句柄
参数:dev 是设备结构体指针,代表需要获取 pinctrl 句柄的设备。
返回值:如果成功,返回一个指向 struct pinctrl 结构体的指针;如果失败,返回一个错误指针或错误码。
 
2、struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *state_name):查找给定 pinctrl 句柄中的特定状态
参数:p 是 pinctrl 句柄,state_name 是需要查找的状态名称。
返回值:如果找到对应状态,返回一个指向 struct pinctrl_state 结构体的指针;否则返回 NULL
 
3、int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);:选择并激活指定的状态,以配置设备的引脚
参数:p是要配置的设备的 pinctrl 句柄,s是要应用到设备引脚的状态
返回 0 表示成功,负值表示出现错误。
 
4、void pinctrl_put(struct pinctrl *p);用于释放 pinctrl 句柄的函数
参数:p表示要释放的 pinctrl 句柄,释放后该句柄将不再可用
无返回值
 
5、struct pinctrl *pinctrl_get(struct device *dev);获取指定设备的 pinctrl 结构体的函数
参数:dev是指向要获取 pinctrl 结构体的设备结构体指针
成功获取到指定设备的 pinctrl 结构体,则返回该 pinctrl 结构体的指针;获取失败或者该设备没有配置 pinctrl,则返回 NULL
 
pinctrl_get和pinctrl_put结合使用,效果等于devm_pinctrl_get
devm开头表示设备管理(device management)的函数,使用devm_前缀表示它是一种设备管理资源,并且会与设备的生命周期进行关联。所以devm_pinctrl_get获取到的pinctrl句柄不用释放
posted @ 2024-03-23 22:40  lethe1203  阅读(43)  评论(0编辑  收藏  举报