/*
 *  Driver for Conexant Digicolor serial ports (USART)
 *
 * Author: Baruch Siach <baruch@tkos.co.il>
 *
 * Copyright (C) 2014 Paradox Innovation Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#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;

	spin_lock_irqsave(&port->lock, flags);

	while (1) {
		u8 status, ch;
		unsigned int 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);
	}

	spin_unlock_irqrestore(&port->lock, 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;

	spin_lock_irqsave(&port->lock, 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);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;

		if (digicolor_uart_tx_full(port))
			break;
	}

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

out:
	spin_unlock_irqrestore(&port->lock, 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,
				       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;
		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;

	spin_lock_irqsave(&port->lock, 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);

	spin_unlock_irqrestore(&port->lock, 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, int 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 = spin_trylock_irqsave(&port->lock, flags);
	else
		spin_lock_irqsave(&port->lock, flags);

	uart_console_write(port, c, n, digicolor_uart_console_putchar);

	if (locked)
		spin_unlock_irqrestore(&port->lock, 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 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);

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

	dp->port.irq = platform_get_irq(pdev, 0);
	if (IS_ERR_VALUE(dp->port.irq))
		return dp->port.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 int digicolor_uart_remove(struct platform_device *pdev)
{
	struct uart_port *port = platform_get_drvdata(pdev);

	uart_remove_one_port(&digicolor_uart, port);

	return 0;
}

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	= 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;

	return platform_driver_register(&digicolor_uart_platform);
}
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");
