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 #ifdef CONFIG_LED_BLINK 94 if (cmd == LEDST_BLINK) { 95 if (argc < 4) 96 return CMD_RET_USAGE; 97 freq_ms = simple_strtoul(argv[3], NULL, 10); 98 } 99 #endif 100 ret = led_get_by_label(led_label, &dev); 101 if (ret) { 102 printf("LED '%s' not found (err=%d)\n", led_label, ret); 103 return CMD_RET_FAILURE; 104 } 105 switch (cmd) { 106 case LEDST_OFF: 107 case LEDST_ON: 108 case LEDST_TOGGLE: 109 ret = led_set_state(dev, cmd); 110 break; 111 #ifdef CONFIG_LED_BLINK 112 case LEDST_BLINK: 113 ret = led_set_period(dev, freq_ms); 114 if (!ret) 115 ret = led_set_state(dev, LEDST_BLINK); 116 break; 117 #endif 118 case LEDST_COUNT: 119 printf("LED '%s': ", led_label); 120 ret = show_led_state(dev); 121 break; 122 } 123 if (ret < 0) { 124 printf("LED '%s' operation failed (err=%d)\n", led_label, ret); 125 return CMD_RET_FAILURE; 126 } 127 128 return 0; 129 } 130 131 #ifdef CONFIG_LED_BLINK 132 #define BLINK "|blink [blink-freq in ms]" 133 #else 134 #define BLINK "" 135 #endif 136 137 U_BOOT_CMD( 138 led, 4, 1, do_led, 139 "manage LEDs", 140 "<led_label> on|off|toggle" BLINK "\tChange LED state\n" 141 "led [<led_label>\tGet LED state\n" 142 "led list\t\tshow a list of LEDs" 143 ); 144