- Wait for mouse acks properly.
[cake.git] / arch / i386-pc / drivers / keyboard / kbd_common.c
blob8e17d400c90ec5263fd2166d027410479b1ab16e
1 /*
2 Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PS/2 mouse driver.
6 Lang: English.
7 */
9 #include "kbd.h"
10 #define TIMER_RPROK 3599597124UL
12 int kbd_wait_for_input(void);
14 static ULONG usec2tick(ULONG usec)
16 ULONG ret;
17 ULONG prok = TIMER_RPROK;
18 asm volatile("movl $0,%%eax; divl %2":"=a"(ret):"d"(usec),"m"(prok));
19 return ret;
22 static void mouse_usleep(LONG usec)
24 int oldtick, tick;
25 usec = usec2tick(usec);
27 outb(0x80, 0x43);
28 oldtick = inb(0x42);
29 oldtick += inb(0x42) << 8;
31 while (usec > 0)
33 outb(0x80, 0x43);
34 tick = inb(0x42);
35 tick += inb(0x42) << 8;
37 usec -= (oldtick - tick);
38 if (tick > oldtick) usec -= 0x10000;
39 oldtick = tick;
44 unsigned char handle_kbd_event(void)
46 unsigned char status = kbd_read_status();
47 unsigned int work = 10000;
49 while (status & KBD_STATUS_OBF)
51 unsigned char scancode;
53 scancode = kbd_read_input();
55 status = kbd_read_status();
56 if(!work--)
58 //printf(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n",status);
59 break;
62 return status;
66 * Wait until we can write to a peripheral again. Any input that comes in
67 * while we're waiting is discarded.
69 void kb_wait(void)
71 ULONG timeout = 1000; /* 1 sec should be enough */
75 unsigned char status = handle_kbd_event();
76 if (! (status & KBD_STATUS_IBF))
77 return;
79 mouse_usleep(1000);
80 timeout--;
81 } while (timeout);
84 void kbd_write_cmd(int cmd)
86 kb_wait();
87 kbd_write_command(KBD_CTRLCMD_WRITE_MODE);
88 kb_wait();
89 kbd_write_output(cmd);
92 void aux_write_ack(int val)
94 kb_wait();
95 kbd_write_command(KBD_CTRLCMD_WRITE_MOUSE);
96 kb_wait();
97 kbd_write_output(val);
98 kbd_wait_for_input();
101 void aux_write_noack(int val)
103 kb_wait();
104 kbd_write_command(KBD_CTRLCMD_WRITE_MOUSE);
105 kb_wait();
106 kbd_write_output(val);
109 void kbd_write_output_w(int data)
111 kb_wait();
112 kbd_write_output(data);
115 void kbd_write_command_w(int data)
117 kb_wait();
118 kbd_write_command(data);
121 #define KBD_NO_DATA (-1)
122 #define KBD_BAD_DATA (-2)
124 int kbd_read_data(void)
126 LONG retval = KBD_NO_DATA;
127 UBYTE status;
129 status = kbd_read_status();
130 if (status & KBD_STATUS_OBF)
132 UBYTE data = kbd_read_input();
134 retval = data;
135 if (status & (KBD_STATUS_GTO | KBD_STATUS_PERR))
136 retval = KBD_BAD_DATA;
139 return retval;
142 int kbd_clear_input(void)
144 int maxread = 100, code, lastcode = KBD_NO_DATA;
145 UBYTE status;
149 status = kbd_read_status();
150 if ((code = kbd_read_data()) == KBD_NO_DATA)
151 break;
152 if (!(status & KBD_STATUS_MOUSE_OBF))
153 lastcode = code;
154 } while (--maxread);
156 return lastcode;
159 int kbd_wait_for_input(void)
161 ULONG timeout = 1000;
165 int retval = kbd_read_data();
166 if (retval >= 0)
167 return retval;
168 mouse_usleep(1000);
169 } while(--timeout);
170 return -1;