pinmux.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  4. */
  5. #include <common.h>
  6. #include <command.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <dm/pinctrl.h>
  10. #include <dm/uclass-internal.h>
  11. #define LIMIT_DEVNAME 30
  12. static struct udevice *currdev;
  13. static int do_dev(struct cmd_tbl *cmdtp, int flag, int argc,
  14. char *const argv[])
  15. {
  16. const char *name;
  17. int ret;
  18. switch (argc) {
  19. case 2:
  20. name = argv[1];
  21. ret = uclass_get_device_by_name(UCLASS_PINCTRL, name, &currdev);
  22. if (ret) {
  23. printf("Can't get the pin-controller: %s!\n", name);
  24. return CMD_RET_FAILURE;
  25. }
  26. /* fall through */
  27. case 1:
  28. if (!currdev) {
  29. printf("Pin-controller device is not set!\n");
  30. return CMD_RET_USAGE;
  31. }
  32. printf("dev: %s\n", currdev->name);
  33. }
  34. return CMD_RET_SUCCESS;
  35. }
  36. /**
  37. * Print the muxing information for one or all pins of one pinctrl device
  38. *
  39. * @param dev pinctrl device
  40. * @param name NULL to display all the pins
  41. * or name of the pin to display
  42. * @return 0 on success, non-0 on error
  43. */
  44. static int show_pinmux(struct udevice *dev, char *name)
  45. {
  46. char pin_name[PINNAME_SIZE];
  47. char pin_mux[PINMUX_SIZE];
  48. int pins_count;
  49. int i;
  50. int ret;
  51. bool found = false;
  52. pins_count = pinctrl_get_pins_count(dev);
  53. if (pins_count == -ENOSYS) {
  54. printf("Ops get_pins_count not supported by %s\n", dev->name);
  55. return pins_count;
  56. }
  57. for (i = 0; i < pins_count; i++) {
  58. ret = pinctrl_get_pin_name(dev, i, pin_name, PINNAME_SIZE);
  59. if (ret) {
  60. printf("Ops get_pin_name error (%d) by %s\n", ret, dev->name);
  61. return ret;
  62. }
  63. if (name && strcmp(name, pin_name))
  64. continue;
  65. found = true;
  66. ret = pinctrl_get_pin_muxing(dev, i, pin_mux, PINMUX_SIZE);
  67. if (ret) {
  68. printf("Ops get_pin_muxing error (%d) by %s in %s\n",
  69. ret, pin_name, dev->name);
  70. return ret;
  71. }
  72. printf("%-*s: %-*s\n", PINNAME_SIZE, pin_name,
  73. PINMUX_SIZE, pin_mux);
  74. }
  75. if (!found)
  76. return -ENOENT;
  77. return 0;
  78. }
  79. static int do_status(struct cmd_tbl *cmdtp, int flag, int argc,
  80. char *const argv[])
  81. {
  82. struct udevice *dev;
  83. char *name;
  84. int ret;
  85. if (argc < 2) {
  86. if (!currdev) {
  87. printf("pin-controller device not selected\n");
  88. return CMD_RET_FAILURE;
  89. }
  90. show_pinmux(currdev, NULL);
  91. return CMD_RET_SUCCESS;
  92. }
  93. if (strcmp(argv[1], "-a"))
  94. name = argv[1];
  95. else
  96. name = NULL;
  97. uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) {
  98. if (!name) {
  99. /* insert a separator between each pin-controller display */
  100. printf("--------------------------\n");
  101. printf("%s:\n", dev->name);
  102. }
  103. ret = show_pinmux(dev, name);
  104. /* stop when the status of requested pin is displayed */
  105. if (name && !ret)
  106. return CMD_RET_SUCCESS;
  107. }
  108. if (name) {
  109. printf("%s not found\n", name);
  110. return CMD_RET_FAILURE;
  111. }
  112. return CMD_RET_SUCCESS;
  113. }
  114. static int do_list(struct cmd_tbl *cmdtp, int flag, int argc,
  115. char *const argv[])
  116. {
  117. struct udevice *dev;
  118. printf("| %-*.*s| %-*.*s| %s\n",
  119. LIMIT_DEVNAME, LIMIT_DEVNAME, "Device",
  120. LIMIT_DEVNAME, LIMIT_DEVNAME, "Driver",
  121. "Parent");
  122. uclass_foreach_dev_probe(UCLASS_PINCTRL, dev) {
  123. printf("| %-*.*s| %-*.*s| %s\n",
  124. LIMIT_DEVNAME, LIMIT_DEVNAME, dev->name,
  125. LIMIT_DEVNAME, LIMIT_DEVNAME, dev->driver->name,
  126. dev->parent->name);
  127. }
  128. return CMD_RET_SUCCESS;
  129. }
  130. static struct cmd_tbl pinmux_subcmd[] = {
  131. U_BOOT_CMD_MKENT(dev, 2, 1, do_dev, "", ""),
  132. U_BOOT_CMD_MKENT(list, 1, 1, do_list, "", ""),
  133. U_BOOT_CMD_MKENT(status, 2, 1, do_status, "", ""),
  134. };
  135. static int do_pinmux(struct cmd_tbl *cmdtp, int flag, int argc,
  136. char *const argv[])
  137. {
  138. struct cmd_tbl *cmd;
  139. argc--;
  140. argv++;
  141. cmd = find_cmd_tbl(argv[0], pinmux_subcmd, ARRAY_SIZE(pinmux_subcmd));
  142. if (!cmd || argc > cmd->maxargs)
  143. return CMD_RET_USAGE;
  144. return cmd->cmd(cmdtp, flag, argc, argv);
  145. }
  146. U_BOOT_CMD(pinmux, CONFIG_SYS_MAXARGS, 1, do_pinmux,
  147. "show pin-controller muxing",
  148. "list - list UCLASS_PINCTRL devices\n"
  149. "pinmux dev [pincontroller-name] - select pin-controller device\n"
  150. "pinmux status [-a | pin-name] - print pin-controller muxing [for all | for pin-name]\n"
  151. )