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

#include <drivers/led_strip.h>

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

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

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

#include <zephyr.h>
#include <device.h>
#include <drivers/spi.h>
#include <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) |    \
			       SPI_LINES_SINGLE)

struct lpd880x_config {
	struct spi_dt_spec bus;
};

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 = ceiling_fraction(ceiling_fraction(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: %d", 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 int lpd880x_strip_init(const struct device *dev)
{
	const struct lpd880x_config *config = dev->config;

	if (!spi_is_ready(&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)
};

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

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