/*
 * Copyright (c) 2021 Telink Semiconductor
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "analog.h"
#include "clock.h"

#include <device.h>
#include <drivers/uart.h>
#include <drivers/pinmux.h>
#include <dt-bindings/pinctrl/b91-pinctrl.h>


/* Driver dts compatibility: telink,b91_uart */
#define DT_DRV_COMPAT telink_b91_uart

/* Get UART instance */
#define GET_UART(dev)      ((volatile struct uart_b91_t *) \
			    ((const struct uart_b91_config *)dev->config)->uart_addr)

/* Get UART configuration */
#define GET_CFG(dev)       ((const struct uart_b91_config *)dev->config)

/* Get instance data */
#define DEV_DATA(dev)      ((struct uart_b91_data *const)dev->data)

/* UART TX buffer count max value */
#define UART_TX_BUF_CNT    ((uint8_t)8u)

/* Parity type */
#define UART_PARITY_NONE   ((uint8_t)0u)
#define UART_PARITY_EVEN   ((uint8_t)1u)
#define UART_PARITY_ODD    ((uint8_t)2u)

/* Stop bits length */
#define UART_STOP_BIT_1    ((uint8_t)0u)
#define UART_STOP_BIT_1P5  BIT(4)
#define UART_STOP_BIT_2    BIT(5)


/* B91 UART registers structure */
struct uart_b91_t {
	uint8_t data_buf[4];
	uint16_t clk_div;
	uint8_t ctrl0;
	uint8_t ctrl1;
	uint8_t ctrl2;
	uint8_t ctrl3;
	uint16_t rxtimeout;
	uint8_t bufcnt;
	uint8_t status;
	uint8_t txrx_status;
	uint8_t state;
};

/* B91 UART data structure */
struct uart_b91_data {
	uint8_t tx_byte_index;
	uint8_t rx_byte_index;
	struct uart_config cfg;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	uart_irq_callback_user_data_t callback;
	void *cb_data;
#endif
};

/* B91 UART config structure */
struct uart_b91_config {
	const uint32_t *pinctrl_list;
	size_t pinctrl_list_size;
	uint32_t uart_addr;
	uint32_t baud_rate;
	void (*pirq_connect)(void);
};

/* rxtimeout register enums */
enum {
	UART_ERR_IRQ_MASK = BIT(15),
};

/* ctrl0 register enums */
enum {
	UART_RX_IRQ_MASK        = BIT(6),
	UART_TX_IRQ_MASK        = BIT(7),
};

/* ctrl3 register enums */
enum {
	FLD_UART_RX_IRQ_TRIQ_LEV_OFFSET = 0,
	FLD_UART_TX_IRQ_TRIQ_LEV_OFFSET = 4,
};

/* bufcnt register enums */
enum {
	FLD_UART_RX_BUF_CNT_OFFSET      = 0,
	FLD_UART_TX_BUF_CNT_OFFSET      = 4,
};

/* status register enums */
enum {
	UART_IRQ_STATUS         = BIT(3),
	UART_RX_ERR_STATUS      = BIT(7),
};


/* Get tx fifo count */
static inline uint8_t uart_b91_get_tx_bufcnt(volatile struct uart_b91_t *uart)
{
	return (uart->bufcnt & FLD_UART_TX_BUF_CNT) >> FLD_UART_TX_BUF_CNT_OFFSET;
}

/* Get rx fifo count */
static inline uint8_t uart_b91_get_rx_bufcnt(volatile struct uart_b91_t *uart)
{
	return (uart->bufcnt & FLD_UART_RX_BUF_CNT) >> FLD_UART_RX_BUF_CNT_OFFSET;
}

/* Check for prime */
static uint8_t uart_b91_is_prime(uint32_t n)
{
	uint32_t i = 5;

	if (n <= 3) {
		return 1;
	} else if ((n % 2 == 0) || (n % 3 == 0)) {
		return 0;
	}

	for (i = 5; i * i < n; i += 6) {
		if ((n % i == 0) || (n % (i + 2)) == 0) {
			return 0;
		}
	}

	return 1;
}

/* Calculate the best bit width */
static void uart_b91_cal_div_and_bwpc(uint32_t baudrate, uint32_t pclk,
				      uint16_t *divider, uint8_t *bwpc)
{
	uint8_t i = 0, j = 0;
	uint32_t primeInt = 0;
	uint8_t primeDec = 0;
	uint32_t D_intdec[13], D_int[13];
	uint8_t D_dec[13];

	primeInt = pclk / baudrate;
	primeDec = 10 * pclk / baudrate - 10 * primeInt;

	if (uart_b91_is_prime(primeInt)) {
		primeInt += 1;
	} else if (primeDec > 5) {
		primeInt += 1;
		if (uart_b91_is_prime(primeInt)) {
			primeInt -= 1;
		}
	}

	for (i = 3; i <= 15; i++) {
		D_intdec[i - 3] = (10 * primeInt) / (i + 1);
		D_dec[i - 3] = D_intdec[i - 3] - 10 * (D_intdec[i - 3] / 10);
		D_int[i - 3] = D_intdec[i - 3] / 10;
	}

	/* find the max and min one decimation point */
	uint8_t position_min = 0, position_max = 0;
	uint32_t min = 0xffffffff, max = 0x00;

	for (j = 0; j < 13; j++) {
		if ((D_dec[j] <= min) && (D_int[j] != 0x01)) {
			min = D_dec[j];
			position_min = j;
		}
		if (D_dec[j] >= max) {
			max = D_dec[j];
			position_max = j;
		}
	}

	if ((D_dec[position_min] < 5) && (D_dec[position_max] >= 5)) {
		if (D_dec[position_min] < (10 - D_dec[position_max])) {
			*bwpc = position_min + 3;
			*divider = D_int[position_min] - 1;
		} else {
			*bwpc = position_max + 3;
			*divider = D_int[position_max];
		}
	} else if ((D_dec[position_min] < 5) && (D_dec[position_max] < 5)) {
		*bwpc = position_min + 3;
		*divider = D_int[position_min] - 1;
	} else {
		*bwpc = position_max + 3;
		*divider = D_int[position_max];
	}
}

/* Initializes the UART instance */
static void uart_b91_init(volatile struct uart_b91_t *uart, uint16_t divider,
			  uint8_t bwpc, uint8_t parity, uint8_t stop_bit)
{
	/* config clock */
	divider = divider | FLD_UART_CLK_DIV_EN;
	uart->ctrl0 = bwpc;
	uart->clk_div = divider;

	/* config parity */
	if (parity) {
		/* enable parity function */
		uart->ctrl1 |= FLD_UART_PARITY_ENABLE;

		if (parity == UART_PARITY_EVEN) {
			/* enable even parity */
			uart->ctrl1 &= (~FLD_UART_PARITY_POLARITY);
		} else if (parity == UART_PARITY_ODD) {
			/* enable odd parity */
			uart->ctrl1 |= FLD_UART_PARITY_POLARITY;
		}
	} else {
		uart->ctrl1 &= (~FLD_UART_PARITY_ENABLE); /* disable parity function */
	}

	/* stop bit config */
	uart->ctrl1 &= (~FLD_UART_STOP_SEL);
	uart->ctrl1 |= stop_bit;
}

/* API implementation: irq handler */
static void uart_b91_irq_handler(const struct device *dev)
{
#ifndef CONFIG_UART_INTERRUPT_DRIVEN
	ARG_UNUSED(dev);
#else
	struct uart_b91_data *data = DEV_DATA(dev);

	if (data->callback != NULL) {
		data->callback(dev, data->cb_data);
	}
#endif
}

/* API implementation: configure */
static int uart_b91_configure(const struct device *dev,
			      const struct uart_config *cfg)
{
	uint16_t divider;
	uint8_t bwpc;
	uint8_t parity;
	uint8_t stop_bits;

	volatile struct uart_b91_t *uart = GET_UART(dev);

	/* check parity */
	if (cfg->parity == UART_CFG_PARITY_NONE) {
		parity = UART_PARITY_NONE;
	} else if (cfg->parity == UART_CFG_PARITY_ODD) {
		parity = UART_PARITY_ODD;
	} else if (cfg->parity == UART_CFG_PARITY_EVEN) {
		parity = UART_PARITY_EVEN;
	} else {
		return -ENOTSUP;
	}

	/* check stop bits */
	if (cfg->stop_bits == UART_CFG_STOP_BITS_1) {
		stop_bits = UART_STOP_BIT_1;
	} else if (cfg->stop_bits == UART_CFG_STOP_BITS_1_5) {
		stop_bits = UART_STOP_BIT_1P5;
	} else if (cfg->stop_bits == UART_CFG_STOP_BITS_2) {
		stop_bits = UART_STOP_BIT_2;
	} else {
		return -ENOTSUP;
	}

	/* check flow control */
	if (cfg->flow_ctrl != UART_CFG_FLOW_CTRL_NONE) {
		return -ENOTSUP;
	}

	/* UART configure */
	uart_b91_cal_div_and_bwpc(cfg->baudrate, sys_clk.pclk * 1000 * 1000, &divider, &bwpc);
	uart_b91_init(uart, divider, bwpc, parity, stop_bits);

	/* save configuration */
	DEV_DATA(dev)->cfg = *cfg;

	return 0;
}

/* API implementation: config_get */
static int uart_b91_config_get(const struct device *dev,
			       struct uart_config *cfg)
{
	*cfg = DEV_DATA(dev)->cfg;

	return 0;
}

/* API implementation: driver initialization */
static int uart_b91_driver_init(const struct device *dev)
{
	uint16_t divider = 0u;
	uint8_t bwpc = 0u;
	const struct device *pinmux;
	volatile struct uart_b91_t *uart = GET_UART(dev);
	const struct uart_b91_config *cfg = GET_CFG(dev);

	pinmux = DEVICE_DT_GET(DT_NODELABEL(pinmux));
	if (!device_is_ready(pinmux)) {
		return -ENODEV;
	}

	for (int i = 0; i < cfg->pinctrl_list_size; i++) {
		pinmux_pin_set(pinmux, B91_PINMUX_GET_PIN(cfg->pinctrl_list[i]),
			       B91_PINMUX_GET_FUNC(cfg->pinctrl_list[i]));
	}

	uart_b91_cal_div_and_bwpc(cfg->baud_rate, sys_clk.pclk * 1000 * 1000, &divider, &bwpc);
	uart_b91_init(uart, divider, bwpc, UART_PARITY_NONE, UART_STOP_BIT_1);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	cfg->pirq_connect();
#endif

	return 0;
}

/* API implementation: poll_out */
static void uart_b91_poll_out(const struct device *dev, uint8_t c)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);
	struct uart_b91_data *data = DEV_DATA(dev);

	while (uart_b91_get_tx_bufcnt(uart) >= UART_TX_BUF_CNT) {
	};

	uart->data_buf[data->tx_byte_index] = c;
	data->tx_byte_index = (data->tx_byte_index + 1) % ARRAY_SIZE(uart->data_buf);
}

/* API implementation: poll_in */
static int uart_b91_poll_in(const struct device *dev, unsigned char *c)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);
	struct uart_b91_data *data = DEV_DATA(dev);

	if (uart_b91_get_rx_bufcnt(uart) == 0) {
		return -1;
	}

	*c = uart->data_buf[data->rx_byte_index];
	data->rx_byte_index = (data->rx_byte_index + 1) % ARRAY_SIZE(uart->data_buf);

	return 0;
}

/* API implementation: err_check */
static int uart_b91_err_check(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	return ((uart->status & UART_RX_ERR_STATUS) != 0) ? 1 : 0;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN

/* API implementation: fifo_fill */
static int uart_b91_fifo_fill(const struct device *dev,
			      const uint8_t *tx_data,
			      int size)
{
	int i = 0;
	volatile struct uart_b91_t *uart = GET_UART(dev);

	for (i = 0; i < size; i++) {
		if (uart_b91_get_rx_bufcnt(uart) != 0) {
			break;
		}

		uart_b91_poll_out(dev, tx_data[i]);
	}

	return i;
}

/* API implementation: fifo_read */
static int uart_b91_fifo_read(const struct device *dev,
			      uint8_t *rx_data,
			      const int size)
{
	int rx_count;
	volatile struct uart_b91_t *uart = GET_UART(dev);

	for (rx_count = 0; rx_count < size; rx_count++) {
		if (uart_b91_get_rx_bufcnt(uart) == 0) {
			break;
		}

		uart_b91_poll_in(dev, &rx_data[rx_count]);
	}

	return rx_count;
}

/* API implementation: irq_tx_enable */
static void uart_b91_irq_tx_enable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->ctrl3 = (uart->ctrl3 & (~FLD_UART_TX_IRQ_TRIQ_LEV)) |
		      BIT(FLD_UART_TX_IRQ_TRIQ_LEV_OFFSET);
	uart->ctrl0 |= UART_TX_IRQ_MASK;
}

/* API implementation: irq_tx_disable */
static void uart_b91_irq_tx_disable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->ctrl0 &= ~UART_TX_IRQ_MASK;
}

/* API implementation: irq_tx_ready */
static int uart_b91_irq_tx_ready(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	return (uart_b91_get_tx_bufcnt(uart) < UART_TX_BUF_CNT) ? 1 : 0;
}

/* API implementation: irq_tx_complete */
static int uart_b91_irq_tx_complete(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	return (uart_b91_get_tx_bufcnt(uart) == 0) ? 1 : 0;
}

/* API implementation: irq_rx_enable */
static void uart_b91_irq_rx_enable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->ctrl3 = (uart->ctrl3 & (~FLD_UART_RX_IRQ_TRIQ_LEV)) |
		      BIT(FLD_UART_RX_IRQ_TRIQ_LEV_OFFSET);
	uart->ctrl0 |= UART_RX_IRQ_MASK;
}

/* API implementation: irq_rx_disable */
static void uart_b91_irq_rx_disable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->ctrl0 &= ~UART_RX_IRQ_MASK;
}

/* API implementation: irq_rx_ready */
static int uart_b91_irq_rx_ready(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	return (uart_b91_get_rx_bufcnt(uart) > 0) ? 1 : 0;
}

/* API implementation: irq_err_enable */
static void uart_b91_irq_err_enable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->rxtimeout |= UART_ERR_IRQ_MASK;
}

/* API implementation: irq_err_disable*/
static void uart_b91_irq_err_disable(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	uart->rxtimeout &= ~UART_ERR_IRQ_MASK;
}

/* API implementation: irq_is_pending */
static int uart_b91_irq_is_pending(const struct device *dev)
{
	volatile struct uart_b91_t *uart = GET_UART(dev);

	return ((uart->status & UART_IRQ_STATUS) != 0) ? 1 : 0;
}

/* API implementation: irq_update */
static int uart_b91_irq_update(const struct device *dev)
{
	ARG_UNUSED(dev);

	/* nothing to be done */
	return 1;
}

/* API implementation: irq_callback_set */
static void uart_b91_irq_callback_set(const struct device *dev,
				      uart_irq_callback_user_data_t cb,
				      void *cb_data)
{
	struct uart_b91_data *data = DEV_DATA(dev);

	data->callback = cb;
	data->cb_data = cb_data;
}

#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static const struct uart_driver_api uart_b91_driver_api = {
	.poll_in = uart_b91_poll_in,
	.poll_out = uart_b91_poll_out,
	.err_check = uart_b91_err_check,
	.configure = uart_b91_configure,
	.config_get = uart_b91_config_get,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill = uart_b91_fifo_fill,
	.fifo_read = uart_b91_fifo_read,
	.irq_tx_enable = uart_b91_irq_tx_enable,
	.irq_tx_disable = uart_b91_irq_tx_disable,
	.irq_tx_ready = uart_b91_irq_tx_ready,
	.irq_tx_complete = uart_b91_irq_tx_complete,
	.irq_rx_enable = uart_b91_irq_rx_enable,
	.irq_rx_disable = uart_b91_irq_rx_disable,
	.irq_rx_ready = uart_b91_irq_rx_ready,
	.irq_err_enable = uart_b91_irq_err_enable,
	.irq_err_disable = uart_b91_irq_err_disable,
	.irq_is_pending = uart_b91_irq_is_pending,
	.irq_update = uart_b91_irq_update,
	.irq_callback_set = uart_b91_irq_callback_set,
#endif
};


#define UART_B91_INIT(n)							    \
										    \
	static void uart_b91_irq_connect_##n(void);				    \
										    \
	static const uint32_t uart_pins_##n[] =					    \
		B91_PINMUX_DT_INST_GET_ARRAY(n, 0);				    \
										    \
	static const struct uart_b91_config uart_b91_cfg_##n =			    \
	{									    \
		.uart_addr = DT_INST_REG_ADDR(n),				    \
		.baud_rate = DT_INST_PROP(n, current_speed),			    \
		.pinctrl_list_size = ARRAY_SIZE(uart_pins_##n),			    \
		.pinctrl_list = uart_pins_##n,					    \
		.pirq_connect = uart_b91_irq_connect_##n			    \
	};									    \
										    \
	static struct uart_b91_data uart_b91_data_##n;				    \
										    \
	DEVICE_DT_INST_DEFINE(n, uart_b91_driver_init,				    \
			      NULL,						    \
			      &uart_b91_data_##n,				    \
			      &uart_b91_cfg_##n,				    \
			      PRE_KERNEL_1,					    \
			      CONFIG_SERIAL_INIT_PRIORITY,			    \
			      (void *)&uart_b91_driver_api);			    \
										    \
	static void uart_b91_irq_connect_##n(void)				    \
	{									    \
		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority),		    \
			    uart_b91_irq_handler,				    \
			    DEVICE_DT_INST_GET(n), 0);				    \
										    \
		riscv_plic_irq_enable(DT_INST_IRQN(n));				    \
		riscv_plic_set_priority(DT_INST_IRQN(n), DT_INST_IRQ(n, priority)); \
	}

DT_INST_FOREACH_STATUS_OKAY(UART_B91_INIT)
