/*
 * 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)

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

/* UART TX/RX data registers size */
#define UART_DATA_SIZE     ((uint8_t)4u)

/* 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[UART_DATA_SIZE];
	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;

	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)
{
	struct uart_b91_data *data = dev->data;
	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 */
	data->cfg = *cfg;

	return 0;
}

/* API implementation: config_get */
static int uart_b91_config_get(const struct device *dev,
			       struct uart_config *cfg)
{
	struct uart_b91_data *data = dev->data;
	*cfg = data->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 = dev->config;

	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;

	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;

	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);

	if (size > UART_DATA_SIZE) {
		size = UART_DATA_SIZE;
	}

	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) &&
		((uart->ctrl0 & UART_TX_IRQ_MASK) != 0)) ? 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;

	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)
