// SPDX-License-Identifier: GPL-2.0+
/*
 *  Driver for Conexant Digicolor serial ports (USART)
 *
 * Author: Baruch Siach <baruch@tkos.co.il>
 *
 * Copyright (C) 2014 Paradox Innovation Ltd.
 */

#include <linux/module.h>
#include <linux/console.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/workqueue.h>

#define UA_ENABLE			0x00
#define UA_ENABLE_ENABLE		BIT(0)

#define UA_CONTROL			0x01
#define UA_CONTROL_RX_ENABLE		BIT(0)
#define UA_CONTROL_TX_ENABLE		BIT(1)
#define UA_CONTROL_SOFT_RESET		BIT(2)

#define UA_STATUS			0x02
#define UA_STATUS_PARITY_ERR		BIT(0)
#define UA_STATUS_FRAME_ERR		BIT(1)
#define UA_STATUS_OVERRUN_ERR		BIT(2)
#define UA_STATUS_TX_READY		BIT(6)

#define UA_CONFIG			0x03
#define UA_CONFIG_CHAR_LEN		BIT(0)
#define UA_CONFIG_STOP_BITS		BIT(1)
#define UA_CONFIG_PARITY		BIT(2)
#define UA_CONFIG_ODD_PARITY		BIT(4)

#define UA_EMI_REC			0x04

#define UA_HBAUD_LO			0x08
#define UA_HBAUD_HI			0x09

#define UA_STATUS_FIFO			0x0a
#define UA_STATUS_FIFO_RX_EMPTY		BIT(2)
#define UA_STATUS_FIFO_RX_INT_ALMOST	BIT(3)
#define UA_STATUS_FIFO_TX_FULL		BIT(4)
#define UA_STATUS_FIFO_TX_INT_ALMOST	BIT(7)

#define UA_CONFIG_FIFO			0x0b
#define UA_CONFIG_FIFO_RX_THRESH	7
#define UA_CONFIG_FIFO_RX_FIFO_MODE	BIT(3)
#define UA_CONFIG_FIFO_TX_FIFO_MODE	BIT(7)

#define UA_INTFLAG_CLEAR		0x1c
#define UA_INTFLAG_SET			0x1d
#define UA_INT_ENABLE			0x1e
#define UA_INT_STATUS			0x1f

#define UA_INT_TX			BIT(0)
#define UA_INT_RX			BIT(1)

#define DIGICOLOR_USART_NR		3

/*
 * We use the 16 bytes hardware FIFO to buffer Rx traffic. Rx interrupt is
 * only produced when the FIFO is filled more than a certain configurable
 * threshold. Unfortunately, there is no way to set this threshold below half
 * FIFO. This means that we must periodically poll the FIFO status register to
 * see whether there are waiting Rx bytes.
 */

struct digicolor_port {
	struct uart_port port;
	struct delayed_work rx_poll_work;
};

static struct uart_port *digicolor_ports[DIGICOLOR_USART_NR];

static bool digicolor_uart_tx_full(struct uart_port *port)
{
	return !!(readb_relaxed(port->membase + UA_STATUS_FIFO) &
		  UA_STATUS_FIFO_TX_FULL);
}

static bool digicolor_uart_rx_empty(struct uart_port *port)
{
	return !!(readb_relaxed(port->membase + UA_STATUS_FIFO) &
		  UA_STATUS_FIFO_RX_EMPTY);
}

static void digicolor_uart_stop_tx(struct uart_port *port)
{
	u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE);

	int_enable &= ~UA_INT_TX;
	writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE);
}

static void digicolor_uart_start_tx(struct uart_port *port)
{
	u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE);

	int_enable |= UA_INT_TX;
	writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE);
}

static void digicolor_uart_stop_rx(struct uart_port *port)
{
	u8 int_enable = readb_relaxed(port->membase + UA_INT_ENABLE);

	int_enable &= ~UA_INT_RX;
	writeb_relaxed(int_enable, port->membase + UA_INT_ENABLE);
}

static void digicolor_rx_poll(struct work_struct *work)
{
	struct digicolor_port *dp =
		container_of(to_delayed_work(work),
			     struct digicolor_port, rx_poll_work);

	if (!digicolor_uart_rx_empty(&dp->port))
		/* force RX interrupt */
		writeb_relaxed(UA_INT_RX, dp->port.membase + UA_INTFLAG_SET);

	schedule_delayed_work(&dp->rx_poll_work, msecs_to_jiffies(100));
}

static void digicolor_uart_rx(struct uart_port *port)
{
	unsigned long flags;

	uart_port_lock_irqsave(port, &flags);

	while (1) {
		u8 status, ch, ch_flag;

		if (digicolor_uart_rx_empty(port))
			break;

		ch = readb_relaxed(port->membase + UA_EMI_REC);
		status = readb_relaxed(port->membase + UA_STATUS);

		port->icount.rx++;
		ch_flag = TTY_NORMAL;

		if (status) {
			if (status & UA_STATUS_PARITY_ERR)
				port->icount.parity++;
			else if (status & UA_STATUS_FRAME_ERR)
				port->icount.frame++;
			else if (status & UA_STATUS_OVERRUN_ERR)
				port->icount.overrun++;

			status &= port->read_status_mask;

			if (status & UA_STATUS_PARITY_ERR)
				ch_flag = TTY_PARITY;
			else if (status & UA_STATUS_FRAME_ERR)
				ch_flag = TTY_FRAME;
			else if (status & UA_STATUS_OVERRUN_ERR)
				ch_flag = TTY_OVERRUN;
		}

		if (status & port->ignore_status_mask)
			continue;

		uart_insert_char(port, status, UA_STATUS_OVERRUN_ERR, ch,
				 ch_flag);
	}

	uart_port_unlock_irqrestore(port, flags);

	tty_flip_buffer_push(&port->state->port);
}

static void digicolor_uart_tx(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	unsigned long flags;

	if (digicolor_uart_tx_full(port))
		return;

	uart_port_lock_irqsave(port, &flags);

	if (port->x_char) {
		writeb_relaxed(port->x_char, port->membase + UA_EMI_REC);
		port->icount.tx++;
		port->x_char = 0;
		goto out;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		digicolor_uart_stop_tx(port);
		goto out;
	}

	while (!uart_circ_empty(xmit)) {
		writeb(xmit->buf[xmit->tail], port->membase + UA_EMI_REC);
		uart_xmit_advance(port, 1);

		if (digicolor_uart_tx_full(port))
			break;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

out:
	uart_port_unlock_irqrestore(port, flags);
}

static irqreturn_t digicolor_uart_int(int irq, void *dev_id)
{
	struct uart_port *port = dev_id;
	u8 int_status = readb_relaxed(port->membase + UA_INT_STATUS);

	writeb_relaxed(UA_INT_RX | UA_INT_TX,
		       port->membase + UA_INTFLAG_CLEAR);

	if (int_status & UA_INT_RX)
		digicolor_uart_rx(port);
	if (int_status & UA_INT_TX)
		digicolor_uart_tx(port);

	return IRQ_HANDLED;
}

static unsigned int digicolor_uart_tx_empty(struct uart_port *port)
{
	u8 status = readb_relaxed(port->membase + UA_STATUS);

	return (status & UA_STATUS_TX_READY) ? TIOCSER_TEMT : 0;
}

static unsigned int digicolor_uart_get_mctrl(struct uart_port *port)
{
	return TIOCM_CTS;
}

static void digicolor_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
}

static void digicolor_uart_break_ctl(struct uart_port *port, int state)
{
}

static int digicolor_uart_startup(struct uart_port *port)
{
	struct digicolor_port *dp =
		container_of(port, struct digicolor_port, port);

	writeb_relaxed(UA_ENABLE_ENABLE, port->membase + UA_ENABLE);
	writeb_relaxed(UA_CONTROL_SOFT_RESET, port->membase + UA_CONTROL);
	writeb_relaxed(0, port->membase + UA_CONTROL);

	writeb_relaxed(UA_CONFIG_FIFO_RX_FIFO_MODE
		       | UA_CONFIG_FIFO_TX_FIFO_MODE | UA_CONFIG_FIFO_RX_THRESH,
		       port->membase + UA_CONFIG_FIFO);
	writeb_relaxed(UA_STATUS_FIFO_RX_INT_ALMOST,
		       port->membase + UA_STATUS_FIFO);
	writeb_relaxed(UA_CONTROL_RX_ENABLE | UA_CONTROL_TX_ENABLE,
		       port->membase + UA_CONTROL);
	writeb_relaxed(UA_INT_TX | UA_INT_RX,
		       port->membase + UA_INT_ENABLE);

	schedule_delayed_work(&dp->rx_poll_work, msecs_to_jiffies(100));

	return 0;
}

static void digicolor_uart_shutdown(struct uart_port *port)
{
	struct digicolor_port *dp =
		container_of(port, struct digicolor_port, port);

	writeb_relaxed(0, port->membase + UA_ENABLE);
	cancel_delayed_work_sync(&dp->rx_poll_work);
}

static void digicolor_uart_set_termios(struct uart_port *port,
				       struct ktermios *termios,
				       const struct ktermios *old)
{
	unsigned int baud, divisor;
	u8 config = 0;
	unsigned long flags;

	/* Mask termios capabilities we don't support */
	termios->c_cflag &= ~CMSPAR;
	termios->c_iflag &= ~(BRKINT | IGNBRK);

	/* Limit baud rates so that we don't need the fractional divider */
	baud = uart_get_baud_rate(port, termios, old,
				  port->uartclk / (0x10000*16),
				  port->uartclk / 256);
	divisor = uart_get_divisor(port, baud) - 1;

	switch (termios->c_cflag & CSIZE) {
	case CS7:
		break;
	case CS8:
	default:
		config |= UA_CONFIG_CHAR_LEN;
		termios->c_cflag &= ~CSIZE;
		termios->c_cflag |= CS8;
		break;
	}

	if (termios->c_cflag & CSTOPB)
		config |= UA_CONFIG_STOP_BITS;

	if (termios->c_cflag & PARENB) {
		config |= UA_CONFIG_PARITY;
		if (termios->c_cflag & PARODD)
			config |= UA_CONFIG_ODD_PARITY;
	}

	/* Set read status mask */
	port->read_status_mask = UA_STATUS_OVERRUN_ERR;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UA_STATUS_PARITY_ERR
			| UA_STATUS_FRAME_ERR;

	/* Set status ignore mask */
	port->ignore_status_mask = 0;
	if (!(termios->c_cflag & CREAD))
		port->ignore_status_mask |= UA_STATUS_OVERRUN_ERR
			| UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR;

	uart_port_lock_irqsave(port, &flags);

	uart_update_timeout(port, termios->c_cflag, baud);

	writeb_relaxed(config, port->membase + UA_CONFIG);
	writeb_relaxed(divisor & 0xff, port->membase + UA_HBAUD_LO);
	writeb_relaxed(divisor >> 8, port->membase + UA_HBAUD_HI);

	uart_port_unlock_irqrestore(port, flags);
}

static const char *digicolor_uart_type(struct uart_port *port)
{
	return (port->type == PORT_DIGICOLOR) ? "DIGICOLOR USART" : NULL;
}

static void digicolor_uart_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE)
		port->type = PORT_DIGICOLOR;
}

static void digicolor_uart_release_port(struct uart_port *port)
{
}

static int digicolor_uart_request_port(struct uart_port *port)
{
	return 0;
}

static const struct uart_ops digicolor_uart_ops = {
	.tx_empty	= digicolor_uart_tx_empty,
	.set_mctrl	= digicolor_uart_set_mctrl,
	.get_mctrl	= digicolor_uart_get_mctrl,
	.stop_tx	= digicolor_uart_stop_tx,
	.start_tx	= digicolor_uart_start_tx,
	.stop_rx	= digicolor_uart_stop_rx,
	.break_ctl	= digicolor_uart_break_ctl,
	.startup	= digicolor_uart_startup,
	.shutdown	= digicolor_uart_shutdown,
	.set_termios	= digicolor_uart_set_termios,
	.type		= digicolor_uart_type,
	.config_port	= digicolor_uart_config_port,
	.release_port	= digicolor_uart_release_port,
	.request_port	= digicolor_uart_request_port,
};

static void digicolor_uart_console_putchar(struct uart_port *port, unsigned char ch)
{
	while (digicolor_uart_tx_full(port))
		cpu_relax();

	writeb_relaxed(ch, port->membase + UA_EMI_REC);
}

static void digicolor_uart_console_write(struct console *co, const char *c,
					 unsigned n)
{
	struct uart_port *port = digicolor_ports[co->index];
	u8 status;
	unsigned long flags;
	int locked = 1;

	if (oops_in_progress)
		locked = uart_port_trylock_irqsave(port, &flags);
	else
		uart_port_lock_irqsave(port, &flags);

	uart_console_write(port, c, n, digicolor_uart_console_putchar);

	if (locked)
		uart_port_unlock_irqrestore(port, flags);

	/* Wait for transmitter to become empty */
	do {
		status = readb_relaxed(port->membase + UA_STATUS);
	} while ((status & UA_STATUS_TX_READY) == 0);
}

static int digicolor_uart_console_setup(struct console *co, char *options)
{
	int baud = 115200, bits = 8, parity = 'n', flow = 'n';
	struct uart_port *port;

	if (co->index < 0 || co->index >= DIGICOLOR_USART_NR)
		return -EINVAL;

	port = digicolor_ports[co->index];
	if (!port)
		return -ENODEV;

	if (options)
		uart_parse_options(options, &baud, &parity, &bits, &flow);

	return uart_set_options(port, co, baud, parity, bits, flow);
}

static struct console digicolor_console = {
	.name	= "ttyS",
	.device	= uart_console_device,
	.write	= digicolor_uart_console_write,
	.setup	= digicolor_uart_console_setup,
	.flags	= CON_PRINTBUFFER,
	.index	= -1,
};

static struct uart_driver digicolor_uart = {
	.driver_name	= "digicolor-usart",
	.dev_name	= "ttyS",
	.nr		= DIGICOLOR_USART_NR,
};

static int digicolor_uart_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	int irq, ret, index;
	struct digicolor_port *dp;
	struct resource *res;
	struct clk *uart_clk;

	if (!np) {
		dev_err(&pdev->dev, "Missing device tree node\n");
		return -ENXIO;
	}

	index = of_alias_get_id(np, "serial");
	if (index < 0 || index >= DIGICOLOR_USART_NR)
		return -EINVAL;

	dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
	if (!dp)
		return -ENOMEM;

	uart_clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(uart_clk))
		return PTR_ERR(uart_clk);

	dp->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(dp->port.membase))
		return PTR_ERR(dp->port.membase);
	dp->port.mapbase = res->start;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;
	dp->port.irq = irq;

	dp->port.iotype = UPIO_MEM;
	dp->port.uartclk = clk_get_rate(uart_clk);
	dp->port.fifosize = 16;
	dp->port.dev = &pdev->dev;
	dp->port.ops = &digicolor_uart_ops;
	dp->port.line = index;
	dp->port.type = PORT_DIGICOLOR;
	spin_lock_init(&dp->port.lock);

	digicolor_ports[index] = &dp->port;
	platform_set_drvdata(pdev, &dp->port);

	INIT_DELAYED_WORK(&dp->rx_poll_work, digicolor_rx_poll);

	ret = devm_request_irq(&pdev->dev, dp->port.irq, digicolor_uart_int, 0,
			       dev_name(&pdev->dev), &dp->port);
	if (ret)
		return ret;

	return uart_add_one_port(&digicolor_uart, &dp->port);
}

static void digicolor_uart_remove(struct platform_device *pdev)
{
	struct uart_port *port = platform_get_drvdata(pdev);

	uart_remove_one_port(&digicolor_uart, port);
}

static const struct of_device_id digicolor_uart_dt_ids[] = {
	{ .compatible = "cnxt,cx92755-usart", },
	{ }
};
MODULE_DEVICE_TABLE(of, digicolor_uart_dt_ids);

static struct platform_driver digicolor_uart_platform = {
	.driver = {
		.name		= "digicolor-usart",
		.of_match_table	= of_match_ptr(digicolor_uart_dt_ids),
	},
	.probe	= digicolor_uart_probe,
	.remove_new = digicolor_uart_remove,
};

static int __init digicolor_uart_init(void)
{
	int ret;

	if (IS_ENABLED(CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE)) {
		digicolor_uart.cons = &digicolor_console;
		digicolor_console.data = &digicolor_uart;
	}

	ret = uart_register_driver(&digicolor_uart);
	if (ret)
		return ret;

	ret = platform_driver_register(&digicolor_uart_platform);
	if (ret)
		uart_unregister_driver(&digicolor_uart);

	return ret;
}
module_init(digicolor_uart_init);

static void __exit digicolor_uart_exit(void)
{
	platform_driver_unregister(&digicolor_uart_platform);
	uart_unregister_driver(&digicolor_uart);
}
module_exit(digicolor_uart_exit);

MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Conexant Digicolor USART serial driver");
MODULE_LICENSE("GPL");
