/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <drivers/led_strip.h>
#include <string.h>

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

#include <zephyr.h>
#include <soc.h>
#include <drivers/gpio.h>
#include <device.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/nrf_clock_control.h>

static int send_buf(u8_t *buf, size_t len)
{
	/* Address of OUTSET. OUTCLR is OUTSET + 4 */
	volatile u32_t *base = (u32_t *)(NRF_GPIO_BASE + 0x508);
	u32_t pin = BIT(CONFIG_WS2812B_SW_GPIO_PIN);
	struct device *clock;
	unsigned int key;
	/* Initilization of i is strictly not needed, but it avoids an
	 * uninitialized warning with the inline assembly.
	 */
	u32_t i = 0U;

	clock = device_get_binding(DT_INST_0_NORDIC_NRF_CLOCK_LABEL);
	if (!clock) {
		LOG_ERR("Unable to get HF clock");
		return -EIO;
	}

	/* The inline assembly further below is designed to work only with
	 * the 16 MHz clock enabled.
	 */
	clock_control_on(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);
	key = irq_lock();

	while (len--) {
		u32_t b = *buf++;

		/* Generate signal out of the bits, MSB. 1-bit should be
		 * roughly 0.85us high, 0.4us low, whereas a 0-bit should be
		 * roughly 0.4us high, 0.85us low.
		 */
		__asm volatile ("movs %[i], #8\n" /* i = 8 */
				".start_bit:\n"

				/* OUTSET = BIT(LED_PIN) */
				"strb %[p], [%[r], #0]\n"

				/* if (b & 0x80) goto .long */
				"tst %[b], %[m]\n"
				"bne .long\n"

				/* 0-bit */
				"nop\nnop\n"
				/* OUTCLR = BIT(LED_PIN) */
				"strb %[p], [%[r], #4]\n"
				"nop\nnop\nnop\n"
				"b .next_bit\n"

				/* 1-bit */
				".long:\n"
				"nop\nnop\nnop\nnop\nnop\nnop\nnop\n"
				/* OUTCLR = BIT(LED_PIN) */
				"strb %[p], [%[r], #4]\n"

				".next_bit:\n"
				/* b <<= 1 */
				"lsl %[b], #1\n"
				/* i-- */
				"sub %[i], #1\n"
				/* if (i > 0) goto .start_bit */
				"bne .start_bit\n"
				:
				[i] "+r" (i)
				:
				[b] "l" (b),
				[m] "l" (0x80),
				[r] "l" (base),
				[p] "r" (pin)
				:);
	}

	irq_unlock(key);
	clock_control_off(clock, CLOCK_CONTROL_NRF_SUBSYS_HF);

	return 0;
}

static int ws2812b_sw_update_rgb(struct device *dev, struct led_rgb *pixels,
				 size_t num_pixels)
{
	u8_t *ptr = (u8_t *)pixels;
	size_t i;

	/* Convert from RGB to GRB format */
	for (i = 0; i < num_pixels; i++) {
		u8_t r = pixels[i].r;
		u8_t b = pixels[i].b;
		u8_t g = pixels[i].g;

		*ptr++ = g;
		*ptr++ = r;
		*ptr++ = b;
	}

	return send_buf((u8_t *)pixels, num_pixels * 3);
}

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

static int ws2812b_sw_init(struct device *dev)
{
	struct device *gpio;

	gpio = device_get_binding(CONFIG_WS2812B_SW_GPIO_NAME);
	if (!gpio) {
		LOG_ERR("Unable to find %s", CONFIG_WS2812B_SW_GPIO_NAME);
		return -ENODEV;
	}

	gpio_pin_configure(gpio, CONFIG_WS2812B_SW_GPIO_PIN, GPIO_DIR_OUT);

	return 0;
}

static const struct led_strip_driver_api ws2812b_sw_api = {
	.update_rgb = ws2812b_sw_update_rgb,
	.update_channels = ws2812b_sw_update_channels,
};

DEVICE_AND_API_INIT(ws2812b_sw, CONFIG_WS2812B_SW_NAME, ws2812b_sw_init, NULL,
		    NULL, POST_KERNEL, CONFIG_LED_STRIP_INIT_PRIORITY,
		    &ws2812b_sw_api);
