/*
 * Copyright (c) 2009 Wind River Systems, Inc.
 * Tom Rix <Tom.Rix@windriver.com>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 *
 * This file was adapted from cpu/mpc5xxx/serial.c
 *
 */

#include <common.h>
#include <serial.h>
#include <ns16550.h>
#include <asm/arch/cpu.h>
#include "zoom2_serial.h"

int quad_init_dev (unsigned long base)
{
	/*
	 * The Quad UART is on the debug board.
	 * Check if the debug board is attached before using the UART
	 */
	if (zoom2_debug_board_connected ()) {
		NS16550_t com_port = (NS16550_t) base;
		int baud_divisor = CONFIG_SYS_NS16550_CLK / 16 /
			CONFIG_BAUDRATE;

		/*
		 * Zoom2 has a board specific initialization of its UART.
		 * This generic initialization has been copied from
		 * drivers/serial/ns16550.c. The macros have been expanded.
		 *
		 * Do the following instead of
		 *
		 * NS16550_init (com_port, clock_divisor);
		 */
		com_port->ier = 0x00;

		/*
		 * On Zoom2 board Set pre-scalar to 1
		 * CLKSEL is GND => MCR[7] is 1 => preslr is 4
		 * So change the prescl to 1
		 */
		com_port->lcr = 0xBF;
		com_port->fcr |= 0x10;
		com_port->mcr &= 0x7F;

		/* This is generic ns16550.c setup */
		com_port->lcr = UART_LCR_BKSE | UART_LCR_8N1;
		com_port->dll = 0;
		com_port->dlm = 0;
		com_port->lcr = UART_LCR_8N1;
		com_port->mcr = UART_MCR_DTR | UART_MCR_RTS;
		com_port->fcr = UART_FCR_FIFO_EN | UART_FCR_RXSR |
			UART_FCR_TXSR;
		com_port->lcr = UART_LCR_BKSE | UART_LCR_8N1;
		com_port->dll = baud_divisor & 0xff;
		com_port->dlm = (baud_divisor >> 8) & 0xff;
		com_port->lcr = UART_LCR_8N1;
	}
	/*
	 * We have to lie here, otherwise the board init code will hang
	 * on the check
	 */
	return 0;
}

void quad_putc_dev (unsigned long base, const char c)
{
	if (zoom2_debug_board_connected ()) {

		if (c == '\n')
			quad_putc_dev (base, '\r');

		NS16550_putc ((NS16550_t) base, c);
	}
}

void quad_puts_dev (unsigned long base, const char *s)
{
	if (zoom2_debug_board_connected ()) {
		while ((s != NULL) && (*s != '\0'))
			quad_putc_dev (base, *s++);
	}
}

int quad_getc_dev (unsigned long base)
{
	if (zoom2_debug_board_connected ())
		return NS16550_getc ((NS16550_t) base);
	else
		return 0;
}

int quad_tstc_dev (unsigned long base)
{
	if (zoom2_debug_board_connected ())
		return NS16550_tstc ((NS16550_t) base);
	else
		return 0;
}

void quad_setbrg_dev (unsigned long base)
{
	if (zoom2_debug_board_connected ()) {

		int clock_divisor = CONFIG_SYS_NS16550_CLK / 16 /
			CONFIG_BAUDRATE;

		NS16550_reinit ((NS16550_t) base, clock_divisor);
	}
}

QUAD_INIT (0)
QUAD_INIT (1)
QUAD_INIT (2)
QUAD_INIT (3)
