2 * BK Id: SCCS/s.kbd.c 1.14 03/12/02 16:07:29 paulus
5 #include <linux/keyboard.h>
7 #include "defkeymap.c" /* yeah I know it's bad -- Cort */
10 unsigned char shfts, ctls, alts, caps;
12 #define KBDATAP 0x60 /* kbd data port */
13 #define KBSTATUSPORT 0x61 /* kbd status */
14 #define KBSTATP 0x64 /* kbd status port */
18 extern unsigned char inb(int port);
19 extern void outb(int port, char val);
20 extern void puts(const char *);
21 extern void puthex(unsigned long val);
22 extern void udelay(long x);
24 static int kbd(int noblock)
26 unsigned char dt, brk, val;
30 if ((inb(KBSTATP) & KBINRDY) == 0)
32 } else while((inb(KBSTATP) & KBINRDY) == 0) ;
36 brk = dt & 0x80; /* brk == 1 on key release */
37 dt = dt & 0x7f; /* keycode */
47 switch (KTYP(code) & 0x0f) {
53 if (val == 0x7f) /* map delete to backspace */
67 if (val == KVAL(K_CAPS))
69 else if (val == KVAL(K_ENTER)) {
70 enter: /* Wait for key up */
72 while((inb(KBSTATP) & KBINRDY) == 0) ;
74 if (dt & 0x80) /* key up */ break;
85 if (val == KVAL(K_PENTER))
130 if (brk) return (-1); /* Ignore initial 'key up' codes */
134 static int __kbdreset(void)
139 /* flush input queue */
141 while ((inb(KBSTATP) & KBINRDY))
149 while (inb(KBSTATP) & KBOUTRDY)
154 while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */
157 if ((c = inb(KBDATAP)) != 0x55)
159 puts("Keyboard self test failed - result:");
163 /* Enable interrupts and keyboard controller */
165 while (inb(KBSTATP) & KBOUTRDY)
166 if (--t == 0) return 4;
169 while (inb(KBSTATP) & KBOUTRDY)
170 if (--t == 0) return 5;
172 for (i = 0; i < 10000; i++) udelay(1);
175 while (inb(KBSTATP) & KBOUTRDY)
176 if (--t == 0) return 6;
179 while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */
180 if (--t == 0) return 7;
181 if (! (inb(KBDATAP) & 0x40)) {
183 * Quote from PS/2 System Reference Manual:
185 * "Address hex 0060 and address hex 0064 should be
186 * written only when the input-buffer-full bit and
187 * output-buffer-full bit in the Controller Status
188 * register are set 0." (KBINRDY and KBOUTRDY)
191 while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
192 if (--t == 0) return 8;
195 while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
196 if (--t == 0) return 9;
200 while (inb(KBSTATP) & KBOUTRDY)
201 if (--t == 0) return 10;
206 static void kbdreset(void)
208 int ret = __kbdreset();
211 puts("__kbdreset failed: ");
217 /* We have to actually read the keyboard when CRT_tstc is called,
218 * since the pending data might be a key release code, and therefore
219 * not valid data. In this case, kbd() will return -1, even though there's
220 * data to be read. Of course, we might actually read a valid key press,
221 * in which case it gets queued into key_pending for use by CRT_getc.
224 static int kbd_reset = 0;
226 static int key_pending = -1;
231 if (!kbd_reset) {kbdreset(); kbd_reset++; }
233 if (key_pending != -1) {
238 while ((c = kbd(0)) == 0) ;
245 if (!kbd_reset) {kbdreset(); kbd_reset++; }
247 while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
248 key_pending = kbd(1);
251 return (key_pending != -1);