led.c 2.6 KB

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