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