pinctrl子系统和gpio子系统

前言

        前几节引入了设备数下的led驱动,但它本质上还是配置led驱动的寄存器,与裸机开发并无区别。本节引入了pinctrl子系统和gpio子系统来简化led驱动的配置。


一、pinctrl子系统

        (1)pinctrl 子系统简介

        大多数SOC的PIN都是支持复用的,所以在配置时要考虑复用的设置,此外还要配置PIN的电气特性,比如上下拉、速度、驱动等。pinctrl子系统的主要工作内容:

获取设备树中pin信息
根据获得到的pin信息来设置pin的复用功能
根据获得到的pin信息来设置pin的电气特性,比如上下拉、速度、驱动能力

        (2)设备树中添加 pinctrl 节点

  • 设备树中的 iomuxc 节点就是 I.MX6ULL 的 IOMUXC 外设对应的节点
  • “iomuxc”节点下引用了 pinctrl_hog_1 节点, Linux 内核中的 iomuxc 驱动自动初始化 pinctrl_hog_1 节点下的所有 PIN

        在设备树(imx6ull-alientek-emmc.dts)创建一个节点来描述 PIN 的配置信息
1、创建对应节点
2、添加“fsl,pins”属性
3、 在“ fsl,pins ”属性中添加 PIN 配置信息
例:
在 iomuxc 节点中的“imx6ul-evk ”子节点下添加“ pinctrl_test ”节点。

pinctrl_test: testgrp { 
    fsl,pins = < 
    MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 config /*config 是具体设置值*/
    >;
};

(3)Linux 内核的 pinctrl 子系统实现原理

        imx6ul_pinctrl_probe 函数就是 I.MX6ULL 这个 SOC 的 PIN 配置入口函数,其实现原理如下所示:

二、gpio 子系统

        (1)gpio 子系统简介

  • gpio 子系统用于初始化 GPIO 并且提供相应的 API 函数,比如设置 GPIO 为输入输出,读取 GPIO 的值等。
  • 在设备树中添加 gpio 相关信息,在驱动程序中使用 gpio 子系统提供的 API 函数来操作 GPIO。

        (2)gpio 子系统 API 函数

申请  GPIO 管脚

int gpio_request (unsigned gpio, const char *label)
gpio :要申请的 gpio 标号,使用 of_get_named_gpio 函数从设备树获取指定 GPIO 属性信息,此函数会返回这个 GPIO 的标号。
label :给 gpio 设置个名字。
返回值 :

0 :申请成功;

其他值:申请失败

释放  GPIO 管脚

void gpio_free (unsigned gpio)

gpio :要释放的 gpio 标号

设置  GPIO 为输入

int gpio_direction_input (unsigned gpio)
gpio :要设置为输入的 GPIO 标号。
返回值 :

0 :设置成功;

负值:设置失败

设置  GPIO 为输出

int gpio_direction_output (unsigned gpio, int value)
gpio :要设置为输出的 GPIO 标号。
value : GPIO 默认输出值。
返回值 :

0 :设置成功;

负值:设置失败

获取  GPIO 的值 (0 或 1)

#define gpio_get_value __gpio_get_value
int __gpio_get_value (unsigned gpio)
gpio :要获取的 GPIO 标号。
返回值 :

非负值:得到的 GPIO 值;

负值:获取失败

设置  GPIO 的值#define gpio_set_value __gpio_set_value
void __gpio_set_value (unsigned gpio, int value)
gpio :要设置的 GPIO 标号。
value : 要设置的值。
 

        (3)设备树中添加 gpio 节点

1、创建 test 设备节点

2、添加 pinctrl 信息

3、添加 GPIO 属性信息

例:

test { 
    pinctrl-names = "default"; 
    pinctrl-0 = <&pinctrl_test>;
    gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
};

        (4)与 gpio 相关的 OF 函数

获取设备树某个属性里面的  GPIO 数量

(统计任意属性的 GPIO 信息)

int of_gpio_named_count (struct device_node *np, const char *propname)
np :设备节点。
propname :要统计的 GPIO 属性。
返回值 :

正值:统计到的 GPIO 数量;

负值:失败

获取设备树某个属性里面的  GPIO 数量

(统计“gpios”属性的 GPIO 数量 

int of_gpio_count (struct device_node *np)
np :设备节点。
返回值 :

正值:统计到的 GPIO 数量;

负值:失败

获取 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 编号;

负值:失败

总结

        详细参考Linux驱动架构之pinctrl子系统分析(一) - Cqlismy - 博客园

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值