Home | History | Annotate | Download | only in cmd
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright (c) 2017 Google, Inc
      4  * Written by Simon Glass <sjg (at) 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 
     15 static 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 
     24 enum 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 
     36 static 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 
     49 static 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_platdata(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 
     74 int do_led(cmd_tbl_t *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 (*led_label == 'l')
     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 = simple_strtoul(argv[3], NULL, 10);
     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 
    136 U_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