gpio.c 6.6 KB

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