ns16550.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.ns16550.c 1.12 10/08/01 17:16:50 paulus
  3.  */
  4. /*
  5.  * COM1 NS16550 support
  6.  */
  7. #include <linux/config.h>
  8. #include <linux/serialP.h>
  9. #include <linux/serial_reg.h>
  10. #include <asm/serial.h>
  11. /* Default serial baud rate */
  12. #define SERIAL_BAUD 9600
  13. extern void outb(int port, unsigned char val);
  14. extern unsigned char inb(int port);
  15. extern unsigned long ISA_io;
  16. static struct serial_state rs_table[RS_TABLE_SIZE] = {
  17. SERIAL_PORT_DFNS /* Defined in <asm/serial.h> */
  18. };
  19. static int shift;
  20. unsigned long serial_init(int chan) {
  21. unsigned long com_port;
  22. /* We need to find out which type io we're expecting.  If it's
  23.  * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
  24.  * If it's 'SERIAL_IO_MEM', we can the exact location.  -- Tom */
  25. switch (rs_table[chan].io_type) {
  26. case SERIAL_IO_PORT:
  27. com_port = rs_table[chan].port;
  28. break;
  29. case SERIAL_IO_MEM:
  30. com_port = (unsigned long)rs_table[chan].iomem_base;
  31. break;
  32. default:
  33. /* We can't deal with it. */
  34. return -1;
  35. }
  36. /* How far apart the registers are. */
  37. shift = rs_table[chan].iomem_reg_shift;
  38. /* See if port is present */
  39. outb(com_port + (UART_LCR << shift), 0x00);
  40. outb(com_port + (UART_IER << shift), 0x00);
  41. /* Access baud rate */
  42. outb(com_port + (UART_LCR << shift), 0x80);
  43. /*
  44.  * Test if serial port is unconfigured.
  45.  * We assume that no-one uses less than 110 baud or
  46.  * less than 7 bits per character these days.
  47.  *  -- paulus.
  48.  */
  49. if (inb(com_port + (UART_DLM << shift)) > 4
  50.     || (inb(com_port + (UART_LCR << shift)) & 2) == 0) {
  51. /* Input clock. */
  52. outb(com_port + (UART_DLL << shift),
  53.      (BASE_BAUD / SERIAL_BAUD));
  54. outb(com_port + (UART_DLM << shift),
  55.      (BASE_BAUD / SERIAL_BAUD) >> 8);
  56. }
  57.  /* 8 data, 1 stop, no parity */
  58. outb(com_port + (UART_LCR << shift), 0x03);
  59. /* RTS/DTR */
  60. outb(com_port + (UART_MCR << shift), 0x03);
  61. /* Clear & enable FIFOs */
  62. outb(com_port + (UART_FCR << shift), 0x07);
  63. return (com_port);
  64. }
  65. void
  66. serial_putc(unsigned long com_port, unsigned char c)
  67. {
  68. while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
  69. ;
  70. outb(com_port, c);
  71. }
  72. unsigned char
  73. serial_getc(unsigned long com_port)
  74. {
  75. while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
  76. ;
  77. return inb(com_port);
  78. }
  79. int
  80. serial_tstc(unsigned long com_port)
  81. {
  82. return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
  83. }