summaryrefslogtreecommitdiffstats
path: root/arch/ppc/boot/kbd.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
commitdb7d4daea91e105e3859cf461d7e53b9b77454b2 (patch)
tree9bb65b95440af09e8aca63abe56970dd3360cc57 /arch/ppc/boot/kbd.c
parent9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff)
Merge with Linux 2.2.8.
Diffstat (limited to 'arch/ppc/boot/kbd.c')
-rw-r--r--arch/ppc/boot/kbd.c55
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);
}