s3c2410xSio_.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:19k
- /* s3c2410xSio.c - Samsung s3c2410x UART tty driver */
- /* Copyright 2004 HITSAT, Inc. */
- #include "copyright_wrs.h"
- /*
- DESCRIPTION
- This is the device driver for the Advanced RISC Machines (ARM) s3c2410x
- UART. This is a generic design of UART used within a number of chips
- containing (or for use with) ARM CPUs such as in the Digital Semiconductor
- 21285 chip as used in the EBSA-285 BSP.
- This design contains a universal asynchronous receiver/transmitter, a
- baud-rate generator, and an InfraRed Data Association (IrDa) Serial
- InfraRed (SiR) protocol encoder. The Sir encoder is not supported by
- this driver. The UART contains two 16-entry deep FIFOs for receive and
- transmit: if a framing, overrun or parity error occurs during
- reception, the appropriate error bits are stored in the receive FIFO
- along with the received data. The FIFOs can be programmed to be one
- byte deep only, like a conventional UART with double buffering, but the
- only mode of operation supported is with the FIFOs enabled.
- The UART design does not support the modem control output signals: DTR,
- RI and RTS. Moreover, the implementation in the 21285 chip does not
- support the modem control inputs: DCD, CTS and DSR.
- The UART design can generate four interrupts: Rx, Tx, modem status
- change and a UART disabled interrupt (which is asserted when a start
- bit is detected on the receive line when the UART is disabled). The
- implementation in the 21285 chip has only two interrupts: Rx and Tx,
- but the Rx interrupt is a combination of the normal Rx interrupt status
- and the UART disabled interrupt status.
- Only asynchronous serial operation is supported by the UART which
- supports 5 to 8 bit bit word lengths with or without parity and with
- one or two stop bits. The only serial word format supported by the
- driver is 8 data bits, 1 stop bit, no parity, The default baud rate is
- determined by the BSP by filling in the s3c2410x_CHAN structure before
- calling s3c2410xDevInit().
- The exact baud rates supported by this driver will depend on the
- crystal fitted (and consequently the input clock to the baud-rate
- generator), but in general, baud rates from about 300 to about 115200
- are possible.
- In theory, any number of UART channels could be implemented within a
- chip. This driver has been designed to cope with an arbitrary number of
- channels, but at the time of writing, has only ever been tested with
- one channel.
- .SH DATA STRUCTURES
- An s3c2410x_CHAN data structure is used to describe each channel, this
- structure is described in h/drv/sio/s3c2410xSio.h.
- .SH CALLBACKS
- Servicing a "transmitter ready" interrupt involves making a callback to
- a higher level library in order to get a character to transmit. By
- default, this driver installs dummy callback routines which do nothing.
- A higher layer library that wants to use this driver (e.g. ttyDrv)
- will install its own callback routine using the SIO_INSTALL_CALLBACK
- ioctl command. Likewise, a receiver interrupt handler makes a callback
- to pass the character to the higher layer library.
-
- .SH MODES
- This driver supports both polled and interrupt modes.
- .SH USAGE
- The driver is typically only called by the BSP. The directly callable
- routines in this modules are s3c2410xDevInit(), s3c2410xIntTx() and
- s3c2410xIntRx().
- The BSP's sysHwInit() routine typically calls sysSerialHwInit(), which
- initialises the hardware-specific fields in the s3c2410x_CHAN structure
- (e.g. register I/O addresses etc) before calling s3c2410xDevInit() which
- resets the device and installs the driver function pointers. After
- this the UART will be enabled and ready to generate interrupts, but
- those interrupts will be disabled in the interrupt controller.
- The following example shows the first parts of the initialisation:
- .CS
- #include "s3c2410xSio.h"
- LOCAL s3c2410x_CHAN s3c2410xChan[N_s3c2410x_UART_CHANS];
- void sysSerialHwInit (void)
- {
- int i;
- for (i = 0; i < N_s3c2410x_UART_CHANS; i++)
- {
- s3c2410xChan[i].regs = devParas[i].baseAdrs;
- s3c2410xChan[i].baudRate = CONSOLE_BAUD_RATE;
- s3c2410xChan[i].xtal = UART_XTAL_FREQ;
- s3c2410xChan[i].levelRx = devParas[i].intLevelRx;
- s3c2410xChan[i].levelTx = devParas[i].intLevelTx;
- /@
- * Initialise driver functions, getTxChar, putRcvChar and
- * channelMode, then initialise UART
- @/
- s3c2410xDevInit(&s3c2410xChan[i]);
- }
- }
- .CE
- The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(),
- which connects the chips interrupts via intConnect() (the two
- interrupts `s3c2410xIntTx' and `s3c2410xIntRx') and enables those interrupts,
- as shown in the following example:
- .CS
- void sysSerialHwInit2 (void)
- {
- /@ connect and enable Rx interrupt @/
- (void) intConnect (INUM_TO_IVEC(devParas[0].vectorRx),
- s3c2410xIntRx, (int) &s3c2410xChan[0]);
- intEnable (devParas[0].intLevelRx);
- /@ connect Tx interrupt @/
- (void) intConnect (INUM_TO_IVEC(devParas[0].vectorTx),
- s3c2410xIntTx, (int) &s3c2410xChan[0]);
- /@
- * There is no point in enabling the Tx interrupt, as it will
- * interrupt immediately and then be disabled.
- @/
- }
- .CE
- .SH BSP
- By convention all the BSP-specific serial initialisation is performed
- in a file called sysSerial.c, which is #include'ed by sysLib.c.
- sysSerial.c implements at least four functions, sysSerialHwInit()
- sysSerialHwInit2(), sysSerialChanGet(), and sysSerialReset(). The first
- two have been described above, the others work as follows:
- sysSerialChanGet is called by usrRoot to get the serial channel
- descriptor associated with a serial channel number. The routine takes a
- single parameter which is a channel number ranging between zero and
- NUM_TTY. It returns a pointer to the corresponding channel descriptor,
- SIO_CHAN *, which is just the address of the s3c2410x_CHAN structure.
-
- sysSerialReset is called from sysToMonitor() and should reset the
- serial devices to an inactive state (prevent them from generating any
- interrupts).
- .SH INCLUDE FILES:
- drv/sio/s3c2410xSio.h sioLib.h
- .SH SEE ALSO:
- .I "Advanced RISC Machines s3c2410x UART (AP13) Data Sheet,"
- .I "Digital Semiconductor 21285 Core Logic for SA-110 Microprocessor Data
- Sheet,"
- .I "Digital Semiconductor EBSA-285 Evaluation Board Reference Manual."
- */
- #include "vxWorks.h"
- #include "intLib.h"
- #include "errnoLib.h"
- #include "errno.h"
- #include "sioLib.h"
- #include "s3c2410xSio.h"
- /* local defines */
- #define s3c2410x_BAUD_MIN 18
- #define s3c2410x_BAUD_MAX 1152000
- #define s3c2410x_SIO_DEFAULT_BAUD 1152000
- #ifndef s3c2410x_UART_REG
- #define s3c2410x_UART_REG(pChan, reg)
- (*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg)))
- #endif
- #ifndef s3c2410x_UART_REG_READ
- #define s3c2410x_UART_REG_READ(pChan, reg, result)
- (result) = (s3c2410x_UART_REG(pChan, reg))
- #endif
- #ifndef s3c2410x_UART_REG_WRITE
- #define s3c2410x_UART_REG_WRITE(pChan, reg, data)
- (s3c2410x_UART_REG(pChan, reg)) = (data)
- #endif
- #ifndef s3c2410x_UART_REG_BIT_SET
- #define s3c2410x_UART_REG_BIT_SET(pChan, reg, data)
- (s3c2410x_UART_REG(pChan, reg)) |= (data)
- #endif
- #ifndef s3c2410x_UART_REG_BIT_CLR
- #define s3c2410x_UART_REG_BIT_CLR(pChan, reg, data)
- (s3c2410x_UART_REG(pChan, reg)) &= ~(data)
- #endif
- /* hardware access methods */
- #ifndef s3c2410x_INT_REG_READ
- #define s3c2410x_INT_REG_READ(reg,result)
- ((result) = *(volatile UINT32 *)(reg))
- #endif
- #ifndef s3c2410x_INT_REG_WRITE
- #define s3c2410x_INT_REG_WRITE(reg,data)
- (*((volatile UINT32 *)(reg)) = (data))
- #endif
- /* locals */
- /* function prototypes */
- LOCAL STATUS s3c2410xIoctl (SIO_CHAN * pSioChan, int request, int arg);
- LOCAL int s3c2410xTxStartup (SIO_CHAN * pSioChan);
- LOCAL int s3c2410xCallbackInstall (SIO_CHAN * pSioChan, int callbackType,
- STATUS (*callback)(), void * callbackArg);
- LOCAL int s3c2410xPollInput (SIO_CHAN * pSioChan, char *);
- LOCAL int s3c2410xPollOutput (SIO_CHAN * pSioChan, char);
- LOCAL STATUS s3c2410xDummyCallback (void);
- /* driver functions */
- LOCAL SIO_DRV_FUNCS s3c2410xSioDrvFuncs =
- {
- (int (*)())s3c2410xIoctl,
- s3c2410xTxStartup,
- (int (*)())s3c2410xCallbackInstall,
- s3c2410xPollInput,
- s3c2410xPollOutput
- };
- /*
- * s3c2410xDummyCallback - dummy callback routine.
- *
- * RETURNS: ERROR, always.
- */
- LOCAL STATUS s3c2410xDummyCallback (void)
- {
- return ERROR;
- }
- /*
- * s3c2410xInitChannel - initialise UART
- *
- * This routine performs hardware initialisation of the UART channel.
- *
- * RETURNS: N/A
- */
- LOCAL void s3c2410xInitChannel
- (
- s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
- )
- {
- UINT32 tempUINT32;
- /* Set UCLK, polling&interrupt mode. */
- s3c2410x_UART_REG_WRITE(pChan, OFFSET_UCON, CLK_PCLK+TxMode_IntPoll+RxMode_IntPoll);
- /* enable subInterrupt for UART0. */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
- break;
- case UART_0_BASE_ADR:
- default:
- tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
- }
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- /* Set baud rate to 9600. */
- s3c2410xIoctl((SIO_CHAN *)pChan, SIO_BAUD_SET, s3c2410x_SIO_DEFAULT_BAUD);
- /* Set NonInfra-red mode, 8, N, 1. */
- s3c2410xIoctl((SIO_CHAN *)pChan, SIO_HW_OPTS_SET, CLOCAL+CS8);
- s3c2410xIoctl((SIO_CHAN *)pChan, SIO_MODE_SET, SIO_MODE_POLL);
- /* Set disable FIFO */
- s3c2410x_UART_REG_WRITE(pChan, OFFSET_UFCON, FIFO_OFF);
- /* Enable pin for UART */
- s3c2410x_IO_READ(rGPHCON, tempUINT32);
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- tempUINT32 |= (MASK_GPH4(2)+MASK_GPH5(2)+MASK_GPH6(3)+MASK_GPH7(3)); /* +MASK_GPH8(2)); */
- break;
- case UART_0_BASE_ADR:
- default:
- tempUINT32 |= (MASK_GPH0(2)+MASK_GPH1(2)+MASK_GPH2(2)+MASK_GPH3(2)); /* +MASK_GPH8(2)); */
- }
- s3c2410x_IO_WRITE(rGPHCON,tempUINT32);
-
- /* Clear Rx */
- s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, tempUINT32);
- }
- /*
- * s3c2410xSioDevInit - initialise an s3c2410x channel
- *
- * This routine initialises some SIO_CHAN function pointers and then resets
- * the chip to a quiescent state. Before this routine is called, the BSP
- * must already have initialised all the device addresses, etc. in the
- * s3c2410x_CHAN structure.
- *
- * RETURNS: N/A
- */
- void s3c2410xSioDevInit
- (
- s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
- )
- {
- int oldlevel = intLock();
- /* initialise the driver function pointers in the SIO_CHAN */
- pChan->sio.pDrvFuncs = &s3c2410xSioDrvFuncs;
- /* set the non BSP-specific constants */
- pChan->getTxChar = s3c2410xDummyCallback;
- pChan->putRcvChar = s3c2410xDummyCallback;
- pChan->channelMode = 0; /* undefined */
- /* initialise the chip */
- s3c2410xInitChannel(pChan);
- intUnlock(oldlevel);
- }
- /*
- * s3c2410xIoctl - special device control
- *
- * This routine handles the IOCTL messages from the user.
- *
- * RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed
- * request.
- */
- LOCAL int s3c2410xIoctl
- (
- SIO_CHAN* pSioChan, /* device to control */
- int request, /* request code */
- int arg
- )
- {
- s3c2410x_CHAN *pChan = (s3c2410x_CHAN*) pSioChan;
- int oldlevel; /* current interrupt level mask */
- UINT32 tempUINT32 = 0;
- int lvl;
-
- switch (request)
- {
- case SIO_BAUD_SET:
- if(arg < s3c2410x_BAUD_MIN || arg > s3c2410x_BAUD_MAX) return(EIO);
-
- /* disable interrupts during chip access */
- oldlevel = intLock ();
- s3c2410x_UART_REG_WRITE(pChan,OFFSET_UDIV,(((s3c2410x_PCLK/16)/arg)-1));
- intUnlock (oldlevel);
- s3c2410x_UART_REG_READ(pChan,OFFSET_UDIV,tempUINT32);
- pChan->baudRate=((s3c2410x_PCLK/16)/(tempUINT32+1));
- break;
- case SIO_BAUD_GET:
- *(int *)arg = pChan->baudRate;
- break;
- case SIO_MODE_SET:
- switch(arg)
- {
- case SIO_MODE_INT:
- /* clear subpend-flag of RX_TX */
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD1)|(1<<SUBINT_LVL_RXD1)));
- break;
- case UART_0_BASE_ADR:
- default:
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_RXD0)));
- }
-
- /* enable uart_int */
- intEnable(pChan->intLevelRx);
- /* enable subInterrupt for UART0. */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
- break;
- case UART_0_BASE_ADR:
- default:
- tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
- }
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- break;
- case SIO_MODE_POLL:
- /* disable uart_int */
- intDisable(pChan->intLevelRx);
- /* disable subInterrupt for UART0. */
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- tempUINT32 |= ((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
- break;
- case UART_0_BASE_ADR:
- default:
- tempUINT32 |= ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
- }
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
- break;
- default: return(EIO);
- }
- pChan->channelMode = arg;
- break;
- case SIO_MODE_GET:
- *(int *)arg = pChan->channelMode;
- break;
- case SIO_AVAIL_MODES_GET:
- /* Get the available modes and return OK. */
- *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
- break;
- case SIO_HW_OPTS_SET:
- if(arg & 0xffffff00) return EIO;
-
- /* do nothing if options already set */
- if(pChan->options == arg) break;
- switch (arg & CSIZE)
- {
- case CS5:
- tempUINT32 = DATABIT_5; break;
- case CS6:
- tempUINT32 = DATABIT_6; break;
- case CS7:
- tempUINT32 = DATABIT_7; break;
- default:
- case CS8:
- tempUINT32 = DATABIT_8; break;
- }
- if (arg & STOPB)
- {
- tempUINT32 |= TWO_STOPBIT;
- }
- else
- {
- /* tempUINT32 &= ~TWO_STOPBIT */;
- }
-
-
- switch (arg & (PARENB|PARODD))
- {
- case PARENB|PARODD:
- tempUINT32 += ODD_PARITY;
- break;
- case PARENB:
- tempUINT32 += EVEN_PARITY;
- break;
- case 0:
- default:
- ;/* no parity */
- }
- lvl = intLock();
- s3c2410x_UART_REG_WRITE(pChan,OFFSET_ULCON,tempUINT32);
- intUnlock(lvl);
- if (arg & CLOCAL)
- {
- /* clocal disables hardware flow control */
- lvl = intLock();
- s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_OFF);
- intUnlock(lvl);
- }
- else
- {
- lvl = intLock();
- s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_ON);
- intUnlock(lvl);
- }
- pChan->options = arg;
- break;
- case SIO_HW_OPTS_GET:
- *(int*)arg = pChan->options;
- return (OK);
- case SIO_HUP:
- /* check if hupcl option is enabled */
- break;
- case SIO_OPEN:
- break; /* always open */
- default:
- return (ENOSYS);
- }
- return (OK);
- }
- /*
- * s3c2410xSioIntTx - handle a transmitter interrupt
- *
- * This routine handles write interrupts from the UART.
- *
- * RETURNS: N/A
- */
- void s3c2410xSioIntTx
- (
- s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
- )
- {
- char outChar;
- /* clear subpending of the TXn */
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD1));
- break;
- case UART_0_BASE_ADR:
- default:
- s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD0));
- }
-
- if((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
- {
- /* write char. to Transmit Holding Reg. */
- s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, (((UINT32)outChar)&0x000000ff));
- }
- }
- /*
- * s3c2410xSioIntRx - handle a receiver interrupt
- *
- * This routine handles read interrupts from the UART.
- *
- * RETURNS: N/A
- */
- void s3c2410xSioIntRx
- (
- s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
- )
- {
- char inchar;
- /* clear subpending of the RXn */
- switch((int)(pChan->regs))
- {
- case UART_1_BASE_ADR:
- s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD1));
- break;
- case UART_0_BASE_ADR:
- default:
- s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD0));
- }
-
- /* read character from Receive Holding Reg. */
- s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, inchar);
- (*pChan->putRcvChar) (pChan->putRcvArg, inchar);
- }
- /*
- * s3c2410xSioInt - handle any UART interrupt
- *
- * This routine handles interrupts from the UART and determines whether
- * the source is a transmit interrupt or receive/receive-timeout interrupt.
- *
- * The Prime Cell UART generates a receive interrupt when the RX FIFO is
- * half-full, and a receive-timeout interrupt after 32 bit-clocks have
- * elapsed with no incoming data.
- *
- * RETURNS: N/A
- */
- void s3c2410xSioInt
- (
- s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
- )
- {
- UINT32 intId;
- s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND, intId);
- if(intId & ((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_TXD1)))
- {
- s3c2410xSioIntTx(pChan);
-
- }
- if(intId & ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_RXD1)))
- {
- s3c2410xSioIntRx (pChan);
- }
- s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0);
- /* clear pend and enable this level */
- /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<(pChan->intLevelRx)));
- s3c2410xIntLvlEnable(pChan->intLevelRx);
- */
- }
- /*
- * s3c2410xTxStartup - transmitter startup routine
- *
- * Enable interrupt so that interrupt-level char output routine will be called.
- *
- * RETURNS: OK on success, ENOSYS if the device is polled-only, or
- * EIO on hardware error.
- */
- LOCAL int s3c2410xTxStartup
- (
- SIO_CHAN * pSioChan /* ptr to SIO_CHAN describing this channel */
- )
- {
- s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
- if(pChan->channelMode == SIO_MODE_INT)
- {
- intEnable(pChan->intLevelTx);
- s3c2410xSioIntTx(pChan);
- return OK;
- }
- else
- {
- return ENOSYS;
- }
- }
- /*
- * s3c2410xPollOutput - output a character in polled mode.
- *
- * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
- * if the output buffer is full, ENOSYS if the device is interrupt-only.
- */
- LOCAL int s3c2410xPollOutput
- (
- SIO_CHAN* pSioChan, /* ptr to SIO_CHAN describing this channel */
- char outChar /* to output */
- )
- {
- s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
- FAST UINT32 pollStatus;
- s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);
- /* is the transmitter ready to accept a character? */
- if(!(pollStatus & UTRSTAT_TRNSR_EM))
- {
- return EAGAIN;
- }
- /* write out the character */
- s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, outChar); /* transmit character */
- return OK;
- }
- /*
- * s3c2410xPollInput - poll the device for input.
- *
- * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
- * if the input buffer is empty, ENOSYS if the device is interrupt-only.
- */
- LOCAL int s3c2410xPollInput
- (
- SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
- char* thisChar /* pointer to where to return character */
- )
- {
- s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
- FAST UINT32 pollStatus;
- s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);
- if(!(pollStatus & UTRSTAT_RB_RDY))
- {
- return EAGAIN;
- }
- /* got a character */
- s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, *thisChar);
- return OK;
- }
- /*
- * s3c2410xCallbackInstall - install ISR callbacks to get/put chars.
- *
- * This routine installs interrupt callbacks for transmitting characters
- * and receiving characters.
- *
- * RETURNS: OK on success, or ENOSYS for an unsupported callback type.
- *
- */
- LOCAL int s3c2410xCallbackInstall
- (
- SIO_CHAN* pSioChan, /* ptr to SIO_CHAN describing this channel */
- int callbackType, /* type of callback */
- STATUS (*callback)(), /* callback */
- void* callbackArg /* parameter to callback */
- )
- {
- s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
- switch(callbackType)
- {
- case SIO_CALLBACK_GET_TX_CHAR:
- pChan->getTxChar = callback;
- pChan->getTxArg = callbackArg;
- return OK;
- case SIO_CALLBACK_PUT_RCV_CHAR:
- pChan->putRcvChar = callback;
- pChan->putRcvArg = callbackArg;
- return OK;
- default:
- return ENOSYS;
- }
- }