xref: /openbmc/u-boot/cmd/led.c (revision 1878804a)
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