/*
 * drivers/serial/v850e_uart.c -- Serial I/O using V850E on-chip UART or UARTB
 *
 *  Copyright (C) 2001,02,03  NEC Electronics Corporation
 *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
 *
 * This file is subject to the terms and conditions of the GNU General
 * Public License.  See the file COPYING in the main directory of this
 * archive for more details.
 *
 * Written by Miles Bader <miles@gnu.org>
 */

/* This driver supports both the original V850E UART interface (called
   merely `UART' in the docs) and the newer `UARTB' interface, which is
   roughly a superset of the first one.  The selection is made at
   configure time -- if CONFIG_V850E_UARTB is defined, then UARTB is
   presumed, otherwise the old UART -- as these are on-CPU UARTS, a system
   can never have both.

   The UARTB interface also has a 16-entry FIFO mode, which is not
   yet supported by this driver.  */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/serial_core.h>

#include <asm/v850e_uart.h>

/* Initial UART state.  This may be overridden by machine-dependent headers. */
#ifndef V850E_UART_INIT_BAUD
#define V850E_UART_INIT_BAUD	115200
#endif
#ifndef V850E_UART_INIT_CFLAGS
#define V850E_UART_INIT_CFLAGS	(B115200 | CS8 | CREAD)
#endif

/* A string used for prefixing printed descriptions; since the same UART
   macro is actually used on other chips than the V850E.  This must be a
   constant string.  */
#ifndef V850E_UART_CHIP_NAME
#define V850E_UART_CHIP_NAME	"V850E"
#endif

#define V850E_UART_MINOR_BASE	64	   /* First tty minor number */


/* Low-level UART functions.  */

/* Configure and turn on uart channel CHAN, using the termios `control
   modes' bits in CFLAGS, and a baud-rate of BAUD.  */
void v850e_uart_configure (unsigned chan, unsigned cflags, unsigned baud)
{
	int flags;
	v850e_uart_speed_t old_speed;
	v850e_uart_config_t old_config;
	v850e_uart_speed_t new_speed = v850e_uart_calc_speed (baud);
	v850e_uart_config_t new_config = v850e_uart_calc_config (cflags);

	/* Disable interrupts while we're twiddling the hardware.  */
	local_irq_save (flags);

#ifdef V850E_UART_PRE_CONFIGURE
	V850E_UART_PRE_CONFIGURE (chan, cflags, baud);
#endif

	old_config = V850E_UART_CONFIG (chan);
	old_speed = v850e_uart_speed (chan);

	if (! v850e_uart_speed_eq (old_speed, new_speed)) {
		/* The baud rate has changed.  First, disable the UART.  */
		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_FINI;
		old_config = 0;	/* Force the uart to be re-initialized. */

		/* Reprogram the baud-rate generator.  */
		v850e_uart_set_speed (chan, new_speed);
	}

	if (! (old_config & V850E_UART_CONFIG_ENABLED)) {
		/* If we are using the uart for the first time, start by
		   enabling it, which must be done before turning on any
		   other bits.  */
		V850E_UART_CONFIG (chan) = V850E_UART_CONFIG_INIT;
		/* See the initial state.  */
		old_config = V850E_UART_CONFIG (chan);
	}

	if (new_config != old_config) {
		/* Which of the TXE/RXE bits we'll temporarily turn off
		   before changing other control bits.  */
		unsigned temp_disable = 0;
		/* Which of the TXE/RXE bits will be enabled.  */
		unsigned enable = 0;
		unsigned changed_bits = new_config ^ old_config;

		/* Which of RX/TX will be enabled in the new configuration.  */
		if (new_config & V850E_UART_CONFIG_RX_BITS)
			enable |= (new_config & V850E_UART_CONFIG_RX_ENABLE);
		if (new_config & V850E_UART_CONFIG_TX_BITS)
			enable |= (new_config & V850E_UART_CONFIG_TX_ENABLE);

		/* Figure out which of RX/TX needs to be disabled; note
		   that this will only happen if they're not already
		   disabled.  */
		if (changed_bits & V850E_UART_CONFIG_RX_BITS)
			temp_disable
				|= (old_config & V850E_UART_CONFIG_RX_ENABLE);
		if (changed_bits & V850E_UART_CONFIG_TX_BITS)
			temp_disable
				|= (old_config & V850E_UART_CONFIG_TX_ENABLE);

		/* We have to turn off RX and/or TX mode before changing
		   any associated control bits.  */
		if (temp_disable)
			V850E_UART_CONFIG (chan) = old_config & ~temp_disable;

		/* Write the new control bits, while RX/TX are disabled. */ 
		if (changed_bits & ~enable)
			V850E_UART_CONFIG (chan) = new_config & ~enable;

		v850e_uart_config_delay (new_config, new_speed);

		/* Write the final version, with enable bits turned on.  */
		V850E_UART_CONFIG (chan) = new_config;
	}

	local_irq_restore (flags);
}


/*  Low-level console. */

#ifdef CONFIG_V850E_UART_CONSOLE

static void v850e_uart_cons_write (struct console *co,
				   const char *s, unsigned count)
{
	if (count > 0) {
		unsigned chan = co->index;
		unsigned irq = V850E_UART_TX_IRQ (chan);
		int irq_was_enabled, irq_was_pending, flags;

		/* We don't want to get `transmission completed'
		   interrupts, since we're busy-waiting, so we disable them
		   while sending (we don't disable interrupts entirely
		   because sending over a serial line is really slow).  We
		   save the status of the tx interrupt and restore it when
		   we're done so that using printk doesn't interfere with
		   normal serial transmission (other than interleaving the
		   output, of course!).  This should work correctly even if
		   this function is interrupted and the interrupt printks
		   something.  */

		/* Disable interrupts while fiddling with tx interrupt.  */
		local_irq_save (flags);
		/* Get current tx interrupt status.  */
		irq_was_enabled = v850e_intc_irq_enabled (irq);
		irq_was_pending = v850e_intc_irq_pending (irq);
		/* Disable tx interrupt if necessary.  */
		if (irq_was_enabled)
			v850e_intc_disable_irq (irq);
		/* Turn interrupts back on.  */
		local_irq_restore (flags);

		/* Send characters.  */
		while (count > 0) {
			int ch = *s++;

			if (ch == '\n') {
				/* We don't have the benefit of a tty
				   driver, so translate NL into CR LF.  */
				v850e_uart_wait_for_xmit_ok (chan);
				v850e_uart_putc (chan, '\r');
			}

			v850e_uart_wait_for_xmit_ok (chan);
			v850e_uart_putc (chan, ch);

			count--;
		}

		/* Restore saved tx interrupt status.  */
		if (irq_was_enabled) {
			/* Wait for the last character we sent to be
			   completely transmitted (as we'll get an
			   interrupt interrupt at that point).  */
			v850e_uart_wait_for_xmit_done (chan);
			/* Clear pending interrupts received due
			   to our transmission, unless there was already
			   one pending, in which case we want the
			   handler to be called.  */
			if (! irq_was_pending)
				v850e_intc_clear_pending_irq (irq);
			/* ... and then turn back on handling.  */
			v850e_intc_enable_irq (irq);
		}
	}
}

extern struct uart_driver v850e_uart_driver;
static struct console v850e_uart_cons =
{
    .name	= "ttyS",
    .write	= v850e_uart_cons_write,
    .device	= uart_console_device,
    .flags	= CON_PRINTBUFFER,
    .cflag	= V850E_UART_INIT_CFLAGS,
    .index	= -1,
    .data	= &v850e_uart_driver,
};

void v850e_uart_cons_init (unsigned chan)
{
	v850e_uart_configure (chan, V850E_UART_INIT_CFLAGS,
			      V850E_UART_INIT_BAUD);
	v850e_uart_cons.index = chan;
	register_console (&v850e_uart_cons);
	printk ("Console: %s on-chip UART channel %d\n",
		V850E_UART_CHIP_NAME, chan);
}

/* This is what the init code actually calls.  */
static int v850e_uart_console_init (void)
{
	v850e_uart_cons_init (V850E_UART_CONSOLE_CHANNEL);
	return 0;
}
console_initcall(v850e_uart_console_init);

#define V850E_UART_CONSOLE &v850e_uart_cons

#else /* !CONFIG_V850E_UART_CONSOLE */
#define V850E_UART_CONSOLE 0
#endif /* CONFIG_V850E_UART_CONSOLE */

/* TX/RX interrupt handlers.  */

static void v850e_uart_stop_tx (struct uart_port *port);

void v850e_uart_tx (struct uart_port *port)
{
	struct circ_buf *xmit = &port->info->xmit;
	int stopped = uart_tx_stopped (port);

	if (v850e_uart_xmit_ok (port->line)) {
		int tx_ch;

		if (port->x_char) {
			tx_ch = port->x_char;
			port->x_char = 0;
		} else if (!uart_circ_empty (xmit) && !stopped) {
			tx_ch = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		} else
			goto no_xmit;

		v850e_uart_putc (port->line, tx_ch);
		port->icount.tx++;

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

 no_xmit:
	if (uart_circ_empty (xmit) || stopped)
		v850e_uart_stop_tx (port, stopped);
}

static irqreturn_t v850e_uart_tx_irq(int irq, void *data)
{
	struct uart_port *port = data;
	v850e_uart_tx (port);
	return IRQ_HANDLED;
}

static irqreturn_t v850e_uart_rx_irq(int irq, void *data)
{
	struct uart_port *port = data;
	unsigned ch_stat = TTY_NORMAL;
	unsigned ch = v850e_uart_getc (port->line);
	unsigned err = v850e_uart_err (port->line);

	if (err) {
		if (err & V850E_UART_ERR_OVERRUN) {
			ch_stat = TTY_OVERRUN;
			port->icount.overrun++;
		} else if (err & V850E_UART_ERR_FRAME) {
			ch_stat = TTY_FRAME;
			port->icount.frame++;
		} else if (err & V850E_UART_ERR_PARITY) {
			ch_stat = TTY_PARITY;
			port->icount.parity++;
		}
	}

	port->icount.rx++;

	tty_insert_flip_char (port->info->tty, ch, ch_stat);
	tty_schedule_flip (port->info->tty);

	return IRQ_HANDLED;
}


/* Control functions for the serial framework.  */

static void v850e_uart_nop (struct uart_port *port) { }
static int v850e_uart_success (struct uart_port *port) { return 0; }

static unsigned v850e_uart_tx_empty (struct uart_port *port)
{
	return TIOCSER_TEMT;	/* Can't detect.  */
}

static void v850e_uart_set_mctrl (struct uart_port *port, unsigned mctrl)
{
#ifdef V850E_UART_SET_RTS
	V850E_UART_SET_RTS (port->line, (mctrl & TIOCM_RTS));
#endif
}

static unsigned v850e_uart_get_mctrl (struct uart_port *port)
{
	/* We don't support DCD or DSR, so consider them permanently active. */
	int mctrl = TIOCM_CAR | TIOCM_DSR;

	/* We may support CTS.  */
#ifdef V850E_UART_CTS
	mctrl |= V850E_UART_CTS(port->line) ? TIOCM_CTS : 0;
#else
	mctrl |= TIOCM_CTS;
#endif

	return mctrl;
}

static void v850e_uart_start_tx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
	v850e_uart_tx (port);
	v850e_intc_enable_irq (V850E_UART_TX_IRQ (port->line));
}

static void v850e_uart_stop_tx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_TX_IRQ (port->line));
}

static void v850e_uart_start_rx (struct uart_port *port)
{
	v850e_intc_enable_irq (V850E_UART_RX_IRQ (port->line));
}

static void v850e_uart_stop_rx (struct uart_port *port)
{
	v850e_intc_disable_irq (V850E_UART_RX_IRQ (port->line));
}

static void v850e_uart_break_ctl (struct uart_port *port, int break_ctl)
{
	/* Umm, do this later.  */
}

static int v850e_uart_startup (struct uart_port *port)
{
	int err;

	/* Alloc RX irq.  */
	err = request_irq (V850E_UART_RX_IRQ (port->line), v850e_uart_rx_irq,
			   IRQF_DISABLED, "v850e_uart", port);
	if (err)
		return err;

	/* Alloc TX irq.  */
	err = request_irq (V850E_UART_TX_IRQ (port->line), v850e_uart_tx_irq,
			   IRQF_DISABLED, "v850e_uart", port);
	if (err) {
		free_irq (V850E_UART_RX_IRQ (port->line), port);
		return err;
	}

	v850e_uart_start_rx (port);

	return 0;
}

static void v850e_uart_shutdown (struct uart_port *port)
{
	/* Disable port interrupts.  */
	free_irq (V850E_UART_TX_IRQ (port->line), port);
	free_irq (V850E_UART_RX_IRQ (port->line), port);

	/* Turn off xmit/recv enable bits.  */
	V850E_UART_CONFIG (port->line)
		&= ~(V850E_UART_CONFIG_TX_ENABLE
		     | V850E_UART_CONFIG_RX_ENABLE);
	/* Then reset the channel.  */
	V850E_UART_CONFIG (port->line) = 0;
}

static void
v850e_uart_set_termios (struct uart_port *port, struct ktermios *termios,
		        struct ktermios *old)
{
	unsigned cflags = termios->c_cflag;

	/* Restrict flags to legal values.  */
	if ((cflags & CSIZE) != CS7 && (cflags & CSIZE) != CS8)
		/* The new value of CSIZE is invalid, use the old value.  */
		cflags = (cflags & ~CSIZE)
			| (old ? (old->c_cflag & CSIZE) : CS8);

	termios->c_cflag = cflags;

	v850e_uart_configure (port->line, cflags,
			      uart_get_baud_rate (port, termios, old,
						  v850e_uart_min_baud(),
						  v850e_uart_max_baud()));
}

static const char *v850e_uart_type (struct uart_port *port)
{
	return port->type == PORT_V850E_UART ? "v850e_uart" : 0;
}

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

static int
v850e_uart_verify_port (struct uart_port *port, struct serial_struct *ser)
{
	if (ser->type != PORT_UNKNOWN && ser->type != PORT_V850E_UART)
		return -EINVAL;
	if (ser->irq != V850E_UART_TX_IRQ (port->line))
		return -EINVAL;
	return 0;
}

static struct uart_ops v850e_uart_ops = {
	.tx_empty	= v850e_uart_tx_empty,
	.get_mctrl	= v850e_uart_get_mctrl,
	.set_mctrl	= v850e_uart_set_mctrl,
	.start_tx	= v850e_uart_start_tx,
	.stop_tx	= v850e_uart_stop_tx,
	.stop_rx	= v850e_uart_stop_rx,
	.enable_ms	= v850e_uart_nop,
	.break_ctl	= v850e_uart_break_ctl,
	.startup	= v850e_uart_startup,
	.shutdown	= v850e_uart_shutdown,
	.set_termios	= v850e_uart_set_termios,
	.type		= v850e_uart_type,
	.release_port	= v850e_uart_nop,
	.request_port	= v850e_uart_success,
	.config_port	= v850e_uart_config_port,
	.verify_port	= v850e_uart_verify_port,
};

/* Initialization and cleanup.  */

static struct uart_driver v850e_uart_driver = {
	.owner			= THIS_MODULE,
	.driver_name		= "v850e_uart",
	.dev_name		= "ttyS",
	.major			= TTY_MAJOR,
	.minor			= V850E_UART_MINOR_BASE,
	.nr			= V850E_UART_NUM_CHANNELS,
	.cons			= V850E_UART_CONSOLE,
};


static struct uart_port v850e_uart_ports[V850E_UART_NUM_CHANNELS];

static int __init v850e_uart_init (void)
{
	int rval;

	printk (KERN_INFO "%s on-chip UART\n", V850E_UART_CHIP_NAME);

	rval = uart_register_driver (&v850e_uart_driver);
	if (rval == 0) {
		unsigned chan;

		for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++) {
			struct uart_port *port = &v850e_uart_ports[chan];
			
			memset (port, 0, sizeof *port);

			port->ops = &v850e_uart_ops;
			port->line = chan;
			port->iotype = UPIO_MEM;
			port->flags = UPF_BOOT_AUTOCONF;

			/* We actually use multiple IRQs, but the serial
			   framework seems to mainly use this for
			   informational purposes anyway.  Here we use the TX
			   irq.  */
			port->irq = V850E_UART_TX_IRQ (chan);

			/* The serial framework doesn't really use these
			   membase/mapbase fields for anything useful, but
			   it requires that they be something non-zero to
			   consider the port `valid', and also uses them
			   for informational purposes.  */
			port->membase = (void *)V850E_UART_BASE_ADDR (chan);
			port->mapbase = V850E_UART_BASE_ADDR (chan);

			/* The framework insists on knowing the uart's master
			   clock freq, though it doesn't seem to do anything
			   useful for us with it.  We must make it at least
			   higher than (the maximum baud rate * 16), otherwise
			   the framework will puke during its internal
			   calculations, and force the baud rate to be 9600.
			   To be accurate though, just repeat the calculation
			   we use when actually setting the speed.  */
			port->uartclk = v850e_uart_max_clock() * 16;

			uart_add_one_port (&v850e_uart_driver, port);
		}
	}

	return rval;
}

static void __exit v850e_uart_exit (void)
{
	unsigned chan;

	for (chan = 0; chan < V850E_UART_NUM_CHANNELS; chan++)
		uart_remove_one_port (&v850e_uart_driver,
				      &v850e_uart_ports[chan]);

	uart_unregister_driver (&v850e_uart_driver);
}

module_init (v850e_uart_init);
module_exit (v850e_uart_exit);

MODULE_AUTHOR ("Miles Bader");
MODULE_DESCRIPTION ("NEC " V850E_UART_CHIP_NAME " on-chip UART");
MODULE_LICENSE ("GPL");
