/*
 * Copyright (c) 2020 Hubert Miś
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT ftdi_ft800

#include <drivers/misc/ft8xx/ft8xx.h>

#include <stddef.h>
#include <stdint.h>

#include <device.h>
#include <kernel.h>
#include <logging/log.h>

#include <drivers/misc/ft8xx/ft8xx_copro.h>
#include <drivers/misc/ft8xx/ft8xx_common.h>
#include <drivers/misc/ft8xx/ft8xx_dl.h>
#include <drivers/misc/ft8xx/ft8xx_memory.h>

#include "ft8xx_drv.h"
#include "ft8xx_host_commands.h"

LOG_MODULE_REGISTER(ft8xx, CONFIG_DISPLAY_LOG_LEVEL);

#define FT8XX_DLSWAP_FRAME 0x02

#define FT8XX_EXPECTED_ID 0x7C

struct ft8xx_config {
	uint16_t vsize;
	uint16_t voffset;
	uint16_t vcycle;
	uint16_t vsync0;
	uint16_t vsync1;
	uint16_t hsize;
	uint16_t hoffset;
	uint16_t hcycle;
	uint16_t hsync0;
	uint16_t hsync1;
	uint8_t pclk;
	uint8_t pclk_pol :1;
	uint8_t cspread  :1;
	uint8_t swizzle  :4;
};

struct ft8xx_data {
	const struct ft8xx_config *config;
	ft8xx_int_callback irq_callback;
};

const static struct ft8xx_config ft8xx_config = {
	.pclk     = DT_INST_PROP(0, pclk),
	.pclk_pol = DT_INST_PROP(0, pclk_pol),
	.cspread  = DT_INST_PROP(0, cspread),
	.swizzle  = DT_INST_PROP(0, swizzle),
	.vsize    = DT_INST_PROP(0, vsize),
	.voffset  = DT_INST_PROP(0, voffset),
	.vcycle   = DT_INST_PROP(0, vcycle),
	.vsync0   = DT_INST_PROP(0, vsync0),
	.vsync1   = DT_INST_PROP(0, vsync1),
	.hsize    = DT_INST_PROP(0, hsize),
	.hoffset  = DT_INST_PROP(0, hoffset),
	.hcycle   = DT_INST_PROP(0, hcycle),
	.hsync0   = DT_INST_PROP(0, hsync0),
	.hsync1   = DT_INST_PROP(0, hsync1),
};

static struct ft8xx_data ft8xx_data = {
	.config = &ft8xx_config,
	.irq_callback = NULL,
};

static void host_command(uint8_t cmd)
{
	int err;

	err = ft8xx_drv_command(cmd);
	__ASSERT(err == 0, "Writing FT8xx command failed");
}

static void wait(void)
{
	k_sleep(K_MSEC(20));
}

static bool verify_chip(void)
{
	uint32_t id = ft8xx_rd32(FT800_REG_ID);

	return (id & 0xff) == FT8XX_EXPECTED_ID;
}

static int ft8xx_init(const struct device *dev)
{
	int ret;
	struct ft8xx_config *config = (struct ft8xx_config *)dev->config;

	ret = ft8xx_drv_init();
	if (ret < 0) {
		LOG_ERR("FT8xx driver initialization failed with %d", ret);
		return ret;
	}

	/* Reset display controller */
	host_command(CORERST);
	host_command(ACTIVE);
	wait();
	host_command(CLKEXT);
	host_command(CLK48M);
	wait();

	host_command(CORERST);
	host_command(ACTIVE);
	wait();
	host_command(CLKEXT);
	host_command(CLK48M);
	wait();

	if (!verify_chip()) {
		LOG_ERR("FT8xx chip not recognized");
		return -ENODEV;
	}

	/* Disable LCD */
	ft8xx_wr8(FT800_REG_GPIO, 0);
	ft8xx_wr8(FT800_REG_PCLK, 0);

	/* Configure LCD */
	ft8xx_wr16(FT800_REG_HSIZE, config->hsize);
	ft8xx_wr16(FT800_REG_HCYCLE, config->hcycle);
	ft8xx_wr16(FT800_REG_HOFFSET, config->hoffset);
	ft8xx_wr16(FT800_REG_HSYNC0, config->hsync0);
	ft8xx_wr16(FT800_REG_HSYNC1, config->hsync1);
	ft8xx_wr16(FT800_REG_VSIZE, config->vsize);
	ft8xx_wr16(FT800_REG_VCYCLE, config->vcycle);
	ft8xx_wr16(FT800_REG_VOFFSET, config->voffset);
	ft8xx_wr16(FT800_REG_VSYNC0, config->vsync0);
	ft8xx_wr16(FT800_REG_VSYNC1, config->vsync1);
	ft8xx_wr8(FT800_REG_SWIZZLE, config->swizzle);
	ft8xx_wr8(FT800_REG_PCLK_POL, config->pclk_pol);
	ft8xx_wr8(FT800_REG_CSPREAD, config->cspread);

	/* Display initial screen */

	/* Set the initial color */
	ft8xx_wr32(FT800_RAM_DL + 0, FT8XX_CLEAR_COLOR_RGB(0, 0x80, 0));
	/* Clear to the initial color */
	ft8xx_wr32(FT800_RAM_DL + 4, FT8XX_CLEAR(1, 1, 1));
	/* End the display list */
	ft8xx_wr32(FT800_RAM_DL + 8, FT8XX_DISPLAY());
	ft8xx_wr8(FT800_REG_DLSWAP, FT8XX_DLSWAP_FRAME);

	/* Enable LCD */

	/* Enable display bit */
	ft8xx_wr8(FT800_REG_GPIO_DIR, 0x80);
	ft8xx_wr8(FT800_REG_GPIO, 0x80);
	/* Enable backlight */
	ft8xx_wr16(FT800_REG_PWM_HZ, 0x00FA);
	ft8xx_wr8(FT800_REG_PWM_DUTY, 0x10);
	/* Enable LCD signals */
	ft8xx_wr8(FT800_REG_PCLK, config->pclk);

	return 0;
}

DEVICE_DEFINE(ft8xx_spi, "ft8xx_spi", ft8xx_init, NULL,
		&ft8xx_data, &ft8xx_config,
		APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);

int ft8xx_get_touch_tag(void)
{
	/* Read FT800_REG_INT_FLAGS to clear IRQ */
	(void)ft8xx_rd8(FT800_REG_INT_FLAGS);

	return (int)ft8xx_rd8(FT800_REG_TOUCH_TAG);
}

void ft8xx_drv_irq_triggered(const struct device *dev, struct gpio_callback *cb,
			      uint32_t pins)
{
	if (ft8xx_data.irq_callback != NULL) {
		ft8xx_data.irq_callback();
	}
}

void ft8xx_register_int(ft8xx_int_callback callback)
{
	if (ft8xx_data.irq_callback != NULL) {
		return;
	}

	ft8xx_data.irq_callback = callback;
	ft8xx_wr8(FT800_REG_INT_MASK, 0x04);
	ft8xx_wr8(FT800_REG_INT_EN, 0x01);
}

void ft8xx_calibrate(struct ft8xx_touch_transform *data)
{
	uint32_t result = 0;

	do {
		ft8xx_copro_cmd_dlstart();
		ft8xx_copro_cmd(FT8XX_CLEAR_COLOR_RGB(0x00, 0x00, 0x00));
		ft8xx_copro_cmd(FT8XX_CLEAR(1, 1, 1));
		ft8xx_copro_cmd_calibrate(&result);
	} while (result == 0);

	data->a = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_A);
	data->b = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_B);
	data->c = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_C);
	data->d = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_D);
	data->e = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_E);
	data->f = ft8xx_rd32(FT800_REG_TOUCH_TRANSFORM_F);
}

void ft8xx_touch_transform_set(const struct ft8xx_touch_transform *data)
{
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_A, data->a);
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_B, data->b);
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_C, data->c);
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_D, data->d);
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_E, data->e);
	ft8xx_wr32(FT800_REG_TOUCH_TRANSFORM_F, data->f);
}
