led.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright (c) 2017 Google, Inc
  3. * Written by Simon Glass <sjg@chromium.org>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <command.h>
  9. #include <dm.h>
  10. #include <led.h>
  11. #include <dm/uclass-internal.h>
  12. #define LED_TOGGLE LEDST_COUNT
  13. static const char *const state_label[] = {
  14. [LEDST_OFF] = "off",
  15. [LEDST_ON] = "on",
  16. [LEDST_TOGGLE] = "toggle",
  17. #ifdef CONFIG_LED_BLINK
  18. [LEDST_BLINK] = "blink",
  19. #endif
  20. };
  21. enum led_state_t get_led_cmd(char *var)
  22. {
  23. int i;
  24. for (i = 0; i < LEDST_COUNT; i++) {
  25. if (!strncmp(var, state_label[i], strlen(var)))
  26. return i;
  27. }
  28. return -1;
  29. }
  30. static int show_led_state(struct udevice *dev)
  31. {
  32. int ret;
  33. ret = led_get_state(dev);
  34. if (ret >= LEDST_COUNT)
  35. ret = -EINVAL;
  36. if (ret >= 0)
  37. printf("%s\n", state_label[ret]);
  38. return ret;
  39. }
  40. static int list_leds(void)
  41. {
  42. struct udevice *dev;
  43. int ret;
  44. for (uclass_find_first_device(UCLASS_LED, &dev);
  45. dev;
  46. uclass_find_next_device(&dev)) {
  47. struct led_uc_plat *plat = dev_get_uclass_platdata(dev);
  48. if (!plat->label)
  49. continue;
  50. printf("%-15s ", plat->label);
  51. if (device_active(dev)) {
  52. ret = show_led_state(dev);
  53. if (ret < 0)
  54. printf("Error %d\n", ret);
  55. } else {
  56. printf("<inactive>\n");
  57. }
  58. }
  59. return 0;
  60. }
  61. int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  62. {
  63. enum led_state_t cmd;
  64. const char *led_label;
  65. struct udevice *dev;
  66. #ifdef CONFIG_LED_BLINK
  67. int freq_ms = 0;
  68. #endif
  69. int ret;
  70. /* Validate arguments */
  71. if (argc < 2)
  72. return CMD_RET_USAGE;
  73. led_label = argv[1];
  74. if (*led_label == 'l')
  75. return list_leds();
  76. cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT;
  77. if (cmd < 0)
  78. return CMD_RET_USAGE;
  79. #ifdef CONFIG_LED_BLINK
  80. if (cmd == LEDST_BLINK) {
  81. if (argc < 4)
  82. return CMD_RET_USAGE;
  83. freq_ms = simple_strtoul(argv[3], NULL, 10);
  84. }
  85. #endif
  86. ret = led_get_by_label(led_label, &dev);
  87. if (ret) {
  88. printf("LED '%s' not found (err=%d)\n", led_label, ret);
  89. return CMD_RET_FAILURE;
  90. }
  91. switch (cmd) {
  92. case LEDST_OFF:
  93. case LEDST_ON:
  94. case LEDST_TOGGLE:
  95. ret = led_set_state(dev, cmd);
  96. break;
  97. #ifdef CONFIG_LED_BLINK
  98. case LEDST_BLINK:
  99. ret = led_set_period(dev, freq_ms);
  100. if (!ret)
  101. ret = led_set_state(dev, LEDST_BLINK);
  102. break;
  103. #endif
  104. case LEDST_COUNT:
  105. printf("LED '%s': ", led_label);
  106. ret = show_led_state(dev);
  107. break;
  108. }
  109. if (ret < 0) {
  110. printf("LED '%s' operation failed (err=%d)\n", led_label, ret);
  111. return CMD_RET_FAILURE;
  112. }
  113. return 0;
  114. }
  115. #ifdef CONFIG_LED_BLINK
  116. #define BLINK "|blink [blink-freq in ms]"
  117. #else
  118. #define BLINK ""
  119. #endif
  120. U_BOOT_CMD(
  121. led, 4, 1, do_led,
  122. "manage LEDs",
  123. "<led_label> on|off|toggle" BLINK "\tChange LED state\n"
  124. "led [<led_label>\tGet LED state\n"
  125. "led list\t\tshow a list of LEDs"
  126. );