/*
 * 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"
);
