
Dear José Miguel Gonçalves,
Serial driver for the S3C24XX SoCs.
Signed-off-by: José Miguel Gonçalves jose.goncalves@inov.pt
drivers/serial/Makefile | 1 + drivers/serial/s3c24xx_serial.c | 146 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 drivers/serial/s3c24xx_serial.c
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 65d0f23..2cbdaac 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -52,6 +52,7 @@ COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o COBJS-$(CONFIG_PXA_SERIAL) += serial_pxa.o COBJS-$(CONFIG_SA1100_SERIAL) += serial_sa1100.o COBJS-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o +COBJS-$(CONFIG_S3C24XX_SERIAL) += s3c24xx_serial.o
What's the difference between those two drivers ?!
COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o diff --git a/drivers/serial/s3c24xx_serial.c b/drivers/serial/s3c24xx_serial.c new file mode 100644 index 0000000..11f13a5 --- /dev/null +++ b/drivers/serial/s3c24xx_serial.c @@ -0,0 +1,146 @@ +/*
- (C) Copyright 2012 INOV - INESC Inovacao
- Jose Goncalves jose.goncalves@inov.pt
- Based on drivers/serial/s3c64xx.c
- 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> +#include <asm/arch/s3c24xx_cpu.h>
+DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_SERIAL0 +#define UART_NR S3C24XX_UART0
+#elif defined(CONFIG_SERIAL1) +#define UART_NR S3C24XX_UART1
+#elif defined(CONFIG_SERIAL2) +#define UART_NR S3C24XX_UART2
+#elif defined(CONFIG_SERIAL3) +#define UART_NR S3C24XX_UART3
+#else +#error "Bad: you didn't configure serial ..."
Error itself is "Bad:" so remove it
+#endif
+#define barrier() asm volatile("" ::: "memory")
Is that even used ?
+/*
- The coefficient, used to calculate the baudrate on S3C24XX UARTs is
- calculated as C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT
- however, section 2.1.10 of the S3C2416 User's Manual doesn't recommend
- using 1 for 1, 3 for 2, ... (2^n - 1) for n, instead, they suggest
using + * these constants:
- */
+static const int udivslot[] = {
const int const ... const array const members
- 0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4A52, 0x54AA,
- 0x5555, 0xD555, 0xD5D5, 0xDDD5, 0xDDDD, 0xDFDD, 0xDFDF, 0xFFDF,
+};
+void serial_setbrg(void) +{
- s3c24xx_uart *const uart = s3c24xx_get_base_uart(UART_NR);
- u32 pclk;
- u32 baudrate;
- int i;
- pclk = get_PCLK();
- baudrate = gd->baudrate;
- uart->ubrdiv = (pclk / baudrate / 16) - 1;
- uart->udivslot = udivslot[(pclk / baudrate) % 16];
- for (i = 0; i < 100; i++)
barrier();
+}
+/*
- 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) +{
- s3c24xx_uart *const uart = s3c24xx_get_base_uart(UART_NR);
- /* FIFO enable, Tx/Rx FIFO clear */
- uart->ufcon = 0x07;
- uart->umcon = 0x00;
Magic numbers, fix
- /* Normal mode, No parity, 1 stop bit, 8 data bits */
- uart->ulcon = 0x03;
- /* Polling mode */
- uart->ucon = 0x005;
- serial_setbrg();
- return 0;
+}
+/*
- Read a single byte from the serial port.
- */
+int serial_getc(void) +{
- s3c24xx_uart *const uart = s3c24xx_get_base_uart(UART_NR);
- /* Wait for character to arrive */
- while (!(uart->utrstat & 0x1)) ;
- return uart->urxh & 0xff;
+}
+/*
- Output a single byte to the serial port.
- */
+void serial_putc(const char c) +{
- s3c24xx_uart *const uart = s3c24xx_get_base_uart(UART_NR);
- /* Wait for room in the TX FIFO */
- while (!(uart->utrstat & 0x2)) ;
- uart->utxh = c;
- /* If \n, also do \r */
- if (c == '\n')
serial_putc('\r');
+}
+/*
- Test whether a character is in the RX buffer.
- */
+int serial_tstc(void) +{
- s3c24xx_uart *const uart = s3c24xx_get_base_uart(UART_NR);
- return uart->utrstat & 0x1;
+}
+/*
- Output a string to the serial port.
- */
+void serial_puts(const char *s) +{
- while (*s)
serial_putc(*s++);
+}
Can you implement it as a serial multi (CONFIG_SERIAL_MULTI) right away ? thanks.
Best regards, Marek Vasut