]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/input/ps2ser.c
1 /***********************************************************************
3 * (C) Copyright 2004-2009
4 * DENX Software Engineering
5 * Wolfgang Denk, wd@denx.de
7 * Simple 16550A serial driver
9 * Originally from linux source (drivers/char/ps2ser.c)
11 * Used by the PS/2 multiplexer driver (ps2mult.c)
13 ***********************************************************************/
18 #include <asm/atomic.h>
20 /* This is needed for ns16550.h */
21 #ifndef CONFIG_SYS_NS16550_REG_SIZE
22 #define CONFIG_SYS_NS16550_REG_SIZE 1
26 DECLARE_GLOBAL_DATA_PTR
;
30 #define PS2SER_BAUD 57600
32 #if CONFIG_PS2SERIAL == 1
33 #define COM_BASE (CONFIG_SYS_CCSRBAR+0x4500)
34 #elif CONFIG_PS2SERIAL == 2
35 #define COM_BASE (CONFIG_SYS_CCSRBAR+0x4600)
37 #error CONFIG_PS2SERIAL must be in 1 ... 2
40 static int ps2ser_getc_hw(void);
41 static void ps2ser_interrupt(void *dev_id
);
43 extern struct serial_state rs_table
[]; /* in serial.c */
45 static u_char ps2buf
[PS2BUF_SIZE
];
46 static atomic_t ps2buf_cnt
;
47 static int ps2buf_in_idx
;
48 static int ps2buf_out_idx
;
52 NS16550_t com_port
= (NS16550_t
)COM_BASE
;
55 com_port
->lcr
= UART_LCR_BKSE
| UART_LCR_8N1
;
56 com_port
->dll
= (CONFIG_SYS_NS16550_CLK
/ 16 / PS2SER_BAUD
) & 0xff;
57 com_port
->dlm
= ((CONFIG_SYS_NS16550_CLK
/ 16 / PS2SER_BAUD
) >> 8) & 0xff;
58 com_port
->lcr
= UART_LCR_8N1
;
59 com_port
->mcr
= (UART_MCR_DTR
| UART_MCR_RTS
);
60 com_port
->fcr
= (UART_FCR_FIFO_EN
| UART_FCR_RXSR
| UART_FCR_TXSR
);
65 void ps2ser_putc(int chr
)
67 NS16550_t com_port
= (NS16550_t
)COM_BASE
;
68 debug(">>>> 0x%02x\n", chr
);
70 while ((com_port
->lsr
& UART_LSR_THRE
) == 0);
74 static int ps2ser_getc_hw(void)
76 NS16550_t com_port
= (NS16550_t
)COM_BASE
;
79 if (com_port
->lsr
& UART_LSR_DR
) {
93 flags
= disable_interrupts();
96 if (atomic_read(&ps2buf_cnt
) != 0) {
97 chr
= ps2buf
[ps2buf_out_idx
++];
98 ps2buf_out_idx
&= (PS2BUF_SIZE
- 1);
99 atomic_dec(&ps2buf_cnt
);
101 chr
= ps2ser_getc_hw();
109 debug("0x%02x\n", chr
);
114 int ps2ser_check(void)
118 flags
= disable_interrupts();
119 ps2ser_interrupt(NULL
);
120 if (flags
) enable_interrupts();
122 return atomic_read(&ps2buf_cnt
);
125 static void ps2ser_interrupt(void *dev_id
)
127 NS16550_t com_port
= (NS16550_t
)COM_BASE
;
132 chr
= ps2ser_getc_hw();
133 status
= com_port
->lsr
;
134 if (chr
< 0) continue;
136 if (atomic_read(&ps2buf_cnt
) < PS2BUF_SIZE
) {
137 ps2buf
[ps2buf_in_idx
++] = chr
;
138 ps2buf_in_idx
&= (PS2BUF_SIZE
- 1);
139 atomic_inc(&ps2buf_cnt
);
141 printf ("ps2ser.c: buffer overflow\n");
143 } while (status
& UART_LSR_DR
);
144 if (atomic_read(&ps2buf_cnt
)) {
145 ps2mult_callback(atomic_read(&ps2buf_cnt
));