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

#include <drivers/led_strip.h>

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

#ifdef DT_INST_0_COLORWAY_LPD8806
#define DT_INST_0_COLORWAY_LPD880X DT_INST_0_COLORWAY_LPD8806
#define DT_INST_0_COLORWAY_LPD880X_BASE_ADDRESS DT_INST_0_COLORWAY_LPD8806_BASE_ADDRESS
#define DT_INST_0_COLORWAY_LPD880X_BUS_NAME DT_INST_0_COLORWAY_LPD8806_BUS_NAME
#define DT_INST_0_COLORWAY_LPD880X_LABEL DT_INST_0_COLORWAY_LPD8806_LABEL
#define DT_INST_0_COLORWAY_LPD880X_SPI_MAX_FREQUENCY DT_INST_0_COLORWAY_LPD8806_SPI_MAX_FREQUENCY
#else
#define DT_INST_0_COLORWAY_LPD880X DT_INST_0_COLORWAY_LPD8803
#define DT_INST_0_COLORWAY_LPD880X_BASE_ADDRESS DT_INST_0_COLORWAY_LPD8803_BASE_ADDRESS
#define DT_INST_0_COLORWAY_LPD880X_BUS_NAME DT_INST_0_COLORWAY_LPD8803_BUS_NAME
#define DT_INST_0_COLORWAY_LPD880X_LABEL DT_INST_0_COLORWAY_LPD8803_LABEL
#define DT_INST_0_COLORWAY_LPD880X_SPI_MAX_FREQUENCY DT_INST_0_COLORWAY_LPD8803_SPI_MAX_FREQUENCY
#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_data {
	struct device *spi;
	struct spi_config config;
};

static int lpd880x_update(struct device *dev, void *data, size_t size)
{
	struct lpd880x_data *drv_data = dev->driver_data;
	/*
	 * 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.
	 */
	u8_t reset_size = ceiling_fraction(ceiling_fraction(size, 3), 32);
	u8_t reset_buf[reset_size];
	u8_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(drv_data->spi, &drv_data->config, &tx);
	if (rc) {
		LOG_ERR("can't update strip: %d", rc);
	}

	return rc;
}

static int lpd880x_strip_update_rgb(struct device *dev,
				    struct led_rgb *pixels,
				    size_t num_pixels)
{
	u8_t *px = (u8_t *)pixels;
	u8_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(struct device *dev, u8_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(struct device *dev)
{
	struct lpd880x_data *data = dev->driver_data;
	struct spi_config *config = &data->config;

	data->spi = device_get_binding(DT_INST_0_COLORWAY_LPD880X_BUS_NAME);
	if (!data->spi) {
		LOG_ERR("SPI device %s not found",
			    DT_INST_0_COLORWAY_LPD880X_BUS_NAME);
		return -ENODEV;
	}

	config->frequency = DT_INST_0_COLORWAY_LPD880X_SPI_MAX_FREQUENCY;
	config->operation = LPD880X_SPI_OPERATION;
	config->slave = DT_INST_0_COLORWAY_LPD880X_BASE_ADDRESS; /* MOSI/CLK only; CS is not supported. */
	config->cs = NULL;

	return 0;
}

static struct lpd880x_data lpd880x_strip_data;

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

DEVICE_AND_API_INIT(lpd880x_strip, DT_INST_0_COLORWAY_LPD880X_LABEL,
		    lpd880x_strip_init, &lpd880x_strip_data,
		    NULL, POST_KERNEL, CONFIG_LED_STRIP_INIT_PRIORITY,
		    &lpd880x_strip_api);
