/*
 * Copyright (c) 2017 Linaro Limited
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/drivers/led_strip.h>

#include <errno.h>
#include <string.h>

#if DT_NODE_HAS_STATUS_OKAY(DT_INST(0, greeled_lpd8806))
#define DT_DRV_COMPAT greeled_lpd8806
#else
#define DT_DRV_COMPAT greeled_lpd8803
#endif

#define LOG_LEVEL CONFIG_LED_STRIP_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(lpd880x);

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/util.h>

/*
 * LPD880X SPI master configuration:
 *
 * - mode 0 (the default), 8 bit, MSB first, one-line SPI
 * - no shenanigans (no CS hold, release device lock, not an EEPROM)
 */
#define LPD880X_SPI_OPERATION (SPI_OP_MODE_MASTER | \
			       SPI_TRANSFER_MSB |   \
			       SPI_WORD_SET(8))

struct lpd880x_config {
	struct spi_dt_spec bus;
	size_t length;
};

static int lpd880x_update(const struct device *dev, void *data, size_t size)
{
	const struct lpd880x_config *config = dev->config;
	/*
	 * Per the AdaFruit reverse engineering notes on the protocol,
	 * a zero byte propagates through at most 32 LED driver ICs.
	 * The LPD8803 is the worst case, at 3 output channels per IC.
	 */
	uint8_t reset_size = DIV_ROUND_UP(DIV_ROUND_UP(size, 3), 32);
	uint8_t reset_buf[reset_size];
	uint8_t last = 0x00;
	const struct spi_buf bufs[3] = {
		{
			/* Prepares the strip to shift in new data values. */
			.buf = reset_buf,
			.len = reset_size
		},
		{
			/* Displays the serialized pixel data. */
			.buf = data,
			.len = size
		},
		{
			/* Ensures the last byte of pixel data is displayed. */
			.buf = &last,
			.len = sizeof(last)
		}

	};
	const struct spi_buf_set tx = {
		.buffers = bufs,
		.count = 3
	};
	size_t rc;

	(void)memset(reset_buf, 0x00, reset_size);

	rc = spi_write_dt(&config->bus, &tx);
	if (rc) {
		LOG_ERR("can't update strip: %zu", rc);
	}

	return rc;
}

static int lpd880x_strip_update_rgb(const struct device *dev,
				    struct led_rgb *pixels,
				    size_t num_pixels)
{
	uint8_t *px = (uint8_t *)pixels;
	uint8_t r, g, b;
	size_t i;

	/*
	 * Overwrite a prefix of the pixels array with its on-wire
	 * representation, eliminating padding/scratch garbage, if any.
	 */
	for (i = 0; i < num_pixels; i++) {
		r = 0x80 | (pixels[i].r >> 1);
		g = 0x80 | (pixels[i].g >> 1);
		b = 0x80 | (pixels[i].b >> 1);

		/*
		 * GRB is the ordering used by commonly available
		 * LPD880x strips.
		 */
		*px++ = g;
		*px++ = r;
		*px++ = b;
	}

	return lpd880x_update(dev, pixels, 3 * num_pixels);
}

static int lpd880x_strip_update_channels(const struct device *dev,
					 uint8_t *channels,
					 size_t num_channels)
{
	size_t i;

	for (i = 0; i < num_channels; i++) {
		channels[i] = 0x80 | (channels[i] >> 1);
	}

	return lpd880x_update(dev, channels, num_channels);
}

static size_t lpd880x_strip_length(const struct device *dev)
{
	const struct lpd880x_config *config = dev->config;

	return config->length;
}

static int lpd880x_strip_init(const struct device *dev)
{
	const struct lpd880x_config *config = dev->config;

	if (!spi_is_ready_dt(&config->bus)) {
		LOG_ERR("SPI device %s not ready", config->bus.bus->name);
		return -ENODEV;
	}

	return 0;
}

static const struct lpd880x_config lpd880x_config = {
	.bus = SPI_DT_SPEC_INST_GET(0, LPD880X_SPI_OPERATION, 0),
	.length = DT_INST_PROP(0, chain_length),
};

static const struct led_strip_driver_api lpd880x_strip_api = {
	.update_rgb = lpd880x_strip_update_rgb,
	.update_channels = lpd880x_strip_update_channels,
	.length = lpd880x_strip_length,
};

DEVICE_DT_INST_DEFINE(0, lpd880x_strip_init, NULL,
		      NULL, &lpd880x_config,
		      POST_KERNEL, CONFIG_LED_STRIP_INIT_PRIORITY,
		      &lpd880x_strip_api);
