Rev 894 | Rev 958 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 894 | Rev 895 | ||
---|---|---|---|
Line 50... | Line 50... | ||
50 | #define KBD_DISABLE 0xf5 |
50 | #define KBD_DISABLE 0xf5 |
51 | #define KBD_ACK 0xfa |
51 | #define KBD_ACK 0xfa |
52 | 52 | ||
53 | /* |
53 | /* |
54 | * 60 Write 8042 Command Byte: next data byte written to port 60h is |
54 | * 60 Write 8042 Command Byte: next data byte written to port 60h is |
55 | * placed in 8042 command register.Format: |
55 | * placed in 8042 command register. Format: |
56 | * |
56 | * |
57 | * |7|6|5|4|3|2|1|0|8042 Command Byte |
57 | * |7|6|5|4|3|2|1|0|8042 Command Byte |
58 | * | | | | | | | `---- 1=enable output register full interrupt |
58 | * | | | | | | | `---- 1=enable output register full interrupt |
59 | * | | | | | | `----- should be 0 |
59 | * | | | | | | `----- should be 0 |
60 | * | | | | | `------ 1=set status register system, 0=clear |
60 | * | | | | | `------ 1=set status register system, 0=clear |
Line 72... | Line 72... | ||
72 | #define i8042_WAIT_MASK 0x02 |
72 | #define i8042_WAIT_MASK 0x02 |
73 | 73 | ||
74 | #define SPECIAL '?' |
74 | #define SPECIAL '?' |
75 | #define KEY_RELEASE 0x80 |
75 | #define KEY_RELEASE 0x80 |
76 | 76 | ||
- | 77 | /** |
|
- | 78 | * These codes read from i8042 data register are silently ignored. |
|
- | 79 | */ |
|
- | 80 | #define IGNORE_CODE 0x7f |
|
- | 81 | ||
77 | static void key_released(__u8 sc); |
82 | static void key_released(__u8 sc); |
78 | static void key_pressed(__u8 sc); |
83 | static void key_pressed(__u8 sc); |
79 | static char key_read(chardev_t *d); |
84 | static char key_read(chardev_t *d); |
80 | 85 | ||
81 | #define PRESSED_SHIFT (1<<0) |
86 | #define PRESSED_SHIFT (1<<0) |
Line 259... | Line 264... | ||
259 | SPECIAL, /* 0x7e */ |
264 | SPECIAL, /* 0x7e */ |
260 | SPECIAL, /* 0x7f */ |
265 | SPECIAL, /* 0x7f */ |
261 | }; |
266 | }; |
262 | 267 | ||
263 | static void i8042_interrupt(int n, void *stack); |
268 | static void i8042_interrupt(int n, void *stack); |
- | 269 | static void i8042_wait(void); |
|
264 | 270 | ||
265 | /** Initialize i8042. */ |
271 | /** Initialize i8042. */ |
266 | void i8042_init(void) |
272 | void i8042_init(void) |
267 | { |
273 | { |
268 | exc_register(VECTOR_KBD, "i8042_interrupt", i8042_interrupt); |
274 | exc_register(VECTOR_KBD, "i8042_interrupt", i8042_interrupt); |
269 | while (i8042_status_read() & i8042_WAIT_MASK) { |
- | |
270 | /* wait */ |
275 | i8042_wait(); |
271 | } |
- | |
272 | i8042_command_write(i8042_SET_COMMAND); |
276 | i8042_command_write(i8042_SET_COMMAND); |
273 | while (i8042_status_read() & i8042_WAIT_MASK) { |
- | |
274 | /* wait */ |
277 | i8042_wait(); |
275 | } |
- | |
276 | i8042_data_write(i8042_COMMAND); |
278 | i8042_data_write(i8042_COMMAND); |
- | 279 | i8042_wait(); |
|
277 | 280 | ||
278 | trap_virtual_enable_irqs(1<<IRQ_KBD); |
281 | trap_virtual_enable_irqs(1<<IRQ_KBD); |
279 | chardev_initialize("i8042_kbd", &kbrd, &ops); |
282 | chardev_initialize("i8042_kbd", &kbrd, &ops); |
280 | stdin = &kbrd; |
283 | stdin = &kbrd; |
281 | } |
284 | } |
Line 295... | Line 298... | ||
295 | key_released(x ^ KEY_RELEASE); |
298 | key_released(x ^ KEY_RELEASE); |
296 | else |
299 | else |
297 | key_pressed(x); |
300 | key_pressed(x); |
298 | } |
301 | } |
299 | 302 | ||
- | 303 | /** Wait until the controller reads its data. */ |
|
- | 304 | void i8042_wait(void) { |
|
- | 305 | while (i8042_status_read() & i8042_WAIT_MASK) { |
|
- | 306 | /* wait */ |
|
- | 307 | } |
|
- | 308 | } |
|
- | 309 | ||
300 | /** Process release of key. |
310 | /** Process release of key. |
301 | * |
311 | * |
302 | * @param sc Scancode of the key being released. |
312 | * @param sc Scancode of the key being released. |
303 | */ |
313 | */ |
304 | void key_released(__u8 sc) |
314 | void key_released(__u8 sc) |
Line 500... | Line 510... | ||
500 | while(!(ch = active_read_buff_read())) { |
510 | while(!(ch = active_read_buff_read())) { |
501 | __u8 x; |
511 | __u8 x; |
502 | while (!((x=i8042_status_read() & i8042_BUFFER_FULL_MASK))) |
512 | while (!((x=i8042_status_read() & i8042_BUFFER_FULL_MASK))) |
503 | ; |
513 | ; |
504 | x = i8042_data_read(); |
514 | x = i8042_data_read(); |
- | 515 | if (x != IGNORE_CODE) { |
|
505 | if (x & KEY_RELEASE) |
516 | if (x & KEY_RELEASE) |
506 | key_released(x ^ KEY_RELEASE); |
517 | key_released(x ^ KEY_RELEASE); |
507 | else |
518 | else |
508 | active_read_key_pressed(x); |
519 | active_read_key_pressed(x); |
- | 520 | } |
|
509 | } |
521 | } |
510 | return ch; |
522 | return ch; |
511 | } |
523 | } |
- | 524 | ||
- | 525 | /** Poll for key press and release events. |
|
- | 526 | * |
|
- | 527 | * This function can be used to implement keyboard polling. |
|
- | 528 | */ |
|
- | 529 | void i8042_poll(void) |
|
- | 530 | { |
|
- | 531 | __u8 x; |
|
- | 532 | ||
- | 533 | while (((x = i8042_status_read() & i8042_BUFFER_FULL_MASK))) { |
|
- | 534 | x = i8042_data_read(); |
|
- | 535 | if (x != IGNORE_CODE) { |
|
- | 536 | if (x & KEY_RELEASE) |
|
- | 537 | key_released(x ^ KEY_RELEASE); |
|
- | 538 | else |
|
- | 539 | key_pressed(x); |
|
- | 540 | } |
|
- | 541 | } |
|
- | 542 | } |