Rev 1657 | Rev 1707 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1657 | Rev 1694 | ||
---|---|---|---|
Line 36... | Line 36... | ||
36 | * @ingroup kbdamd64 |
36 | * @ingroup kbdamd64 |
37 | */ |
37 | */ |
38 | 38 | ||
39 | #include <arch/kbd.h> |
39 | #include <arch/kbd.h> |
40 | #include <ipc/ipc.h> |
40 | #include <ipc/ipc.h> |
- | 41 | #include <unistd.h> |
|
- | 42 | #include <kbd.h> |
|
- | 43 | #include <keys.h> |
|
- | 44 | ||
- | 45 | /* Interesting bits for status register */ |
|
- | 46 | #define i8042_OUTPUT_FULL 0x1 |
|
- | 47 | #define i8042_INPUT_FULL 0x2 |
|
- | 48 | #define i8042_MOUSE_DATA 0x20 |
|
- | 49 | ||
- | 50 | /* Command constants */ |
|
- | 51 | #define i8042_CMD_KBD 0x60 |
|
- | 52 | #define i8042_CMD_MOUSE 0xd4 |
|
- | 53 | ||
- | 54 | /* Keyboard cmd byte */ |
|
- | 55 | #define i8042_KBD_IE 0x1 |
|
- | 56 | #define i8042_MOUSE_IE 0x2 |
|
- | 57 | #define i8042_KBD_DISABLE 0x10 |
|
- | 58 | #define i8042_MOUSE_DISABLE 0x20 |
|
- | 59 | #define i8042_KBD_TRANSLATE 0x40 |
|
- | 60 | ||
- | 61 | /* Mouse constants */ |
|
- | 62 | #define MOUSE_OUT_INIT 0xf4 |
|
- | 63 | #define MOUSE_ACK 0xfa |
|
- | 64 | ||
41 | 65 | ||
42 | #define SPECIAL 255 |
66 | #define SPECIAL 255 |
43 | #define KEY_RELEASE 0x80 |
67 | #define KEY_RELEASE 0x80 |
44 | 68 | ||
45 | /** |
69 | /** |
Line 229... | Line 253... | ||
229 | SPECIAL, /* 0x7d */ |
253 | SPECIAL, /* 0x7d */ |
230 | SPECIAL, /* 0x7e */ |
254 | SPECIAL, /* 0x7e */ |
231 | SPECIAL, /* 0x7f */ |
255 | SPECIAL, /* 0x7f */ |
232 | }; |
256 | }; |
233 | 257 | ||
234 | irq_cmd_t i8042_cmds[1] = { |
258 | irq_cmd_t i8042_cmds[2] = { |
- | 259 | { CMD_PORT_READ_1, (void *)0x64, 0, 1 }, |
|
235 | { CMD_PORT_READ_1, (void *)0x60, 0 } |
260 | { CMD_PORT_READ_1, (void *)0x60, 0, 2 } |
236 | }; |
261 | }; |
237 | 262 | ||
238 | irq_code_t i8042_kbd = { |
263 | irq_code_t i8042_kbd = { |
239 | 1, |
264 | 2, |
240 | i8042_cmds |
265 | i8042_cmds |
241 | }; |
266 | }; |
242 | 267 | ||
243 | static int key_released(keybuffer_t *keybuffer, unsigned char key) |
268 | static int key_released(keybuffer_t *keybuffer, unsigned char key) |
244 | { |
269 | { |
Line 352... | Line 377... | ||
352 | keybuffer_push(keybuffer, map[key]); |
377 | keybuffer_push(keybuffer, map[key]); |
353 | break; |
378 | break; |
354 | } |
379 | } |
355 | } |
380 | } |
356 | 381 | ||
- | 382 | ||
- | 383 | static void wait_ready(void) { |
|
- | 384 | while (i8042_status_read() & i8042_INPUT_FULL) |
|
- | 385 | ; |
|
- | 386 | } |
|
- | 387 | ||
357 | /** Register uspace irq handler |
388 | /** Register uspace irq handler |
358 | * @return |
389 | * @return |
359 | */ |
390 | */ |
360 | int kbd_arch_init(void) |
391 | int kbd_arch_init(void) |
361 | { |
392 | { |
- | 393 | int rc1, i; |
|
- | 394 | int mouseenabled = 0; |
|
- | 395 | ||
- | 396 | iospace_enable(task_get_id(),(void *)i8042_DATA, 5); |
|
- | 397 | /* Disable kbd, enable mouse */ |
|
- | 398 | i8042_command_write(i8042_CMD_KBD); |
|
- | 399 | wait_ready(); |
|
- | 400 | i8042_command_write(i8042_CMD_KBD); |
|
- | 401 | wait_ready(); |
|
- | 402 | i8042_data_write(i8042_KBD_DISABLE); |
|
- | 403 | wait_ready(); |
|
- | 404 | ||
- | 405 | /* Flush all current IO */ |
|
- | 406 | while (i8042_status_read() & i8042_OUTPUT_FULL) |
|
- | 407 | i8042_data_read(); |
|
- | 408 | /* Initialize mouse */ |
|
- | 409 | i8042_command_write(i8042_CMD_MOUSE); |
|
- | 410 | wait_ready(); |
|
- | 411 | i8042_data_write(MOUSE_OUT_INIT); |
|
- | 412 | wait_ready(); |
|
- | 413 | ||
- | 414 | int mouseanswer = 0; |
|
- | 415 | for (i=0;i < 1000; i++) { |
|
- | 416 | int status = i8042_status_read(); |
|
- | 417 | if (status & i8042_OUTPUT_FULL) { |
|
- | 418 | int data = i8042_data_read(); |
|
- | 419 | if (status & i8042_MOUSE_DATA) { |
|
- | 420 | mouseanswer = data; |
|
- | 421 | break; |
|
- | 422 | } |
|
- | 423 | } |
|
- | 424 | usleep(1000); |
|
- | 425 | } |
|
- | 426 | if (mouseanswer == MOUSE_ACK) { |
|
- | 427 | /* enable mouse */ |
|
- | 428 | mouseenabled = 1; |
|
- | 429 | ||
- | 430 | ipc_register_irq(MOUSE_IRQ, &i8042_kbd); |
|
- | 431 | } |
|
- | 432 | /* Enable kbd */ |
|
362 | return !(ipc_register_irq(1, &i8042_kbd)); |
433 | ipc_register_irq(KBD_IRQ, &i8042_kbd); |
- | 434 | ||
- | 435 | int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE; |
|
- | 436 | if (mouseenabled) |
|
- | 437 | newcontrol |= i8042_MOUSE_IE; |
|
- | 438 | ||
- | 439 | i8042_command_write(i8042_CMD_KBD); |
|
- | 440 | wait_ready(); |
|
- | 441 | i8042_data_write(newcontrol); |
|
- | 442 | wait_ready(); |
|
- | 443 | ||
- | 444 | return 0; |
|
363 | } |
445 | } |
364 | 446 | ||
- | 447 | /** Process keyboard & mouse events */ |
|
365 | int kbd_arch_process(keybuffer_t *keybuffer, int scan_code) |
448 | int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
366 | { |
449 | { |
- | 450 | int status = IPC_GET_ARG1(*call); |
|
- | 451 | ||
- | 452 | if ((status & i8042_MOUSE_DATA)) { |
|
- | 453 | ; |
|
- | 454 | } else { |
|
- | 455 | int scan_code = IPC_GET_ARG2(*call); |
|
- | 456 | ||
367 | if (scan_code != IGNORE_CODE) { |
457 | if (scan_code != IGNORE_CODE) { |
368 | if (scan_code & KEY_RELEASE) |
458 | if (scan_code & KEY_RELEASE) |
369 | key_released(keybuffer, scan_code ^ KEY_RELEASE); |
459 | key_released(keybuffer, scan_code ^ KEY_RELEASE); |
370 | else |
460 | else |
371 | key_pressed(keybuffer, scan_code); |
461 | key_pressed(keybuffer, scan_code); |
- | 462 | } |
|
372 | } |
463 | } |
373 | return 1; |
464 | return 1; |
374 | } |
465 | } |
375 | 466 | ||
376 | /** |
467 | /** |