2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Desc: Low-level routines for i8042 controller.
10 #include "kbd_common.h"
12 #define TIMER_RPROK 3599597124UL
14 static int wait_for_input(ULONG timeout
);
16 static ULONG
usec2tick(ULONG usec
)
19 ULONG prok
= TIMER_RPROK
;
20 asm volatile("movl $0,%%eax; divl %2":"=a"(ret
):"d"(usec
),"m"(prok
));
25 * !!! FIXME PLEASE !!!
26 * These delays cannot be just converted to timer.device, because they are
27 * used also by kbd_updateleds() function, which is called from within interrupt.
28 * Delays inside interrupts are evil, and this needs one more serious refactoring
29 * iteration. I think LED control can be delegated to separate task, which is
30 * signalled by interrupt code when update is needed.
31 * After this delays can be converted to timer.device. Mouse driver does not use
32 * them inside interrupt.
34 void kbd_usleep(LONG usec
)
37 usec
= usec2tick(usec
);
41 oldtick
+= inb(0x42) << 8;
47 tick
+= inb(0x42) << 8;
49 usec
-= (oldtick
- tick
);
50 if (tick
> oldtick
) usec
-= 0x10000;
55 unsigned char handle_kbd_event(void)
57 unsigned char status
= kbd_read_status();
58 unsigned int work
= 10000;
60 while (status
& KBD_STATUS_OBF
)
64 status
= kbd_read_status();
67 //printf(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n",status);
75 * Wait until we can write to a peripheral again. Any input that comes in
76 * while we're waiting is discarded.
78 void kb_wait(ULONG timeout
)
82 unsigned char status
= handle_kbd_event();
83 if (! (status
& KBD_STATUS_IBF
))
91 void kbd_write_cmd(int cmd
)
94 kbd_write_command(KBD_CTRLCMD_WRITE_MODE
);
96 kbd_write_output(cmd
);
100 * Aux (mouse) port uses longer delays, this is necessary
101 * in order to detect IntelliMouse properly
103 void aux_write_ack(int val
)
106 kbd_write_command(KBD_CTRLCMD_WRITE_MOUSE
);
108 kbd_write_output(val
);
109 aux_wait_for_input();
112 void aux_write_noack(int val
)
115 kbd_write_command(KBD_CTRLCMD_WRITE_MOUSE
);
117 kbd_write_output(val
);
120 void kbd_write_output_w(int data
)
123 kbd_write_output(data
);
126 void kbd_write_command_w(int data
)
129 kbd_write_command(data
);
132 int kbd_read_data(void)
134 LONG retval
= KBD_NO_DATA
;
137 status
= kbd_read_status();
138 if (status
& KBD_STATUS_OBF
)
140 UBYTE data
= kbd_read_input();
143 if (status
& (KBD_STATUS_GTO
| KBD_STATUS_PERR
))
144 retval
= KBD_BAD_DATA
;
150 int kbd_clear_input(void)
152 int maxread
= 100, code
, lastcode
= KBD_NO_DATA
;
157 status
= kbd_read_status();
158 if ((code
= kbd_read_data()) == KBD_NO_DATA
)
160 if (!(status
& KBD_STATUS_MOUSE_OBF
))
167 int kbd_wait_for_input(void)
169 return wait_for_input(100);
172 int aux_wait_for_input(void)
174 return wait_for_input(1000);
177 static int wait_for_input(ULONG timeout
)
181 int retval
= kbd_read_data();