/*
 * Copyright (c) 2021 Henrik Brix Andersen <henrik@brixandersen.dk>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT neorv32_uart

#include <zephyr/device.h>
#include <zephyr/drivers/syscon.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/sys_io.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(uart_neorv32, CONFIG_UART_LOG_LEVEL);

/* NEORV32 UART registers offsets */
#define NEORV32_UART_CTRL_OFFSET 0x00
#define NEORV32_UART_DATA_OFFSET 0x04

/* UART_CTRL register bits */
#define NEORV32_UART_CTRL_BAUD_MASK   BIT_MASK(12)
#define NEORV32_UART_CTRL_BAUD_POS    0U
#define NEORV32_UART_CTRL_PRSC_MASK   BIT_MASK(3)
#define NEORV32_UART_CTRL_PRSC_POS    24U
#define NEORV32_UART_CTRL_RTS_EN      BIT(20)
#define NEORV32_UART_CTRL_CTS_EN      BIT(21)
#define NEORV32_UART_CTRL_PMODE_NONE  BIT(22)
#define NEORV32_UART_CTRL_PMODE_EVEN  BIT(23)
#define NEORV32_UART_CTRL_PMODE_ODD  (BIT(22) | BIT(23))
#define NEORV32_UART_CTRL_EN          BIT(28)
#define NEORV32_UART_CTRL_TX_BUSY     BIT(31)

/* UART_DATA register status bits */
#define NEORV32_UART_DATA_PERR  BIT(28)
#define NEORV32_UART_DATA_FERR  BIT(29)
#define NEORV32_UART_DATA_OVERR BIT(30)
#define NEORV32_UART_DATA_AVAIL BIT(31)

struct neorv32_uart_config {
	const struct device *syscon;
	uint32_t feature_mask;
	mm_reg_t base;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	void (*irq_config_func)(const struct device *dev);
	unsigned int tx_irq;
	unsigned int rx_irq;
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

struct neorv32_uart_data {
	struct uart_config uart_cfg;
	uint32_t last_data;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	struct k_timer timer;
	uart_irq_callback_user_data_t callback;
	void *callback_data;
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

static inline uint32_t neorv32_uart_read_ctrl(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;

	return sys_read32(config->base + NEORV32_UART_CTRL_OFFSET);
}

static inline void neorv32_uart_write_ctrl(const struct device *dev, uint32_t ctrl)
{
	const struct neorv32_uart_config *config = dev->config;

	sys_write32(ctrl, config->base + NEORV32_UART_CTRL_OFFSET);
}

static inline uint32_t neorv32_uart_read_data(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;
	struct neorv32_uart_data *data = dev->data;
	uint32_t reg;

	/* Cache status bits as they are cleared upon read */
	reg = sys_read32(config->base + NEORV32_UART_DATA_OFFSET);
	data->last_data = reg;

	return reg;
}

static inline void neorv32_uart_write_data(const struct device *dev, uint32_t data)
{
	const struct neorv32_uart_config *config = dev->config;

	sys_write32(data, config->base + NEORV32_UART_DATA_OFFSET);
}

static int neorv32_uart_poll_in(const struct device *dev, unsigned char *c)
{
	uint32_t data;

	data = neorv32_uart_read_data(dev);

	if ((data & NEORV32_UART_DATA_AVAIL) != 0) {
		*c = data & BIT_MASK(8);
		return 0;
	}

	return -1;
}

static void neorv32_uart_poll_out(const struct device *dev, unsigned char c)
{
	while ((neorv32_uart_read_ctrl(dev) & NEORV32_UART_CTRL_TX_BUSY) != 0) {
	}

	neorv32_uart_write_data(dev, c);
}

static int neorv32_uart_err_check(const struct device *dev)
{
	struct neorv32_uart_data *data = dev->data;
	int err = 0;

	if ((data->last_data & NEORV32_UART_DATA_OVERR) != 0) {
		err |= UART_ERROR_OVERRUN;
	}

	if ((data->last_data & NEORV32_UART_DATA_PERR) != 0) {
		err |= UART_ERROR_PARITY;
	}

	if ((data->last_data & NEORV32_UART_DATA_FERR) != 0) {
		err |= UART_ERROR_FRAMING;
	}

	data->last_data &= ~(NEORV32_UART_DATA_OVERR | NEORV32_UART_DATA_PERR |
		NEORV32_UART_DATA_FERR);

	return err;
}

static int neorv32_uart_configure(const struct device *dev, const struct uart_config *cfg)
{
	const struct neorv32_uart_config *config = dev->config;
	struct neorv32_uart_data *data = dev->data;
	uint32_t ctrl = NEORV32_UART_CTRL_EN;
	uint16_t baudxx = 0;
	uint8_t prscx = 0;
	uint32_t clk;
	int err;

	__ASSERT_NO_MSG(cfg != NULL);

	if (cfg->stop_bits != UART_CFG_STOP_BITS_1) {
		LOG_ERR("hardware only supports one stop bit");
		return -ENOTSUP;
	}

	if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
		LOG_ERR("hardware only supports 8 data bits");
		return -ENOTSUP;
	}

	switch (cfg->parity) {
	case UART_CFG_PARITY_NONE:
		ctrl |= NEORV32_UART_CTRL_PMODE_NONE;
		break;
	case UART_CFG_PARITY_ODD:
		ctrl |= NEORV32_UART_CTRL_PMODE_ODD;
		break;
	case UART_CFG_PARITY_EVEN:
		ctrl |= NEORV32_UART_CTRL_PMODE_EVEN;
		break;
	default:
		LOG_ERR("unsupported parity mode %d", cfg->parity);
		return -ENOTSUP;
	}

	switch (cfg->flow_ctrl) {
	case UART_CFG_FLOW_CTRL_NONE:
		ctrl |= 0;
		break;
	case UART_CFG_FLOW_CTRL_RTS_CTS:
		ctrl |= NEORV32_UART_CTRL_RTS_EN | NEORV32_UART_CTRL_CTS_EN;
		break;
	default:
		LOG_ERR("unsupported flow control mode %d", cfg->flow_ctrl);
		return -ENOTSUP;
	}

	err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_CLK, &clk);
	if (err < 0) {
		LOG_ERR("failed to determine clock rate (err %d)", err);
		return -EIO;
	}

	if (cfg->baudrate == 0) {
		LOG_ERR("invalid baud rate 0");
		return -EINVAL;
	}

	/*
	 * Calculate clock prescaler and baud prescaler. Initial prscx = 0 is
	 * clock / 2.
	 */
	baudxx = clk / (2 * cfg->baudrate);
	while (baudxx >= NEORV32_UART_CTRL_BAUD_MASK) {
		if ((prscx == 2) || (prscx == 4)) {
			baudxx >>= 3;
		} else {
			baudxx >>= 1;
		}

		prscx++;
	}

	if (prscx > NEORV32_UART_CTRL_PRSC_MASK) {
		LOG_ERR("unsupported baud rate %d", cfg->baudrate);
		return -ENOTSUP;
	}

	ctrl |= (baudxx - 1) << NEORV32_UART_CTRL_BAUD_POS;
	ctrl |= prscx << NEORV32_UART_CTRL_PRSC_POS;

	data->uart_cfg = *cfg;
	neorv32_uart_write_ctrl(dev, ctrl);

	return 0;
}

static int neorv32_uart_config_get(const struct device *dev, struct uart_config *cfg)
{
	struct neorv32_uart_data *data = dev->data;

	__ASSERT_NO_MSG(cfg != NULL);

	*cfg = data->uart_cfg;

	return 0;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static int neorv32_uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
{
	uint32_t ctrl;

	if (len <= 0) {
		return 0;
	}

	__ASSERT_NO_MSG(tx_data != NULL);

	ctrl = neorv32_uart_read_ctrl(dev);
	if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
		neorv32_uart_write_data(dev, *tx_data);
		return 1;
	}

	return 0;
}

static int neorv32_uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
{
	struct neorv32_uart_data *data = dev->data;
	int count = 0;

	if (size <= 0) {
		return 0;
	}

	__ASSERT_NO_MSG(rx_data != NULL);

	while ((data->last_data & NEORV32_UART_DATA_AVAIL) != 0) {
		rx_data[count++] = data->last_data & BIT_MASK(8);
		data->last_data &= ~(NEORV32_UART_DATA_AVAIL);

		if (count >= size) {
			break;
		}

		(void)neorv32_uart_read_data(dev);
	}

	return count;
}

static void neorv32_uart_tx_soft_isr(struct k_timer *timer)
{
	const struct device *dev = k_timer_user_data_get(timer);
	struct neorv32_uart_data *data = dev->data;
	uart_irq_callback_user_data_t callback = data->callback;

	if (callback) {
		callback(dev, data->callback_data);
	}
}

static void neorv32_uart_irq_tx_enable(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;
	struct neorv32_uart_data *data = dev->data;
	uint32_t ctrl;

	irq_enable(config->tx_irq);

	ctrl = neorv32_uart_read_ctrl(dev);
	if ((ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0) {
		/*
		 * TX done event already generated an edge interrupt. Generate a
		 * soft interrupt and have it call the callback function in
		 * timer isr context.
		 */
		k_timer_start(&data->timer, K_NO_WAIT, K_NO_WAIT);
	}
}

static void neorv32_uart_irq_tx_disable(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;

	irq_disable(config->tx_irq);
}

static int neorv32_uart_irq_tx_ready(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;
	uint32_t ctrl;

	if (!irq_is_enabled(config->tx_irq)) {
		return 0;
	}

	ctrl = neorv32_uart_read_ctrl(dev);

	return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
}

static void neorv32_uart_irq_rx_enable(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;

	irq_enable(config->rx_irq);
}

static void neorv32_uart_irq_rx_disable(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;

	irq_disable(config->rx_irq);
}

static int neorv32_uart_irq_tx_complete(const struct device *dev)
{
	uint32_t ctrl;

	ctrl = neorv32_uart_read_ctrl(dev);

	return (ctrl & NEORV32_UART_CTRL_TX_BUSY) == 0;
}

static int neorv32_uart_irq_rx_ready(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;
	struct neorv32_uart_data *data = dev->data;

	if (!irq_is_enabled(config->rx_irq)) {
		return 0;
	}

	return (data->last_data & NEORV32_UART_DATA_AVAIL) != 0;
}

static int neorv32_uart_irq_is_pending(const struct device *dev)
{
	return (neorv32_uart_irq_tx_ready(dev) ||
		neorv32_uart_irq_rx_ready(dev));
}

static int neorv32_uart_irq_update(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;

	if (irq_is_enabled(config->rx_irq)) {
		/* Cache data for use by rx_ready() and fifo_read() */
		(void)neorv32_uart_read_data(dev);
	}

	return 1;
}

static void neorv32_uart_irq_callback_set(const struct device *dev,
					  uart_irq_callback_user_data_t cb, void *user_data)
{
	struct neorv32_uart_data *data = dev->data;

	data->callback = cb;
	data->callback_data = user_data;
}

static void neorv32_uart_isr(const struct device *dev)
{
	struct neorv32_uart_data *data = dev->data;
	uart_irq_callback_user_data_t callback = data->callback;

	if (callback) {
		callback(dev, data->callback_data);
	}
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static int neorv32_uart_init(const struct device *dev)
{
	const struct neorv32_uart_config *config = dev->config;
	struct neorv32_uart_data *data = dev->data;
	uint32_t features;
	int err;

	if (!device_is_ready(config->syscon)) {
		LOG_ERR("syscon device not ready");
		return -EINVAL;
	}

	err = syscon_read_reg(config->syscon, NEORV32_SYSINFO_FEATURES, &features);
	if (err < 0) {
		LOG_ERR("failed to determine implemented features (err %d)", err);
		return -EIO;
	}

	if ((features & config->feature_mask) == 0) {
		LOG_ERR("neorv32 uart instance not supported");
		return -ENODEV;
	}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	k_timer_init(&data->timer, &neorv32_uart_tx_soft_isr, NULL);
	k_timer_user_data_set(&data->timer, (void *)dev);

	config->irq_config_func(dev);
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

	return neorv32_uart_configure(dev, &data->uart_cfg);
}

#ifdef CONFIG_PM_DEVICE
static int neorv32_uart_pm_action(const struct device *dev,
				  enum pm_device_action action)
{
	uint32_t ctrl = neorv32_uart_read_ctrl(dev);

	switch (action) {
	case PM_DEVICE_ACTION_SUSPEND:
		ctrl &= ~(NEORV32_UART_CTRL_EN);
		break;
	case PM_DEVICE_ACTION_RESUME:
		ctrl |= NEORV32_UART_CTRL_EN;
		break;
	default:
		return -ENOTSUP;
	}

	neorv32_uart_write_ctrl(dev, ctrl);

	return 0;
}
#endif /* CONFIG_PM_DEVICE */

static const struct uart_driver_api neorv32_uart_driver_api = {
	.poll_in = neorv32_uart_poll_in,
	.poll_out = neorv32_uart_poll_out,
	.err_check = neorv32_uart_err_check,
	.configure = neorv32_uart_configure,
	.config_get = neorv32_uart_config_get,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill = neorv32_uart_fifo_fill,
	.fifo_read = neorv32_uart_fifo_read,
	.irq_tx_enable = neorv32_uart_irq_tx_enable,
	.irq_tx_disable = neorv32_uart_irq_tx_disable,
	.irq_tx_ready = neorv32_uart_irq_tx_ready,
	.irq_rx_enable = neorv32_uart_irq_rx_enable,
	.irq_rx_disable = neorv32_uart_irq_rx_disable,
	.irq_tx_complete = neorv32_uart_irq_tx_complete,
	.irq_rx_ready = neorv32_uart_irq_rx_ready,
	.irq_is_pending = neorv32_uart_irq_is_pending,
	.irq_update = neorv32_uart_irq_update,
	.irq_callback_set = neorv32_uart_irq_callback_set,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
#define NEORV32_UART_CONFIG_FUNC(node_id, n)	\
	static void neorv32_uart_config_func_##n(const struct device *dev) \
	{								\
		IRQ_CONNECT(DT_IRQ_BY_NAME(node_id, tx, irq),		\
			    DT_IRQ_BY_NAME(node_id, tx, priority),	\
			    neorv32_uart_isr,				\
			    DEVICE_DT_GET(node_id), 0);			\
									\
		IRQ_CONNECT(DT_IRQ_BY_NAME(node_id, rx, irq),		\
			    DT_IRQ_BY_NAME(node_id, rx, priority),	\
			    neorv32_uart_isr,				\
			    DEVICE_DT_GET(node_id), 0);			\
	}
#define NEORV32_UART_CONFIG_INIT(node_id, n)				\
	.irq_config_func = neorv32_uart_config_func_##n,		\
	.tx_irq = DT_IRQ_BY_NAME(node_id, tx, irq),			\
	.rx_irq = DT_IRQ_BY_NAME(node_id, rx, irq),
#else
#define NEORV32_UART_CONFIG_FUNC(node_id, n)
#define NEORV32_UART_CONFIG_INIT(node_id, n)
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

#define NEORV32_UART_INIT(node_id, n)					\
	NEORV32_UART_CONFIG_FUNC(node_id, n)				\
									\
	static struct neorv32_uart_data neorv32_uart_##n##_data = {	\
		.uart_cfg = {						\
			.baudrate = DT_PROP(node_id, current_speed),	\
			.parity = DT_ENUM_IDX_OR(node_id, parity,	\
						 UART_CFG_PARITY_NONE),	\
			.stop_bits = UART_CFG_STOP_BITS_1,		\
			.data_bits = UART_CFG_DATA_BITS_8,		\
			.flow_ctrl = DT_PROP(node_id, hw_flow_control) ? \
				UART_CFG_FLOW_CTRL_RTS_CTS :		\
				UART_CFG_FLOW_CTRL_NONE,		\
		},							\
	};								\
									\
	static const struct neorv32_uart_config neorv32_uart_##n##_config = { \
		.syscon = DEVICE_DT_GET(DT_PHANDLE(node_id, syscon)),	\
		.feature_mask = NEORV32_SYSINFO_FEATURES_IO_UART##n,	\
		.base = DT_REG_ADDR(node_id),				\
		NEORV32_UART_CONFIG_INIT(node_id, n)			\
	};								\
									\
	PM_DEVICE_DT_DEFINE(node_id, neorv32_uart_pm_action);		\
									\
	DEVICE_DT_DEFINE(node_id, &neorv32_uart_init,			\
			 PM_DEVICE_DT_GET(node_id),			\
			 &neorv32_uart_##n##_data,			\
			 &neorv32_uart_##n##_config,			\
			 PRE_KERNEL_1,					\
			 CONFIG_SERIAL_INIT_PRIORITY,			\
			 &neorv32_uart_driver_api)

#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(uart0), DT_DRV_COMPAT, okay)
NEORV32_UART_INIT(DT_NODELABEL(uart0), 0);
#endif

#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(uart1), DT_DRV_COMPAT, okay)
NEORV32_UART_INIT(DT_NODELABEL(uart1), 1);
#endif
