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