Detab
[AROS.git] / arch / i386-pc / drivers / keyboard / kbd_common.c
blobfbd12fc969725cc56c0c515711f64d48292b8dca
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PS/2 keyboard 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 kbd_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;
43 unsigned char handle_kbd_event(void)
45 unsigned char status = kbd_read_status();
46 unsigned int work = 10000;
48 while (status & KBD_STATUS_OBF)
50 kbd_read_input();
52 status = kbd_read_status();
53 if(!work--)
55 //printf(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n",status);
56 break;
59 return status;
63 * Wait until we can write to a peripheral again. Any input that comes in
64 * while we're waiting is discarded.
66 void kb_wait(void)
68 ULONG timeout = 100; /* 0.1 sec should be enough */
72 unsigned char status = handle_kbd_event();
73 if (! (status & KBD_STATUS_IBF))
74 return;
76 kbd_usleep(1000);
77 timeout--;
78 } while (timeout);
81 void kbd_write_cmd(int cmd)
83 kb_wait();
84 kbd_write_command(KBD_CTRLCMD_WRITE_MODE);
85 kb_wait();
86 kbd_write_output(cmd);
89 void kbd_write_output_w(int data)
91 kb_wait();
92 kbd_write_output(data);
95 void kbd_write_command_w(int data)
97 kb_wait();
98 kbd_write_command(data);
101 #define KBD_NO_DATA (-1)
102 #define KBD_BAD_DATA (-2)
104 int kbd_read_data(void)
106 LONG retval = KBD_NO_DATA;
107 UBYTE status;
109 status = kbd_read_status();
110 if (status & KBD_STATUS_OBF)
112 UBYTE data = kbd_read_input();
114 retval = data;
115 if (status & (KBD_STATUS_GTO | KBD_STATUS_PERR))
116 retval = KBD_BAD_DATA;
119 return retval;
122 int kbd_clear_input(void)
124 int maxread = 100, code, lastcode = KBD_NO_DATA;
125 UBYTE status;
129 status = kbd_read_status();
130 if ((code = kbd_read_data()) == KBD_NO_DATA)
131 break;
132 if (!(status & KBD_STATUS_MOUSE_OBF))
133 lastcode = code;
134 } while (--maxread);
136 return lastcode;
139 int kbd_wait_for_input(void)
141 ULONG timeout = 100;
145 int retval = kbd_read_data();
146 if (retval >= 0)
147 return retval;
148 kbd_usleep(1000);
149 } while(--timeout);
150 return -1;