38,7 → 38,31 |
|
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <unistd.h> |
#include <kbd.h> |
#include <keys.h> |
|
/* Interesting bits for status register */ |
#define i8042_OUTPUT_FULL 0x1 |
#define i8042_INPUT_FULL 0x2 |
#define i8042_MOUSE_DATA 0x20 |
|
/* Command constants */ |
#define i8042_CMD_KBD 0x60 |
#define i8042_CMD_MOUSE 0xd4 |
|
/* Keyboard cmd byte */ |
#define i8042_KBD_IE 0x1 |
#define i8042_MOUSE_IE 0x2 |
#define i8042_KBD_DISABLE 0x10 |
#define i8042_MOUSE_DISABLE 0x20 |
#define i8042_KBD_TRANSLATE 0x40 |
|
/* Mouse constants */ |
#define MOUSE_OUT_INIT 0xf4 |
#define MOUSE_ACK 0xfa |
|
|
#define SPECIAL 255 |
#define KEY_RELEASE 0x80 |
|
231,12 → 255,13 |
SPECIAL, /* 0x7f */ |
}; |
|
irq_cmd_t i8042_cmds[1] = { |
{ CMD_PORT_READ_1, (void *)0x60, 0 } |
irq_cmd_t i8042_cmds[2] = { |
{ CMD_PORT_READ_1, (void *)0x64, 0, 1 }, |
{ CMD_PORT_READ_1, (void *)0x60, 0, 2 } |
}; |
|
irq_code_t i8042_kbd = { |
1, |
2, |
i8042_cmds |
}; |
|
354,21 → 379,87 |
} |
} |
|
|
static void wait_ready(void) { |
while (i8042_status_read() & i8042_INPUT_FULL) |
; |
} |
|
/** Register uspace irq handler |
* @return |
*/ |
int kbd_arch_init(void) |
{ |
return !(ipc_register_irq(1, &i8042_kbd)); |
int rc1, i; |
int mouseenabled = 0; |
|
iospace_enable(task_get_id(),(void *)i8042_DATA, 5); |
/* Disable kbd, enable mouse */ |
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_data_write(i8042_KBD_DISABLE); |
wait_ready(); |
|
/* Flush all current IO */ |
while (i8042_status_read() & i8042_OUTPUT_FULL) |
i8042_data_read(); |
/* Initialize mouse */ |
i8042_command_write(i8042_CMD_MOUSE); |
wait_ready(); |
i8042_data_write(MOUSE_OUT_INIT); |
wait_ready(); |
|
int mouseanswer = 0; |
for (i=0;i < 1000; i++) { |
int status = i8042_status_read(); |
if (status & i8042_OUTPUT_FULL) { |
int data = i8042_data_read(); |
if (status & i8042_MOUSE_DATA) { |
mouseanswer = data; |
break; |
} |
} |
usleep(1000); |
} |
if (mouseanswer == MOUSE_ACK) { |
/* enable mouse */ |
mouseenabled = 1; |
|
ipc_register_irq(MOUSE_IRQ, &i8042_kbd); |
} |
/* Enable kbd */ |
ipc_register_irq(KBD_IRQ, &i8042_kbd); |
|
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE; |
if (mouseenabled) |
newcontrol |= i8042_MOUSE_IE; |
|
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_data_write(newcontrol); |
wait_ready(); |
|
return 0; |
} |
|
int kbd_arch_process(keybuffer_t *keybuffer, int scan_code) |
/** Process keyboard & mouse events */ |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
if (scan_code != IGNORE_CODE) { |
if (scan_code & KEY_RELEASE) |
key_released(keybuffer, scan_code ^ KEY_RELEASE); |
else |
key_pressed(keybuffer, scan_code); |
int status = IPC_GET_ARG1(*call); |
|
if ((status & i8042_MOUSE_DATA)) { |
; |
} else { |
int scan_code = IPC_GET_ARG2(*call); |
|
if (scan_code != IGNORE_CODE) { |
if (scan_code & KEY_RELEASE) |
key_released(keybuffer, scan_code ^ KEY_RELEASE); |
else |
key_pressed(keybuffer, scan_code); |
} |
} |
return 1; |
} |