/*
 * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon company) or
 * an affiliate of Cypress Semiconductor Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief UART driver for Infineon CAT1 MCU family.
 *
 * Note:
 * - Uart ASYNC functionality is not implemented in current
 *   version of Uart CAT1 driver.
 */

#define DT_DRV_COMPAT infineon_cat1_uart

#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/pinctrl.h>
#include <cyhal_uart.h>
#include <cyhal_utils_psoc.h>
#include <cyhal_scb_common.h>

/* Data structure */
struct ifx_cat1_uart_data {
	cyhal_uart_t obj;                               /* UART CYHAL object */
	struct uart_config cfg;
	cyhal_resource_inst_t hw_resource;
	cyhal_clock_t clock;

#if CONFIG_UART_INTERRUPT_DRIVEN
	uart_irq_callback_user_data_t irq_cb;           /* Interrupt Callback */
	void *irq_cb_data;                              /* Interrupt Callback Arg */
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

/* Device config structure */
struct ifx_cat1_uart_config {
	const struct pinctrl_dev_config *pcfg;
	CySCB_Type *reg_addr;
	struct uart_config dt_cfg;
	uint8_t irq_priority;
};

/* Default Counter configuration structure */
static const cy_stc_scb_uart_config_t _cyhal_uart_default_config = {
	.uartMode = CY_SCB_UART_STANDARD,
	.enableMutliProcessorMode = false,
	.smartCardRetryOnNack = false,
	.irdaInvertRx = false,
	.irdaEnableLowPowerReceiver = false,
	.oversample = 12,
	.enableMsbFirst = false,
	.dataWidth = 8UL,
	.parity = CY_SCB_UART_PARITY_NONE,
	.stopBits = CY_SCB_UART_STOP_BITS_1,
	.enableInputFilter = false,
	.breakWidth = 11UL,
	.dropOnFrameError = false,
	.dropOnParityError = false,

	.receiverAddress = 0x0UL,
	.receiverAddressMask = 0x0UL,
	.acceptAddrInFifo = false,

	.enableCts = false,
	.ctsPolarity = CY_SCB_UART_ACTIVE_LOW,
#if defined(COMPONENT_CAT1A) || defined(COMPONENT_CAT1B)
	.rtsRxFifoLevel = 20UL,
#elif defined(COMPONENT_CAT2)
	.rtsRxFifoLevel = 3UL,
#endif
	.rtsPolarity = CY_SCB_UART_ACTIVE_LOW,

	/* Level triggers when at least one element is in FIFO */
	.rxFifoTriggerLevel = 0UL,
	.rxFifoIntEnableMask = 0x0UL,

	/* Level triggers when half-fifo is half empty */
	.txFifoTriggerLevel = (CY_SCB_FIFO_SIZE / 2 - 1),
	.txFifoIntEnableMask = 0x0UL
};

/* Helper API */
static cyhal_uart_parity_t _convert_uart_parity_z_to_cyhal(enum uart_config_parity parity)
{
	cyhal_uart_parity_t cyhal_parity;

	switch (parity) {
	case UART_CFG_PARITY_NONE:
		cyhal_parity = CYHAL_UART_PARITY_NONE;
		break;
	case UART_CFG_PARITY_ODD:
		cyhal_parity = CYHAL_UART_PARITY_ODD;
		break;
	case UART_CFG_PARITY_EVEN:
		cyhal_parity = CYHAL_UART_PARITY_EVEN;
		break;
	default:
		cyhal_parity = CYHAL_UART_PARITY_NONE;
	}
	return cyhal_parity;
}

static uint32_t _convert_uart_stop_bits_z_to_cyhal(enum uart_config_stop_bits stop_bits)
{
	uint32_t cyhal_stop_bits;

	switch (stop_bits) {
	case UART_CFG_STOP_BITS_1:
		cyhal_stop_bits = 1u;
		break;

	case UART_CFG_STOP_BITS_2:
		cyhal_stop_bits = 2u;
		break;
	default:
		cyhal_stop_bits = 1u;
	}
	return cyhal_stop_bits;
}

static uint32_t _convert_uart_data_bits_z_to_cyhal(enum uart_config_data_bits data_bits)
{
	uint32_t cyhal_data_bits;

	switch (data_bits) {
	case UART_CFG_DATA_BITS_5:
		cyhal_data_bits = 1u;
		break;

	case UART_CFG_DATA_BITS_6:
		cyhal_data_bits = 6u;
		break;

	case UART_CFG_DATA_BITS_7:
		cyhal_data_bits = 7u;
		break;

	case UART_CFG_DATA_BITS_8:
		cyhal_data_bits = 8u;
		break;

	case UART_CFG_DATA_BITS_9:
		cyhal_data_bits = 9u;
		break;

	default:
		cyhal_data_bits = 1u;
	}
	return cyhal_data_bits;
}

static int32_t _get_hw_block_num(CySCB_Type *reg_addr)
{
	uint32_t i;

	for (i = 0u; i < _SCB_ARRAY_SIZE; i++) {
		if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) {
			return i;
		}
	}

	return -1;
}

static int ifx_cat1_uart_poll_in(const struct device *dev, unsigned char *c)
{
	cy_rslt_t rec;
	struct ifx_cat1_uart_data *data = dev->data;

	rec = cyhal_uart_getc(&data->obj, c, 0u);

	return ((rec == CY_SCB_UART_RX_NO_DATA) ? -1 : 0);
}

static void ifx_cat1_uart_poll_out(const struct device *dev, unsigned char c)
{
	struct ifx_cat1_uart_data *data = dev->data;

	(void) cyhal_uart_putc(&data->obj, (uint32_t)c);
}

static int ifx_cat1_uart_err_check(const struct device *dev)
{
	struct ifx_cat1_uart_data *data = dev->data;
	uint32_t status = Cy_SCB_UART_GetRxFifoStatus(data->obj.base);
	int errors = 0;

	if (status & CY_SCB_UART_RX_OVERFLOW) {
		errors |= UART_ERROR_OVERRUN;
	}

	if (status & CY_SCB_UART_RX_ERR_PARITY) {
		errors |= UART_ERROR_PARITY;
	}

	if (status & CY_SCB_UART_RX_ERR_FRAME) {
		errors |= UART_ERROR_FRAMING;
	}

	return errors;
}

static int ifx_cat1_uart_configure(const struct device *dev,
				   const struct uart_config *cfg)
{
	__ASSERT_NO_MSG(cfg != NULL);

	cy_rslt_t result;
	struct ifx_cat1_uart_data *data = dev->data;

	cyhal_uart_cfg_t uart_cfg = {
		.data_bits = _convert_uart_data_bits_z_to_cyhal(cfg->data_bits),
		.stop_bits = _convert_uart_stop_bits_z_to_cyhal(cfg->stop_bits),
		.parity = _convert_uart_parity_z_to_cyhal(cfg->parity)
	};

	/* Store Uart Zephyr configuration (uart config) into data structure */
	data->cfg = *cfg;

	/* Configure parity, data and stop bits */
	result = cyhal_uart_configure(&data->obj, &uart_cfg);

	/* Configure the baud rate */
	if (result == CY_RSLT_SUCCESS) {
		result = cyhal_uart_set_baud(&data->obj, cfg->baudrate, NULL);
	}

	/* Enable RTS/CTS flow control */
	if ((result == CY_RSLT_SUCCESS) && cfg->flow_ctrl) {
		result = cyhal_uart_enable_flow_control(&data->obj, true, true);
	}

	return (result == CY_RSLT_SUCCESS) ? 0 : -ENOTSUP;
};

static int ifx_cat1_uart_config_get(const struct device *dev,
				    struct uart_config *cfg)
{
	ARG_UNUSED(dev);

	struct ifx_cat1_uart_data *const data = dev->data;

	if (cfg == NULL) {
		return -EINVAL;
	}

	*cfg = data->cfg;
	return 0;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN

/* Uart event callback for Interrupt driven mode */
static void _uart_event_callback_irq_mode(void *arg, cyhal_uart_event_t event)
{
	ARG_UNUSED(event);

	const struct device *dev = (const struct device *) arg;
	struct ifx_cat1_uart_data *const data = dev->data;

	if (data->irq_cb != NULL) {
		data->irq_cb(dev, data->irq_cb_data);
	}
}

/* Fill FIFO with data */
static int ifx_cat1_uart_fifo_fill(const struct device *dev,
				   const uint8_t *tx_data, int size)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	size_t _size = (size_t) size;

	(void)cyhal_uart_write(&data->obj, (uint8_t *) tx_data,  &_size);
	return (int) _size;
}

/* Read data from FIFO */
static int ifx_cat1_uart_fifo_read(const struct device *dev,
				   uint8_t *rx_data, const int size)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	size_t _size = (size_t) size;

	(void)cyhal_uart_read(&data->obj, rx_data, &_size);
	return (int) _size;
}

/* Enable TX interrupt */
static void ifx_cat1_uart_irq_tx_enable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj,
				(cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY,
				config->irq_priority, 1);
}

/* Disable TX interrupt */
static void ifx_cat1_uart_irq_tx_disable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj,
				(cyhal_uart_event_t) CYHAL_UART_IRQ_TX_EMPTY,
				config->irq_priority, 0);
}

/* Check if UART TX buffer can accept a new char */
static int ifx_cat1_uart_irq_tx_ready(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	uint32_t mask = Cy_SCB_GetTxInterruptStatusMasked(data->obj.base);

	return (((mask & (CY_SCB_UART_TX_NOT_FULL | SCB_INTR_TX_EMPTY_Msk)) != 0u) ? 1 : 0);
}

/* Check if UART TX block finished transmission */
static int ifx_cat1_uart_irq_tx_complete(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;

	return (int) !(cyhal_uart_is_tx_active(&data->obj));
}

/* Enable RX interrupt */
static void ifx_cat1_uart_irq_rx_enable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj,
				(cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY,
				config->irq_priority, 1);
}

/* Disable TX interrupt */
static void ifx_cat1_uart_irq_rx_disable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj,
				(cyhal_uart_event_t) CYHAL_UART_IRQ_RX_NOT_EMPTY,
				config->irq_priority, 0);
}

/* Check if UART RX buffer has a received char */
static int ifx_cat1_uart_irq_rx_ready(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;

	return cyhal_uart_readable(&data->obj) ? 1 : 0;
}

/* Enable Error interrupts */
static void ifx_cat1_uart_irq_err_enable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)
				(CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR),
				config->irq_priority, 1);
}

/* Disable Error interrupts */
static void ifx_cat1_uart_irq_err_disable(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;

	cyhal_uart_enable_event(&data->obj, (cyhal_uart_event_t)
				(CYHAL_UART_IRQ_TX_ERROR | CYHAL_UART_IRQ_RX_ERROR),
				config->irq_priority, 0);
}

/* Check if any IRQs is pending */
static int ifx_cat1_uart_irq_is_pending(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	uint32_t intcause = Cy_SCB_GetInterruptCause(data->obj.base);

	return (int) (intcause & (CY_SCB_TX_INTR | CY_SCB_RX_INTR));
}

/* Start processing interrupts in ISR.
 * This function should be called the first thing in the ISR. Calling
 * uart_irq_rx_ready(), uart_irq_tx_ready(), uart_irq_tx_complete()
 * allowed only after this.
 */
static int ifx_cat1_uart_irq_update(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	int status = 1;

	if (((ifx_cat1_uart_irq_is_pending(dev) & CY_SCB_RX_INTR) != 0u) &&
	    (Cy_SCB_UART_GetNumInRxFifo(data->obj.base) == 0u)) {
		status = 0;
	}

	return status;
}

static void ifx_cat1_uart_irq_callback_set(const struct device *dev,
					   uart_irq_callback_user_data_t cb,
					   void *cb_data)
{
	struct ifx_cat1_uart_data *data = dev->data;
	cyhal_uart_t *uart_obj = &data->obj;

	/* Store user callback info */
	data->irq_cb = cb;
	data->irq_cb_data = cb_data;

	/* Register a uart general callback handler  */
	cyhal_uart_register_callback(uart_obj, _uart_event_callback_irq_mode, (void *) dev);
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */


static int ifx_cat1_uart_init(const struct device *dev)
{
	struct ifx_cat1_uart_data *const data = dev->data;
	const struct ifx_cat1_uart_config *const config = dev->config;
	cy_rslt_t result;
	int ret;

	cyhal_uart_configurator_t uart_init_cfg = {
		.resource = &data->hw_resource,
		.config = &_cyhal_uart_default_config,
		.clock = &data->clock,
	};

	/* Dedicate SCB HW resource */
	data->hw_resource.type = CYHAL_RSC_SCB;
	data->hw_resource.block_num = _get_hw_block_num(config->reg_addr);

	/* Configure dt provided device signals when available */
	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		return ret;
	}

	/* Allocates clock for selected IP block */
	result = _cyhal_utils_allocate_clock(&data->clock, &data->hw_resource,
					     CYHAL_CLOCK_BLOCK_PERIPHERAL_16BIT, true);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}

	/* Assigns a programmable divider to a selected IP block */
	en_clk_dst_t clk_idx = _cyhal_scb_get_clock_index(uart_init_cfg.resource->block_num);

	result = _cyhal_utils_peri_pclk_assign_divider(clk_idx, uart_init_cfg.clock);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}

	/* Initialize the UART peripheral */
	result = cyhal_uart_init_cfg(&data->obj, &uart_init_cfg);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}

	/* Perform initial Uart configuration */
	data->obj.is_clock_owned = true;
	ret = ifx_cat1_uart_configure(dev, &config->dt_cfg);

	return ret;
}

static const struct uart_driver_api ifx_cat1_uart_driver_api = {
	.poll_in = ifx_cat1_uart_poll_in,
	.poll_out = ifx_cat1_uart_poll_out,
	.err_check = ifx_cat1_uart_err_check,

#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
	.configure = ifx_cat1_uart_configure,
	.config_get = ifx_cat1_uart_config_get,
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill = ifx_cat1_uart_fifo_fill,
	.fifo_read = ifx_cat1_uart_fifo_read,
	.irq_tx_enable = ifx_cat1_uart_irq_tx_enable,
	.irq_tx_disable = ifx_cat1_uart_irq_tx_disable,
	.irq_tx_ready = ifx_cat1_uart_irq_tx_ready,
	.irq_rx_enable = ifx_cat1_uart_irq_rx_enable,
	.irq_rx_disable = ifx_cat1_uart_irq_rx_disable,
	.irq_tx_complete = ifx_cat1_uart_irq_tx_complete,
	.irq_rx_ready = ifx_cat1_uart_irq_rx_ready,
	.irq_err_enable = ifx_cat1_uart_irq_err_enable,
	.irq_err_disable = ifx_cat1_uart_irq_err_disable,
	.irq_is_pending = ifx_cat1_uart_irq_is_pending,
	.irq_update = ifx_cat1_uart_irq_update,
	.irq_callback_set = ifx_cat1_uart_irq_callback_set,
#endif    /* CONFIG_UART_INTERRUPT_DRIVEN */
};

#define INFINEON_CAT1_UART_INIT(n)							     \
	PINCTRL_DT_INST_DEFINE(n);							     \
	static struct ifx_cat1_uart_data ifx_cat1_uart##n##_data;			     \
											     \
	static struct ifx_cat1_uart_config ifx_cat1_uart##n##_cfg = {			     \
		.dt_cfg.baudrate = DT_INST_PROP(n, current_speed),			     \
		.dt_cfg.parity = DT_INST_ENUM_IDX_OR(n, parity, UART_CFG_PARITY_NONE),	     \
		.dt_cfg.stop_bits = DT_INST_ENUM_IDX_OR(n, stop_bits, UART_CFG_STOP_BITS_1), \
		.dt_cfg.data_bits = DT_INST_ENUM_IDX_OR(n, data_bits, UART_CFG_DATA_BITS_8), \
		.dt_cfg.flow_ctrl = DT_INST_PROP(n, hw_flow_control),			     \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),				     \
		.reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n),				     \
		.irq_priority = DT_INST_IRQ(n, priority)				     \
	};										     \
											     \
	DEVICE_DT_INST_DEFINE(n,							     \
			      &ifx_cat1_uart_init, NULL,				     \
			      &ifx_cat1_uart##n##_data,					     \
			      &ifx_cat1_uart##n##_cfg, PRE_KERNEL_1,			     \
			      CONFIG_SERIAL_INIT_PRIORITY,				     \
			      &ifx_cat1_uart_driver_api);

DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_UART_INIT)
