Linux pinctrl subsystem

简单描述以下裸机的gpio pin控制流程:

  1. 使能对应总线
  2. 配置pin为gpio功能(gpio是pin的一种使用方式, pin还可以有其他的作用比如i2c... 谓之复用)
  3. 配置pin上下拉等
  4. 配置pin输入/输出
  5. 控制pin电平

对于上面流程
1 属于依赖问题, 已经被设备树解决了.
2 3 被抽象为pin 的配置问题, 使用 pinctrl subsystem 解决.
4 5 被抽象gpio的功能, 使用 gpio subsystem 解决.

pinctrl & GPIO subsystem 怎么使用

pingctrl subsystem

在设备树里添加pin config块, 内容如下:

uart0_data: uart0-data-pins {
samsung,pins = "gpa0-0", "gpa0-1"; //用到了哪些pin
samsung,pin-function = <EXYNOS_PIN_FUNC_2>; // pin的功能, gpio还是其他, 值根据芯片手册填, 这里是芯片厂商提供了宏
samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; // 配置上下拉
... ...
// 还可以有其他的字段, 除了pins 和 function, 其他的字段都不是必要的, 根据实际情况设置的
};

在client 配置里引用pin config块, 比如有一个串口设备要使用上面的pin config,就在串口设备的设备节点中添加下面的内容, 下面是用的追加的方式:

&serial_0 {
	pinctrl-names = "default", "sleep"; // names是一个状态数组
	pinctrl-0 = <&uart0_data &uart0_fctl>; // -0对应的"default"状态, &uart0_data 是使用上面定义的pin config, 表示在default状态下使用这个配置.
	pinctrl-1 = <&uart0_sleep>; // -1对应的"sleep"状态  
        ... ...
};

gpio subsystem

gpio controller 描述, gpio 控制器是一组gpio的集合, 也叫gpio bank.

gpa0: gpa0-gpio-bank {
   gpio-controller; // 表明这是一个gpio控制器
   #gpio-cells = <2>; //gpio描述要2个cell,通常都是2个 一个是gpio的编号, 另一个是flag,通常是gpio的配置比如有效电平,输入输出模式等
};

gpio 描述

key-vol-up {
   gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; // &gpx2 表示用的是哪个gpio控制器, 0表示gpio(pin)的编号, GPIO_ACTIVE_LOW表示gpio的配置, 这里是低电平有效
... ...
};

使用代码控制gpio

    /* 1 获取设备节点 */
    gpioXXX.nd = of_find_node_by_path("/gpioXXX");

    /* 2 获取设备树中的 gpio 属性,得到 LED 所使用的 LED 编号 */
    gpioXXX.gpio = of_get_named_gpio(gpioXXX.nd,"gpio",0);

    /* 3 设置 GPIO1_IO03 为输出,并且输出高电平,默认关闭 LED 灯 */
    ret = gpio_direction_output(gpioXXX.gpio, 1);
posted @ 2025-04-10 15:12  天刚刚破晓  阅读(21)  评论(0)    收藏  举报