diff options
Diffstat (limited to 'cpu/arm920t/s3c24x0/serial.c')
| -rw-r--r-- | cpu/arm920t/s3c24x0/serial.c | 164 | 
1 files changed, 143 insertions, 21 deletions
| diff --git a/cpu/arm920t/s3c24x0/serial.c b/cpu/arm920t/s3c24x0/serial.c index 36851ad5c..6e853b87a 100644 --- a/cpu/arm920t/s3c24x0/serial.c +++ b/cpu/arm920t/s3c24x0/serial.c @@ -48,18 +48,74 @@ DECLARE_GLOBAL_DATA_PTR;  #error "Bad: you didn't configure serial ..."  #endif -void serial_setbrg (void) +#if defined(CONFIG_SERIAL_MULTI) +#include <serial.h> + +/* Multi serial device functions */ +#define DECLARE_S3C_SERIAL_FUNCTIONS(port) \ +    int  s3serial##port##_init (void) {\ +	return serial_init_dev(port);}\ +    void s3serial##port##_setbrg (void) {\ +	serial_setbrg_dev(port);}\ +    int  s3serial##port##_getc (void) {\ +	return serial_getc_dev(port);}\ +    int  s3serial##port##_tstc (void) {\ +	return serial_tstc_dev(port);}\ +    void s3serial##port##_putc (const char c) {\ +	serial_putc_dev(port, c);}\ +    void s3serial##port##_puts (const char *s) {\ +	serial_puts_dev(port, s);} + +#define INIT_S3C_SERIAL_STRUCTURE(port,name,bus) {\ +	name,\ +	bus,\ +	s3serial##port##_init,\ +	s3serial##port##_setbrg,\ +	s3serial##port##_getc,\ +	s3serial##port##_tstc,\ +	s3serial##port##_putc,\ +	s3serial##port##_puts, } + +#endif /* CONFIG_SERIAL_MULTI */ + +void _serial_setbrg(const int dev_index)  { -	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); -	int i; +	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(dev_index);  	unsigned int reg = 0; +	int i;  	/* value is calculated so : (int)(PCLK/16./baudrate) -1 */  	reg = get_PCLK() / (16 * gd->baudrate) - 1; +	uart->UBRDIV = reg; +	for (i = 0; i < 100; i++); +} +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_setbrg_dev(unsigned int dev_index) +{ +	_serial_setbrg(dev_index); +} +#else +void serial_setbrg(void) +{ +	_serial_setbrg(UART_NR); +} +#endif + + +/* Initialise the serial port. The settings are always 8 data bits, no parity, + * 1 stop bit, no start bits. + */ +static int serial_init_dev(const int dev_index) +{ +	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(dev_index); +	int i; +  	/* FIFO enable, Tx/Rx FIFO clear */  	uart->UFCON = 0x07;  	uart->UMCON = 0x0; +  	/* Normal,No parity,1 stop,8 bit */  	uart->ULCON = 0x3;  	/* @@ -67,40 +123,57 @@ void serial_setbrg (void)  	 * normal,interrupt or polling  	 */  	uart->UCON = 0x245; -	uart->UBRDIV = reg;  #ifdef CONFIG_HWFLOW  	uart->UMCON = 0x1; /* RTS up */  #endif -	for (i = 0; i < 100; i++); + +	/* FIXME: This is sooooooooooooooooooo ugly */ +#if defined(CONFIG_ARCH_GTA02_v1) || defined(CONFIG_ARCH_GTA02_v2) +	/* we need auto hw flow control on the gsm and gps port */ +	if (dev_index == 0 || dev_index == 1) +		uart->UMCON = 0x10; +#endif +	_serial_setbrg(dev_index); + +	return (0);  } -/* - * Initialise the serial port with the given baudrate. The settings - * are always 8 data bits, no parity, 1 stop bit, no start bits. - * +#if !defined(CONFIG_SERIAL_MULTI) +/* Initialise the serial port. The settings are always 8 data bits, no parity, + * 1 stop bit, no start bits.   */  int serial_init (void)  { -	serial_setbrg (); - -	return (0); +	return serial_init_dev(UART_NR);  } +#endif  /*   * 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 _serial_getc (const int dev_index)  { -	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); +	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(dev_index);  	/* wait for character to arrive */  	while (!(uart->UTRSTAT & 0x1));  	return uart->URXH & 0xff;  } +#if defined(CONFIG_SERIAL_MULTI) +static inline int serial_getc_dev(unsigned int dev_index) +{ +	return _serial_getc(dev_index); +} +#else +int serial_getc (void) +{ +	return _serial_getc(UART_NR); +} +#endif  #ifdef CONFIG_HWFLOW  static int hwflow = 0; /* turned off by default */ @@ -138,9 +211,9 @@ void enable_putc(void)  /*   * Output a single byte to the serial port.   */ -void serial_putc (const char c) +void _serial_putc (const char c, const int dev_index)  { -	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); +	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(dev_index);  #ifdef CONFIG_MODEM_SUPPORT  	if (be_quiet)  		return; @@ -161,23 +234,72 @@ void serial_putc (const char c)  	if (c == '\n')  		serial_putc ('\r');  } +#if defined(CONFIG_SERIAL_MULTI) +static inline void serial_putc_dev(unsigned int dev_index, const char c) +{ +	_serial_putc(c, dev_index); +} +#else +void serial_putc(const char c) +{ +	_serial_putc(c, UART_NR); +} +#endif +  /*   * Test whether a character is in the RX buffer   */ -int serial_tstc (void) +int _serial_tstc(const int dev_index)  { -	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR); +	S3C24X0_UART * const uart = S3C24X0_GetBase_UART(dev_index);  	return uart->UTRSTAT & 0x1;  } +#if defined(CONFIG_SERIAL_MULTI) +static inline int +serial_tstc_dev(unsigned int dev_index) +{ +	return _serial_tstc(dev_index); +} +#else +int serial_tstc(void) +{ +	return _serial_tstc(UART_NR); +} +#endif -void -serial_puts (const char *s) +void _serial_puts(const char *s, const int dev_index)  {  	while (*s) { -		serial_putc (*s++); +		_serial_putc (*s++, dev_index);  	}  } +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_puts_dev(int dev_index, const char *s) +{ +	_serial_puts(s, dev_index); +} +#else +void +serial_puts (const char *s) +{ +	_serial_puts(s, UART_NR); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +DECLARE_S3C_SERIAL_FUNCTIONS(0); +struct serial_device s3c24xx_serial0_device = +	INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0", "S3UART1"); +DECLARE_S3C_SERIAL_FUNCTIONS(1); +struct serial_device s3c24xx_serial1_device = +	INIT_S3C_SERIAL_STRUCTURE(1, "s3ser1", "S3UART2"); +DECLARE_S3C_SERIAL_FUNCTIONS(2); +struct serial_device s3c24xx_serial2_device = +	INIT_S3C_SERIAL_STRUCTURE(2, "s3ser2", "S3UART3"); + +#endif /* CONFIG_SERIAL_MULTI */  #endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */ |