2007-09-05 10:54:14 +00:00
|
|
|
/*
|
|
|
|
* (C) Copyright 2005
|
|
|
|
* Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
|
|
|
|
*
|
|
|
|
* See file CREDITS for list of people who contributed to this
|
|
|
|
* project.
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
2009-10-22 12:21:25 +00:00
|
|
|
#include <mach/netx-regs.h>
|
2007-09-05 10:54:14 +00:00
|
|
|
#include <driver.h>
|
|
|
|
#include <init.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
|
|
|
|
#define IO_WRITE(addr, val) (*(volatile unsigned long *)(addr) = (val))
|
|
|
|
#define IO_READ(addr) (*(volatile unsigned long *)(addr))
|
|
|
|
|
|
|
|
unsigned long addr = 0x100a00;
|
|
|
|
|
|
|
|
enum uart_regs {
|
|
|
|
UART_DR = 0x00,
|
|
|
|
UART_SR = 0x04,
|
|
|
|
UART_LINE_CR = 0x08,
|
|
|
|
UART_BAUDDIV_MSB = 0x0c,
|
|
|
|
UART_BAUDDIV_LSB = 0x10,
|
|
|
|
UART_CR = 0x14,
|
|
|
|
UART_FR = 0x18,
|
|
|
|
UART_IIR = 0x1c,
|
|
|
|
UART_ILPR = 0x20,
|
|
|
|
UART_RTS_CR = 0x24,
|
|
|
|
UART_RTS_LEAD = 0x28,
|
|
|
|
UART_RTS_TRAIL = 0x2c,
|
|
|
|
UART_DRV_ENABLE = 0x30,
|
|
|
|
UART_BRM_CR = 0x34,
|
|
|
|
UART_RXFIFO_IRQLEVEL = 0x38,
|
|
|
|
UART_TXFIFO_IRQLEVEL = 0x3c,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define LINE_CR_5BIT (0<<5)
|
|
|
|
#define LINE_CR_6BIT (1<<5)
|
|
|
|
#define LINE_CR_7BIT (2<<5)
|
|
|
|
#define LINE_CR_8BIT (3<<5)
|
|
|
|
#define LINE_CR_FEN (1<<4)
|
|
|
|
|
|
|
|
#define CR_UARTEN (1<<0)
|
|
|
|
|
|
|
|
#define FR_TXFE (1<<7)
|
|
|
|
#define FR_RXFF (1<<6)
|
|
|
|
#define FR_TXFF (1<<5)
|
|
|
|
#define FR_RXFE (1<<4)
|
|
|
|
#define FR_BUSY (1<<3)
|
|
|
|
#define FR_DCD (1<<2)
|
|
|
|
#define FR_DSR (1<<1)
|
|
|
|
#define FR_CTS (1<<0)
|
|
|
|
|
|
|
|
#define DRV_ENABLE_TX (1<<1)
|
|
|
|
#define DRV_ENABLE_RTS (1<<0)
|
|
|
|
|
|
|
|
#define BRM_CR_BAUD_RATE_MODE (1<<0)
|
|
|
|
|
|
|
|
static int netx_serial_init_port(struct console_device *cdev)
|
|
|
|
{
|
|
|
|
struct device_d *dev = cdev->dev;
|
|
|
|
unsigned int divisor;
|
|
|
|
|
|
|
|
/* disable uart */
|
|
|
|
IO_WRITE( dev->map_base + UART_CR, 0);
|
|
|
|
|
|
|
|
IO_WRITE( dev->map_base + UART_LINE_CR, LINE_CR_8BIT | LINE_CR_FEN);
|
|
|
|
|
|
|
|
IO_WRITE( dev->map_base + UART_DRV_ENABLE, DRV_ENABLE_TX | DRV_ENABLE_RTS );
|
|
|
|
|
|
|
|
/* set baud rate */
|
|
|
|
divisor = 115200 * 4096;
|
|
|
|
divisor /= 1000;
|
|
|
|
divisor *= 256;
|
|
|
|
divisor /= 100000;
|
|
|
|
|
|
|
|
IO_WRITE( dev->map_base + UART_BAUDDIV_MSB, (divisor >> 8) & 0xff );
|
|
|
|
IO_WRITE( dev->map_base + UART_BAUDDIV_LSB, divisor & 0xff );
|
|
|
|
IO_WRITE( dev->map_base + UART_BRM_CR, BRM_CR_BAUD_RATE_MODE);
|
|
|
|
|
|
|
|
/* Finally, enable the UART */
|
|
|
|
IO_WRITE( dev->map_base + UART_CR, CR_UARTEN);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netx_serial_setbaudrate(struct console_device *cdev, int baudrate)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void netx_serial_putc(struct console_device *cdev, char c)
|
|
|
|
{
|
|
|
|
struct device_d *dev = cdev->dev;
|
|
|
|
|
|
|
|
while( IO_READ(dev->map_base + UART_FR) & FR_TXFF );
|
|
|
|
|
|
|
|
IO_WRITE(dev->map_base + UART_DR, c);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netx_serial_getc(struct console_device *cdev)
|
|
|
|
{
|
|
|
|
struct device_d *dev = cdev->dev;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
while( IO_READ(dev->map_base + UART_FR) & FR_RXFE );
|
|
|
|
|
|
|
|
c = IO_READ(dev->map_base + UART_DR);
|
|
|
|
|
|
|
|
IO_READ(dev->map_base + UART_SR);
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netx_serial_tstc(struct console_device *cdev)
|
|
|
|
{
|
|
|
|
struct device_d *dev = cdev->dev;
|
|
|
|
|
|
|
|
return (IO_READ(dev->map_base + UART_FR) & FR_RXFE) ? 0 : 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netx_serial_probe(struct device_d *dev)
|
|
|
|
{
|
|
|
|
struct console_device *cdev;
|
|
|
|
|
2011-01-06 15:23:01 +00:00
|
|
|
cdev = xmalloc(sizeof(struct console_device));
|
2007-09-05 10:54:14 +00:00
|
|
|
dev->type_data = cdev;
|
|
|
|
cdev->dev = dev;
|
|
|
|
cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
|
|
|
|
cdev->tstc = netx_serial_tstc;
|
|
|
|
cdev->putc = netx_serial_putc;
|
|
|
|
cdev->getc = netx_serial_getc;
|
|
|
|
cdev->setbrg = netx_serial_setbaudrate;
|
|
|
|
|
|
|
|
netx_serial_init_port(cdev);
|
|
|
|
|
|
|
|
console_register(cdev);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct driver_d netx_serial_driver = {
|
|
|
|
.name = "netx_serial",
|
|
|
|
.probe = netx_serial_probe,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int netx_serial_init(void)
|
|
|
|
{
|
|
|
|
register_driver(&netx_serial_driver);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
console_initcall(netx_serial_init);
|
|
|
|
|