linux gpio接口 .

来源:互联网 发布:最小的中文linux系统 编辑:程序博客网 时间:2024/05/03 20:00

一.相关结构体

1.gpio_chip代表一个芯片的一个gpio bank

[cpp] view plaincopyprint?
  1. struct gpio_chip {  //gpio bank  
  2.     const char  *label;     //bank名  
  3.     struct device   *dev;   //设备文件  
  4.     struct module   *owner; //模块所有者  
  5.     int     (*request)(struct gpio_chip *chip,unsigned offset);  
  6.     void    (*free)(struct gpio_chip *chip,unsigned offset);  
  7.     int     (*direction_input)(struct gpio_chip *chip,unsigned offset); //配置gpio为输入  
  8.     int     (*get)(struct gpio_chip *chip,unsigned offset); //获取值  
  9.     int     (*direction_output)(struct gpio_chip *chip,unsigned offset, int value); //配置gpio为输出  
  10.     int     (*direction_output_array)(struct gpio_chip*chip, unsigned value, unsigned mask);  
  11.     int     (*set_debounce)(struct gpio_chip *chip,unsigned offset, unsigned debounce); //去抖动时间  
  12.     void    (*set)(struct gpio_chip *chip,unsigned offset, int value);  //设置gpio值  
  13.     int     (*to_irq)(struct gpio_chip *chip,unsigned offset);  //中断  
  14.     void    (*dbg_show)(struct seq_file *s,struct gpio_chip *chip);  
  15.     int base;   //gpio基数  
  16.     u16 ngpio;  //gpio个数   
  17.     const char  *const *names;  
  18.     unsigned    can_sleep:1;    //能否睡眠   
  19.     unsigned    exported:1;  
  20. #if defined(CONFIG_OF_GPIO)   
  21.     struct device_node *of_node;  
  22.     int of_gpio_n_cells;  
  23.     int (*of_xlate)(struct gpio_chip *gc, struct device_node *np,const void *gpio_spec, u32 *flags);  
  24. #endif   
  25. };  

2.gpio_desc 代表一个gpio口

[cpp] view plaincopyprint?
  1. struct gpio_desc {  //GPIO描述符   
  2.     struct gpio_chip    *chip;  //所属gpio_chip  
  3.     unsigned long   flags;      //gpio标志  
  4. #ifdef CONFIG_DEBUG_FS   
  5.     const char  *label;  
  6. #endif   
  7. };  

2.1 gpio_desc flags标志

[cpp] view plaincopyprint?
  1. #define FLAG_REQUESTED  0   //已请求资源  
  2. #define FLAG_IS_OUT 1   //输出io   
  3. #define FLAG_RESERVED   2   //保留  
  4. #define FLAG_EXPORT 3   /* protected by sysfs_lock */  
  5. #define FLAG_SYSFS      4   /* exported via /sys/class/gpio/control */  
  6. #define FLAG_TRIG_FALL  5   /* trigger on falling edge */  
  7. #define FLAG_TRIG_RISE  6   /* trigger on rising edge */  
  8. #define FLAG_ACTIVE_LOW 7   /* sysfs value has active low */  

2.2 全局gpio_desc数组

[cpp] view plaincopyprint?
  1. static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];  

3.gpio类

[cpp] view plaincopyprint?
  1. static struct class gpio_class = {  
  2.     .name =     "gpio",  
  3.     .owner =    THIS_MODULE,  
  4.     .class_attrs =  gpio_class_attrs,  
  5. };  


二.api接口

[cpp] view plaincopyprint?
  1. int gpiochip_add(struct gpio_chip *chip)                //添加初始化gpio_chip管理的gpio_desc  
  2. int gpiochip_remove(struct gpio_chip *chip)             //清空gpio_chip管理的全局gpio_desc数组项  
  3. struct gpio_chip *gpiochip_find(void *data,int (*match)(struct gpio_chip *chip, void *data))    //查找获取gpio_chip  
  4.   
  5. int gpio_request(unsigned gpio, const char *label)      //请求gpio资源  
  6. void gpio_free(unsigned gpio)                           //释放gpio资源  
  7.   
  8. int gpio_set_debounce(unsigned gpio, unsigned debounce) //设置去抖动时间  
  9. int gpio_direction_input(unsigned gpio)                 //设置gpio为输入io  
  10. int gpio_direction_output(unsigned gpio, int value)     //设置gpio为输出io  
  11.   
  12. int gpio_cansleep(unsigned gpio)                        //判断gpio可否睡眠  
  13. int gpio_get_value_cansleep(unsigned gpio)              //获取gpio值(gpio可睡眠)  
  14. void gpio_set_value_cansleep(unsigned gpio, int value)  //设置gpio值(gpio可睡眠)  
  15. int gpio_get_value(unsigned gpio)                       //获取gpio值(gpio不可睡眠)  
  16.   
  17. int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) //请求一个gpio资源  
  18. int gpio_request_array(struct gpio *array, size_t num)  //请求一组gpio资源  
  19. void gpio_free_array(struct gpio *array, size_t num)    //释放一组gpio资源  
  20.   
  21. int gpio_to_irq(unsigned gpio)                          //根据gpio号获取对应的中断号  
  22.   
  23. int gpio_export(unsigned gpio, bool direction_may_change)   //gpio创建用户接口  
  24. void gpio_unexport(unsigned gpio)                       //gpio移除用户接口  


三.api及调用到的相关函数解析

1.设置gpio_chip管理的全局gpio_desc数组项

[cpp] view plaincopyprint?
  1. int gpiochip_add(struct gpio_chip *chip)  
  2. {  
  3.     unsigned long   flags;  
  4.     int status = 0;  
  5.     unsigned    id;  
  6.     int base = chip->base;   //获取gpio_chip基数  
  7.     //验证gpio的基数,gpio的最后一个io的编号正确性  
  8.     if ((!gpio_is_valid(base) || !gpio_is_valid(base + chip->ngpio - 1))&& base >= 0) {     
  9.         status = -EINVAL;  
  10.         goto fail;  
  11.     }  
  12.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  13.     if (base < 0) {  //若gpio的基数小于0  
  14.         base = gpiochip_find_base(chip->ngpio);  //根据gpio个数分配新的基数  
  15.         if (base < 0) {  
  16.             status = base;  
  17.             goto unlock;  
  18.         }  
  19.         chip->base = base;   //设置新的基数  
  20.     }  
  21.     for (id = base; id < base + chip->ngpio; id++) {  
  22.         if (gpio_desc[id].chip != NULL) {   //判断gpio_desc是否给其他gpio_chip管理  
  23.             status = -EBUSY;  
  24.             break;  
  25.         }  
  26.     }  
  27.     if (status == 0) {  
  28.         for (id = base; id < base + chip->ngpio; id++) {  //填充对应的全局gpio_desc数组项  
  29.             gpio_desc[id].chip = chip;  //gpio_chip  
  30.             gpio_desc[id].flags = !chip->direction_input?(1 << FLAG_IS_OUT):0; //设置输入输出标志位  
  31.         }  
  32.     }  
  33.     of_gpiochip_add(chip);  
  34. unlock:  
  35.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  36.     if (status)  
  37.         goto fail;  
  38.     status = gpiochip_export(chip); //gpio_chip创建用户接口  
  39.     if (status)  
  40.         goto fail;  
  41.     return 0;  
  42. fail:  
  43.     pr_err("gpiochip_add: gpios %d..%d (%s) failed to register\n",chip->base,chip->base+chip->ngpio-1,chip->label?:"generic");  
  44.     return status;  
  45. }  
  46. EXPORT_SYMBOL_GPL(gpiochip_add);  

2.清空gpio_chip管理的全局gpio_desc数组项

[cpp] view plaincopyprint?
  1. int gpiochip_remove(struct gpio_chip *chip)  
  2. {  
  3.     unsigned long   flags;  
  4.     int status = 0;  
  5.     unsigned    id;  
  6.   
  7.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  8.     of_gpiochip_remove(chip);  
  9.     for (id = chip->base; id < chip->base + chip->ngpio; id++) {    //查找对应全局gpio_desc数组项  
  10.         if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {   //判断是否存在标志含FLAG_REQUESTED的gpio口  
  11.             status = -EBUSY;  
  12.             break;  
  13.         }  
  14.     }  
  15.     if (status == 0) {  
  16.         for (id = chip->base; id < chip->base + chip->ngpio; id++)  //清空对应全局gpio_desc数组项  
  17.             gpio_desc[id].chip = NULL;  
  18.     }  
  19.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  20.     if (status == 0)  
  21.         gpiochip_unexport(chip);    //gpio_chip移除用户接口  
  22.     return status;  
  23. }  
  24. EXPORT_SYMBOL_GPL(gpiochip_remove);  

3.查找获取gpio_chip

[cpp] view plaincopyprint?
  1. struct gpio_chip *gpiochip_find(void *data,int (*match)(struct gpio_chip *chip, void *data))  
  2. {  
  3.     struct gpio_chip *chip = NULL;  
  4.     unsigned long flags;  
  5.     int i;  
  6.   
  7.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  8.     for (i = 0; i < ARCH_NR_GPIOS; i++) {    //遍历整个全局gpio_desc数组  
  9.         if (!gpio_desc[i].chip) //若没被某个gpio_chip管理,则跳过继续  
  10.             continue;  
  11.         if (match(gpio_desc[i].chip, data)) {   //调用传递进来的匹配函数  
  12.             chip = gpio_desc[i].chip;   //匹配则获取其gpio_chip  
  13.             break;  
  14.         }  
  15.     }  
  16.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  17.     return chip;    //返回查找到的gpio_chip指针  
  18. }  

4.验证gpio号是否正确

[cpp] view plaincopyprint?
  1. static inline int gpio_is_valid(int number)  
  2. {  
  3.     return ((unsigned)number) < ARCH_NR_GPIOS;  
  4. }  

5.请求gpio资源

[cpp] view plaincopyprint?
  1. int gpio_request(unsigned gpio, const char *label)  
  2. {  
  3.     struct gpio_desc    *desc;  
  4.     struct gpio_chip    *chip;  
  5.     int status = -EINVAL;  
  6.     unsigned long   flags;  
  7.   
  8.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  9.     if (!gpio_is_valid(gpio))   //验证gpio号是否正确  
  10.         goto done;  
  11.     desc = &gpio_desc[gpio];    //获取gpio描述符  
  12.     chip = desc->chip;   //获取gpio_chip   
  13.     if (chip == NULL)   //获取gpio_chip失败  
  14.         goto done;  
  15.     if (!try_module_get(chip->owner))    //增加模块引用计数  
  16.         goto done;  
  17.     if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {   //测试并设置gpio_desc的FLAG_REQUESTED标志  
  18.         desc_set_label(desc, label ? : "?");    //设置gpio_desc的label  
  19.         status = 0;  
  20.     }   
  21.     else {  
  22.         status = -EBUSY;  
  23.         module_put(chip->owner); //减少模块引用计数  
  24.         goto done;  
  25.     }  
  26.     if (chip->request) { //gpio_chip存在request方法  
  27.         spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  28.         status = chip->request(chip, gpio - chip->base);  //调用gpio_chip的request方法  
  29.         spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  30.         if (status < 0) {  
  31.             desc_set_label(desc, NULL); //清除gpio_desc的label  
  32.             module_put(chip->owner); //减少模块引用计数  
  33.             clear_bit(FLAG_REQUESTED, &desc->flags); //清除gpio_chip的FLAG_REQUESTED标志  
  34.         }  
  35.     }  
  36. done:  
  37.     if (status)  
  38.         pr_debug("gpio_request: gpio-%d (%s) status %d\n",gpio, label ? : "?", status);  
  39.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  40.     return status;  
  41. }  
  42. EXPORT_SYMBOL_GPL(gpio_request);  

6.释放gpio资源

[cpp] view plaincopyprint?
  1. void gpio_free(unsigned gpio)     
  2. {  
  3.     unsigned long       flags;  
  4.     struct gpio_desc    *desc;  
  5.     struct gpio_chip    *chip;  
  6.   
  7.     might_sleep();  
  8.     if (!gpio_is_valid(gpio)) { //验证gpio号  
  9.         WARN_ON(extra_checks);  
  10.         return;  
  11.     }  
  12.     gpio_unexport(gpio);    //gpio移除用户接口   
  13.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  14.     desc = &gpio_desc[gpio];    //获取gpio_desc  
  15.     chip = desc->chip;           //获取gpio_chip  
  16.     if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {    //测试gpio_desc的FLAG_REQUESTED标志  
  17.         if (chip->free) {    //gpio_chip存在free方法  
  18.             spin_unlock_irqrestore(&gpio_lock, flags);  //上自旋锁  
  19.             might_sleep_if(chip->can_sleep);  
  20.             chip->free(chip, gpio - chip->base);  //调用gpio_chip的free方法  
  21.             spin_lock_irqsave(&gpio_lock, flags);   //解自旋锁  
  22.         }  
  23.         desc_set_label(desc, NULL); //清除gpio_desc的label信息  
  24.         module_put(desc->chip->owner);    //减少模块引用计数  
  25.         clear_bit(FLAG_ACTIVE_LOW, &desc->flags);    //清除FLAG_ACTIVE_LOW的标志  
  26.         clear_bit(FLAG_REQUESTED, &desc->flags); //清除FLAG_REQUESTED的标志  
  27.     }   
  28.     else  
  29.         WARN_ON(extra_checks);  
  30.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  31. }  
  32. EXPORT_SYMBOL_GPL(gpio_free);  

7.设置去抖动时间

[cpp] view plaincopyprint?
  1. int gpio_set_debounce(unsigned gpio, unsigned debounce)   
  2. {  
  3.     unsigned long       flags;  
  4.     struct gpio_chip    *chip;  
  5.     struct gpio_desc    *desc = &gpio_desc[gpio];   //获取gpio_desc项  
  6.     int status = -EINVAL;  
  7.   
  8.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  9.     if (!gpio_is_valid(gpio))   //验证gpio号  
  10.         goto fail;  
  11.     chip = desc->chip;   //获取gpio_chip  
  12.     if (!chip || !chip->set || !chip->set_debounce)   //判断gpio_chip是否存在且是否存在set和set_debounce方法  
  13.         goto fail;  
  14.     gpio -= chip->base;  //计算gpio在该gpio_chip的偏移量  
  15.     if (gpio >= chip->ngpio)  //超过该gpio_chip的gpio数范围  
  16.         goto fail;  
  17.     status = gpio_ensure_requested(desc, gpio); //确保gpio是request请求过了的  
  18.     if (status < 0)  
  19.         goto fail;  
  20.     /* now we know the gpio is valid and chip won't vanish */  
  21.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  22.     might_sleep_if(chip->can_sleep);  
  23.     return chip->set_debounce(chip, gpio, debounce); //调用gpio_chip的set_debounce方法  
  24. fail:  
  25.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  26.     if (status)  
  27.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);  
  28.     return status;  
  29. }  
  30. EXPORT_SYMBOL_GPL(gpio_set_debounce);  

8.设置gpio为输入io

[cpp] view plaincopyprint?
  1. int gpio_direction_input(unsigned gpio)  
  2. {  
  3.     unsigned long   flags;  
  4.     struct gpio_chip    *chip;  
  5.     struct gpio_desc    *desc = &gpio_desc[gpio];   //获取gpio_desc项  
  6.     int status = -EINVAL;  
  7.   
  8.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  9.     if (!gpio_is_valid(gpio))  
  10.         goto fail;  
  11.     chip = desc->chip;   //获取gpio_chip  
  12.     if (!chip || !chip->get || !chip->direction_input)    //判断gpio_chip是否存在且存在get和directon_input方法  
  13.         goto fail;  
  14.     gpio -= chip->base;  //计算gpio在该gpio_chip的偏移量  
  15.     if (gpio >= chip->ngpio)  //超过该gpio_chip的gpio数范围  
  16.         goto fail;  
  17.     status = gpio_ensure_requested(desc, gpio); //确保gpio是request请求过了的  
  18.     if (status < 0)  
  19.         goto fail;  
  20.     /* now we know the gpio is valid and chip won't vanish */  
  21.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  22.     might_sleep_if(chip->can_sleep);  
  23.     if (status) {  
  24.         status = chip->request(chip, gpio);  //调用chip_gpio的request方法  
  25.         if (status < 0) {  
  26.             pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);  
  27.             goto lose;  
  28.         }  
  29.     }  
  30.     status = chip->direction_input(chip, gpio);  //调用chip_gpio的direction_input方法  
  31.     if (status == 0)  
  32.         clear_bit(FLAG_IS_OUT, &desc->flags);  
  33. lose:  
  34.     return status;  
  35. fail:  
  36.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  37.     if (status)  
  38.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);  
  39.     return status;  
  40. }  
  41. EXPORT_SYMBOL_GPL(gpio_direction_input);  

9.设备gpio为输出io

[cpp] view plaincopyprint?
  1. int gpio_direction_output(unsigned gpio, int value)  
  2. {  
  3.     unsigned long   flags;  
  4.     struct gpio_chip    *chip;  
  5.     struct gpio_desc    *desc = &gpio_desc[gpio];   //获取gpio_desc项  
  6.     int status = -EINVAL;  
  7.   
  8.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  9.     if (!gpio_is_valid(gpio))  
  10.         goto fail;  
  11.     chip = desc->chip;   //获取gpio_chip  
  12.     if (!chip || !chip->set || !chip->direction_output)   //判断gpio_chip是否存在且存在set和direction_output方法  
  13.         goto fail;  
  14.     gpio -= chip->base;  //计算gpio在该gpio_chip的偏移量  
  15.     if (gpio >= chip->ngpio)  //超过该gpio_chip的gpio数范围  
  16.         goto fail;  
  17.     status = gpio_ensure_requested(desc, gpio); //确保gpio是request请求过了的  
  18.     if (status < 0)  
  19.         goto fail;  
  20.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  21.     might_sleep_if(chip->can_sleep);  
  22.     if (status) {  
  23.         status = chip->request(chip, gpio);  //调用gpio_chip的request方法  
  24.         if (status < 0) {  
  25.             pr_debug("GPIO-%d: chip request fail, %d\n",chip->base + gpio, status);  
  26.             goto lose;  
  27.         }  
  28.     }  
  29.     status = chip->direction_output(chip, gpio, value);  //调用gpio_chip的direction_output方法  
  30.     if (status == 0)  
  31.         set_bit(FLAG_IS_OUT, &desc->flags);  
  32. lose:  
  33.     return status;  
  34. fail:  
  35.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  36.     if (status)  
  37.         pr_debug("%s: gpio-%d status %d\n",__func__, gpio, status);  
  38.     return status;  
  39. }  
  40. EXPORT_SYMBOL_GPL(gpio_direction_output);  

10.判断gpio可否睡眠

[cpp] view plaincopyprint?
  1. #define gpio_cansleep     __gpio_cansleep  
  2. int __gpio_cansleep(unsigned gpio)  
  3. {  
  4.     struct gpio_chip    *chip;  
  5.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  6.     return chip->can_sleep;      //调用gpio_chip的can_sleep方法  
  7. }  
  8. EXPORT_SYMBOL_GPL(__gpio_cansleep);  

11.获取gpio值(gpio可睡眠)

[cpp] view plaincopyprint?
  1. int gpio_get_value_cansleep(unsigned gpio)  
  2. {  
  3.     struct gpio_chip    *chip;  
  4.     might_sleep_if(extra_checks);  
  5.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  6.     return chip->get ? chip->get(chip, gpio - chip->base) : 0; //若存在gpio_chip的get方法则调用该方法  
  7. }  
  8. EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);  

12.设置gpio值(gpio可睡眠)

[cpp] view plaincopyprint?
  1. void gpio_set_value_cansleep(unsigned gpio, int value)  
  2. {  
  3.     struct gpio_chip    *chip;  
  4.     might_sleep_if(extra_checks);  
  5.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  6.     chip->set(chip, gpio - chip->base, value);    //调用gpio_chip的set方法  
  7. }  
  8. EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);  

13.获取gpio值(gpio不可睡眠)

[cpp] view plaincopyprint?
  1. #define gpio_get_value    __gpio_get_value    
  2. int __gpio_get_value(unsigned gpio)  
  3. {  
  4.     struct gpio_chip    *chip;  
  5.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  6.     WARN_ON(chip->can_sleep);  
  7.     return chip->get ? chip->get(chip, gpio - chip->base) : 0; //若存在gpio_chip的get方法则调用该方法  
  8. }  
  9. EXPORT_SYMBOL_GPL(__gpio_get_value);  

14.设置gpio值(gpio不可睡眠)

[cpp] view plaincopyprint?
  1. #define gpio_set_value    __gpio_set_value    
  2. void __gpio_set_value(unsigned gpio, int value)  
  3. {  
  4.     struct gpio_chip    *chip;  
  5.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  6.     WARN_ON(chip->can_sleep);  
  7.     chip->set(chip, gpio - chip->base, value);    //调用gpio_chip的set方法  
  8. }  
  9. EXPORT_SYMBOL_GPL(__gpio_set_value);  

15.请求一个gpio资源

[cpp] view plaincopyprint?
  1. int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)  
  2. {  
  3.     int err;  
  4.     err = gpio_request(gpio, label);    //请求gpio资源  
  5.     if (err)  
  6.         return err;  
  7.     if (flags & GPIOF_DIR_IN)   //输入gpio  
  8.         err = gpio_direction_input(gpio);   //设置gpio为输入  
  9.     else                        //输出gpio  
  10.         err = gpio_direction_output(gpio,(flags & GPIOF_INIT_HIGH) ? 1 : 0);    //设置gpio为输出  
  11.     if (err)    //出错  
  12.         gpio_free(gpio);    //释放gpio资源   
  13.     return err;  
  14. }  
  15. EXPORT_SYMBOL_GPL(gpio_request_one);  

16.请求一组gpio资源

[cpp] view plaincopyprint?
  1. int gpio_request_array(struct gpio *array, size_t num)  
  2. {  
  3.     int i, err;  
  4.     for (i = 0; i < num; i++, array++) { //批量请求gpio资源  
  5.         err = gpio_request_one(array->gpio, array->flags, array->label);  
  6.         if (err)  
  7.             goto err_free;  
  8.     }  
  9.     return 0;  
  10. err_free:  
  11.     while (i--)  
  12.         gpio_free((--array)->gpio);  //释放gpio资源  
  13.     return err;  
  14. }  
  15. EXPORT_SYMBOL_GPL(gpio_request_array);  

17.释放一组gpio资源

[cpp] view plaincopyprint?
  1. void gpio_free_array(struct gpio *array, size_t num)  
  2. {  
  3.     while (num--)  
  4.         gpio_free((array++)->gpio);  //批量是否gpio资源  
  5. }  
  6. EXPORT_SYMBOL_GPL(gpio_free_array);  

18.根据gpio号获取对应的中断号

[cpp] view plaincopyprint?
  1. int __gpio_to_irq(unsigned gpio)  
  2. {  
  3.     struct gpio_chip    *chip;  
  4.     chip = gpio_to_chip(gpio);  //获取gpio_chip  
  5.     return chip->to_irq?chip->to_irq(chip,gpio-chip->base):-ENXIO; //若gpio_chip的to_irq方法存在则调用其方法  
  6. }  
  7. EXPORT_SYMBOL_GPL(__gpio_to_irq);  

19.gpio_chip创建用户接口

[cpp] view plaincopyprint?
  1. static int gpiochip_export(struct gpio_chip *chip)  
  2. {  
  3.     int     status;  
  4.     struct device   *dev;  
  5.   
  6.     if (!gpio_class.p)  
  7.         return 0;  
  8.     mutex_lock(&sysfs_lock);    //上互斥锁   
  9.     dev = device_create(&gpio_class, chip->dev, MKDEV(0, 0), chip,"gpiochip%d", chip->base);  //创建设备  
  10.     if (!IS_ERR(dev)) {  
  11.         status = sysfs_create_group(&dev->kobj,&gpiochip_attr_group);  
  12.     }   
  13.     else  
  14.         status = PTR_ERR(dev);  
  15.     chip->exported = (status == 0);  //设置gpio_chip的exported标志  
  16.     mutex_unlock(&sysfs_lock);  //解互斥锁   
  17.   
  18.     if (status) {  
  19.         unsigned long   flags;  
  20.         unsigned    gpio;  
  21.         spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  22.         gpio = chip->base;   //获取gpio_chip的基数  
  23.         while (gpio_desc[gpio].chip == chip)    //遍历该gpio_chip管理的所有gpio_desc  
  24.             gpio_desc[gpio++].chip = NULL;      //清除该gpio_desc的chip成员  
  25.         spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  26.         pr_debug("%s: chip %s status %d\n", __func__,chip->label, status);  
  27.     }  
  28.   
  29.     return status;  
  30. }  

20.gpio_chip移除用户接口

[cpp] view plaincopyprint?
  1. static void gpiochip_unexport(struct gpio_chip *chip)  
  2. {  
  3.     int status;  
  4.     struct device   *dev;  
  5.   
  6.     mutex_lock(&sysfs_lock);    //上互斥锁   
  7.     dev = class_find_device(&gpio_class, NULL, chip, match_export); //找到export的gpio_chip的设备文件  
  8.     if (dev) {  
  9.         put_device(dev);    //减少引用计数  
  10.         device_unregister(dev); //注销设备文件   
  11.         chip->exported = 0;  //清除export标志  
  12.         status = 0; //设置status   
  13.     }   
  14.     else  
  15.         status = -ENODEV;  
  16.     mutex_unlock(&sysfs_lock);  //解互斥锁   
  17.     if (status)  
  18.         pr_debug("%s: chip %s status %d\n", __func__,chip->label, status);  
  19. }  

21.gpio创建用户接口

[cpp] view plaincopyprint?
  1. int gpio_export(unsigned gpio, bool direction_may_change)  
  2. {  
  3.     unsigned long   flags;  
  4.     struct gpio_desc    *desc;  
  5.     int status = -EINVAL;  
  6.     const char  *ioname = NULL;  
  7.   
  8.     if (!gpio_class.p) {  
  9.         pr_debug("%s: called too early!\n", __func__);  
  10.         return -ENOENT;  
  11.     }  
  12.     if (!gpio_is_valid(gpio))   //验证gpio号的正确性  
  13.         goto done;  
  14.     mutex_lock(&sysfs_lock);    //上互斥锁   
  15.     spin_lock_irqsave(&gpio_lock, flags);   //上自旋锁  
  16.     desc = &gpio_desc[gpio];    //获取gpio_desc数组项  
  17.     if (test_bit(FLAG_REQUESTED, &desc->flags)&& !test_bit(FLAG_EXPORT, &desc->flags)) {  //已请求但没export  
  18.         status = 0;  
  19.         if (!desc->chip->direction_input|| !desc->chip->direction_output)   //gpio_chip不存在direction_input和direction_output方法  
  20.             direction_may_change = false;   //那么gpio的方向不可能会改变  
  21.     }  
  22.     spin_unlock_irqrestore(&gpio_lock, flags);  //解自旋锁  
  23.     if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])  //gpio_chip存在名字数组且存在对应数组项的名字  
  24.         ioname = desc->chip->names[gpio - desc->chip->base];    //设置gpio名  
  25.     if (status == 0) {  
  26.         struct device   *dev;  
  27.         dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),desc, ioname ? ioname : "gpio%u", gpio);    //创建设备文件  
  28.         if (!IS_ERR(dev)) {  
  29.             status = sysfs_create_group(&dev->kobj,&gpio_attr_group);    //创建属性  
  30.             if (!status && direction_may_change)    //gpio方向可能会改变  
  31.                 status = device_create_file(dev,&dev_attr_direction);   //则创建跟方向相关的属性  
  32.             if (!status && gpio_to_irq(gpio) >= 0&& (direction_may_change|| !test_bit(FLAG_IS_OUT,&desc->flags))) //可设置中断的引荐  
  33.                 status = device_create_file(dev,&dev_attr_edge);    //则创建跟中断触发相关的属性  
  34.             if (status != 0)  
  35.                 device_unregister(dev); //注销设备  
  36.         }   
  37.         else  
  38.             status = PTR_ERR(dev);  
  39.         if (status == 0)  
  40.             set_bit(FLAG_EXPORT, &desc->flags);  //设置export标志  
  41.     }  
  42.     mutex_unlock(&sysfs_lock);  //解互斥锁   
  43. done:  
  44.     if (status)  
  45.         pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);  
  46.     return status;  
  47. }  
  48. EXPORT_SYMBOL_GPL(gpio_export);  

22.gpio移除用户接口

[cpp] view plaincopyprint?
  1. void gpio_unexport(unsigned gpio)  
  2. {  
  3.     struct gpio_desc    *desc;  
  4.     int         status = 0;  
  5.       
  6.     if (!gpio_is_valid(gpio)) { //验证gpio号的正确性  
  7.         status = -EINVAL;  
  8.         goto done;  
  9.     }  
  10.     mutex_lock(&sysfs_lock);    //上锁互斥锁   
  11.     desc = &gpio_desc[gpio];    //获取gpio_desc  
  12.     if (test_bit(FLAG_EXPORT, &desc->flags)) {   //判断是否export  
  13.         struct device   *dev = NULL;  
  14.         dev = class_find_device(&gpio_class, NULL, desc, match_export); //获取设备文件  
  15.         if (dev) {  
  16.             gpio_setup_irq(desc, dev, 0);   //中断gpio的处理  
  17.             clear_bit(FLAG_EXPORT, &desc->flags);    //清除export标志  
  18.             put_device(dev);    //增加dev引用计数  
  19.             device_unregister(dev); //注销设备  
  20.         }   
  21.         else  
  22.             status = -ENODEV;  
  23.     }  
  24.     mutex_unlock(&sysfs_lock);  //解锁互斥锁   
  25. done:  
  26.     if (status)  
  27.         pr_debug("%s: gpio%d status %d\n", __func__, gpio, status);  
  28. }  
  29. EXPORT_SYMBOL_GPL(gpio_unexport);  

23.中断gpio处理

[cpp] view plaincopyprint?
  1. static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,unsigned long gpio_flags)  
  2. {  
  3.     struct sysfs_dirent *value_sd;  
  4.     unsigned long   irq_flags;  
  5.     int ret, irq, id;  
  6.   
  7.     if ((desc->flags & GPIO_TRIGGER_MASK) == gpio_flags) //有FLAG_TRIG_FALL或FLAG_TRIG_RISE标志  
  8.         return 0;  
  9.     irq = gpio_to_irq(desc - gpio_desc);    //根据gpio获取对应的中断号  
  10.     if (irq < 0)  
  11.         return -EIO;  
  12.     id = desc->flags >> ID_SHIFT;  //#define ID_SHIFT  16  
  13.     value_sd = idr_find(&dirent_idr, id);   //获取设备id  
  14.     if (value_sd)   //获取设备id成功,说明是申请过gpio中断的了  
  15.         free_irq(irq, value_sd);    //释放中断  
  16.     desc->flags &= ~GPIO_TRIGGER_MASK;   //屏蔽gpio_desc标志位FLAG_TRIG_FALL或FLAG_TRIG_RISE  
  17.     if (!gpio_flags) {  //gpio_unexport中的gpio_setup_irq跑到这里返回  
  18.         ret = 0;  
  19.         goto free_id;  
  20.     }  
  21.     irq_flags = IRQF_SHARED;    //设置为共享中断类型  
  22.     if (test_bit(FLAG_TRIG_FALL, &gpio_flags))  //FLAG_TRIG_FALL 下降沿触发  
  23.         irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;  
  24.     if (test_bit(FLAG_TRIG_RISE, &gpio_flags))  //FLAG_TRIG_RISE 上升沿触发  
  25.         irq_flags |= test_bit(FLAG_ACTIVE_LOW, &desc->flags) ?IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;  
  26.     if (!value_sd) {    //获取设备id不成功  
  27.         value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");    //获取设备id  
  28.         if (!value_sd) {  
  29.             ret = -ENODEV;  
  30.             goto err_out;  
  31.         }  
  32.         do {  
  33.             ret = -ENOMEM;  
  34.             if (idr_pre_get(&dirent_idr, GFP_KERNEL))  
  35.                 ret = idr_get_new_above(&dirent_idr, value_sd,1, &id);  
  36.         } while (ret == -EAGAIN);//id机制中获取新的id该id指向value_sd  
  37.         if (ret)  
  38.             goto free_sd;  
  39.         desc->flags &= GPIO_FLAGS_MASK;      //设置gpio_desc标志  
  40.         desc->flags |= (unsigned long)id << ID_SHIFT;  //或上idr机制获取的id  
  41.         if (desc->flags >> ID_SHIFT != id) {   //验证下是否id存放正确  
  42.             ret = -ERANGE;  
  43.             goto free_id;  
  44.         }  
  45.     }  
  46.     ret = request_any_context_irq(irq, gpio_sysfs_irq, irq_flags,"gpiolib", value_sd);  //申请中断  
  47.     if (ret < 0)  
  48.         goto free_id;  
  49.     desc->flags |= gpio_flags;   //gpio_desc设置传递进来的标志  
  50.     return 0;  
  51. free_id:  
  52.     idr_remove(&dirent_idr, id);  
  53.     desc->flags &= GPIO_FLAGS_MASK;  
  54. free_sd:  
  55.     if (value_sd)  
  56.         sysfs_put(value_sd);  
  57. err_out:  
  58.     return ret;  
  59. }  


四.sysfs的初始化

[cpp] view plaincopyprint?
  1. static int __init gpiolib_sysfs_init(void)  
  2. {  
  3.     int status;  
  4.     unsigned long   flags;  
  5.     unsigned    gpio;  
  6.   
  7.     status = class_register(&gpio_class);   //注册gpio_class  
  8.     if (status < 0)  
  9.         return status;  
  10.   
  11.     spin_lock_irqsave(&gpio_lock, flags);  
  12.     for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) {   //遍历全局gpio_desc数组  
  13.         struct gpio_chip    *chip;  
  14.   
  15.         chip = gpio_desc[gpio].chip;    //获取数组项的gpio_chip  
  16.         if (!chip || chip->exported) //gpio_chip为空或已经exported了  
  17.             continue;  
  18.   
  19.         spin_unlock_irqrestore(&gpio_lock, flags);  //上自旋锁  
  20.         status = gpiochip_export(chip); //exported该项  
  21.         spin_lock_irqsave(&gpio_lock, flags);   //解自旋锁  
  22.     }  
  23.     spin_unlock_irqrestore(&gpio_lock, flags);  
  24.   
  25.   
  26.     return status;  
  27. }  
  28. postcore_initcall(gpiolib_sysfs_init);  


























 

原创粉丝点击