Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:05

0001 /*
0002  *  console driver for S3C2400 UARTs
0003  *
0004  *  This driver uses the shared console driver in
0005  *  ...../libbsp/shared/console.c
0006  *
0007  *  If you want the driver to be interrupt driven, you
0008  *  need to write the ISR, and in the ISR insert the
0009  *  chars into termios's queue.
0010  *
0011  *  Copyright (c) 2004 Cogent Computer Systems
0012  *  Written by Jay Monkman <jtm@lopingdog.com>
0013  *
0014  *  The license and distribution terms for this file may be
0015  *  found in the file LICENSE in this distribution or at
0016  *  http://www.rtems.org/license/LICENSE.
0017 */
0018 #include <bsp.h>                /* Must be before libio.h */
0019 #include <rtems/libio.h>
0020 #include <termios.h>
0021 #include <rtems/bspIo.h>
0022 
0023 /* Put the CPU (or UART) specific header file #include here */
0024 #include <s3c24xx.h>
0025 #include <libchip/serial.h>
0026 #include <libchip/sersupp.h>
0027 
0028 /* How many serial ports? */
0029 #define NUM_DEVS       1
0030 
0031 int     uart_poll_read(int minor);
0032 
0033 int dbg_dly;
0034 
0035 /* static function prototypes */
0036 static int     uart_first_open(int major, int minor, void *arg);
0037 static int     uart_last_close(int major, int minor, void *arg);
0038 static int     uart_read(int minor);
0039 static ssize_t uart_write(int minor, const char *buf, size_t len);
0040 static void    uart_init(int minor);
0041 static void    uart_write_polled(int minor, char c);
0042 static int     uart_set_attributes(int minor, const struct termios *t);
0043 
0044 /* These are used by code in console.c */
0045 unsigned long Console_Configuration_Count = NUM_DEVS;
0046 
0047 /* Pointers to functions for handling the UART. */
0048 const console_fns uart_fns =
0049 {
0050     libchip_serial_default_probe,
0051     uart_first_open,
0052     uart_last_close,
0053     uart_read,
0054     uart_write,
0055     uart_init,
0056     uart_write_polled,   /* not used in this driver */
0057     uart_set_attributes,
0058     FALSE      /* TRUE if interrupt driven, FALSE if not. */
0059 };
0060 
0061 /*
0062  * There's one item in array for each UART.
0063  *
0064  * Some of these fields are marked "NOT USED". They are not used
0065  * by console.c, but may be used by drivers in libchip
0066  *
0067  */
0068 console_tbl Console_Configuration_Ports[] = {
0069     {
0070         "/dev/com0",                      /* sDeviceName */
0071         SERIAL_CUSTOM,                    /* deviceType */
0072         &uart_fns,                        /* pDeviceFns */
0073         NULL,                             /* deviceProbe */
0074         NULL,                             /* pDeviceFlow */
0075         0,                                /* ulMargin - NOT USED */
0076         0,                                /* ulHysteresis - NOT USED */
0077         NULL,                             /* pDeviceParams */
0078         0,                                /* ulCtrlPort1  - NOT USED */
0079         0,                                /* ulCtrlPort2  - NOT USED */
0080         0,                                /* ulDataPort  - NOT USED */
0081         NULL,                             /* getRegister - NOT USED */
0082         NULL,                             /* setRegister - NOT USED */
0083         NULL,                             /* getData - NOT USED */
0084         NULL,                             /* setData - NOT USED */
0085         0,                                /* ulClock - NOT USED */
0086         0                                 /* ulIntVector - NOT USED */
0087     }
0088 };
0089 
0090 /*********************************************************************/
0091 /* Functions called via termios callbacks (i.e. the ones in uart_fns */
0092 /*********************************************************************/
0093 
0094 /*
0095  * This is called the first time each device is opened. If the driver
0096  * is interrupt driven, you should enable interrupts here. Otherwise,
0097  * it's probably safe to do nothing.
0098  *
0099  * Since micromonitor already set up the UART, we do nothing.
0100  */
0101 static int uart_first_open(int major, int minor, void *arg)
0102 {
0103     return 0;
0104 }
0105 
0106 
0107 /*
0108  * This is called the last time each device is closed. If the driver
0109  * is interrupt driven, you should disable interrupts here. Otherwise,
0110  * it's probably safe to do nothing.
0111  */
0112 static int uart_last_close(int major, int minor, void *arg)
0113 {
0114     return 0;
0115 }
0116 
0117 
0118 /*
0119  * Read one character from UART.
0120  *
0121  * Return -1 if there's no data, otherwise return
0122  * the character in lowest 8 bits of returned int.
0123  */
0124 static int uart_read(int minor)
0125 {
0126     char c;
0127 
0128     if (minor == 0) {
0129         if (rUTRSTAT0 & 0x1) {
0130             c = rURXH0 & 0xff;
0131             return c;
0132         } else {
0133             return -1;
0134         }
0135     } else {
0136         printk("Unknown console minor number: %d\n", minor);
0137         return -1;
0138     }
0139 
0140 }
0141 
0142 
0143 /*
0144  * Write buffer to UART
0145  *
0146  * return 1 on success, -1 on error
0147  */
0148 static ssize_t uart_write(int minor, const char *buf, size_t len)
0149 {
0150     int i;
0151 
0152     if (minor == 0) {
0153         for (i = 0; i < len; i++) {
0154             /* Wait for fifo to have room */
0155             while(!(rUTRSTAT0 & 0x2)) {
0156                 continue;
0157             }
0158 
0159            rUTXH0 = (char) buf[i];
0160         }
0161     } else {
0162         printk("Unknown console minor number: %d\n", minor);
0163         return -1;
0164     }
0165 
0166     return 1;
0167 }
0168 
0169 
0170 /* Set up the UART. */
0171 static void uart_init(int minor)
0172 {
0173     int i;
0174     unsigned int reg = 0;
0175 
0176     /* enable UART0 */
0177     rCLKCON|=0x100;
0178 
0179     /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
0180     reg = get_PCLK() / (16 * 115200) - 1;
0181 
0182     /* FIFO enable, Tx/Rx FIFO clear */
0183     rUFCON0 = 0x07;
0184     rUMCON0 = 0x0;
0185     /* Normal,No parity,1 stop,8 bit */
0186     rULCON0 = 0x3;
0187     /*
0188      * tx=level,rx=edge,disable timeout int.,enable rx error int.,
0189      * normal,interrupt or polling
0190      */
0191     rUCON0 = 0x245;
0192     rUBRDIV0 = reg;
0193 
0194     for (i = 0; i < 100; i++);
0195 
0196 }
0197 
0198 /* I'm not sure this is needed for the shared console driver. */
0199 static void    uart_write_polled(int minor, char c)
0200 {
0201     uart_write(minor, &c, 1);
0202 }
0203 
0204 /* This is for setting baud rate, bits, etc. */
0205 static int     uart_set_attributes(int minor, const struct termios *t)
0206 {
0207     return 0;
0208 }
0209 
0210 /***********************************************************************/
0211 /*
0212  * The following functions are not used by TERMIOS, but other RTEMS
0213  * functions use them instead.
0214  */
0215 /***********************************************************************/
0216 /*
0217  * Read from UART. This is used in the exit code, and can't
0218  * rely on interrupts.
0219 */
0220 int uart_poll_read(int minor)
0221 {
0222     return uart_read(minor);
0223 }
0224 
0225 
0226 /*
0227  * Write a character to the console. This is used by printk() and
0228  * maybe other low level functions. It should not use interrupts or any
0229  * RTEMS system calls. It needs to be very simple
0230  */
0231 static void _BSP_put_char( char c ) {
0232     uart_write_polled(0, c);
0233 }
0234 
0235 BSP_output_char_function_type BSP_output_char = _BSP_put_char;
0236 
0237 static int _BSP_get_char(void)
0238 {
0239   return uart_poll_read(0);
0240 }
0241 
0242 BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;