GPIO相关的内核参考文档为Documentation/gpio.txt
GPIO相应的API
标准GPIO API
这些API的头文件定义于include/linux/gpio.h中,实际位于include/asm-generic/gpio.h中
bool gpio_is_valid(int number);
int gpio_request(unsigned gpio, const char *label);
void gpio_free(unsigned gpio);
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
int __gpio_get_value(unsigned gpio);
void __gpio_set_value(unsigned gpio, int value);
int gpio_export(unsigned gpio, bool direction_may_change);
void gpio_unexport(unsigned gpio);
int __gpio_cansleep(unsigned gpio);
int gpio_get_value_cansleep(unsigned gpio);
void gpio_set_value_cansleep(unsigned gpio, int value);
int gpio_request_one(unsigned gpio, unsigned long flags, const char *label);
int gpio_request_array(const struct gpio *array, size_t num);
void gpio_free_array(const struct gpio *array, size_t num);
中断部分的API
中断函数的原型实现在kernel/irq目录下
int __gpio_to_irq(unsigned gpio);
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev);
void free_irq(unsigned int irq, void *dev_id);
int irq_set_irq_type(unsigned int irq, unsigned int type);
void enable_irq(unsigned int irq);
void disable_irq(unsigned int irq);
int __disable_irq_nosync(unsigned int irq);
使用GPIO步骤
- include header 
 #include <linux/gpio.h>
- check valid (optional) 
 每一个chip上的gpio数量是有限制的(而且gpio号码一定>=0),为了防止指定的gpio号码是错的,可以先使用gpio_is_valid来检查。
 int gpio_is_valid(int number);//return true if valid.
- request gpio (optional, but recommended) 
 gpio_request可以检查gpio number是否超出范围或小于0及指定的gpio是否正在使用,因为有时候别的地方也控制着同一个gpio可能会发生预期外的结果。
/**
* return -EINVAL if GPIO is not valid(same as gpio_is_valid)
* return -EBUSY if GPIO is already used
* return 0 if GPIO is fine to use
* 因此我們只要檢查回傳質是否>=0就可以判斷是否可用。
* 第一個參數是填入GPIO的號碼、第二個參數是想要對這個GPIO的命名。
* $ cat /sys/kernel/debug/gpio就可以看到
*/
int gpio_request(unsigned gpio, const char *label);
- configure gpio
/* set as input or output, returning 0 or negative errno */
int gpio_direction_input(unsigned gpio);
int gpio_direction_output(unsigned gpio, int value);
- access gpio
/* GPIO INPUT: return zero or nonzero */
int gpio_get_value(unsigned gpio);
/* GPIO OUTPUT */
void gpio_set_value(unsigned gpio, int value);
- free gpio 
 当使用完GPIO之后利用gpio_free来释放GPIO
 int gpio_free(unsigned gpio);
GPIO源码架构分析
gpio相应的API其实调用的是注册的struct gpio_chip中的一些方法,来看下struct gpio_chip这个结构体,
struct gpio_chip {
        const char              *label;
        struct device           *dev;
        struct module           *owner;
        struct list_head        list;
        int                     (*request)(struct gpio_chip *chip, unsigned offset);
        void                    (*free)(struct gpio_chip *chip, unsigned offset);
        int                     (*get_direction)(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                     (*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;
        struct gpio_desc        *desc;
        const char              *const *names;
        unsigned                can_sleep:1;
        unsigned                exported:1;所以要使用gpio相应的API,必须事先注册一个struct gpio_chip结构体,并实现其中的方法,如下是一个例子,
static struct gpio_chip template_chip = {
        .label                  = "wm8994",
        .owner                  = THIS_MODULE,
        .request                = wm8994_gpio_request,
        .direction_input        = wm8994_gpio_direction_in,
        .get                    = wm8994_gpio_get,
        .direction_output       = wm8994_gpio_direction_out,
        .set                    = wm8994_gpio_set,
        .to_irq                 = wm8994_gpio_to_irq,
        .dbg_show               = wm8994_gpio_dbg_show,
        .can_sleep              = 1,
};另外需要说明一点是在struct gpio_chip结构体的这些函数中,既可以直接去操作gpio相应的寄存器,也可以通过i2c等接口去操作gpio,也可以调用pinctrl中提供的一些操作gpio的方法,总之,这个结构体的这些函数必须实现能够操作gpio。
                










