Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3115135
  • 博文数量: 685
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5303
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-19 14:17
个人简介

文章分类

全部博文(685)

文章存档

2015年(116)

2014年(569)

分类: LINUX

2014-11-04 14:41:53

原文地址:http://blog.csdn.net/maopig/article/details/7428561
其原型为 int gpio_request(unsigned gpio, const char *label) 先说说其参数,gpio则为你要申请的哪一个管脚,label则是为其取一个名字。其具体实现如下:


  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. spin_lock_irqsave(&gpio_lock, flags);//屏蔽中断
  8. if (!gpio_is_valid(gpio))//判断是否有效,也就是参数的取值范围判断
  9. goto done;
  10. desc = &gpio_desc[gpio];
  11. //这个是关键gpio_desc为定义的一个全局的数组变量,这个函数的实值也就是,
  12. //用gpio_desc里面的一个变量来表示数组中的这个元素已经被申请了,而这个变量就是下面会看到的desc->flags。
  13. chip = desc->chip;//按理说这个这个全局的gpio_desc如果没有初始化的话,这个chip就为空了,随后就直接返回-EINVAL了。
  14. if (chip == NULL)如果不为空继续往下走
  15. goto done;
  16. if (!try_module_get(chip->owner))
  17. goto done;
  18. /* NOTE: gpio_request() can be called in early boot,
  19. * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
  20. */
  21. if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
  22. //这里测试并设置flags的第FLAG_REQUESTED位,如果没有被申请就返回该位的原值0,分析到这儿,也差不多满足了我的个人要求。
  23. desc_set_label(desc, label ? : "?");
  24. status = 0;
  25. } else {
  26. status = -EBUSY;
  27. module_put(chip->owner);
  28. goto done;
  29. }
  30. if (chip->request) {
  31. /* chip->request may sleep */
  32. spin_unlock_irqrestore(&gpio_lock, flags);
  33. status = chip->request(chip, gpio - chip->base);
  34. spin_lock_irqsave(&gpio_lock, flags);
  35. if (status < 0) {
  36. desc_set_label(desc, NULL);
  37. module_put(chip->owner);
  38. clear_bit(FLAG_REQUESTED, &desc->flags);
  39. }
  40. }
  41. done:
  42. if (status)
  43. pr_debug("gpio_request: gpio-%d (%s) status %d\n",
  44. gpio, label ? : "?", status);
  45. spin_unlock_irqrestore(&gpio_lock, flags);
  46. return status;
  47. }
  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. spin_lock_irqsave(&gpio_lock, flags);//屏蔽中断
  8. if (!gpio_is_valid(gpio))//判断是否有效,也就是参数的取值范围判断
  9. goto done;
  10. desc = &gpio_desc[gpio];
  11. //这个是关键gpio_desc为定义的一个全局的数组变量,这个函数的实值也就是,
  12. //用gpio_desc里面的一个变量来表示数组中的这个元素已经被申请了,而这个变量就是下面会看到的desc->flags。
  13. chip = desc->chip;//按理说这个这个全局的gpio_desc如果没有初始化的话,这个chip就为空了,随后就直接返回-EINVAL了。
  14. if (chip == NULL)如果不为空继续往下走
  15. goto done;
  16. if (!try_module_get(chip->owner))
  17. goto done;
  18. /* NOTE: gpio_request() can be called in early boot,
  19. * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
  20. */
  21. if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
  22. //这里测试并设置flags的第FLAG_REQUESTED位,如果没有被申请就返回该位的原值0,分析到这儿,也差不多满足了我的个人要求。
  23. desc_set_label(desc, label ? : "?");
  24. status = 0;
  25. } else {
  26. status = -EBUSY;
  27. module_put(chip->owner);
  28. goto done;
  29. }
  30. if (chip->request) {
  31. /* chip->request may sleep */
  32. spin_unlock_irqrestore(&gpio_lock, flags);
  33. status = chip->request(chip, gpio - chip->base);
  34. spin_lock_irqsave(&gpio_lock, flags);
  35. if (status < 0) {
  36. desc_set_label(desc, NULL);
  37. module_put(chip->owner);
  38. clear_bit(FLAG_REQUESTED, &desc->flags);
  39. }
  40. }
  41. done:
  42. if (status)
  43. pr_debug("gpio_request: gpio-%d (%s) status %d\n",
  44. gpio, label ? : "?", status);
  45. spin_unlock_irqrestore(&gpio_lock, flags);
  46. return status;
  47. }
int gpio_request(unsigned gpio, const char *label) { struct gpio_desc *desc;//这个自己看源码 struct gpio_chip *chip;//这个自己看源码 int status = -EINVAL; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags);//屏蔽中断 if (!gpio_is_valid(gpio))//判断是否有效,也就是参数的取值范围判断 goto done; desc = &gpio_desc[gpio]; //这个是关键gpio_desc为定义的一个全局的数组变量,这个函数的实值也就是, //用gpio_desc里面的一个变量来表示数组中的这个元素已经被申请了,而这个变量就是下面会看到的desc->flags。 chip = desc->chip;//按理说这个这个全局的gpio_desc如果没有初始化的话,这个chip就为空了,随后就直接返回-EINVAL了。 if (chip == NULL)如果不为空继续往下走 goto done; if (!try_module_get(chip->owner)) goto done; /* NOTE: gpio_request() can be called in early boot, * before IRQs are enabled, for non-sleeping (SOC) GPIOs. */ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) { //这里测试并设置flags的第FLAG_REQUESTED位,如果没有被申请就返回该位的原值0,分析到这儿,也差不多满足了我的个人要求。 desc_set_label(desc, label ? : "?"); status = 0; } else { status = -EBUSY; module_put(chip->owner); goto done; } if (chip->request) { /* chip->request may sleep */ spin_unlock_irqrestore(&gpio_lock, flags); status = chip->request(chip, gpio - chip->base); spin_lock_irqsave(&gpio_lock, flags); if (status < 0) { desc_set_label(desc, NULL); module_put(chip->owner); clear_bit(FLAG_REQUESTED, &desc->flags); } } done: if (status) pr_debug("gpio_request: gpio-%d (%s) status %d\n", gpio, label ? : "?", status); spin_unlock_irqrestore(&gpio_lock, flags); return status; }
davinci 平台:
  1. /*
  2. * TI DaVinci GPIO Support
  3. *
  4. * Copyright (c) 2006 David Brownell
  5. * Copyright (c) 2007, MontaVista Software, Inc.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. */
  12. #include
  13. #include
  14. #include
  15. #include
  16. #include
  17. #include
  18. #include
  19. #include
  20. #include
  21. #include
  22. #include
  23. #include
  24. #include
  25. #include
  26. /*
  27. 该文件实现了gpio的各种应用功能和向内核注册gpio的中断例程等功能。
  28. 用户的驱动程序可调用gpio_request和gpio_free使用或释放该gpio,
  29. 可以调用gpio_direction_input和gpio_direction_output函数设置gpio输入输出方向,
  30. 调用gpio_get_value和gpio_set_value获取设置值。
  31. */
  32. static DEFINE_SPINLOCK(gpio_lock);
  33. /* 总共有DAVINCI_N_GPIO(71)个gpio引脚,故使用相应多的bit来记录这些引脚的使用状态 */
  34. static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
  35. /*
  36. 申请一个gpio,其实就是检查该gpio是否空闲,如果空闲就可以使用并将该gpio相应的bit置位
  37. (在gpio_in_use中)。
  38. */
  39. int gpio_request(unsigned gpio, const char *tag)
  40. {
  41. if (gpio >= DAVINCI_N_GPIO)
  42. return -EINVAL;
  43. if (test_and_set_bit(gpio, gpio_in_use))
  44. return -EBUSY;
  45. return 0;
  46. }
  47. EXPORT_SYMBOL(gpio_request);
  48. /*
  49. 释放一个gpio,其实就是清除gpio相应的控制bit位(在gpio_in_use中)。
  50. */
  51. void gpio_free(unsigned gpio)
  52. {
  53. if (gpio >= DAVINCI_N_GPIO)
  54. return;
  55. clear_bit(gpio, gpio_in_use);
  56. }
  57. EXPORT_SYMBOL(gpio_free);
  58. /* 获得gpio_controller结构体指针,gpio_controller结构体是gpio的核心控制单元,里面包含
  59. gpio的设置和数据寄存器。该结构体和__gpio_to_controller函数在/include/asm-arm/
  60. arch-davinci/gpio.h中定义,具体如下:
  61. struct gpio_controller {
  62. u32 dir;
  63. u32 out_data;
  64. u32 set_data;
  65. u32 clr_data;
  66. u32 in_data;
  67. u32 set_rising;
  68. u32 clr_rising;
  69. u32 set_falling;
  70. u32 clr_falling;
  71. u32 intstat;
  72. };
  73. static inline struct gpio_controller *__iomem
  74. __gpio_to_controller(unsigned gpio)
  75. {
  76. void *__iomem ptr;
  77. if (gpio >= DAVINCI_N_GPIO)
  78. return NULL;
  79. if (gpio < 32)
  80. ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x10);
  81. else if (gpio < 64)
  82. ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x38);
  83. else if (gpio < 96)
  84. ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x60);
  85. else
  86. ptr = (void *__iomem)IO_ADDRESS(DAVINCI_GPIO_BASE + 0x88);
  87. return ptr;
  88. }
  89. 由上面的定义和ti的SPRUE25.pdf手册可以看出,__gpio_to_controller函数返回的是
  90. gpio_controller结构体到第一个成员dir的虚拟地址。获取了这个结构体指针后,
  91. 便可以控制相应的gpio了。dm644x共有71个gpio,
  92. 所以使用三个gpio_controller结构体控制,关于这个后面会由更详细的分析,
  93. */
  94. /* create a non-inlined version */
  95. static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
  96. {
  97. return __gpio_to_controller(gpio);
  98. }
  99. /*
  100. 向某个gpio设置值,0或1。如果向gpio写1,则向set_data寄存器相应的位置1,如果写0,
  101. 则向clr_data寄存器相应的位置1.__gpio_mask函数在gpio.h中定义,定义如下,
  102. static inline u32 __gpio_mask(unsigned gpio)
  103. {
  104. return 1 << (gpio % 32);
  105. }
  106. 因为71个引脚由3个结构体控制,第一个控制前32个gpio,第二个控制次32个gpio,
  107. 最后一个控制剩余的7个gpio,故__gpio_mask函数的作用是找到在其相应控制结构体里的偏移数,
  108. 比如gpio34,那么其由第二个结构体控制,在这个机构体里的偏移是3(从0开始算,就是第二位)。
  109. 使用这个函数之前,必须确认该gpio设置成输出模式。
  110. */
  111. /*
  112. * Assuming the pin is muxed as a gpio output, set its output value.
  113. */
  114. void __gpio_set(unsigned gpio, int value)
  115. {
  116. struct gpio_controller *__iomem g = gpio2controller(gpio);
  117. // 设置gpio的值
  118. __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
  119. }
  120. EXPORT_SYMBOL(__gpio_set);
  121. /*
  122. 通过读取in_data寄存器相应该gpio的位来读取gpio的值。
  123. 使用这个函数之前,必须确认该gpio设置成输入模式,否则获得到值不可预料。
  124. */
  125. /*
  126. * Read the pin's value (works even if it's set up as output);
  127. * returns zero/nonzero.
阅读(1054) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~