/* * Copyright (c) 2017 Google, Inc * Written by Simon Glass * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #define LED_TOGGLE LEDST_COUNT static const char *const state_label[] = { [LEDST_OFF] = "off", [LEDST_ON] = "on", [LEDST_TOGGLE] = "toggle", #ifdef CONFIG_LED_BLINK [LEDST_BLINK] = "blink", #endif }; enum led_state_t get_led_cmd(char *var) { int i; for (i = 0; i < LEDST_COUNT; i++) { if (!strncmp(var, state_label[i], strlen(var))) return i; } return -1; } static int show_led_state(struct udevice *dev) { int ret; ret = led_get_state(dev); if (ret >= LEDST_COUNT) ret = -EINVAL; if (ret >= 0) printf("%s\n", state_label[ret]); return ret; } static int list_leds(void) { struct udevice *dev; int ret; for (uclass_find_first_device(UCLASS_LED, &dev); dev; uclass_find_next_device(&dev)) { struct led_uc_plat *plat = dev_get_uclass_platdata(dev); if (!plat->label) continue; printf("%-15s ", plat->label); if (device_active(dev)) { ret = show_led_state(dev); if (ret < 0) printf("Error %d\n", ret); } else { printf("\n"); } } return 0; } int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { enum led_state_t cmd; const char *led_label; struct udevice *dev; #ifdef CONFIG_LED_BLINK int freq_ms = 0; #endif int ret; /* Validate arguments */ if (argc < 2) return CMD_RET_USAGE; led_label = argv[1]; if (*led_label == 'l') return list_leds(); cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT; #ifdef CONFIG_LED_BLINK if (cmd == LEDST_BLINK) { if (argc < 4) return CMD_RET_USAGE; freq_ms = simple_strtoul(argv[3], NULL, 10); } #endif ret = led_get_by_label(led_label, &dev); if (ret) { printf("LED '%s' not found (err=%d)\n", led_label, ret); return CMD_RET_FAILURE; } switch (cmd) { case LEDST_OFF: case LEDST_ON: case LEDST_TOGGLE: ret = led_set_state(dev, cmd); break; #ifdef CONFIG_LED_BLINK case LEDST_BLINK: ret = led_set_period(dev, freq_ms); if (!ret) ret = led_set_state(dev, LEDST_BLINK); break; #endif case LEDST_COUNT: printf("LED '%s': ", led_label); ret = show_led_state(dev); break; } if (ret < 0) { printf("LED '%s' operation failed (err=%d)\n", led_label, ret); return CMD_RET_FAILURE; } return 0; } #ifdef CONFIG_LED_BLINK #define BLINK "|blink [blink-freq in ms]" #else #define BLINK "" #endif U_BOOT_CMD( led, 4, 1, do_led, "manage LEDs", " on|off|toggle" BLINK "\tChange LED state\n" "led [\tGet LED state\n" "led list\t\tshow a list of LEDs" );