在Linux中,会在gpiolib.c中定义一个 ARCH_NR_GPIOS 大小的数组static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];。每个元素对应于当前CPU上各个GPIO接口的信息,记录各个GPIO的描述符,即对应struct gpio_desc结构体。struct gpio_desc内的成员gpio_chip又指向了一系列关于GPIO的操作。具体的操作在 driver/gpio/gpio_**.c中实现。
gpio_desc结构体中,flags为一标志位,用来指示当前GPIO是否已经占用,当用gpio_request申请GPIO资源时,flags位就会置位,当调用gpio_free释放GPIO资源时,flags就会清零。
当我们调用gpio_request(),实际上会将参数gpio在数组中查找其对应的gpio_desc,在根据gpio_chip就可以找到底层关于request()的实现。
所有的GPIO控制器驱动应包括下面的头文件,包含 struct gpio_chip 的定义。 include <linux/gpio/driver.h>
struct gpio_chip:标记GPIO所属的控制器,里面包含诸多回调函数,用于控制GPIO的行为,各个板卡都有实现自己的gpio_chip控制模块;
struct gpio_desc:用于标记一个GPIO;
在driver/gpio/gpio_**.c文件中会注册特定平台**的GPIO驱动 定义了GPIO板级控制的内容,包括设置 set gpio,get gpio,dir_in,dir_out,gpio_to_irq等行为; 获取GPIO板级的资源,包括 gpio_reg_base,并赋值给 struct gpio_chip; 将struct gpio_chip添加到GPIOLIB中;
driver/gpio/gpio_**.c会定义平台驱动并初始化
板级文件或设备树会添加平台设备
当设备与驱动匹配就会执行**_gpio_probe()的内容。
probe() 中初始化struct gpio_chip结构体的成员。并调用 gpiochip_add()将gpio_chip添加到 GPIOLIB 中。
GPIOLIB 提供GPIO调用的接口函数。比如常见的 gpio_request()/gpio_free()/gpio_get_value()/gpio_is_valid() 等。 相关结构体gpio_chip代表一个芯片的一个gpio bank
struct gpio_chip { const char *label; struct device *dev; struct module *owner; int (*request)(struct gpio_chip *chip,unsigned offset); void (*free)(struct gpio_chip *chip,unsigned offset); int (*direction_input)(struct gpio_chip *chip,unsigned offset); int (*get)(struct gpio_chip *chip,unsigned offset); int (*direction_output)(struct gpio_chip *chip,unsigned offset, int value); int (*direction_output_array)(struct gpio_chip*chip, unsigned value, unsigned mask); int (*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce); void (*set)(struct gpio_chip *chip,unsigned offset, int value); int (*to_irq)(struct gpio_chip *chip,unsigned offset); void (*dbg_show)(struct seq_file *s,struct gpio_chip *chip); int base; u16 ngpio; const char *const *names; unsigned can_sleep:1; unsigned exported:
|