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 | } |
|