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