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

#include <led_strip.h>

#include <string.h>

#define SYS_LOG_LEVEL CONFIG_SYS_LOG_LED_STRIP_LEVEL
#include <logging/sys_log.h>

#include <zephyr.h>
#include <device.h>
#include <spi.h>
#include <misc/util.h>

/*
 * WS2812-ish SPI master configuration:
 *
 * - mode 0 (the default), 8 bit, MSB first (arbitrary), one-line SPI
 * - no shenanigans (don't hold CS, don't hold the device lock, this
 *   isn't an EEPROM)
 */
#define SPI_OPER (SPI_OP_MODE_MASTER |		\
		  SPI_TRANSFER_MSB |		\
		  SPI_WORD_SET(8) |		\
		  SPI_LINES_SINGLE)

#define SPI_FREQ              CONFIG_WS2812_STRIP_SPI_BAUD_RATE
#define ONE_FRAME             CONFIG_WS2812_STRIP_ONE_FRAME
#define ZERO_FRAME            CONFIG_WS2812_STRIP_ZERO_FRAME
#define RED_OFFSET            (8 * sizeof(u8_t) * CONFIG_WS2812_RED_ORDER)
#define GRN_OFFSET            (8 * sizeof(u8_t) * CONFIG_WS2812_GRN_ORDER)
#define BLU_OFFSET            (8 * sizeof(u8_t) * CONFIG_WS2812_BLU_ORDER)
#ifdef CONFIG_WS2812_HAS_WHITE_CHANNEL
#define WHT_OFFSET            (8 * sizeof(u8_t) * CONFIG_WS2812_WHT_ORDER)
#else
#define WHT_OFFSET            -1
#endif

/*
 * Despite datasheet claims (see blog post link in Kconfig.ws2812), a
 * 6 microsecond pulse is enough to reset the strip. Convert that into
 * a number of 8 bit SPI frames, adding another just to be safe.
 */
#define RESET_NFRAMES ((size_t)ceiling_fraction(3 * SPI_FREQ, 4000000) + 1)

struct ws2812_data {
	struct spi_config config;
};

/*
 * Convert a color channel's bits into a sequence of SPI frames (with
 * the proper pulse and inter-pulse widths) to shift out.
 */
static inline void ws2812_serialize_color(u8_t buf[8], u8_t color)
{
	int i;

	for (i = 0; i < 8; i++) {
		buf[i] = color & BIT(7 - i) ? ONE_FRAME : ZERO_FRAME;
	}
}

/*
 * Convert a pixel into SPI frames, returning the number of bytes used.
 */
static size_t ws2812_serialize_pixel(u8_t px[32], struct led_rgb *pixel)
{
	ws2812_serialize_color(px + RED_OFFSET, pixel->r);
	ws2812_serialize_color(px + GRN_OFFSET, pixel->g);
	ws2812_serialize_color(px + BLU_OFFSET, pixel->b);
	if (IS_ENABLED(CONFIG_WS2812_HAS_WHITE_CHANNEL)) {
		ws2812_serialize_color(px + WHT_OFFSET, 0); /* unused */
		return 32;
	}
	return 24;
}

/*
 * Latch current color values on strip and reset its state machines.
 */
static int ws2812_reset_strip(struct spi_config *config)
{
	u8_t reset_buf[RESET_NFRAMES];
	struct spi_buf reset = {
		.buf = reset_buf,
		.len = sizeof(reset_buf),
	};

	memset(reset_buf, 0x00, sizeof(reset_buf));

	return spi_write(config, &reset, 1);
}

static int ws2812_strip_update_rgb(struct device *dev, struct led_rgb *pixels,
				   size_t num_pixels)
{
	struct ws2812_data *drv_data = dev->driver_data;
	struct spi_config *config = &drv_data->config;
	u8_t px_buf[32]; /* 32 are needed when a white channel is present. */
	struct spi_buf buf = {
		.buf = px_buf,
	};
	size_t i;
	int rc;

	for (i = 0; i < num_pixels; i++) {
		buf.len = ws2812_serialize_pixel(px_buf, &pixels[i]);
		rc = spi_write(config, &buf, 1);
		if (rc) {
			/*
			 * Latch anything we've shifted out first, to
			 * call visual attention to the problematic
			 * pixel.
			 */
			(void)ws2812_reset_strip(config);
			SYS_LOG_ERR("can't set pixel %u: %d", i, rc);
			return rc;
		}
	}

	return ws2812_reset_strip(config);
}

static int ws2812_strip_update_channels(struct device *dev, u8_t *channels,
					size_t num_channels)
{
	struct ws2812_data *drv_data = dev->driver_data;
	struct spi_config *config = &drv_data->config;
	u8_t px_buf[8]; /* one byte per bit */
	struct spi_buf buf = {
		.buf = px_buf,
		.len = sizeof(px_buf),
	};
	size_t i;
	int rc;

	for (i = 0; i < num_channels; i++) {
		ws2812_serialize_color(px_buf, channels[i]);
		rc = spi_write(config, &buf, 1);
		if (rc) {
			/*
			 * Latch anything we've shifted out first, to
			 * call visual attention to the problematic
			 * pixel.
			 */
			(void)ws2812_reset_strip(config);
			SYS_LOG_ERR("can't set channel %u: %d", i, rc);
			return rc;
		}
	}

	return ws2812_reset_strip(config);
}

static int ws2812_strip_init(struct device *dev)
{
	struct ws2812_data *data = dev->driver_data;
	struct spi_config *config = &data->config;
	struct device *spi;

	spi = device_get_binding(CONFIG_WS2812_STRIP_SPI_DEV_NAME);
	if (!spi) {
		SYS_LOG_ERR("SPI device %s not found",
			    CONFIG_WS2812_STRIP_SPI_DEV_NAME);
		return -ENODEV;
	}

	config->dev = spi;
	config->frequency = SPI_FREQ;
	config->operation = SPI_OPER;
	config->slave = 0;	/* MOSI only. */
	config->cs = NULL;

	return 0;
}

static struct ws2812_data ws2812_strip_data;

static const struct led_strip_driver_api ws2812_strip_api = {
	.update_rgb = ws2812_strip_update_rgb,
	.update_channels = ws2812_strip_update_channels,
};

DEVICE_AND_API_INIT(ws2812_strip, CONFIG_WS2812_STRIP_NAME,
		    ws2812_strip_init, &ws2812_strip_data,
		    NULL, POST_KERNEL, CONFIG_LED_STRIP_INIT_PRIORITY,
		    &ws2812_strip_api);
