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 15static 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 24enum 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 36static 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 49static 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_plat(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 74int do_led(struct cmd_tbl *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 (strncmp(led_label, "list", 4) == 0) 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 = dectoul(argv[3], NULL); 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 136U_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