// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <led.h>
#include <log.h>
#include <asm/io.h>
#include <dm/lists.h>

#define LEDS_MAX			24

/* LED Init register */
#define LED_INIT_REG			0x00
#define LED_INIT_FASTINTV_MS		20
#define LED_INIT_FASTINTV_SHIFT		6
#define LED_INIT_FASTINTV_MASK		(0x3f << LED_INIT_FASTINTV_SHIFT)
#define LED_INIT_SLEDEN_SHIFT		12
#define LED_INIT_SLEDEN_MASK		(1 << LED_INIT_SLEDEN_SHIFT)
#define LED_INIT_SLEDMUX_SHIFT		13
#define LED_INIT_SLEDMUX_MASK		(1 << LED_INIT_SLEDMUX_SHIFT)
#define LED_INIT_SLEDCLKNPOL_SHIFT	14
#define LED_INIT_SLEDCLKNPOL_MASK	(1 << LED_INIT_SLEDCLKNPOL_SHIFT)
#define LED_INIT_SLEDDATAPPOL_SHIFT	15
#define LED_INIT_SLEDDATANPOL_MASK	(1 << LED_INIT_SLEDDATAPPOL_SHIFT)
#define LED_INIT_SLEDSHIFTDIR_SHIFT	16
#define LED_INIT_SLEDSHIFTDIR_MASK	(1 << LED_INIT_SLEDSHIFTDIR_SHIFT)

/* LED Mode registers */
#define LED_MODE_REG_HI			0x04
#define LED_MODE_REG_LO			0x08
#define LED_MODE_ON			0
#define LED_MODE_FAST			1
#define LED_MODE_BLINK			2
#define LED_MODE_OFF			3
#define LED_MODE_MASK			0x3

struct bcm6328_led_priv {
	void __iomem *regs;
	void __iomem *mode;
	uint8_t shift;
	bool active_low;
};

static unsigned long bcm6328_led_get_mode(struct bcm6328_led_priv *priv)
{
	return ((readl_be(priv->mode) >> priv->shift) & LED_MODE_MASK);
}

static int bcm6328_led_set_mode(struct bcm6328_led_priv *priv, uint8_t mode)
{
	clrsetbits_be32(priv->mode, (LED_MODE_MASK << priv->shift),
			(mode << priv->shift));

	return 0;
}

static enum led_state_t bcm6328_led_get_state(struct udevice *dev)
{
	struct bcm6328_led_priv *priv = dev_get_priv(dev);
	enum led_state_t state = LEDST_OFF;

	switch (bcm6328_led_get_mode(priv)) {
#ifdef CONFIG_LED_BLINK
	case LED_MODE_BLINK:
	case LED_MODE_FAST:
		state = LEDST_BLINK;
		break;
#endif
	case LED_MODE_OFF:
		state = (priv->active_low ? LEDST_ON : LEDST_OFF);
		break;
	case LED_MODE_ON:
		state = (priv->active_low ? LEDST_OFF : LEDST_ON);
		break;
	}

	return state;
}

static int bcm6328_led_set_state(struct udevice *dev, enum led_state_t state)
{
	struct bcm6328_led_priv *priv = dev_get_priv(dev);
	unsigned long mode;

	switch (state) {
#ifdef CONFIG_LED_BLINK
	case LEDST_BLINK:
		mode = LED_MODE_BLINK;
		break;
#endif
	case LEDST_OFF:
		mode = (priv->active_low ? LED_MODE_ON : LED_MODE_OFF);
		break;
	case LEDST_ON:
		mode = (priv->active_low ? LED_MODE_OFF : LED_MODE_ON);
		break;
	case LEDST_TOGGLE:
		if (bcm6328_led_get_state(dev) == LEDST_OFF)
			return bcm6328_led_set_state(dev, LEDST_ON);
		else
			return bcm6328_led_set_state(dev, LEDST_OFF);
		break;
	default:
		return -ENOSYS;
	}

	return bcm6328_led_set_mode(priv, mode);
}

#ifdef CONFIG_LED_BLINK
static unsigned long bcm6328_blink_delay(int delay)
{
	unsigned long bcm6328_delay = delay;

	bcm6328_delay += (LED_INIT_FASTINTV_MS / 2);
	bcm6328_delay /= LED_INIT_FASTINTV_MS;
	bcm6328_delay <<= LED_INIT_FASTINTV_SHIFT;

	if (bcm6328_delay > LED_INIT_FASTINTV_MASK)
		return LED_INIT_FASTINTV_MASK;
	else
		return bcm6328_delay;
}

static int bcm6328_led_set_period(struct udevice *dev, int period_ms)
{
	struct bcm6328_led_priv *priv = dev_get_priv(dev);

	clrsetbits_be32(priv->regs + LED_INIT_REG, LED_INIT_FASTINTV_MASK,
			bcm6328_blink_delay(period_ms));

	return 0;
}
#endif

static const struct led_ops bcm6328_led_ops = {
	.get_state = bcm6328_led_get_state,
	.set_state = bcm6328_led_set_state,
#ifdef CONFIG_LED_BLINK
	.set_period = bcm6328_led_set_period,
#endif
};

static int bcm6328_led_probe(struct udevice *dev)
{
	struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);

	/* Top-level LED node */
	if (!uc_plat->label) {
		void __iomem *regs;
		u32 set_bits = 0;

		regs = dev_remap_addr(dev);
		if (!regs)
			return -EINVAL;

		if (dev_read_bool(dev, "brcm,serial-leds"))
			set_bits |= LED_INIT_SLEDEN_MASK;
		if (dev_read_bool(dev, "brcm,serial-mux"))
			set_bits |= LED_INIT_SLEDMUX_MASK;
		if (dev_read_bool(dev, "brcm,serial-clk-low"))
			set_bits |= LED_INIT_SLEDCLKNPOL_MASK;
		if (!dev_read_bool(dev, "brcm,serial-dat-low"))
			set_bits |= LED_INIT_SLEDDATANPOL_MASK;
		if (!dev_read_bool(dev, "brcm,serial-shift-inv"))
			set_bits |= LED_INIT_SLEDSHIFTDIR_MASK;

		clrsetbits_be32(regs + LED_INIT_REG, ~0, set_bits);
	} else {
		struct bcm6328_led_priv *priv = dev_get_priv(dev);
		unsigned int pin;

		priv->regs = dev_remap_addr(dev_get_parent(dev));
		if (!priv->regs)
			return -EINVAL;

		pin = dev_read_u32_default(dev, "reg", LEDS_MAX);
		if (pin >= LEDS_MAX)
			return -EINVAL;

		if (pin < 8) {
			/* LEDs 0-7 (bits 47:32) */
			priv->mode = priv->regs + LED_MODE_REG_HI;
			priv->shift = (pin << 1);
		} else {
			/* LEDs 8-23 (bits 31:0) */
			priv->mode = priv->regs + LED_MODE_REG_LO;
			priv->shift = ((pin - 8) << 1);
		}

		if (dev_read_bool(dev, "active-low"))
			priv->active_low = true;
	}

	return 0;
}

static int bcm6328_led_bind(struct udevice *parent)
{
	ofnode node;

	dev_for_each_subnode(node, parent) {
		struct udevice *dev;
		int ret;

		ret = device_bind_driver_to_node(parent, "bcm6328-led",
						 ofnode_get_name(node),
						 node, &dev);
		if (ret)
			return ret;
	}

	return 0;
}

static const struct udevice_id bcm6328_led_ids[] = {
	{ .compatible = "brcm,bcm6328-leds" },
	{ /* sentinel */ }
};

U_BOOT_DRIVER(bcm6328_led) = {
	.name = "bcm6328-led",
	.id = UCLASS_LED,
	.of_match = bcm6328_led_ids,
	.ops = &bcm6328_led_ops,
	.bind = bcm6328_led_bind,
	.probe = bcm6328_led_probe,
	.priv_auto	= sizeof(struct bcm6328_led_priv),
};
