/*
 * Copyright (c) 2022 Libre Solar Technologies GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp32_usb_serial

#include <hal/usb_serial_jtag_ll.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <errno.h>
#include <soc.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/sys/util.h>
#include <esp_attr.h>

#define USBSERIAL_TIMEOUT_MAX_US 50000

static int s_usbserial_timeout;

struct serial_esp32_usb_config {
	const struct device *clock_dev;
	const clock_control_subsys_t clock_subsys;
	int irq_source;
};

struct serial_esp32_usb_data {
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	uart_irq_callback_user_data_t irq_cb;
	void *irq_cb_data;
#endif
	int irq_line;
};

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void serial_esp32_usb_isr(void *arg);
#endif

static int serial_esp32_usb_poll_in(const struct device *dev, unsigned char *p_char)
{
	struct serial_esp32_usb_data *data = dev->data;

	if (!usb_serial_jtag_ll_rxfifo_data_available()) {
		return -1;
	}

	usb_serial_jtag_ll_read_rxfifo(p_char, 1);

	return 0;
}

static void serial_esp32_usb_poll_out(const struct device *dev, unsigned char c)
{
	ARG_UNUSED(dev);

	/* Wait for space in FIFO */
	while (!usb_serial_jtag_ll_txfifo_writable() &&
		s_usbserial_timeout < (USBSERIAL_TIMEOUT_MAX_US / 100)) {
		k_usleep(100);
		s_usbserial_timeout++;
	}

	if (usb_serial_jtag_ll_txfifo_writable()) {
		usb_serial_jtag_ll_write_txfifo(&c, 1);
		usb_serial_jtag_ll_txfifo_flush();
		s_usbserial_timeout = 0;
	}
}

static int serial_esp32_usb_err_check(const struct device *dev)
{
	ARG_UNUSED(dev);

	return 0;
}

static int serial_esp32_usb_init(const struct device *dev)
{
	const struct serial_esp32_usb_config *config = dev->config;
	struct serial_esp32_usb_data *data = dev->data;

	if (!device_is_ready(config->clock_dev)) {
		return -ENODEV;
	}

	int ret = clock_control_on(config->clock_dev, config->clock_subsys);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	data->irq_line = esp_intr_alloc(config->irq_source, 0, (isr_handler_t)serial_esp32_usb_isr,
					(void *)dev, NULL);
#endif
	return ret;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN

static int serial_esp32_usb_fifo_fill(const struct device *dev, const uint8_t *tx_data, int len)
{
	ARG_UNUSED(dev);

	int ret = usb_serial_jtag_ll_write_txfifo(tx_data, len);

	usb_serial_jtag_ll_txfifo_flush();

	return ret;
}

static int serial_esp32_usb_fifo_read(const struct device *dev, uint8_t *rx_data, const int len)
{
	ARG_UNUSED(dev);

	return usb_serial_jtag_ll_read_rxfifo(rx_data, len);
}

static void serial_esp32_usb_irq_tx_enable(const struct device *dev)
{
	struct serial_esp32_usb_data *data = dev->data;

	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
	usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);

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

static void serial_esp32_usb_irq_tx_disable(const struct device *dev)
{
	ARG_UNUSED(dev);

	usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
}

static int serial_esp32_usb_irq_tx_ready(const struct device *dev)
{
	ARG_UNUSED(dev);

	return (usb_serial_jtag_ll_txfifo_writable() &&
		usb_serial_jtag_ll_get_intr_ena_status() & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
}

static void serial_esp32_usb_irq_rx_enable(const struct device *dev)
{
	ARG_UNUSED(dev);

	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
	usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
}

static void serial_esp32_usb_irq_rx_disable(const struct device *dev)
{
	ARG_UNUSED(dev);

	usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
}

static int serial_esp32_usb_irq_tx_complete(const struct device *dev)
{
	ARG_UNUSED(dev);

	return usb_serial_jtag_ll_txfifo_writable();
}

static int serial_esp32_usb_irq_rx_ready(const struct device *dev)
{
	ARG_UNUSED(dev);

	return usb_serial_jtag_ll_rxfifo_data_available();
}

static void serial_esp32_usb_irq_err_enable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static void serial_esp32_usb_irq_err_disable(const struct device *dev)
{
	ARG_UNUSED(dev);
}

static int serial_esp32_usb_irq_is_pending(const struct device *dev)
{
	return serial_esp32_usb_irq_rx_ready(dev) || serial_esp32_usb_irq_tx_ready(dev);
}

static int serial_esp32_usb_irq_update(const struct device *dev)
{
	ARG_UNUSED(dev);

	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
	usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);

	return 1;
}

static void serial_esp32_usb_irq_callback_set(const struct device *dev,
					      uart_irq_callback_user_data_t cb, void *cb_data)
{
	struct serial_esp32_usb_data *data = dev->data;

	data->irq_cb = cb;
	data->irq_cb_data = cb_data;
}

static void serial_esp32_usb_isr(void *arg)
{
	const struct device *dev = (const struct device *)arg;
	struct serial_esp32_usb_data *data = dev->data;
	uint32_t uart_intr_status = usb_serial_jtag_ll_get_intsts_mask();

	if (uart_intr_status == 0) {
		return;
	}
	usb_serial_jtag_ll_clr_intsts_mask(uart_intr_status);

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

#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static const DRAM_ATTR struct uart_driver_api serial_esp32_usb_api = {
	.poll_in = serial_esp32_usb_poll_in,
	.poll_out = serial_esp32_usb_poll_out,
	.err_check = serial_esp32_usb_err_check,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill = serial_esp32_usb_fifo_fill,
	.fifo_read = serial_esp32_usb_fifo_read,
	.irq_tx_enable = serial_esp32_usb_irq_tx_enable,
	.irq_tx_disable = serial_esp32_usb_irq_tx_disable,
	.irq_tx_ready = serial_esp32_usb_irq_tx_ready,
	.irq_rx_enable = serial_esp32_usb_irq_rx_enable,
	.irq_rx_disable = serial_esp32_usb_irq_rx_disable,
	.irq_tx_complete = serial_esp32_usb_irq_tx_complete,
	.irq_rx_ready = serial_esp32_usb_irq_rx_ready,
	.irq_err_enable = serial_esp32_usb_irq_err_enable,
	.irq_err_disable = serial_esp32_usb_irq_err_disable,
	.irq_is_pending = serial_esp32_usb_irq_is_pending,
	.irq_update = serial_esp32_usb_irq_update,
	.irq_callback_set = serial_esp32_usb_irq_callback_set,
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */
};

static const DRAM_ATTR struct serial_esp32_usb_config serial_esp32_usb_cfg = {
	.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
	.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(0, offset),
	.irq_source = DT_INST_IRQN(0)
};

static struct serial_esp32_usb_data serial_esp32_usb_data_0;

DEVICE_DT_INST_DEFINE(0, &serial_esp32_usb_init, NULL, &serial_esp32_usb_data_0,
		      &serial_esp32_usb_cfg, PRE_KERNEL_1,
		      CONFIG_SERIAL_INIT_PRIORITY, &serial_esp32_usb_api);
