diff mbox

[U-Boot,v2,9/9] dm: led: Add a new 'led' command

Message ID 20170410173459.30461-10-sjg@chromium.org
State Accepted
Commit ffe2052d6e8add8ea66a7d1647255aa28715f067
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass April 10, 2017, 5:34 p.m. UTC
When driver model is used for LEDs, provide a command to allow LED access.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v2: None

 cmd/Kconfig  |   9 ++++
 cmd/Makefile |   1 +
 cmd/led.c    | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 cmd/led.c

Comments

techping.chan@gmail.com April 12, 2017, 8:53 a.m. UTC | #1
2017-04-11 1:34 GMT+08:00 Simon Glass <sjg@chromium.org>:

> When driver model is used for LEDs, provide a command to allow LED access.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> Changes in v2: None
>
>  cmd/Kconfig  |   9 ++++
>  cmd/Makefile |   1 +
>  cmd/led.c    | 145 ++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++
>  3 files changed, 155 insertions(+)
>  create mode 100644 cmd/led.c
>
> diff --git a/cmd/Kconfig b/cmd/Kconfig
> index 661ae7a98c..13dc46a174 100644
> --- a/cmd/Kconfig
> +++ b/cmd/Kconfig
> @@ -667,6 +667,15 @@ config CMD_CACHE
>         help
>           Enable the "icache" and "dcache" commands
>
> +config CMD_LED
> +       bool "led"
> +       default y if LED
> +       help
> +         Enable the 'led' command which allows for control of LEDs
> supported
> +         by the board. The LEDs can be listed with 'led list' and
> controlled
> +         with led on/off/togle/blink. Any LED drivers can be controlled
> with
> +         this command, e.g. led_gpio.
> +
>  config CMD_TIME
>         bool "time"
>         help
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 19d450e0fb..3cb0cfde7b 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -79,6 +79,7 @@ obj-$(CONFIG_CMD_JFFS2) += jffs2.o
>  obj-$(CONFIG_CMD_CRAMFS) += cramfs.o
>  obj-$(CONFIG_CMD_LDRINFO) += ldrinfo.o
>  obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
> +obj-$(CONFIG_CMD_LED) += led.o
>  obj-$(CONFIG_CMD_LICENSE) += license.o
>  obj-y += load.o
>  obj-$(CONFIG_LOGBUFFER) += log.o
> diff --git a/cmd/led.c b/cmd/led.c
> new file mode 100644
> index 0000000000..84173f86f2
> --- /dev/null
> +++ b/cmd/led.c
> @@ -0,0 +1,145 @@
> +/*
> + * Copyright (c) 2017 Google, Inc
> + * Written by Simon Glass <sjg@chromium.org>
> + *
> + * SPDX-License-Identifier:     GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <dm.h>
> +#include <led.h>
> +#include <dm/uclass-internal.h>
> +
> +#define LED_TOGGLE LEDST_COUNT
> +
> +static const char *const state_label[] = {
> +       [LEDST_OFF]     = "off",
> +       [LEDST_ON]      = "on",
> +       [LEDST_TOGGLE]  = "toggle",
> +#ifdef CONFIG_LED_BLINK
> +       [LEDST_BLINK]   = "blink",
> +#endif
> +};
> +
> +enum led_state_t get_led_cmd(char *var)
> +{
> +       int i;
> +
> +       for (i = 0; i < LEDST_COUNT; i++) {
> +               if (!strncmp(var, state_label[i], strlen(var)))
> +                       return i;
> +       }
> +
> +       return -1;
> +}
> +
> +static int show_led_state(struct udevice *dev)
> +{
> +       int ret;
> +
> +       ret = led_get_state(dev);
> +       if (ret >= LEDST_COUNT)
> +               ret = -EINVAL;
> +       if (ret >= 0)
> +               printf("%s\n", state_label[ret]);
> +
> +       return ret;
> +}
> +
> +static int list_leds(void)
> +{
> +       struct udevice *dev;
> +       int ret;
> +
> +       for (uclass_find_first_device(UCLASS_LED, &dev);
> +            dev;
> +            uclass_find_next_device(&dev)) {
> +               struct led_uc_plat *plat = dev_get_uclass_platdata(dev);
> +
> +               if (!plat->label)
> +                       continue;
> +               printf("%-15s ", plat->label);
> +               if (device_active(dev)) {
> +                       ret = show_led_state(dev);
> +                       if (ret < 0)
> +                               printf("Error %d\n", ret);
> +               } else {
> +                       printf("<inactive>\n");
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +       enum led_state_t cmd;
> +       const char *led_label;
> +       struct udevice *dev;
> +#ifdef CONFIG_LED_BLINK
> +       int freq_ms = 0;
> +#endif
> +       int ret;
> +
> +       /* Validate arguments */
> +       if (argc < 2)
> +               return CMD_RET_USAGE;
> +       led_label = argv[1];
> +       if (*led_label == 'l')
> +               return list_leds();
> +
> +       cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT;
> +       if (cmd < 0)
> +               return CMD_RET_USAGE;
> +#ifdef CONFIG_LED_BLINK
> +       if (cmd == LEDST_BLINK) {
> +               if (argc < 4)
> +                       return CMD_RET_USAGE;
> +               freq_ms = simple_strtoul(argv[3], NULL, 10);
> +       }
> +#endif
> +       ret = led_get_by_label(led_label, &dev);
> +       if (ret) {
> +               printf("LED '%s' not found (err=%d)\n", led_label, ret);
> +               return CMD_RET_FAILURE;
> +       }
> +       switch (cmd) {
> +       case LEDST_OFF:
> +       case LEDST_ON:
> +       case LEDST_TOGGLE:
> +               ret = led_set_state(dev, cmd);
> +               break;
> +#ifdef CONFIG_LED_BLINK
> +       case LEDST_BLINK:
> +               ret = led_set_period(dev, freq_ms);
> +               if (!ret)
> +                       ret = led_set_state(dev, LEDST_BLINK);
> +               break;
> +#endif
> +       case LEDST_COUNT:
> +               printf("LED '%s': ", led_label);
> +               ret = show_led_state(dev);
> +               break;
> +       }
> +       if (ret < 0) {
> +               printf("LED '%s' operation failed (err=%d)\n", led_label,
> ret);
> +               return CMD_RET_FAILURE;
> +       }
> +
> +       return 0;
> +}
> +
> +#ifdef CONFIG_LED_BLINK
> +#define BLINK "|blink [blink-freq in ms]"
> +#else
> +#define BLINK ""
> +#endif
> +
> +U_BOOT_CMD(
> +       led, 4, 1, do_led,
> +       "manage LEDs",
> +       "<led_label> on|off|toggle" BLINK "\tChange LED state\n"
> +       "led [<led_label>\tGet LED state\n"
> +       "led list\t\tshow a list of LEDs"
> +);
> --
> 2.12.2.715.g7642488e1d-goog
>
>
Reviewed-by: Ziping Chen <techping.chan@gmail.com>
Simon Glass April 15, 2017, 4:08 p.m. UTC | #2
On 12 April 2017 at 02:53, Ziping Chen <techping.chan@gmail.com> wrote:
>
>
> 2017-04-11 1:34 GMT+08:00 Simon Glass <sjg@chromium.org>:
>>
>> When driver model is used for LEDs, provide a command to allow LED access.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>> Changes in v2: None
>>
>>  cmd/Kconfig  |   9 ++++
>>  cmd/Makefile |   1 +
>>  cmd/led.c    | 145
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 155 insertions(+)
>>  create mode 100644 cmd/led.c
>>
>>
>
> Reviewed-by: Ziping Chen <techping.chan@gmail.com>

Applied to u-boot-dm
diff mbox

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 661ae7a98c..13dc46a174 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -667,6 +667,15 @@  config CMD_CACHE
 	help
 	  Enable the "icache" and "dcache" commands
 
+config CMD_LED
+	bool "led"
+	default y if LED
+	help
+	  Enable the 'led' command which allows for control of LEDs supported
+	  by the board. The LEDs can be listed with 'led list' and controlled
+	  with led on/off/togle/blink. Any LED drivers can be controlled with
+	  this command, e.g. led_gpio.
+
 config CMD_TIME
 	bool "time"
 	help
diff --git a/cmd/Makefile b/cmd/Makefile
index 19d450e0fb..3cb0cfde7b 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -79,6 +79,7 @@  obj-$(CONFIG_CMD_JFFS2) += jffs2.o
 obj-$(CONFIG_CMD_CRAMFS) += cramfs.o
 obj-$(CONFIG_CMD_LDRINFO) += ldrinfo.o
 obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
+obj-$(CONFIG_CMD_LED) += led.o
 obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
 obj-$(CONFIG_LOGBUFFER) += log.o
diff --git a/cmd/led.c b/cmd/led.c
new file mode 100644
index 0000000000..84173f86f2
--- /dev/null
+++ b/cmd/led.c
@@ -0,0 +1,145 @@ 
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <led.h>
+#include <dm/uclass-internal.h>
+
+#define LED_TOGGLE LEDST_COUNT
+
+static const char *const state_label[] = {
+	[LEDST_OFF]	= "off",
+	[LEDST_ON]	= "on",
+	[LEDST_TOGGLE]	= "toggle",
+#ifdef CONFIG_LED_BLINK
+	[LEDST_BLINK]	= "blink",
+#endif
+};
+
+enum led_state_t get_led_cmd(char *var)
+{
+	int i;
+
+	for (i = 0; i < LEDST_COUNT; i++) {
+		if (!strncmp(var, state_label[i], strlen(var)))
+			return i;
+	}
+
+	return -1;
+}
+
+static int show_led_state(struct udevice *dev)
+{
+	int ret;
+
+	ret = led_get_state(dev);
+	if (ret >= LEDST_COUNT)
+		ret = -EINVAL;
+	if (ret >= 0)
+		printf("%s\n", state_label[ret]);
+
+	return ret;
+}
+
+static int list_leds(void)
+{
+	struct udevice *dev;
+	int ret;
+
+	for (uclass_find_first_device(UCLASS_LED, &dev);
+	     dev;
+	     uclass_find_next_device(&dev)) {
+		struct led_uc_plat *plat = dev_get_uclass_platdata(dev);
+
+		if (!plat->label)
+			continue;
+		printf("%-15s ", plat->label);
+		if (device_active(dev)) {
+			ret = show_led_state(dev);
+			if (ret < 0)
+				printf("Error %d\n", ret);
+		} else {
+			printf("<inactive>\n");
+		}
+	}
+
+	return 0;
+}
+
+int do_led(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	enum led_state_t cmd;
+	const char *led_label;
+	struct udevice *dev;
+#ifdef CONFIG_LED_BLINK
+	int freq_ms = 0;
+#endif
+	int ret;
+
+	/* Validate arguments */
+	if (argc < 2)
+		return CMD_RET_USAGE;
+	led_label = argv[1];
+	if (*led_label == 'l')
+		return list_leds();
+
+	cmd = argc > 2 ? get_led_cmd(argv[2]) : LEDST_COUNT;
+	if (cmd < 0)
+		return CMD_RET_USAGE;
+#ifdef CONFIG_LED_BLINK
+	if (cmd == LEDST_BLINK) {
+		if (argc < 4)
+			return CMD_RET_USAGE;
+		freq_ms = simple_strtoul(argv[3], NULL, 10);
+	}
+#endif
+	ret = led_get_by_label(led_label, &dev);
+	if (ret) {
+		printf("LED '%s' not found (err=%d)\n", led_label, ret);
+		return CMD_RET_FAILURE;
+	}
+	switch (cmd) {
+	case LEDST_OFF:
+	case LEDST_ON:
+	case LEDST_TOGGLE:
+		ret = led_set_state(dev, cmd);
+		break;
+#ifdef CONFIG_LED_BLINK
+	case LEDST_BLINK:
+		ret = led_set_period(dev, freq_ms);
+		if (!ret)
+			ret = led_set_state(dev, LEDST_BLINK);
+		break;
+#endif
+	case LEDST_COUNT:
+		printf("LED '%s': ", led_label);
+		ret = show_led_state(dev);
+		break;
+	}
+	if (ret < 0) {
+		printf("LED '%s' operation failed (err=%d)\n", led_label, ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_LED_BLINK
+#define BLINK "|blink [blink-freq in ms]"
+#else
+#define BLINK ""
+#endif
+
+U_BOOT_CMD(
+	led, 4, 1, do_led,
+	"manage LEDs",
+	"<led_label> on|off|toggle" BLINK "\tChange LED state\n"
+	"led [<led_label>\tGet LED state\n"
+	"led list\t\tshow a list of LEDs"
+);