diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /arch/ppc/boot/kbd.c | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'arch/ppc/boot/kbd.c')
-rw-r--r-- | arch/ppc/boot/kbd.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/arch/ppc/boot/kbd.c b/arch/ppc/boot/kbd.c index 9f5cd330b..49a102e9c 100644 --- a/arch/ppc/boot/kbd.c +++ b/arch/ppc/boot/kbd.c @@ -1,7 +1,6 @@ - #include <linux/keyboard.h> -#include <../drivers/char/defkeymap.c> /* yeah I know it's bad */ +#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */ unsigned char shfts, ctls, alts, caps; @@ -119,7 +118,7 @@ enter: /* Wait for key up */ } break; } - if (brk) return (0); /* Ignore initial 'key up' codes */ + if (brk) return (-1); /* Ignore initial 'key up' codes */ goto loop; } @@ -128,6 +127,11 @@ static void kbdreset(void) unsigned char c; int i; + /* flush input queue */ + while ((inb(KBSTATP) & KBINRDY)) + { + (void)inb(KBDATAP); + } /* Send self-test */ while (inb(KBSTATP) & KBOUTRDY) ; outb(KBSTATP,0xAA); @@ -144,22 +148,63 @@ static void kbdreset(void) while (inb(KBSTATP) & KBOUTRDY) ; outb(KBDATAP,0x45); for (i = 0; i < 10000; i++) udelay(1); + + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0x20); + while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + if (! (inb(KBDATAP) & 0x40)) { + /* + * Quote from PS/2 System Reference Manual: + * + * "Address hex 0060 and address hex 0064 should be + * written only when the input-buffer-full bit and + * output-buffer-full bit in the Controller Status + * register are set 0." (KBINRDY and KBOUTRDY) + */ + + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0xF0); + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0x01); + } + while (inb(KBSTATP) & KBOUTRDY) ; outb(KBSTATP,0xAE); } +/* We have to actually read the keyboard when CRT_tstc is called, + * since the pending data might be a key release code, and therefore + * not valid data. In this case, kbd() will return -1, even though there's + * data to be read. Of course, we might actually read a valid key press, + * in which case it gets queued into key_pending for use by CRT_getc. + */ + static int kbd_reset = 0; +static int key_pending = -1; + int CRT_getc(void) { int c; if (!kbd_reset) {kbdreset(); kbd_reset++; } + + if (key_pending != -1) { + c = key_pending; + key_pending = -1; + return c; + } else { while ((c = kbd(0)) == 0) ; - return(c); + return c; + } } int CRT_tstc(void) { if (!kbd_reset) {kbdreset(); kbd_reset++; } - return ((inb(KBSTATP) & KBINRDY) != 0); + + while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { + key_pending = kbd(1); + } + + return (key_pending != -1); } |