// SPDX-License-Identifier: GPL-2.0

#include <linux/leds.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
#include <uapi/linux/uleds.h>

/*
 *  APA102 SPI protocol description:
 *  +------+----------------------------------------+------+
 *  |START |               DATA FIELD:              | END  |
 *  |FRAME |               N LED FRAMES             |FRAME |
 *  +------+------+------+------+------+-----+------+------+
 *  | 0*32 | LED1 | LED2 | LED3 | LED4 | --- | LEDN | 1*32 |
 *  +------+------+------+------+------+-----+------+------+
 *
 *  +-----------------------------------+
 *  |START FRAME 32bits                 |
 *  +--------+--------+--------+--------+
 *  |00000000|00000000|00000000|00000000|
 *  +--------+--------+--------+--------+
 *
 *  +------------------------------------+
 *  |LED  FRAME 32bits                   |
 *  +---+-----+--------+--------+--------+
 *  |111|LUMA |  BLUE  | GREEN  |  RED   |
 *  +---+-----+--------+--------+--------+
 *  |3b |5bits| 8bits  | 8bits  | 8bits  |
 *  +---+-----+--------+--------+--------+
 *  |MSB   LSB|MSB  LSB|MSB  LSB|MSB  LSB|
 *  +---+-----+--------+--------+--------+
 *
 *  +-----------------------------------+
 *  |END FRAME 32bits                   |
 *  +--------+--------+--------+--------+
 *  |11111111|11111111|11111111|11111111|
 *  +--------+--------+--------+--------+
 */

/* apa102 default settings */
#define CR_MAX_BRIGHTNESS	GENMASK(7, 0)
#define LM_MAX_BRIGHTNESS	GENMASK(4, 0)
#define CH_NUM			4
#define START_BYTE		0
#define END_BYTE		GENMASK(7, 0)
#define LED_FRAME_HEADER	GENMASK(7, 5)

enum led_channels {
	RED,
	GREEN,
	BLUE,
	LUMA,
};

struct apa102_led {
	char			name[LED_MAX_NAME_SIZE];
	struct apa102		*priv;
	struct led_classdev	ldev;
	u8			brightness;
};

struct apa102 {
	size_t			led_count;
	struct device		*dev;
	struct mutex		lock;
	struct spi_device	*spi;
	u8			*buf;
	struct apa102_led	leds[];
};

static int apa102_sync(struct apa102 *priv)
{
	int	ret;
	size_t	i;
	size_t	bytes = 0;

	for (i = 0; i < 4; i++)
		priv->buf[bytes++] = START_BYTE;

	for (i = 0; i < priv->led_count; i++) {
		priv->buf[bytes++] = LED_FRAME_HEADER |
				     priv->leds[i * CH_NUM + LUMA].brightness;
		priv->buf[bytes++] = priv->leds[i * CH_NUM + BLUE].brightness;
		priv->buf[bytes++] = priv->leds[i * CH_NUM + GREEN].brightness;
		priv->buf[bytes++] = priv->leds[i * CH_NUM + RED].brightness;
	}

	for (i = 0; i < 4; i++)
		priv->buf[bytes++] = END_BYTE;

	ret = spi_write(priv->spi, priv->buf, bytes);

	return ret;
}

static int apa102_set_sync(struct led_classdev *ldev,
			   enum led_brightness brightness)
{
	int			ret;
	struct apa102_led	*led = container_of(ldev,
						    struct apa102_led,
						    ldev);

	dev_dbg(led->priv->dev, "Set brightness of %s to %d\n",
		led->name, brightness);

	mutex_lock(&led->priv->lock);
	led->brightness = (u8)brightness;
	ret = apa102_sync(led->priv);
	mutex_unlock(&led->priv->lock);

	return ret;
}

static int apa102_probe_dt(struct apa102 *priv)
{
	u32			i = 0;
	int			j = 0;
	struct apa102_led	*led;
	struct fwnode_handle	*child;
	struct device_node	*np;
	int			ret;
	const char		*str;
	static const char	* const rgb_name[] = {"red",
						      "green",
						      "blue",
						      "luma"};

	device_for_each_child_node(priv->dev, child) {
		np = to_of_node(child);
		/* for each physical LED, 4 LEDs are created representing
		 * the 4 components: red, green, blue and global luma.
		 */
		for (j = 0; j < CH_NUM; j++) {
			ret = fwnode_property_read_u32(child, "reg", &i);
			if (ret)
				return ret;

			if (i >= priv->led_count)
				return -EINVAL;

			led = &priv->leds[i * CH_NUM + j];
			ret = fwnode_property_read_string(child, "label", &str);
			if (ret)
				snprintf(led->name, sizeof(led->name),
					 "apa102:%s:%d", rgb_name[j], i);
			else
				snprintf(led->name, sizeof(led->name),
					 "apa102:%s:%s", rgb_name[j], str);

			fwnode_property_read_string(child,
						    "linux,default-trigger",
						    &led->ldev.default_trigger);

			led->priv			  = priv;
			led->ldev.name			  = led->name;
			if (j == LUMA) {
				led->ldev.brightness	 = led->brightness
							 = LM_MAX_BRIGHTNESS;
				led->ldev.max_brightness = LM_MAX_BRIGHTNESS;
			} else {
				led->ldev.brightness	 = led->brightness
							 = 0;
				led->ldev.max_brightness = CR_MAX_BRIGHTNESS;
			}

			led->ldev.brightness_set_blocking = apa102_set_sync;

			ret = devm_of_led_classdev_register(priv->dev, np,
							    &led->ldev);
			if (ret) {
				dev_err(priv->dev,
					"failed to register LED %s, err %d",
					led->name, ret);
				fwnode_handle_put(child);
				return ret;
			}

			led->ldev.dev->of_node = np;

		}
	}

	return 0;
}

static int apa102_probe(struct spi_device *spi)
{
	struct apa102	*priv;
	size_t		led_count;
	int		ret;

	led_count = device_get_child_node_count(&spi->dev);
	if (!led_count) {
		dev_err(&spi->dev, "No LEDs defined in device tree!");
		return -ENODEV;
	}

	priv = devm_kzalloc(&spi->dev,
			    struct_size(priv, leds, led_count * CH_NUM),
			    GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->buf = devm_kzalloc(&spi->dev, led_count * CH_NUM + 8, GFP_KERNEL);
	if (!priv->buf)
		return -ENOMEM;

	mutex_init(&priv->lock);
	priv->led_count	= led_count;
	priv->dev	= &spi->dev;
	priv->spi	= spi;

	ret = apa102_probe_dt(priv);
	if (ret)
		return ret;

	/* Set the LEDs with default values at start */
	apa102_sync(priv);
	if (ret)
		return ret;

	spi_set_drvdata(spi, priv);

	return 0;
}

static int apa102_remove(struct spi_device *spi)
{
	struct apa102 *priv = spi_get_drvdata(spi);

	mutex_destroy(&priv->lock);

	return 0;
}

static const struct of_device_id apa102_dt_ids[] = {
	{ .compatible = "shiji,apa102", },
	{},
};

MODULE_DEVICE_TABLE(of, apa102_dt_ids);

static struct spi_driver apa102_driver = {
	.probe		= apa102_probe,
	.remove		= apa102_remove,
	.driver = {
		.name		= KBUILD_MODNAME,
		.of_match_table	= apa102_dt_ids,
	},
};

module_spi_driver(apa102_driver);

MODULE_AUTHOR("Nicolas Belin <nbelin@baylibre.com>");
MODULE_DESCRIPTION("apa102 LED driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:apa102");
