Merge branch 'master' of git://git.denx.de/u-boot
[oweals/u-boot.git] / cmd / led.c
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 );