在2.6.x的代码里面对于PIN脚复用都是在对应的芯片的broad code里面进行配置的,直接调用相关的特有API去设置。如我使用的AT91 MSA9260里面的at91_set_GPIO_periph()用于设置一个PIN为GPIO的模式,at91_set_A_periph() 用于设置一个PIN为A mode。而且每家chip厂商提供的风格和形式都不相同。在3.x之后的代码里面kernel引入了pinctl的驱动,对这些进行了更好的设计:
PINCTRL (PIN CONTROL) subsystem
This document outlines the pin control subsystem in Linux
This subsystem deals with:
- Enumerating and naming controllable pins
- Multiplexing of pins, pads, fingers (etc) see below for details
- Configuration of pins, pads, fingers (etc), such as software-controlled
biasing and driving mode specific pins, such as pull-up/down, open drain,
load capacitance etc.
这些描述是来自kernel的document里面的(pinctrl.txt)根据我的测试,我认为它可以更好的和DTS工作,更好的和GPIO工作,使得GPIO的API更加通用,这样我们自己写的驱动调用GPIO的部分就不用去区别不同的chip厂家了。
比如我们配置PINB17为GPIO mode:
gpio0 {
pinctrl_gpio0: gpio0-0 {
atmel,pins =
<AT91_PIOB 16 AT91_PERIPH_B GPIO_ACTIVE_LOW/* CAN reset active Low */
AT91_PIOB 17 AT91_PERIPH_B GPIO_ACTIVE_HIGH>;/* CAN Power active High */
};usart2: serial@fffb8000 {
/* ttyS3 -- RS485 */
/* DTR HW/SW enabled/disabled from userspace using ioctl */
linux,rs485-enabled-at-boot-time; /* enable RS485 mode in the bootup */
dtr-gpios = <&pioB 17 0>; /*xxx, the AT91_PIN_PB17 is a dtr control signal. */
status = "okay";
};
然后我们在我们的驱动代码里面只需要调用对应的GPIO 通用接口,如:
gpio_is_valid(int number);
/* set as input or output, returning 0 or negative errno */
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);/* GPIO INPUT: return zero or nonzero */
int gpio_get_value(unsigned gpio);
/* GPIO OUTPUT */
void gpio_set_value(unsigned gpio, int value);
这样我们的驱动的代码就不用在意不同的chip厂商不同的实现了。是需要把项目的DTS配置好,代码的移植性可想而知了。
Note:kernel里面的document文件时非常有用的资料,特别是在我们从低版本的kernel升级到高版本时,很多变化我们都是可以从这里得到最权威的信息的。
本文介绍Linux内核PINCTRL子系统的工作原理及其在不同版本间的演变。该子系统负责枚举和命名可控引脚,并处理引脚的复用及配置问题。通过DTS配置,简化了GPIO API,提高了驱动代码的通用性和移植性。

4119

被折叠的 条评论
为什么被折叠?



