/*
 * Copyright (c) 2004	Cucy Systems (http://www.cucy.com)
 * Curt Brune <curt@cucy.com>
 *
 * (C) Copyright 2004
 * DAVE Srl
 * http://www.dave-tech.it
 * http://www.wawnet.biz
 * mailto:info@wawnet.biz
 *
 * (C) Copyright 2002-2004
 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.de>
 *
 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * 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
 *
 * MODULE:        $Id:$
 * Description:   UART/Serial interface for Samsung S3C4510B SoC
 * Runtime Env:   ARM7TDMI
 * Change History:
 *     03-02-04    Create (Curt Brune) curt@cucy.com
 *
 */

#include <common.h>

#include <asm/hardware.h>
#include "s3c4510b_uart.h"

DECLARE_GLOBAL_DATA_PTR;

static UART    *uart;

/* flush serial input queue. returns 0 on success or negative error
 * number otherwise
 */
static int serial_flush_input(void)
{
	volatile u32 tmp;

	/* keep on reading as long as the receiver is not empty */
	while( uart->m_stat.bf.rxReady) {
		tmp = uart->m_rx;
	}

	return 0;
}


/* flush output queue. returns 0 on success or negative error number
 * otherwise
 */
static int serial_flush_output(void)
{
	/* wait until the transmitter is no longer busy */
	while( !uart->m_stat.bf.txBufEmpty);

	return 0;
}


void serial_setbrg (void)
{
	UART_LINE_CTRL ulctrl;
	UART_CTRL      uctrl;
	UART_BAUD_DIV  ubd;

	serial_flush_output();
	serial_flush_input();

	/* control register */
	uctrl.ui = 0x0;
	uctrl.bf.rxMode = 0x1;
	uctrl.bf.rxIrq = 0x0;
	uctrl.bf.txMode = 0x1;
	uctrl.bf.DSR = 0x0;
	uctrl.bf.sendBreak = 0x0;
	uctrl.bf.loopBack = 0x0;
	uart->m_ctrl.ui = uctrl.ui;

	/* line control register */
	ulctrl.ui  = 0x0;
	ulctrl.bf.wordLen   = 0x3; /* 8 bit data */
	ulctrl.bf.nStop     = 0x0; /* 1 stop bit */
	ulctrl.bf.parity    = 0x0; /* no parity */
	ulctrl.bf.clk       = 0x0; /* internal clock */
	ulctrl.bf.infra_red = 0x0; /* no infra_red */
	uart->m_lineCtrl.ui = ulctrl.ui;

	ubd.ui = 0x0;

	/* see table on page 10-15 in SAMSUNG S3C4510B manual */
	/* get correct divisor */
	switch(gd->baudrate) {
	case   1200:	ubd.bf.cnt0 = 1301;	break;
	case   2400:	ubd.bf.cnt0 =  650;	break;
	case   4800:	ubd.bf.cnt0 =  324;	break;
	case   9600:	ubd.bf.cnt0 =  162;	break;
	case  19200:	ubd.bf.cnt0 =   80;	break;
	case  38400:	ubd.bf.cnt0 =   40;	break;
	case  57600:	ubd.bf.cnt0 =   26;	break;
	case 115200:	ubd.bf.cnt0 =   13;	break;
	}

	uart->m_baudDiv.ui = ubd.ui;
	uart->m_baudCnt = 0x0;
	uart->m_baudClk = 0x0;

}


/*
 * Initialise the serial port with the given baudrate. The settings
 * are always 8 data bits, no parity, 1 stop bit, no start bits.
 *
 */
int serial_init (void)
{

#if   CONFIG_SERIAL1 == 1
	uart = (UART *)UART0_BASE;
#elif CONFIG_SERIAL1 == 2
	uart = (UART *)UART1_BASE;
#else
#error CONFIG_SERIAL1 not equal to 1 or 2
#endif

	serial_setbrg ();

	return (0);
}


/*
 * Output a single byte to the serial port.
 */
void serial_putc (const char c)
{
	/* wait for room in the transmit FIFO */
	while( !uart->m_stat.bf.txBufEmpty);

	uart->m_tx = c;

	/*
		to be polite with serial console add a line feed
		to the carriage return character
	*/
	if (c=='\n')
		serial_putc('\r');
}

/*
 * Test if an input byte is ready from the serial port. Returns non-zero on
 * success, 0 otherwise.
 */
int serial_tstc (void)
{
	return uart->m_stat.bf.rxReady;
}

/*
 * Read a single byte from the serial port. Returns 1 on success, 0
 * otherwise. When the function is succesfull, the character read is
 * written into its argument c.
 */
int serial_getc (void)
{
	int rv;

	for(;;) {
		rv = serial_tstc();

		if (rv) {
			return uart->m_rx & 0xFF;
		}
	}
}

void serial_puts (const char *s)
{
	while (*s) {
		serial_putc (*s++);
	}

	/* busy wait for tx complete */
	while ( !uart->m_stat.bf.txComplete);

	/* clear break */
	uart->m_ctrl.bf.sendBreak = 0;

}
