/*
 * Copyright (c) 2020 PHYTEC Messtechnik GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <device.h>
#include <init.h>
#include <drivers/display.h>
#include <drivers/gpio.h>
#include <drivers/spi.h>
#include <sys/byteorder.h>

#include "gd7965_regs.h"

#include <logging/log.h>
LOG_MODULE_REGISTER(gd7965, CONFIG_DISPLAY_LOG_LEVEL);

/**
 * GD7965 compatible EPD controller driver.
 *
 * Currently only the black/white pannels are supported (KW mode),
 * also first gate/source should be 0.
 */

#define GD7965_SPI_FREQ DT_INST_0_GOODDISPLAY_GD7965_SPI_MAX_FREQUENCY
#define GD7965_BUS_NAME DT_INST_0_GOODDISPLAY_GD7965_BUS_NAME
#define GD7965_DC_PIN DT_INST_0_GOODDISPLAY_GD7965_DC_GPIOS_PIN
#define GD7965_DC_FLAGS DT_INST_0_GOODDISPLAY_GD7965_DC_GPIOS_FLAGS
#define GD7965_DC_CNTRL DT_INST_0_GOODDISPLAY_GD7965_DC_GPIOS_CONTROLLER
#define GD7965_CS_PIN DT_INST_0_GOODDISPLAY_GD7965_CS_GPIOS_PIN
#if defined(DT_INST_0_GOODDISPLAY_GD7965_CS_GPIOS_CONTROLLER)
#define GD7965_CS_CNTRL DT_INST_0_GOODDISPLAY_GD7965_CS_GPIOS_CONTROLLER
#endif
#define GD7965_BUSY_PIN DT_INST_0_GOODDISPLAY_GD7965_BUSY_GPIOS_PIN
#define GD7965_BUSY_CNTRL DT_INST_0_GOODDISPLAY_GD7965_BUSY_GPIOS_CONTROLLER
#define GD7965_BUSY_FLAGS DT_INST_0_GOODDISPLAY_GD7965_BUSY_GPIOS_FLAGS
#define GD7965_RESET_PIN DT_INST_0_GOODDISPLAY_GD7965_RESET_GPIOS_PIN
#define GD7965_RESET_CNTRL DT_INST_0_GOODDISPLAY_GD7965_RESET_GPIOS_CONTROLLER
#define GD7965_RESET_FLAGS DT_INST_0_GOODDISPLAY_GD7965_RESET_GPIOS_FLAGS

#define EPD_PANEL_WIDTH			DT_INST_0_GOODDISPLAY_GD7965_WIDTH
#define EPD_PANEL_HEIGHT		DT_INST_0_GOODDISPLAY_GD7965_HEIGHT
#define GD7965_PIXELS_PER_BYTE		8U

/* Horizontally aligned page! */
#define GD7965_NUMOF_PAGES		(EPD_PANEL_WIDTH / \
					 GD7965_PIXELS_PER_BYTE)
#define GD7965_PANEL_FIRST_GATE		0U
#define GD7965_PANEL_LAST_GATE		(EPD_PANEL_HEIGHT - 1)
#define GD7965_PANEL_FIRST_PAGE		0U
#define GD7965_PANEL_LAST_PAGE		(GD7965_NUMOF_PAGES - 1)


struct gd7965_data {
	struct device *reset;
	struct device *dc;
	struct device *busy;
	struct device *spi_dev;
	struct spi_config spi_config;
#if defined(GD7965_CS_CNTRL)
	struct spi_cs_control cs_ctrl;
#endif
};

static u8_t gd7965_softstart[] = DT_INST_0_GOODDISPLAY_GD7965_SOFTSTART;
static u8_t gd7965_pwr[] = DT_INST_0_GOODDISPLAY_GD7965_PWR;

/* Border and data polarity settings */
static u8_t bdd_polarity;

static bool blanking_on = true;

static inline int gd7965_write_cmd(struct gd7965_data *driver,
				   u8_t cmd, u8_t *data, size_t len)
{
	struct spi_buf buf = {.buf = &cmd, .len = sizeof(cmd)};
	struct spi_buf_set buf_set = {.buffers = &buf, .count = 1};

	gpio_pin_set(driver->dc, GD7965_DC_PIN, 1);
	if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) {
		return -EIO;
	}

	if (data != NULL) {
		buf.buf = data;
		buf.len = len;
		gpio_pin_set(driver->dc, GD7965_DC_PIN, 0);
		if (spi_write(driver->spi_dev, &driver->spi_config, &buf_set)) {
			return -EIO;
		}
	}

	return 0;
}

static inline void gd7965_busy_wait(struct gd7965_data *driver)
{
	int pin = gpio_pin_get(driver->busy, GD7965_BUSY_PIN);

	while (pin > 0) {
		__ASSERT(pin >= 0, "Failed to get pin level");
		LOG_DBG("wait %u", pin);
		k_sleep(GD7965_BUSY_DELAY);
		pin = gpio_pin_get(driver->busy, GD7965_BUSY_PIN);
	}
}

static int gd7965_update_display(const struct device *dev)
{
	struct gd7965_data *driver = dev->driver_data;

	LOG_DBG("Trigger update sequence");
	if (gd7965_write_cmd(driver, GD7965_CMD_DRF, NULL, 0)) {
		return -EIO;
	}

	k_sleep(GD7965_BUSY_DELAY);

	return 0;
}

static int gd7965_blanking_off(const struct device *dev)
{
	struct gd7965_data *driver = dev->driver_data;

	if (blanking_on) {
		/* Update EPD pannel in normal mode */
		gd7965_busy_wait(driver);
		if (gd7965_update_display(dev)) {
			return -EIO;
		}
	}

	blanking_on = false;

	return 0;
}

static int gd7965_blanking_on(const struct device *dev)
{
	blanking_on = true;

	return 0;
}

static int gd7965_write(const struct device *dev, const u16_t x, const u16_t y,
			const struct display_buffer_descriptor *desc,
			const void *buf)
{
	struct gd7965_data *driver = dev->driver_data;
	u16_t x_end_idx = x + desc->width - 1;
	u16_t y_end_idx = y + desc->height - 1;
	u8_t ptl[GD7965_PTL_REG_LENGTH] = {0};
	size_t buf_len;

	LOG_DBG("x %u, y %u, height %u, width %u, pitch %u",
		x, y, desc->height, desc->width, desc->pitch);

	buf_len = MIN(desc->buf_size,
		      desc->height * desc->width / GD7965_PIXELS_PER_BYTE);
	__ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width");
	__ASSERT(buf != NULL, "Buffer is not available");
	__ASSERT(buf_len != 0U, "Buffer of length zero");
	__ASSERT(!(desc->width % GD7965_PIXELS_PER_BYTE),
		 "Buffer width not multiple of %d", GD7965_PIXELS_PER_BYTE);

	if ((y_end_idx > (EPD_PANEL_HEIGHT - 1)) ||
	    (x_end_idx > (EPD_PANEL_WIDTH - 1))) {
		LOG_ERR("Position out of bounds");
		return -EINVAL;
	}

	/* Setup Partial Window and enable Partial Mode */
	sys_put_be16(x, &ptl[GD7965_PTL_HRST_IDX]);
	sys_put_be16(x_end_idx, &ptl[GD7965_PTL_HRED_IDX]);
	sys_put_be16(y, &ptl[GD7965_PTL_VRST_IDX]);
	sys_put_be16(y_end_idx, &ptl[GD7965_PTL_VRED_IDX]);
	ptl[sizeof(ptl) - 1] = GD7965_PTL_PT_SCAN;
	LOG_HEXDUMP_DBG(ptl, sizeof(ptl), "ptl");

	gd7965_busy_wait(driver);
	if (gd7965_write_cmd(driver, GD7965_CMD_PTIN, NULL, 0)) {
		return -EIO;
	}

	if (gd7965_write_cmd(driver, GD7965_CMD_PTL, ptl, sizeof(ptl))) {
		return -EIO;
	}

	/* Disable boarder output */
	bdd_polarity |= GD7965_CDI_BDZ;
	if (gd7965_write_cmd(driver, GD7965_CMD_CDI,
			     &bdd_polarity, sizeof(bdd_polarity))) {
		return -EIO;
	}

	if (gd7965_write_cmd(driver, GD7965_CMD_DTM2, (u8_t *)buf, buf_len)) {
		return -EIO;
	}

	/* Update partial window and disable Partial Mode */
	if (blanking_on == false) {
		if (gd7965_update_display(dev)) {
			return -EIO;
		}
	}

	/* Enable boarder output */
	bdd_polarity &= ~GD7965_CDI_BDZ;
	if (gd7965_write_cmd(driver, GD7965_CMD_CDI,
			     &bdd_polarity, sizeof(bdd_polarity))) {
		return -EIO;
	}

	if (gd7965_write_cmd(driver, GD7965_CMD_PTOUT, NULL, 0)) {
		return -EIO;
	}

	return 0;
}

static int gd7965_read(const struct device *dev, const u16_t x, const u16_t y,
		       const struct display_buffer_descriptor *desc, void *buf)
{
	LOG_ERR("not supported");
	return -ENOTSUP;
}

static void *gd7965_get_framebuffer(const struct device *dev)
{
	LOG_ERR("not supported");
	return NULL;
}

static int gd7965_set_brightness(const struct device *dev,
				 const u8_t brightness)
{
	LOG_WRN("not supported");
	return -ENOTSUP;
}

static int gd7965_set_contrast(const struct device *dev, u8_t contrast)
{
	LOG_WRN("not supported");
	return -ENOTSUP;
}

static void gd7965_get_capabilities(const struct device *dev,
				    struct display_capabilities *caps)
{
	memset(caps, 0, sizeof(struct display_capabilities));
	caps->x_resolution = EPD_PANEL_WIDTH;
	caps->y_resolution = EPD_PANEL_HEIGHT;
	caps->supported_pixel_formats = PIXEL_FORMAT_MONO10;
	caps->current_pixel_format = PIXEL_FORMAT_MONO10;
	caps->screen_info = SCREEN_INFO_MONO_MSB_FIRST | SCREEN_INFO_EPD;
}

static int gd7965_set_orientation(const struct device *dev,
				  const enum display_orientation
				  orientation)
{
	LOG_ERR("Unsupported");
	return -ENOTSUP;
}

static int gd7965_set_pixel_format(const struct device *dev,
				   const enum display_pixel_format pf)
{
	if (pf == PIXEL_FORMAT_MONO10) {
		return 0;
	}

	LOG_ERR("not supported");
	return -ENOTSUP;
}

static int gd7965_clear_and_write_buffer(struct device *dev,
					 u8_t pattern, bool update)
{
	struct display_buffer_descriptor desc = {
		.buf_size = GD7965_NUMOF_PAGES,
		.width = EPD_PANEL_WIDTH,
		.height = 1,
		.pitch = EPD_PANEL_WIDTH,
	};
	u8_t *line;

	line = k_malloc(GD7965_NUMOF_PAGES);
	if (line == NULL) {
		return -ENOMEM;
	}

	memset(line, pattern, GD7965_NUMOF_PAGES);
	for (int i = 0; i < EPD_PANEL_HEIGHT; i++) {
		gd7965_write(dev, 0, i, &desc, line);
	}

	k_free(line);

	if (update == true) {
		if (gd7965_update_display(dev)) {
			return -EIO;
		}
	}

	return 0;
}

static int gd7965_controller_init(struct device *dev)
{
	struct gd7965_data *driver = dev->driver_data;
	u8_t tmp[GD7965_TRES_REG_LENGTH];

	gpio_pin_set(driver->reset, GD7965_RESET_PIN, 1);
	k_sleep(GD7965_RESET_DELAY);
	gpio_pin_set(driver->reset, GD7965_RESET_PIN, 0);
	k_sleep(GD7965_RESET_DELAY);
	gd7965_busy_wait(driver);

	LOG_DBG("Initialize GD7965 controller");

	if (gd7965_write_cmd(driver, GD7965_CMD_PWR, gd7965_pwr,
			     sizeof(gd7965_pwr))) {
		return -EIO;
	}

	if (gd7965_write_cmd(driver, GD7965_CMD_BTST,
			     gd7965_softstart, sizeof(gd7965_softstart))) {
		return -EIO;
	}

	/* Turn on: booster, controller, regulators, and sensor. */
	if (gd7965_write_cmd(driver, GD7965_CMD_PON, NULL, 0)) {
		return -EIO;
	}

	k_sleep(GD7965_PON_DELAY);
	gd7965_busy_wait(driver);

	/* Pannel settings, KW mode */
	tmp[0] = GD7965_PSR_KW_R |
		 GD7965_PSR_UD |
		 GD7965_PSR_SHL |
		 GD7965_PSR_SHD |
		 GD7965_PSR_RST;
	if (gd7965_write_cmd(driver, GD7965_CMD_PSR, tmp, 1)) {
		return -EIO;
	}

	/* Set panel resolution */
	sys_put_be16(EPD_PANEL_WIDTH, &tmp[GD7965_TRES_HRES_IDX]);
	sys_put_be16(EPD_PANEL_HEIGHT, &tmp[GD7965_TRES_VRES_IDX]);
	LOG_HEXDUMP_DBG(tmp, sizeof(tmp), "TRES");
	if (gd7965_write_cmd(driver, GD7965_CMD_TRES,
			     tmp, GD7965_TRES_REG_LENGTH)) {
		return -EIO;
	}

	bdd_polarity = GD7965_CDI_BDV1 |
		       GD7965_CDI_N2OCP | GD7965_CDI_DDX0;
	tmp[GD7965_CDI_BDZ_DDX_IDX] = bdd_polarity;
	tmp[GD7965_CDI_CDI_IDX] = DT_INST_0_GOODDISPLAY_GD7965_CDI;
	LOG_HEXDUMP_DBG(tmp, GD7965_CDI_REG_LENGTH, "CDI");
	if (gd7965_write_cmd(driver, GD7965_CMD_CDI, tmp,
			     GD7965_CDI_REG_LENGTH)) {
		return -EIO;
	}

	tmp[0] = DT_INST_0_GOODDISPLAY_GD7965_TCON;
	if (gd7965_write_cmd(driver, GD7965_CMD_TCON, tmp, 1)) {
		return -EIO;
	}

	/* Enable Auto Sequence */
	tmp[0] = GD7965_AUTO_PON_DRF_POF;
	if (gd7965_write_cmd(driver, GD7965_CMD_AUTO, tmp, 1)) {
		return -EIO;
	}

	if (gd7965_clear_and_write_buffer(dev, 0xff, false)) {
		return -1;
	}

	return 0;
}

static int gd7965_init(struct device *dev)
{
	struct gd7965_data *driver = dev->driver_data;

	LOG_DBG("");

	driver->spi_dev = device_get_binding(GD7965_BUS_NAME);
	if (driver->spi_dev == NULL) {
		LOG_ERR("Could not get SPI device for GD7965");
		return -EIO;
	}

	driver->spi_config.frequency = GD7965_SPI_FREQ;
	driver->spi_config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
	driver->spi_config.slave = DT_INST_0_GOODDISPLAY_GD7965_BASE_ADDRESS;
	driver->spi_config.cs = NULL;

	driver->reset = device_get_binding(GD7965_RESET_CNTRL);
	if (driver->reset == NULL) {
		LOG_ERR("Could not get GPIO port for GD7965 reset");
		return -EIO;
	}

	gpio_pin_configure(driver->reset, GD7965_RESET_PIN,
			   GPIO_OUTPUT_INACTIVE | GD7965_RESET_FLAGS);

	driver->dc = device_get_binding(GD7965_DC_CNTRL);
	if (driver->dc == NULL) {
		LOG_ERR("Could not get GPIO port for GD7965 DC signal");
		return -EIO;
	}

	gpio_pin_configure(driver->dc, GD7965_DC_PIN,
			   GPIO_OUTPUT_INACTIVE | GD7965_DC_FLAGS);

	driver->busy = device_get_binding(GD7965_BUSY_CNTRL);
	if (driver->busy == NULL) {
		LOG_ERR("Could not get GPIO port for GD7965 busy signal");
		return -EIO;
	}

	gpio_pin_configure(driver->busy, GD7965_BUSY_PIN,
			   GPIO_INPUT | GD7965_BUSY_FLAGS);

#if defined(GD7965_CS_CNTRL)
	driver->cs_ctrl.gpio_dev = device_get_binding(GD7965_CS_CNTRL);
	if (!driver->cs_ctrl.gpio_dev) {
		LOG_ERR("Unable to get SPI GPIO CS device");
		return -EIO;
	}

	driver->cs_ctrl.gpio_pin = GD7965_CS_PIN;
	driver->cs_ctrl.delay = 0U;
	driver->spi_config.cs = &driver->cs_ctrl;
#endif

	return gd7965_controller_init(dev);
}

static struct gd7965_data gd7965_driver;

static struct display_driver_api gd7965_driver_api = {
	.blanking_on = gd7965_blanking_on,
	.blanking_off = gd7965_blanking_off,
	.write = gd7965_write,
	.read = gd7965_read,
	.get_framebuffer = gd7965_get_framebuffer,
	.set_brightness = gd7965_set_brightness,
	.set_contrast = gd7965_set_contrast,
	.get_capabilities = gd7965_get_capabilities,
	.set_pixel_format = gd7965_set_pixel_format,
	.set_orientation = gd7965_set_orientation,
};


DEVICE_AND_API_INIT(gd7965, DT_INST_0_GOODDISPLAY_GD7965_LABEL, gd7965_init,
		    &gd7965_driver, NULL,
		    POST_KERNEL, CONFIG_APPLICATION_INIT_PRIORITY,
		    &gd7965_driver_api);
