[U-Boot-Users] [PATCH] ARM: s3c24xx: Multiple serial port support

Harald Welte laforge at openmoko.org
Wed Dec 19 14:24:40 CET 2007


This patch adds support for CONFIG_SERIAL_MULTI on s3c24x0 CPU's

Signed-off-by: Harald Welte <laforge at openmoko.org>

Index: u-boot/common/serial.c
===================================================================
--- u-boot.orig/common/serial.c
+++ u-boot/common/serial.c
@@ -59,6 +59,16 @@
 #else
 		return &serial0_device;
 #endif
+#elif defined(CONFIG_S3C2410)
+#if defined(CONFIG_SERIAL1)
+	return &s3c24xx_serial0_device;
+#elif defined(CONFIG_SERIAL2)
+	return &s3c24xx_serial1_device;
+#elif defined(CONFIG_SERIAL3)
+	return &s3c24xx_serial2_device;
+#else
+#error "CONFIG_SERIAL? missing."
+#endif
 #else
 #error No default console
 #endif
@@ -119,6 +129,11 @@
 #if defined (CONFIG_STUART)
 	serial_register(&serial_stuart_device);
 #endif
+#if defined(CONFIG_S3C2410)
+	serial_register(&s3c24xx_serial0_device);
+	serial_register(&s3c24xx_serial1_device);
+	serial_register(&s3c24xx_serial2_device);
+#endif
 	serial_assign (default_serial_console ()->name);
 }
 
Index: u-boot/cpu/arm920t/s3c24x0/serial.c
===================================================================
--- u-boot.orig/cpu/arm920t/s3c24x0/serial.c
+++ u-boot/cpu/arm920t/s3c24x0/serial.c
@@ -48,18 +48,74 @@
 #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 @@
 	 * 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 @@
 /*
  * 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 @@
 	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) */
Index: u-boot/include/serial.h
===================================================================
--- u-boot.orig/include/serial.h
+++ u-boot/include/serial.h
@@ -35,6 +35,11 @@
 
 #endif
 
+#if defined(CONFIG_S3C2410)
+extern struct serial_device s3c24xx_serial0_device;
+extern struct serial_device s3c24xx_serial1_device;
+extern struct serial_device s3c24xx_serial2_device;
+#endif
 
 extern struct serial_device serial_ffuart_device;
 extern struct serial_device serial_btuart_device;
-- 
- Harald Welte <laforge at openmoko.org>          	        http://openmoko.org/
============================================================================
Software for the world's first truly open Free Software mobile phone




More information about the U-Boot mailing list