xref: /openbmc/u-boot/cmd/led.c (revision 94ba26f2bcc02013e8b7561d070d6d2eb4f091be)
1  /*
2   * (C) Copyright 2010
3   * Jason Kridner <jkridner@beagleboard.org>
4   *
5   * Based on cmd_led.c patch from:
6   * http://www.mail-archive.com/u-boot@lists.denx.de/msg06873.html
7   * (C) Copyright 2008
8   * Ulf Samuelsson <ulf.samuelsson@atmel.com>
9   *
10   * SPDX-License-Identifier:	GPL-2.0+
11   */
12  
13  #include <common.h>
14  #include <config.h>
15  #include <command.h>
16  #include <status_led.h>
17  
18  struct led_tbl_s {
19  	char		*string;	/* String for use in the command */
20  	led_id_t	mask;		/* Mask used for calling __led_set() */
21  	void		(*off)(void);	/* Optional function for turning LED off */
22  	void		(*on)(void);	/* Optional function for turning LED on */
23  	void		(*toggle)(void);/* Optional function for toggling LED */
24  };
25  
26  typedef struct led_tbl_s led_tbl_t;
27  
28  static const led_tbl_t led_commands[] = {
29  #ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
30  #ifdef CONFIG_LED_STATUS0
31  	{ "0", CONFIG_LED_STATUS_BIT, NULL, NULL, NULL },
32  #endif
33  #ifdef CONFIG_LED_STATUS1
34  	{ "1", CONFIG_LED_STATUS_BIT1, NULL, NULL, NULL },
35  #endif
36  #ifdef CONFIG_LED_STATUS2
37  	{ "2", CONFIG_LED_STATUS_BIT2, NULL, NULL, NULL },
38  #endif
39  #ifdef CONFIG_LED_STATUS3
40  	{ "3", CONFIG_LED_STATUS_BIT3, NULL, NULL, NULL },
41  #endif
42  #ifdef CONFIG_LED_STATUS4
43  	{ "4", CONFIG_LED_STATUS_BIT4, NULL, NULL, NULL },
44  #endif
45  #ifdef CONFIG_LED_STATUS5
46  	{ "5", CONFIG_LED_STATUS_BIT5, NULL, NULL, NULL },
47  #endif
48  #endif
49  #ifdef CONFIG_LED_STATUS_GREEN
50  	{ "green", CONFIG_LED_STATUS_GREEN, green_led_off, green_led_on, NULL },
51  #endif
52  #ifdef CONFIG_LED_STATUS_YELLOW
53  	{ "yellow", CONFIG_LED_STATUS_YELLOW, yellow_led_off, yellow_led_on,
54  	  NULL },
55  #endif
56  #ifdef CONFIG_LED_STATUS_RED
57  	{ "red", CONFIG_LED_STATUS_RED, red_led_off, red_led_on, NULL },
58  #endif
59  #ifdef CONFIG_LED_STATUS_BLUE
60  	{ "blue", CONFIG_LED_STATUS_BLUE, blue_led_off, blue_led_on, NULL },
61  #endif
62  	{ NULL, 0, NULL, NULL, NULL }
63  };
64  
65  enum led_cmd { LED_ON, LED_OFF, LED_TOGGLE, LED_BLINK };
66  
67  enum led_cmd get_led_cmd(char *var)
68  {
69  	if (strcmp(var, "off") == 0)
70  		return LED_OFF;
71  	if (strcmp(var, "on") == 0)
72  		return LED_ON;
73  	if (strcmp(var, "toggle") == 0)
74  		return LED_TOGGLE;
75  	if (strcmp(var, "blink") == 0)
76  		return LED_BLINK;
77  
78  	return -1;
79  }
80  
81  /*
82   * LED drivers providing a blinking LED functionality, like the
83   * PCA9551, can override this empty weak function
84   */
85  void __weak __led_blink(led_id_t mask, int freq)
86  {
87  }
88  
89  int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
90  {
91  	int i, match = 0;
92  	enum led_cmd cmd;
93  	int freq;
94  
95  	/* Validate arguments */
96  	if ((argc < 3) || (argc > 4))
97  		return CMD_RET_USAGE;
98  
99  	cmd = get_led_cmd(argv[2]);
100  	if (cmd < 0) {
101  		return CMD_RET_USAGE;
102  	}
103  
104  	for (i = 0; led_commands[i].string; i++) {
105  		if ((strcmp("all", argv[1]) == 0) ||
106  		    (strcmp(led_commands[i].string, argv[1]) == 0)) {
107  			match = 1;
108  			switch (cmd) {
109  			case LED_ON:
110  				if (led_commands[i].on)
111  					led_commands[i].on();
112  				else
113  					__led_set(led_commands[i].mask,
114  							  CONFIG_LED_STATUS_ON);
115  				break;
116  			case LED_OFF:
117  				if (led_commands[i].off)
118  					led_commands[i].off();
119  				else
120  					__led_set(led_commands[i].mask,
121  						  CONFIG_LED_STATUS_OFF);
122  				break;
123  			case LED_TOGGLE:
124  				if (led_commands[i].toggle)
125  					led_commands[i].toggle();
126  				else
127  					__led_toggle(led_commands[i].mask);
128  				break;
129  			case LED_BLINK:
130  				if (argc != 4)
131  					return CMD_RET_USAGE;
132  
133  				freq = simple_strtoul(argv[3], NULL, 10);
134  				__led_blink(led_commands[i].mask, freq);
135  			}
136  			/* Need to set only 1 led if led_name wasn't 'all' */
137  			if (strcmp("all", argv[1]) != 0)
138  				break;
139  		}
140  	}
141  
142  	/* If we ran out of matches, print Usage */
143  	if (!match) {
144  		return CMD_RET_USAGE;
145  	}
146  
147  	return 0;
148  }
149  
150  U_BOOT_CMD(
151  	led, 4, 1, do_led,
152  	"["
153  #ifdef CONFIG_LED_STATUS_BOARD_SPECIFIC
154  #ifdef CONFIG_LED_STATUS0
155  	"0|"
156  #endif
157  #ifdef CONFIG_LED_STATUS1
158  	"1|"
159  #endif
160  #ifdef CONFIG_LED_STATUS2
161  	"2|"
162  #endif
163  #ifdef CONFIG_LED_STATUS3
164  	"3|"
165  #endif
166  #ifdef CONFIG_LED_STATUS4
167  	"4|"
168  #endif
169  #ifdef CONFIG_LED_STATUS5
170  	"5|"
171  #endif
172  #endif
173  #ifdef CONFIG_LED_STATUS_GREEN
174  	"green|"
175  #endif
176  #ifdef CONFIG_LED_STATUS_YELLOW
177  	"yellow|"
178  #endif
179  #ifdef CONFIG_LED_STATUS_RED
180  	"red|"
181  #endif
182  #ifdef CONFIG_LED_STATUS_BLUE
183  	"blue|"
184  #endif
185  	"all] [on|off|toggle|blink] [blink-freq in ms]",
186  	"[led_name] [on|off|toggle|blink] sets or clears led(s)"
187  );
188