how to port 2.6.x driver to 4.x --关于pinctl 和GPIO

在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 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开始)