gpio.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Control GPIO pins on the fly
  3. *
  4. * Copyright (c) 2008-2011 Analog Devices Inc.
  5. *
  6. * Licensed under the GPL-2 or later.
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <errno.h>
  11. #include <dm.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <asm/gpio.h>
  15. #include <linux/err.h>
  16. __weak int name_to_gpio(const char *name)
  17. {
  18. return dectoul(name, NULL);
  19. }
  20. enum gpio_cmd {
  21. GPIOC_INPUT,
  22. GPIOC_SET,
  23. GPIOC_CLEAR,
  24. GPIOC_TOGGLE,
  25. };
  26. #if defined(CONFIG_DM_GPIO) && !defined(gpio_status)
  27. /* A few flags used by show_gpio() */
  28. enum {
  29. FLAG_SHOW_ALL = 1 << 0,
  30. FLAG_SHOW_BANK = 1 << 1,
  31. FLAG_SHOW_NEWLINE = 1 << 2,
  32. };
  33. static void gpio_get_description(struct udevice *dev, const char *bank_name,
  34. int offset, int *flagsp, bool show_all)
  35. {
  36. char buf[80];
  37. int ret;
  38. ret = gpio_get_function(dev, offset, NULL);
  39. if (ret < 0)
  40. goto err;
  41. if (!show_all && !(*flagsp & FLAG_SHOW_ALL) && ret == GPIOF_UNUSED)
  42. return;
  43. if ((*flagsp & FLAG_SHOW_BANK) && bank_name) {
  44. if (*flagsp & FLAG_SHOW_NEWLINE) {
  45. putc('\n');
  46. *flagsp &= ~FLAG_SHOW_NEWLINE;
  47. }
  48. printf("Bank %s:\n", bank_name);
  49. *flagsp &= ~FLAG_SHOW_BANK;
  50. }
  51. ret = gpio_get_status(dev, offset, buf, sizeof(buf));
  52. if (ret)
  53. goto err;
  54. printf("%s\n", buf);
  55. return;
  56. err:
  57. printf("Error %d\n", ret);
  58. }
  59. static int do_gpio_status(bool all, const char *gpio_name)
  60. {
  61. struct udevice *dev;
  62. int banklen;
  63. int flags;
  64. int ret;
  65. flags = 0;
  66. if (gpio_name && !*gpio_name)
  67. gpio_name = NULL;
  68. for (ret = uclass_first_device(UCLASS_GPIO, &dev);
  69. dev;
  70. ret = uclass_next_device(&dev)) {
  71. const char *bank_name;
  72. int num_bits;
  73. flags |= FLAG_SHOW_BANK;
  74. if (all)
  75. flags |= FLAG_SHOW_ALL;
  76. bank_name = gpio_get_bank_info(dev, &num_bits);
  77. if (!num_bits) {
  78. debug("GPIO device %s has no bits\n", dev->name);
  79. continue;
  80. }
  81. banklen = bank_name ? strlen(bank_name) : 0;
  82. if (!gpio_name || !bank_name ||
  83. !strncasecmp(gpio_name, bank_name, banklen)) {
  84. const char *p;
  85. int offset;
  86. p = gpio_name + banklen;
  87. if (gpio_name && *p) {
  88. offset = dectoul(p, NULL);
  89. gpio_get_description(dev, bank_name, offset,
  90. &flags, true);
  91. } else {
  92. for (offset = 0; offset < num_bits; offset++) {
  93. gpio_get_description(dev, bank_name,
  94. offset, &flags, false);
  95. }
  96. }
  97. }
  98. /* Add a newline between bank names */
  99. if (!(flags & FLAG_SHOW_BANK))
  100. flags |= FLAG_SHOW_NEWLINE;
  101. }
  102. return ret;
  103. }
  104. #endif
  105. static int do_gpio(struct cmd_tbl *cmdtp, int flag, int argc,
  106. char *const argv[])
  107. {
  108. unsigned int gpio;
  109. enum gpio_cmd sub_cmd;
  110. int value;
  111. const char *str_cmd, *str_gpio = NULL;
  112. int ret;
  113. #ifdef CONFIG_DM_GPIO
  114. bool all = false;
  115. #endif
  116. if (argc < 2)
  117. show_usage:
  118. return CMD_RET_USAGE;
  119. str_cmd = argv[1];
  120. argc -= 2;
  121. argv += 2;
  122. #ifdef CONFIG_DM_GPIO
  123. if (argc > 0 && !strcmp(*argv, "-a")) {
  124. all = true;
  125. argc--;
  126. argv++;
  127. }
  128. #endif
  129. if (argc > 0)
  130. str_gpio = *argv;
  131. if (!strncmp(str_cmd, "status", 2)) {
  132. /* Support deprecated gpio_status() */
  133. #ifdef gpio_status
  134. gpio_status();
  135. return 0;
  136. #elif defined(CONFIG_DM_GPIO)
  137. return cmd_process_error(cmdtp, do_gpio_status(all, str_gpio));
  138. #else
  139. goto show_usage;
  140. #endif
  141. }
  142. if (!str_gpio)
  143. goto show_usage;
  144. /* parse the behavior */
  145. switch (*str_cmd) {
  146. case 'i':
  147. sub_cmd = GPIOC_INPUT;
  148. break;
  149. case 's':
  150. sub_cmd = GPIOC_SET;
  151. break;
  152. case 'c':
  153. sub_cmd = GPIOC_CLEAR;
  154. break;
  155. case 't':
  156. sub_cmd = GPIOC_TOGGLE;
  157. break;
  158. default:
  159. goto show_usage;
  160. }
  161. #if defined(CONFIG_DM_GPIO)
  162. /*
  163. * TODO(sjg@chromium.org): For now we must fit into the existing GPIO
  164. * framework, so we look up the name here and convert it to a GPIO number.
  165. * Once all GPIO drivers are converted to driver model, we can change the
  166. * code here to use the GPIO uclass interface instead of the numbered
  167. * GPIO compatibility layer.
  168. */
  169. ret = gpio_lookup_name(str_gpio, NULL, NULL, &gpio);
  170. if (ret) {
  171. printf("GPIO: '%s' not found\n", str_gpio);
  172. return cmd_process_error(cmdtp, ret);
  173. }
  174. #else
  175. /* turn the gpio name into a gpio number */
  176. gpio = name_to_gpio(str_gpio);
  177. if (gpio < 0)
  178. goto show_usage;
  179. #endif
  180. /* grab the pin before we tweak it */
  181. ret = gpio_request(gpio, "cmd_gpio");
  182. if (ret && ret != -EBUSY) {
  183. printf("gpio: requesting pin %u failed\n", gpio);
  184. return -1;
  185. }
  186. /* finally, let's do it: set direction and exec command */
  187. if (sub_cmd == GPIOC_INPUT) {
  188. gpio_direction_input(gpio);
  189. value = gpio_get_value(gpio);
  190. } else {
  191. switch (sub_cmd) {
  192. case GPIOC_SET:
  193. value = 1;
  194. break;
  195. case GPIOC_CLEAR:
  196. value = 0;
  197. break;
  198. case GPIOC_TOGGLE:
  199. value = gpio_get_value(gpio);
  200. if (!IS_ERR_VALUE(value))
  201. value = !value;
  202. break;
  203. default:
  204. goto show_usage;
  205. }
  206. gpio_direction_output(gpio, value);
  207. }
  208. printf("gpio: pin %s (gpio %u) value is ", str_gpio, gpio);
  209. if (IS_ERR_VALUE(value)) {
  210. printf("unknown (ret=%d)\n", value);
  211. goto err;
  212. } else {
  213. printf("%d\n", value);
  214. }
  215. if (sub_cmd != GPIOC_INPUT && !IS_ERR_VALUE(value)) {
  216. int nval = gpio_get_value(gpio);
  217. if (IS_ERR_VALUE(nval)) {
  218. printf(" Warning: no access to GPIO output value\n");
  219. goto err;
  220. } else if (nval != value) {
  221. printf(" Warning: value of pin is still %d\n", nval);
  222. goto err;
  223. }
  224. }
  225. if (ret != -EBUSY)
  226. gpio_free(gpio);
  227. /*
  228. * Whilst wrong, the legacy gpio input command returns the pin
  229. * value, or CMD_RET_FAILURE (which is indistinguishable from a
  230. * valid pin value).
  231. */
  232. return (sub_cmd == GPIOC_INPUT) ? value : CMD_RET_SUCCESS;
  233. err:
  234. if (ret != -EBUSY)
  235. gpio_free(gpio);
  236. return CMD_RET_FAILURE;
  237. }
  238. U_BOOT_CMD(gpio, 4, 0, do_gpio,
  239. "query and control gpio pins",
  240. "<input|set|clear|toggle> <pin>\n"
  241. " - input/set/clear/toggle the specified pin\n"
  242. "gpio status [-a] [<bank> | <pin>] - show [all/claimed] GPIOs");