gpio-uclass.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * Copyright (c) 2013 Google, Inc
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <asm/gpio.h>
  10. #include <linux/ctype.h>
  11. /**
  12. * gpio_to_device() - Convert global GPIO number to device, number
  13. * gpio: The numeric representation of the GPIO
  14. *
  15. * Convert the GPIO number to an entry in the list of GPIOs
  16. * or GPIO blocks registered with the GPIO controller. Returns
  17. * entry on success, NULL on error.
  18. */
  19. static int gpio_to_device(unsigned int gpio, struct udevice **devp,
  20. unsigned int *offset)
  21. {
  22. struct gpio_dev_priv *uc_priv;
  23. struct udevice *dev;
  24. int ret;
  25. for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  26. dev;
  27. ret = uclass_next_device(&dev)) {
  28. uc_priv = dev->uclass_priv;
  29. if (gpio >= uc_priv->gpio_base &&
  30. gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
  31. *devp = dev;
  32. *offset = gpio - uc_priv->gpio_base;
  33. return 0;
  34. }
  35. }
  36. /* No such GPIO */
  37. return ret ? ret : -EINVAL;
  38. }
  39. int gpio_lookup_name(const char *name, struct udevice **devp,
  40. unsigned int *offsetp, unsigned int *gpiop)
  41. {
  42. struct gpio_dev_priv *uc_priv = NULL;
  43. struct udevice *dev;
  44. ulong offset;
  45. int numeric;
  46. int ret;
  47. if (devp)
  48. *devp = NULL;
  49. numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
  50. for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  51. dev;
  52. ret = uclass_next_device(&dev)) {
  53. int len;
  54. uc_priv = dev->uclass_priv;
  55. if (numeric != -1) {
  56. offset = numeric - uc_priv->gpio_base;
  57. /* Allow GPIOs to be numbered from 0 */
  58. if (offset >= 0 && offset < uc_priv->gpio_count)
  59. break;
  60. }
  61. len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
  62. if (!strncasecmp(name, uc_priv->bank_name, len)) {
  63. if (!strict_strtoul(name + len, 10, &offset))
  64. break;
  65. }
  66. }
  67. if (!dev)
  68. return ret ? ret : -EINVAL;
  69. if (devp)
  70. *devp = dev;
  71. if (offsetp)
  72. *offsetp = offset;
  73. if (gpiop)
  74. *gpiop = uc_priv->gpio_base + offset;
  75. return 0;
  76. }
  77. /**
  78. * gpio_request() - [COMPAT] Request GPIO
  79. * gpio: GPIO number
  80. * label: Name for the requested GPIO
  81. *
  82. * This function implements the API that's compatible with current
  83. * GPIO API used in U-Boot. The request is forwarded to particular
  84. * GPIO driver. Returns 0 on success, negative value on error.
  85. */
  86. int gpio_request(unsigned gpio, const char *label)
  87. {
  88. unsigned int offset;
  89. struct udevice *dev;
  90. int ret;
  91. ret = gpio_to_device(gpio, &dev, &offset);
  92. if (ret)
  93. return ret;
  94. if (!gpio_get_ops(dev)->request)
  95. return 0;
  96. return gpio_get_ops(dev)->request(dev, offset, label);
  97. }
  98. /**
  99. * gpio_free() - [COMPAT] Relinquish GPIO
  100. * gpio: GPIO number
  101. *
  102. * This function implements the API that's compatible with current
  103. * GPIO API used in U-Boot. The request is forwarded to particular
  104. * GPIO driver. Returns 0 on success, negative value on error.
  105. */
  106. int gpio_free(unsigned gpio)
  107. {
  108. unsigned int offset;
  109. struct udevice *dev;
  110. int ret;
  111. ret = gpio_to_device(gpio, &dev, &offset);
  112. if (ret)
  113. return ret;
  114. if (!gpio_get_ops(dev)->free)
  115. return 0;
  116. return gpio_get_ops(dev)->free(dev, offset);
  117. }
  118. /**
  119. * gpio_direction_input() - [COMPAT] Set GPIO direction to input
  120. * gpio: GPIO number
  121. *
  122. * This function implements the API that's compatible with current
  123. * GPIO API used in U-Boot. The request is forwarded to particular
  124. * GPIO driver. Returns 0 on success, negative value on error.
  125. */
  126. int gpio_direction_input(unsigned gpio)
  127. {
  128. unsigned int offset;
  129. struct udevice *dev;
  130. int ret;
  131. ret = gpio_to_device(gpio, &dev, &offset);
  132. if (ret)
  133. return ret;
  134. return gpio_get_ops(dev)->direction_input(dev, offset);
  135. }
  136. /**
  137. * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
  138. * gpio: GPIO number
  139. * value: Logical value to be set on the GPIO pin
  140. *
  141. * This function implements the API that's compatible with current
  142. * GPIO API used in U-Boot. The request is forwarded to particular
  143. * GPIO driver. Returns 0 on success, negative value on error.
  144. */
  145. int gpio_direction_output(unsigned gpio, int value)
  146. {
  147. unsigned int offset;
  148. struct udevice *dev;
  149. int ret;
  150. ret = gpio_to_device(gpio, &dev, &offset);
  151. if (ret)
  152. return ret;
  153. return gpio_get_ops(dev)->direction_output(dev, offset, value);
  154. }
  155. /**
  156. * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
  157. * gpio: GPIO number
  158. *
  159. * This function implements the API that's compatible with current
  160. * GPIO API used in U-Boot. The request is forwarded to particular
  161. * GPIO driver. Returns the value of the GPIO pin, or negative value
  162. * on error.
  163. */
  164. int gpio_get_value(unsigned gpio)
  165. {
  166. unsigned int offset;
  167. struct udevice *dev;
  168. int ret;
  169. ret = gpio_to_device(gpio, &dev, &offset);
  170. if (ret)
  171. return ret;
  172. return gpio_get_ops(dev)->get_value(dev, offset);
  173. }
  174. /**
  175. * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
  176. * gpio: GPIO number
  177. * value: Logical value to be set on the GPIO pin.
  178. *
  179. * This function implements the API that's compatible with current
  180. * GPIO API used in U-Boot. The request is forwarded to particular
  181. * GPIO driver. Returns 0 on success, negative value on error.
  182. */
  183. int gpio_set_value(unsigned gpio, int value)
  184. {
  185. unsigned int offset;
  186. struct udevice *dev;
  187. int ret;
  188. ret = gpio_to_device(gpio, &dev, &offset);
  189. if (ret)
  190. return ret;
  191. return gpio_get_ops(dev)->set_value(dev, offset, value);
  192. }
  193. const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
  194. {
  195. struct gpio_dev_priv *priv;
  196. /* Must be called on an active device */
  197. priv = dev->uclass_priv;
  198. assert(priv);
  199. *bit_count = priv->gpio_count;
  200. return priv->bank_name;
  201. }
  202. /* We need to renumber the GPIOs when any driver is probed/removed */
  203. static int gpio_renumber(void)
  204. {
  205. struct gpio_dev_priv *uc_priv;
  206. struct udevice *dev;
  207. struct uclass *uc;
  208. unsigned base;
  209. int ret;
  210. ret = uclass_get(UCLASS_GPIO, &uc);
  211. if (ret)
  212. return ret;
  213. /* Ensure that we have a base for each bank */
  214. base = 0;
  215. uclass_foreach_dev(dev, uc) {
  216. if (device_active(dev)) {
  217. uc_priv = dev->uclass_priv;
  218. uc_priv->gpio_base = base;
  219. base += uc_priv->gpio_count;
  220. }
  221. }
  222. return 0;
  223. }
  224. static int gpio_post_probe(struct udevice *dev)
  225. {
  226. return gpio_renumber();
  227. }
  228. static int gpio_pre_remove(struct udevice *dev)
  229. {
  230. return gpio_renumber();
  231. }
  232. UCLASS_DRIVER(gpio) = {
  233. .id = UCLASS_GPIO,
  234. .name = "gpio",
  235. .post_probe = gpio_post_probe,
  236. .pre_remove = gpio_pre_remove,
  237. .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
  238. };