Linux pinctrl subsystem
简单描述以下裸机的gpio pin控制流程:
- 使能对应总线
- 配置pin为gpio功能(gpio是pin的一种使用方式, pin还可以有其他的作用比如i2c... 谓之复用)
- 配置pin上下拉等
- 配置pin输入/输出
- 控制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);