// 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 tty_port *tport = &port->state->port;
	unsigned long flags;
	unsigned char c;

	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 (kfifo_is_empty(&tport->xmit_fifo) || uart_tx_stopped(port)) {
		digicolor_uart_stop_tx(port);
		goto out;
	}

	while (uart_fifo_get(port, &c)) {
		writeb(c, port->membase + UA_EMI_REC);

		if (digicolor_uart_tx_full(port))
			break;
	}

	if (kfifo_len(&tport->xmit_fifo) < 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");
