s3c2410xSio_.c
上传用户:ske666
上传日期:2022-03-30
资源大小:371k
文件大小:19k
源码类别:

VxWorks

开发平台:

Objective-C

  1. /* s3c2410xSio.c - Samsung s3c2410x UART tty driver */
  2. /* Copyright 2004 HITSAT, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. DESCRIPTION
  6. This is the device driver for the Advanced RISC Machines (ARM) s3c2410x
  7. UART. This is a generic design of UART used within a number of chips
  8. containing (or for use with) ARM CPUs such as in the Digital Semiconductor
  9. 21285 chip as used in the EBSA-285 BSP.
  10. This design contains a universal asynchronous receiver/transmitter, a
  11. baud-rate generator, and an InfraRed Data Association (IrDa) Serial
  12. InfraRed (SiR) protocol encoder. The Sir encoder is not supported by
  13. this driver. The UART contains two 16-entry deep FIFOs for receive and
  14. transmit: if a framing, overrun or parity error occurs during
  15. reception, the appropriate error bits are stored in the receive FIFO
  16. along with the received data. The FIFOs can be programmed to be one
  17. byte deep only, like a conventional UART with double buffering, but the
  18. only mode of operation supported is with the FIFOs enabled.
  19. The UART design does not support the modem control output signals: DTR,
  20. RI and RTS. Moreover, the implementation in the 21285 chip does not
  21. support the modem control inputs: DCD, CTS and DSR.
  22. The UART design can generate four interrupts: Rx, Tx, modem status
  23. change and a UART disabled interrupt (which is asserted when a start
  24. bit is detected on the receive line when the UART is disabled). The
  25. implementation in the 21285 chip has only two interrupts: Rx and Tx,
  26. but the Rx interrupt is a combination of the normal Rx interrupt status
  27. and the UART disabled interrupt status.
  28. Only asynchronous serial operation is supported by the UART which
  29. supports 5 to 8 bit bit word lengths with or without parity and with
  30. one or two stop bits. The only serial word format supported by the
  31. driver is 8 data bits, 1 stop bit, no parity,  The default baud rate is
  32. determined by the BSP by filling in the s3c2410x_CHAN structure before
  33. calling s3c2410xDevInit().
  34. The exact baud rates supported by this driver will depend on the
  35. crystal fitted (and consequently the input clock to the baud-rate
  36. generator), but in general, baud rates from about 300 to about 115200
  37. are possible.
  38. In theory, any number of UART channels could be implemented within a
  39. chip. This driver has been designed to cope with an arbitrary number of
  40. channels, but at the time of writing, has only ever been tested with
  41. one channel.
  42. .SH DATA STRUCTURES
  43. An s3c2410x_CHAN data structure is used to describe each channel, this
  44. structure is described in h/drv/sio/s3c2410xSio.h.
  45. .SH CALLBACKS
  46. Servicing a "transmitter ready" interrupt involves making a callback to
  47. a higher level library in order to get a character to transmit.  By
  48. default, this driver installs dummy callback routines which do nothing.
  49. A higher layer library that wants to use this driver (e.g. ttyDrv)
  50. will install its own callback routine using the SIO_INSTALL_CALLBACK
  51. ioctl command.  Likewise, a receiver interrupt handler makes a callback
  52. to pass the character to the higher layer library.
  53.  
  54. .SH MODES
  55. This driver supports both polled and interrupt modes.
  56. .SH USAGE
  57. The driver is typically only called by the BSP. The directly callable
  58. routines in this modules are s3c2410xDevInit(), s3c2410xIntTx() and
  59. s3c2410xIntRx().
  60. The BSP's sysHwInit() routine typically calls sysSerialHwInit(), which
  61. initialises the hardware-specific fields in the s3c2410x_CHAN structure
  62. (e.g. register I/O addresses etc) before calling s3c2410xDevInit() which
  63. resets the device and installs the driver function pointers.  After
  64. this the UART will be enabled and ready to generate interrupts, but
  65. those interrupts will be disabled in the interrupt controller.
  66. The following example shows the first parts of the initialisation:
  67. .CS
  68. #include "s3c2410xSio.h"
  69. LOCAL s3c2410x_CHAN s3c2410xChan[N_s3c2410x_UART_CHANS];
  70. void sysSerialHwInit (void)
  71.     {
  72.     int i;
  73.     for (i = 0; i < N_s3c2410x_UART_CHANS; i++)
  74. {
  75. s3c2410xChan[i].regs = devParas[i].baseAdrs;
  76. s3c2410xChan[i].baudRate = CONSOLE_BAUD_RATE;
  77. s3c2410xChan[i].xtal = UART_XTAL_FREQ; 
  78. s3c2410xChan[i].levelRx = devParas[i].intLevelRx;
  79. s3c2410xChan[i].levelTx = devParas[i].intLevelTx;
  80. /@
  81.  * Initialise driver functions, getTxChar, putRcvChar and
  82.  * channelMode, then initialise UART
  83.  @/
  84. s3c2410xDevInit(&s3c2410xChan[i]);
  85. }
  86.     }
  87. .CE
  88. The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(),
  89. which connects the chips interrupts via intConnect() (the two
  90. interrupts `s3c2410xIntTx' and `s3c2410xIntRx') and enables those interrupts,
  91. as shown in the following example:
  92. .CS
  93. void sysSerialHwInit2 (void)
  94.     {
  95.     /@ connect and enable Rx interrupt @/
  96.     (void) intConnect (INUM_TO_IVEC(devParas[0].vectorRx),
  97.        s3c2410xIntRx, (int) &s3c2410xChan[0]);
  98.     intEnable (devParas[0].intLevelRx);
  99.     /@ connect Tx interrupt @/
  100.     (void) intConnect (INUM_TO_IVEC(devParas[0].vectorTx),
  101.        s3c2410xIntTx, (int) &s3c2410xChan[0]);
  102.     /@
  103.      * There is no point in enabling the Tx interrupt, as it will
  104.      * interrupt immediately and then be disabled.
  105.      @/
  106.     }
  107. .CE
  108. .SH BSP
  109. By convention all the BSP-specific serial initialisation is performed
  110. in a file called sysSerial.c, which is #include'ed by sysLib.c.
  111. sysSerial.c implements at least four functions, sysSerialHwInit()
  112. sysSerialHwInit2(), sysSerialChanGet(), and sysSerialReset(). The first
  113. two have been described above, the others work as follows:
  114. sysSerialChanGet is called by usrRoot to get the serial channel
  115. descriptor associated with a serial channel number. The routine takes a
  116. single parameter which is a channel number ranging between zero and
  117. NUM_TTY. It returns a pointer to the corresponding channel descriptor,
  118. SIO_CHAN *, which is just the address of the s3c2410x_CHAN structure.
  119.  
  120. sysSerialReset is called from sysToMonitor() and should reset the
  121. serial devices to an inactive state (prevent them from generating any
  122. interrupts).
  123. .SH INCLUDE FILES:
  124. drv/sio/s3c2410xSio.h sioLib.h
  125. .SH SEE ALSO:
  126. .I "Advanced RISC Machines s3c2410x UART (AP13) Data Sheet,"
  127. .I "Digital Semiconductor 21285 Core Logic for SA-110 Microprocessor Data
  128. Sheet,"
  129. .I "Digital Semiconductor EBSA-285 Evaluation Board Reference Manual."
  130. */
  131. #include "vxWorks.h"
  132. #include "intLib.h"
  133. #include "errnoLib.h"
  134. #include "errno.h"
  135. #include "sioLib.h"
  136. #include "s3c2410xSio.h"
  137. /* local defines  */
  138. #define s3c2410x_BAUD_MIN         18
  139. #define s3c2410x_BAUD_MAX         1152000
  140. #define s3c2410x_SIO_DEFAULT_BAUD 1152000
  141. #ifndef s3c2410x_UART_REG
  142. #define s3c2410x_UART_REG(pChan, reg) 
  143. (*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg)))
  144. #endif
  145. #ifndef s3c2410x_UART_REG_READ
  146. #define s3c2410x_UART_REG_READ(pChan, reg, result) 
  147. (result) = (s3c2410x_UART_REG(pChan, reg))
  148. #endif
  149. #ifndef s3c2410x_UART_REG_WRITE
  150. #define s3c2410x_UART_REG_WRITE(pChan, reg, data) 
  151. (s3c2410x_UART_REG(pChan, reg)) = (data)
  152. #endif
  153. #ifndef s3c2410x_UART_REG_BIT_SET
  154. #define s3c2410x_UART_REG_BIT_SET(pChan, reg, data) 
  155. (s3c2410x_UART_REG(pChan, reg)) |= (data)
  156. #endif
  157. #ifndef s3c2410x_UART_REG_BIT_CLR
  158. #define s3c2410x_UART_REG_BIT_CLR(pChan, reg, data) 
  159. (s3c2410x_UART_REG(pChan, reg)) &= ~(data)
  160. #endif
  161. /* hardware access methods */
  162. #ifndef s3c2410x_INT_REG_READ
  163. #define s3c2410x_INT_REG_READ(reg,result) 
  164. ((result) = *(volatile UINT32 *)(reg))
  165. #endif
  166. #ifndef s3c2410x_INT_REG_WRITE
  167. #define s3c2410x_INT_REG_WRITE(reg,data) 
  168. (*((volatile UINT32 *)(reg)) = (data))
  169. #endif
  170. /* locals */
  171. /* function prototypes */
  172. LOCAL STATUS s3c2410xIoctl (SIO_CHAN * pSioChan, int request, int arg);
  173. LOCAL int s3c2410xTxStartup (SIO_CHAN * pSioChan);
  174. LOCAL int s3c2410xCallbackInstall (SIO_CHAN * pSioChan, int callbackType,
  175. STATUS (*callback)(), void * callbackArg);
  176. LOCAL int s3c2410xPollInput (SIO_CHAN * pSioChan, char *);
  177. LOCAL int s3c2410xPollOutput (SIO_CHAN * pSioChan, char);
  178. LOCAL STATUS s3c2410xDummyCallback (void);
  179. /* driver functions */
  180. LOCAL SIO_DRV_FUNCS s3c2410xSioDrvFuncs =
  181. {
  182. (int (*)())s3c2410xIoctl,
  183. s3c2410xTxStartup,
  184. (int (*)())s3c2410xCallbackInstall,
  185. s3c2410xPollInput,
  186. s3c2410xPollOutput
  187. };
  188. /*
  189.  * s3c2410xDummyCallback - dummy callback routine.
  190.  *
  191.  * RETURNS: ERROR, always.
  192.  */
  193. LOCAL STATUS s3c2410xDummyCallback (void)
  194. {
  195. return ERROR;
  196. }
  197. /*
  198.  * s3c2410xInitChannel - initialise UART
  199.  *
  200.  * This routine performs hardware initialisation of the UART channel.
  201.  *
  202.  * RETURNS: N/A
  203.  */
  204. LOCAL void s3c2410xInitChannel
  205. (
  206. s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
  207. )
  208. {
  209. UINT32 tempUINT32;
  210. /* Set UCLK, polling&interrupt mode. */
  211. s3c2410x_UART_REG_WRITE(pChan, OFFSET_UCON, CLK_PCLK+TxMode_IntPoll+RxMode_IntPoll);
  212. /* enable subInterrupt for UART0. */
  213. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  214. switch((int)(pChan->regs))
  215. {
  216. case UART_1_BASE_ADR:
  217. tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
  218. break;
  219. case UART_0_BASE_ADR:
  220. default:
  221. tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
  222. }
  223. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  224. /* Set baud rate to 9600. */
  225. s3c2410xIoctl((SIO_CHAN *)pChan, SIO_BAUD_SET, s3c2410x_SIO_DEFAULT_BAUD);
  226. /* Set NonInfra-red mode, 8, N, 1. */
  227. s3c2410xIoctl((SIO_CHAN *)pChan, SIO_HW_OPTS_SET, CLOCAL+CS8);
  228. s3c2410xIoctl((SIO_CHAN *)pChan, SIO_MODE_SET, SIO_MODE_POLL);
  229. /* Set disable FIFO */
  230. s3c2410x_UART_REG_WRITE(pChan, OFFSET_UFCON, FIFO_OFF);
  231. /* Enable pin for UART */
  232. s3c2410x_IO_READ(rGPHCON, tempUINT32);
  233. switch((int)(pChan->regs))
  234. {
  235. case UART_1_BASE_ADR:
  236. tempUINT32 |= (MASK_GPH4(2)+MASK_GPH5(2)+MASK_GPH6(3)+MASK_GPH7(3)); /* +MASK_GPH8(2)); */
  237. break;
  238. case UART_0_BASE_ADR:
  239. default:
  240. tempUINT32 |= (MASK_GPH0(2)+MASK_GPH1(2)+MASK_GPH2(2)+MASK_GPH3(2)); /* +MASK_GPH8(2)); */
  241. }
  242. s3c2410x_IO_WRITE(rGPHCON,tempUINT32);
  243. /* Clear Rx */
  244. s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, tempUINT32);
  245. }
  246. /*
  247.  * s3c2410xSioDevInit - initialise an s3c2410x channel
  248.  *
  249.  * This routine initialises some SIO_CHAN function pointers and then resets
  250.  * the chip to a quiescent state.  Before this routine is called, the BSP
  251.  * must already have initialised all the device addresses, etc. in the
  252.  * s3c2410x_CHAN structure.
  253.  *
  254.  * RETURNS: N/A
  255.  */
  256. void s3c2410xSioDevInit
  257. (
  258. s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
  259. )
  260. {
  261. int oldlevel = intLock();
  262. /* initialise the driver function pointers in the SIO_CHAN */
  263. pChan->sio.pDrvFuncs = &s3c2410xSioDrvFuncs;
  264. /* set the non BSP-specific constants */
  265. pChan->getTxChar = s3c2410xDummyCallback;
  266. pChan->putRcvChar = s3c2410xDummyCallback;
  267. pChan->channelMode = 0;    /* undefined */
  268. /* initialise the chip */
  269. s3c2410xInitChannel(pChan);
  270. intUnlock(oldlevel);
  271. }
  272. /*
  273.  * s3c2410xIoctl - special device control
  274.  *
  275.  * This routine handles the IOCTL messages from the user.
  276.  *
  277.  * RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed
  278.  * request.
  279.  */
  280. LOCAL int s3c2410xIoctl
  281. (
  282. SIO_CHAN* pSioChan, /* device to control */
  283.      int request, /* request code */
  284.      int arg
  285. )
  286. {
  287. s3c2410x_CHAN *pChan = (s3c2410x_CHAN*) pSioChan;
  288. int oldlevel;        /* current interrupt level mask */
  289. UINT32 tempUINT32 = 0;
  290. int lvl;
  291.     
  292. switch (request)
  293. {
  294. case SIO_BAUD_SET:
  295. if(arg < s3c2410x_BAUD_MIN || arg > s3c2410x_BAUD_MAX) return(EIO);
  296. /* disable interrupts during chip access */
  297. oldlevel = intLock ();
  298. s3c2410x_UART_REG_WRITE(pChan,OFFSET_UDIV,(((s3c2410x_PCLK/16)/arg)-1));
  299. intUnlock (oldlevel);
  300. s3c2410x_UART_REG_READ(pChan,OFFSET_UDIV,tempUINT32);
  301. pChan->baudRate=((s3c2410x_PCLK/16)/(tempUINT32+1));
  302. break;
  303. case SIO_BAUD_GET:
  304. *(int *)arg = pChan->baudRate;
  305. break;
  306. case SIO_MODE_SET:
  307. switch(arg)
  308. {
  309. case SIO_MODE_INT:
  310. /* clear subpend-flag of RX_TX */
  311. switch((int)(pChan->regs))
  312. {
  313. case UART_1_BASE_ADR:
  314. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD1)|(1<<SUBINT_LVL_RXD1)));
  315. break;
  316. case UART_0_BASE_ADR:
  317. default:
  318. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SUBSRCPND,((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_RXD0)));
  319. }
  320. /* enable uart_int */
  321. intEnable(pChan->intLevelRx);
  322. /* enable subInterrupt for UART0. */
  323. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  324. switch((int)(pChan->regs))
  325. {
  326. case UART_1_BASE_ADR:
  327. tempUINT32 &= ~((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
  328. break;
  329. case UART_0_BASE_ADR:
  330. default:
  331. tempUINT32 &= ~((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
  332. }
  333. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  334. break;
  335. case SIO_MODE_POLL:
  336. /* disable uart_int */
  337. intDisable(pChan->intLevelRx);
  338. /* disable subInterrupt for UART0. */
  339. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  340. switch((int)(pChan->regs))
  341. {
  342. case UART_1_BASE_ADR:
  343. tempUINT32 |= ((1<<SUBINT_LVL_RXD1)|(1<<SUBINT_LVL_TXD1));
  344. break;
  345. case UART_0_BASE_ADR:
  346. default:
  347. tempUINT32 |= ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_TXD0));
  348. }
  349. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK,tempUINT32);
  350. break;
  351. default: return(EIO);
  352. }
  353. pChan->channelMode = arg;
  354. break;
  355. case SIO_MODE_GET:
  356. *(int *)arg = pChan->channelMode;
  357. break;
  358. case SIO_AVAIL_MODES_GET:
  359. /* Get the available modes and return OK.  */
  360. *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; 
  361. break;
  362. case SIO_HW_OPTS_SET:
  363. if(arg & 0xffffff00) return EIO;
  364. /* do nothing if options already set */
  365. if(pChan->options == arg) break;
  366. switch (arg & CSIZE)
  367. {
  368. case CS5:
  369. tempUINT32 = DATABIT_5; break;
  370. case CS6:
  371. tempUINT32 = DATABIT_6; break;
  372. case CS7:
  373. tempUINT32 = DATABIT_7; break;
  374. default:
  375. case CS8:
  376. tempUINT32 = DATABIT_8; break;
  377. }
  378. if (arg & STOPB)
  379. {
  380. tempUINT32 |= TWO_STOPBIT;
  381. }
  382. else
  383. {
  384. /* tempUINT32 &= ~TWO_STOPBIT */;
  385. }
  386. switch (arg & (PARENB|PARODD))
  387. {
  388. case PARENB|PARODD:
  389. tempUINT32 += ODD_PARITY;
  390. break;
  391. case PARENB:
  392. tempUINT32 += EVEN_PARITY;
  393. break;
  394. case 0:
  395. default:
  396. ;/* no parity */
  397. }
  398. lvl = intLock();
  399.      s3c2410x_UART_REG_WRITE(pChan,OFFSET_ULCON,tempUINT32);
  400. intUnlock(lvl);
  401. if (arg & CLOCAL)
  402. {
  403.          /* clocal disables hardware flow control */
  404. lvl = intLock();
  405. s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_OFF);
  406. intUnlock(lvl);
  407. }
  408. else
  409. {
  410. lvl = intLock();
  411. s3c2410x_UART_REG_WRITE(pChan,OFFSET_UMCON,AFC_ON);
  412. intUnlock(lvl);
  413. }
  414. pChan->options = arg;
  415. break;
  416. case SIO_HW_OPTS_GET:
  417. *(int*)arg = pChan->options;
  418. return (OK);
  419. case SIO_HUP:
  420. /* check if hupcl option is enabled */
  421. break;
  422. case SIO_OPEN:
  423. break; /* always open */
  424. default:
  425. return (ENOSYS);
  426. }
  427. return (OK);
  428. }
  429. /*
  430.  * s3c2410xSioIntTx - handle a transmitter interrupt 
  431.  *
  432.  * This routine handles write interrupts from the UART.
  433.  *
  434.  * RETURNS: N/A
  435.  */
  436. void s3c2410xSioIntTx 
  437. (
  438. s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
  439. )
  440. {
  441. char outChar;
  442. /* clear subpending of the TXn */
  443. switch((int)(pChan->regs))
  444. {
  445. case UART_1_BASE_ADR:
  446. s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD1));
  447. break;
  448. case UART_0_BASE_ADR:
  449. default:
  450. s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_TXD0));
  451. }
  452. if((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR)
  453. {
  454. /* write char. to Transmit Holding Reg. */
  455. s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, (((UINT32)outChar)&0x000000ff));
  456. }
  457. }
  458. /*
  459.  * s3c2410xSioIntRx - handle a receiver interrupt 
  460.  *
  461.  * This routine handles read interrupts from the UART.
  462.  *
  463.  * RETURNS: N/A
  464.  */
  465. void s3c2410xSioIntRx
  466. (
  467. s3c2410x_CHAN * pChan /* ptr to s3c2410x_CHAN describing this channel */
  468. )
  469. {
  470. char inchar;
  471. /* clear subpending of the RXn */
  472. switch((int)(pChan->regs))
  473. {
  474. case UART_1_BASE_ADR:
  475. s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD1));
  476. break;
  477. case UART_0_BASE_ADR:
  478. default:
  479. s3c2410x_IO_WRITE(s3c2410x_INT_CSR_SUBSRCPND, (1<<SUBINT_LVL_RXD0));
  480. }
  481. /* read character from Receive Holding Reg. */
  482. s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, inchar);
  483. (*pChan->putRcvChar) (pChan->putRcvArg, inchar);
  484. }
  485. /*
  486.  * s3c2410xSioInt - handle any UART interrupt
  487.  *
  488.  * This routine handles interrupts from the UART and determines whether
  489.  * the source is a transmit interrupt or receive/receive-timeout interrupt.
  490.  *
  491.  * The Prime Cell UART generates a receive interrupt when the RX FIFO is
  492.  * half-full, and a receive-timeout interrupt after 32 bit-clocks have
  493.  * elapsed with no incoming data.
  494.  *
  495.  * RETURNS: N/A
  496.  */
  497. void s3c2410xSioInt
  498. (
  499. s3c2410x_CHAN * pChan   /* ptr to s3c2410x_CHAN describing this channel */
  500. )
  501. {
  502. UINT32 intId;
  503. s3c2410x_INT_REG_READ(s3c2410x_INT_CSR_SUBSRCPND, intId);
  504. if(intId & ((1<<SUBINT_LVL_TXD0)|(1<<SUBINT_LVL_TXD1)))
  505. {
  506. s3c2410xSioIntTx(pChan);
  507. }
  508. if(intId & ((1<<SUBINT_LVL_RXD0)|(1<<SUBINT_LVL_RXD1)))
  509. {
  510. s3c2410xSioIntRx (pChan);
  511. }
  512. s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_INTSUBMSK, 0);
  513. /* clear pend and enable this level */
  514. /*s3c2410x_INT_REG_WRITE(s3c2410x_INT_CSR_SRCPND, (1<<(pChan->intLevelRx)));
  515. s3c2410xIntLvlEnable(pChan->intLevelRx);
  516. */
  517. }
  518. /*
  519.  * s3c2410xTxStartup - transmitter startup routine
  520.  *
  521.  * Enable interrupt so that interrupt-level char output routine will be called.
  522.  *
  523.  * RETURNS: OK on success, ENOSYS if the device is polled-only, or
  524.  * EIO on hardware error.
  525.  */
  526. LOCAL int s3c2410xTxStartup
  527. (
  528. SIO_CHAN * pSioChan /* ptr to SIO_CHAN describing this channel */
  529. )
  530. {
  531. s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;   
  532. if(pChan->channelMode == SIO_MODE_INT)
  533. {
  534. intEnable(pChan->intLevelTx);
  535. s3c2410xSioIntTx(pChan);
  536. return OK;
  537. }
  538. else
  539. {
  540. return ENOSYS;
  541. }
  542. }
  543. /*
  544.  * s3c2410xPollOutput - output a character in polled mode.
  545.  *
  546.  * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
  547.  * if the output buffer is full, ENOSYS if the device is interrupt-only.
  548.  */
  549. LOCAL int s3c2410xPollOutput
  550. (
  551. SIO_CHAN* pSioChan, /* ptr to SIO_CHAN describing this channel */
  552. char      outChar  /*  to output */
  553. )
  554. {
  555. s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
  556. FAST UINT32 pollStatus;
  557. s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);
  558. /* is the transmitter ready to accept a character? */
  559. if(!(pollStatus & UTRSTAT_TRNSR_EM))
  560. {
  561. return EAGAIN;
  562. }
  563. /* write out the character */
  564. s3c2410x_UART_REG_WRITE(pChan, OFFSET_UTXH, outChar); /* transmit character */
  565. return OK;
  566. }
  567. /*
  568.  * s3c2410xPollInput - poll the device for input.
  569.  *
  570.  * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
  571.  * if the input buffer is empty, ENOSYS if the device is interrupt-only.
  572.  */
  573. LOCAL int s3c2410xPollInput
  574. (
  575. SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
  576. char*  thisChar /* pointer to where to return character */
  577. )
  578. {
  579. s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
  580. FAST UINT32 pollStatus;
  581. s3c2410x_UART_REG_READ(pChan, OFFSET_UTRSTAT, pollStatus);
  582. if(!(pollStatus & UTRSTAT_RB_RDY))
  583. {
  584. return EAGAIN;
  585. }
  586. /* got a character */
  587. s3c2410x_UART_REG_READ(pChan, OFFSET_URXH, *thisChar);
  588. return OK;
  589. }
  590. /*
  591.  * s3c2410xCallbackInstall - install ISR callbacks to get/put chars.
  592.  *
  593.  * This routine installs interrupt callbacks for transmitting characters
  594.  * and receiving characters.
  595.  *
  596.  * RETURNS: OK on success, or ENOSYS for an unsupported callback type.
  597.  *
  598.  */
  599. LOCAL int s3c2410xCallbackInstall
  600. (
  601. SIO_CHAN* pSioChan, /* ptr to SIO_CHAN describing this channel */
  602. int callbackType, /* type of callback */
  603. STATUS (*callback)(), /* callback */
  604. void* callbackArg /* parameter to callback */
  605. )
  606. {
  607. s3c2410x_CHAN * pChan = (s3c2410x_CHAN *)pSioChan;
  608. switch(callbackType)
  609. {
  610. case SIO_CALLBACK_GET_TX_CHAR:
  611. pChan->getTxChar = callback;
  612. pChan->getTxArg = callbackArg;
  613. return OK;
  614. case SIO_CALLBACK_PUT_RCV_CHAR:
  615. pChan->putRcvChar = callback;
  616. pChan->putRcvArg = callbackArg;
  617. return OK;
  618. default:
  619. return ENOSYS;
  620. }
  621. }