diff options
Diffstat (limited to 'drivers/serial/serial_xuartlite.c')
| -rw-r--r-- | drivers/serial/serial_xuartlite.c | 140 | 
1 files changed, 121 insertions, 19 deletions
| diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c index 00d0eaac7..2dc6bd1bc 100644 --- a/drivers/serial/serial_xuartlite.c +++ b/drivers/serial/serial_xuartlite.c @@ -1,5 +1,5 @@  /* - * (C) Copyright 2008 Michal Simek <monstr@monstr.eu> + * (C) Copyright 2008-2011 Michal Simek <monstr@monstr.eu>   * Clean driver and add xilinx constant from header file   *   * (C) Copyright 2004 Atmark Techno, Inc. @@ -25,20 +25,71 @@   */  #include <config.h> +#include <common.h>  #include <asm/io.h> - -#define RX_FIFO_OFFSET		0 /* receive FIFO, read only */ -#define TX_FIFO_OFFSET		4 /* transmit FIFO, write only */ -#define STATUS_REG_OFFSET	8 /* status register, read only */ +#include <linux/compiler.h> +#include <serial.h>  #define SR_TX_FIFO_FULL		0x08 /* transmit FIFO full */  #define SR_RX_FIFO_VALID_DATA	0x01 /* data in receive FIFO */  #define SR_RX_FIFO_FULL		0x02 /* receive FIFO full */ -#define UARTLITE_STATUS		(CONFIG_SERIAL_BASE + STATUS_REG_OFFSET) -#define UARTLITE_TX_FIFO	(CONFIG_SERIAL_BASE + TX_FIFO_OFFSET) -#define UARTLITE_RX_FIFO	(CONFIG_SERIAL_BASE + RX_FIFO_OFFSET) +struct uartlite { +	unsigned int rx_fifo; +	unsigned int tx_fifo; +	unsigned int status; +}; + +static const struct uartlite *userial_ports[4] = { +#ifdef XILINX_UARTLITE_BASEADDR +	[0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR, +#endif +#ifdef XILINX_UARTLITE_BASEADDR1 +	[1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1, +#endif +#ifdef XILINX_UARTLITE_BASEADDR2 +	[2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2, +#endif +#ifdef XILINX_UARTLITE_BASEADDR3 +	[3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3 +#endif +}; + +void uartlite_serial_putc(const char c, const int port) +{ +	struct uartlite *regs = userial_ports[port]; + +	if (c == '\n') +		uartlite_serial_putc('\r', port); + +	while (in_be32(®s->status) & SR_TX_FIFO_FULL) +		; +	out_be32(®s->tx_fifo, c & 0xff); +} + +void uartlite_serial_puts(const char *s, const int port) +{ +	while (*s) +		uartlite_serial_putc(*s++, port); +} + +int uartlite_serial_getc(const int port) +{ +	struct uartlite *regs = userial_ports[port]; + +	while (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) +		; +	return in_be32(®s->rx_fifo) & 0xff; +} + +int uartlite_serial_tstc(const int port) +{ +	struct uartlite *regs = userial_ports[port]; +	return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; +} + +#if !defined(CONFIG_SERIAL_MULTI)  int serial_init(void)  {  	/* FIXME: Nothing for now. We should initialize fifo, etc */ @@ -52,26 +103,77 @@ void serial_setbrg(void)  void serial_putc(const char c)  { -	if (c == '\n') -		serial_putc('\r'); -	while (in_be32((u32 *) UARTLITE_STATUS) & SR_TX_FIFO_FULL); -	out_be32((u32 *) UARTLITE_TX_FIFO, (unsigned char) (c & 0xff)); +	uartlite_serial_putc(c, 0);  } -void serial_puts(const char * s) +void serial_puts(const char *s)  { -	while (*s) { -		serial_putc(*s++); -	} +	uartlite_serial_puts(s, 0);  }  int serial_getc(void)  { -	while (!(in_be32((u32 *) UARTLITE_STATUS) & SR_RX_FIFO_VALID_DATA)); -	return in_be32((u32 *) UARTLITE_RX_FIFO) & 0xff; +	return uartlite_serial_getc(0);  }  int serial_tstc(void)  { -	return (in_be32((u32 *) UARTLITE_STATUS) & SR_RX_FIFO_VALID_DATA); +	return uartlite_serial_tstc(0); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +/* Multi serial device functions */ +#define DECLARE_ESERIAL_FUNCTIONS(port) \ +	int userial##port##_init(void) \ +				{ return(0); } \ +	void userial##port##_setbrg(void) {} \ +	int userial##port##_getc(void) \ +				{ return uartlite_serial_getc(port); } \ +	int userial##port##_tstc(void) \ +				{ return uartlite_serial_tstc(port); } \ +	void userial##port##_putc(const char c) \ +				{ uartlite_serial_putc(c, port); } \ +	void userial##port##_puts(const char *s) \ +				{ uartlite_serial_puts(s, port); } + +/* Serial device descriptor */ +#define INIT_ESERIAL_STRUCTURE(port, name) {\ +	name,\ +	userial##port##_init,\ +	NULL,\ +	userial##port##_setbrg,\ +	userial##port##_getc,\ +	userial##port##_tstc,\ +	userial##port##_putc,\ +	userial##port##_puts, } + +DECLARE_ESERIAL_FUNCTIONS(0); +struct serial_device uartlite_serial0_device = +	INIT_ESERIAL_STRUCTURE(0, "ttyUL0"); +DECLARE_ESERIAL_FUNCTIONS(1); +struct serial_device uartlite_serial1_device = +	INIT_ESERIAL_STRUCTURE(1, "ttyUL1"); +DECLARE_ESERIAL_FUNCTIONS(2); +struct serial_device uartlite_serial2_device = +	INIT_ESERIAL_STRUCTURE(2, "ttyUL2"); +DECLARE_ESERIAL_FUNCTIONS(3); +struct serial_device uartlite_serial3_device = +	INIT_ESERIAL_STRUCTURE(3, "ttyUL3"); + +__weak struct serial_device *default_serial_console(void) +{ +# ifdef XILINX_UARTLITE_BASEADDR +	return &uartlite_serial0_device; +# endif /* XILINX_UARTLITE_BASEADDR */ +# ifdef XILINX_UARTLITE_BASEADDR1 +	return &uartlite_serial1_device; +# endif /* XILINX_UARTLITE_BASEADDR1 */ +# ifdef XILINX_UARTLITE_BASEADDR2 +	return &uartlite_serial2_device; +# endif /* XILINX_UARTLITE_BASEADDR2 */ +# ifdef XILINX_UARTLITE_BASEADDR3 +	return &uartlite_serial3_device; +# endif /* XILINX_UARTLITE_BASEADDR3 */  } +#endif /* CONFIG_SERIAL_MULTI */ |