/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2019, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT worldsemi_ws2812_spi

#include <drivers/led_strip.h>

#include <string.h>

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

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

/* spi-one-frame and spi-zero-frame in DT are for 8-bit frames. */
#define SPI_FRAME_BITS 8

/*
 * Delay time to make sure the strip has latched a signal.
 *
 * Despite datasheet claims, a 6 microsecond delay is enough to reset
 * the strip. Delay for 8 usec just to be safe.
 */
#define RESET_DELAY_USEC 8

/*
 * 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(SPI_FRAME_BITS) | SPI_LINES_SINGLE)

#define BYTES_PER_PX(has_white) ((has_white) ? 32 : 24)

struct ws2812_spi_data {
	struct device *spi;
};

struct ws2812_spi_cfg {
	struct spi_config spi_cfg;
	u8_t *px_buf;
	size_t px_buf_size;
	u8_t one_frame;
	u8_t zero_frame;
	bool has_white;
};

static struct ws2812_spi_data *dev_data(struct device *dev)
{
	return dev->driver_data;
}

static const struct ws2812_spi_cfg *dev_cfg(struct device *dev)
{
	return dev->config_info;
}

/*
 * Serialize an 8-bit color channel value into an equivalent sequence
 * of SPI frames, MSbit first, where a one bit becomes SPI frame
 * one_frame, and zero bit becomes zero_frame.
 */
static inline void ws2812_spi_ser(u8_t buf[8], u8_t color,
				  const u8_t one_frame, const u8_t zero_frame)
{
	int i;

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

/*
 * Returns true if and only if cfg->px_buf is big enough to convert
 * num_pixels RGB color values into SPI frames.
 */
static inline bool num_pixels_ok(const struct ws2812_spi_cfg *cfg,
				 size_t num_pixels)
{
	size_t nbytes;
	bool overflow;

	overflow = size_mul_overflow(num_pixels, BYTES_PER_PX(cfg->has_white),
				     &nbytes);
	return !overflow && (nbytes <= cfg->px_buf_size);
}

/*
 * Latch current color values on strip and reset its state machines.
 */
static inline void ws2812_reset_delay(void)
{
	/*
	 * TODO: swap out with k_usleep() once that can be trusted to
	 * work reliably.
	 */
	k_busy_wait(RESET_DELAY_USEC);
}

static int ws2812_strip_update_rgb(struct device *dev, struct led_rgb *pixels,
				   size_t num_pixels)
{
	const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
	const u8_t one = cfg->one_frame, zero = cfg->zero_frame;
	struct spi_buf buf = {
		.buf = cfg->px_buf,
		.len = cfg->px_buf_size,
	};
	const struct spi_buf_set tx = {
		.buffers = &buf,
		.count = 1
	};
	u8_t *px_buf = cfg->px_buf;
	size_t i;
	int rc;

	if (!num_pixels_ok(cfg, num_pixels)) {
		return -ENOMEM;
	}

	/*
	 * Convert pixel data into SPI frames. Each frame has pixel
	 * data in GRB on-wire format, with zeroed out white channel data
	 * if applicable.
	 */
	for (i = 0; i < num_pixels; i++) {
		ws2812_spi_ser(px_buf, pixels[i].g, one, zero);
		ws2812_spi_ser(px_buf + 8, pixels[i].r, one, zero);
		ws2812_spi_ser(px_buf + 16, pixels[i].b, one, zero);
		if (cfg->has_white) {
			ws2812_spi_ser(px_buf + 24, 0, one, zero);
			px_buf += 32;
		} else {
			px_buf += 24;
		}
	}

	/*
	 * Display the pixel data.
	 */
	rc = spi_write(dev_data(dev)->spi, &cfg->spi_cfg, &tx);
	ws2812_reset_delay();

	return rc;
}

static int ws2812_strip_update_channels(struct device *dev, u8_t *channels,
					size_t num_channels)
{
	LOG_ERR("update_channels not implemented");
	return -ENOTSUP;
}

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

#define WS2812_SPI_LABEL(idx) \
	(DT_INST_LABEL(idx))
#define WS2812_SPI_NUM_PIXELS(idx) \
	(DT_INST_PROP(idx, chain_length))
#define WS2812_SPI_HAS_WHITE(idx) \
	(DT_INST_PROP(idx, has_white_channel) == 1)
#define WS2812_SPI_BUS(idx) \
	(DT_INST_BUS_LABEL(idx))
#define WS2812_SPI_SLAVE(idx) \
	(DT_INST_REG_ADDR(idx))
#define WS2812_SPI_FREQ(idx) \
	(DT_INST_PROP(idx, spi_max_frequency))
#define WS2812_SPI_ONE_FRAME(idx) \
	(DT_INST_PROP(idx, spi_one_frame))
#define WS2812_SPI_ZERO_FRAME(idx)\
	(DT_INST_PROP(idx, spi_zero_frame))
#define WS2812_SPI_BUFSZ(idx) \
	(BYTES_PER_PX(WS2812_SPI_HAS_WHITE(idx)) * WS2812_SPI_NUM_PIXELS(idx))

#define WS2812_SPI_DEVICE(idx)						\
									\
	static struct ws2812_spi_data ws2812_spi_##idx##_data;		\
									\
	static u8_t ws2812_spi_##idx##_px_buf[WS2812_SPI_BUFSZ(idx)];	\
									\
	static const struct ws2812_spi_cfg ws2812_spi_##idx##_cfg = {	\
		.spi_cfg = {						\
			.frequency = WS2812_SPI_FREQ(idx),		\
			.operation = SPI_OPER,				\
			.slave = WS2812_SPI_SLAVE(idx),		\
			.cs = NULL,					\
		},							\
		.px_buf = ws2812_spi_##idx##_px_buf,			\
		.px_buf_size = WS2812_SPI_BUFSZ(idx),			\
		.one_frame = WS2812_SPI_ONE_FRAME(idx),		\
		.zero_frame = WS2812_SPI_ZERO_FRAME(idx),		\
		.has_white = WS2812_SPI_HAS_WHITE(idx),		\
	};								\
									\
	static int ws2812_spi_##idx##_init(struct device *dev)		\
	{								\
		struct ws2812_spi_data *data = dev_data(dev);		\
									\
		data->spi = device_get_binding(WS2812_SPI_BUS(idx));	\
		if (!data->spi) {					\
			LOG_ERR("SPI device %s not found",		\
				WS2812_SPI_BUS(idx));			\
			return -ENODEV;				\
		}							\
									\
		return 0;						\
	}								\
									\
	DEVICE_AND_API_INIT(ws2812_spi_##idx,				\
			    WS2812_SPI_LABEL(idx),			\
			    ws2812_spi_##idx##_init,			\
			    &ws2812_spi_##idx##_data,			\
			    &ws2812_spi_##idx##_cfg,			\
			    POST_KERNEL,				\
			    CONFIG_LED_STRIP_INIT_PRIORITY,		\
			    &ws2812_spi_api);

DT_INST_FOREACH_STATUS_OKAY(WS2812_SPI_DEVICE)
