led.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. #ifdef CONFIG_LED_BLINK
  78. if (cmd == LEDST_BLINK) {
  79. if (argc < 4)
  80. return CMD_RET_USAGE;
  81. freq_ms = simple_strtoul(argv[3], NULL, 10);
  82. }
  83. #endif
  84. ret = led_get_by_label(led_label, &dev);
  85. if (ret) {
  86. printf("LED '%s' not found (err=%d)\n", led_label, ret);
  87. return CMD_RET_FAILURE;
  88. }
  89. switch (cmd) {
  90. case LEDST_OFF:
  91. case LEDST_ON:
  92. case LEDST_TOGGLE:
  93. ret = led_set_state(dev, cmd);
  94. break;
  95. #ifdef CONFIG_LED_BLINK
  96. case LEDST_BLINK:
  97. ret = led_set_period(dev, freq_ms);
  98. if (!ret)
  99. ret = led_set_state(dev, LEDST_BLINK);
  100. break;
  101. #endif
  102. case LEDST_COUNT:
  103. printf("LED '%s': ", led_label);
  104. ret = show_led_state(dev);
  105. break;
  106. }
  107. if (ret < 0) {
  108. printf("LED '%s' operation failed (err=%d)\n", led_label, ret);
  109. return CMD_RET_FAILURE;
  110. }
  111. return 0;
  112. }
  113. #ifdef CONFIG_LED_BLINK
  114. #define BLINK "|blink [blink-freq in ms]"
  115. #else
  116. #define BLINK ""
  117. #endif
  118. U_BOOT_CMD(
  119. led, 4, 1, do_led,
  120. "manage LEDs",
  121. "<led_label> on|off|toggle" BLINK "\tChange LED state\n"
  122. "led [<led_label>\tGet LED state\n"
  123. "led list\t\tshow a list of LEDs"
  124. );