12
#include <drivers/input/keymap.h>
13
#include <drivers/input/input_dev.h>
14
#include <drivers/ps_keyboard.h>
16
#include <kernel/irq.h>
17
#include <embox/unit.h>
18
#include <drivers/diag.h>
19
#include <drivers/tty.h>
20
#include <drivers/video_term.h>
21
#include <drivers/i8042.h>
23
EMBOX_UNIT_INIT(keyboard_init);
25
static void keyboard_send_cmd(uint8_t cmd) {
27
keyboard_wait_write(status);
28
outb(cmd, I8042_CMD_PORT);
31
static unsigned char keyboard_get_mode(void) {
34
keyboard_send_cmd(I8042_CMD_READ_MODE);
35
keyboard_wait_read(status);
36
return inb(I8042_DATA_PORT);
39
static void keyboard_set_mode(unsigned char mode) {
42
keyboard_send_cmd(I8042_CMD_WRITE_MODE);
43
keyboard_wait_write(status);
44
outb(mode, I8042_DATA_PORT);
47
static int keyboard_get_input_event(struct input_dev *dev, struct input_event *event) {
48
uint8_t scan_code, status;
53
status = keyboard_read_stat();
55
if (!(status & I8042_STS_OBF)) {
60
scan_code = inb(I8042_DATA_PORT);
62
if (scan_code == KEYBOARD_SCAN_CODE_EXT) {
67
if (status & I8042_STS_AUXOBF) {
72
keyboard_scan_code_to_event(scan_code, event);
79
static int keyboard_start(struct input_dev *indev) {
86
if (inb(0x64) == 0xFF) {
90
keyboard_send_cmd(I8042_CMD_PORT_DIS);
92
while (keyboard_havechar()) inb(I8042_DATA_PORT);
95
mode = keyboard_get_mode();
98
mode |= I8042_MODE_XLATE;
100
mode &= ~I8042_MODE_DISABLE;
102
mode |= I8042_MODE_INTERRUPT;
104
keyboard_set_mode(mode);
106
keyboard_send_cmd(I8042_CMD_PORT_EN);
109
outb(I8042_KBD_RESET_ENABLE, I8042_DATA_PORT);
116
static int keyboard_stop(struct input_dev *dev) {
122
static const struct input_dev_ops kbd_input_ops = {
124
.stop = keyboard_stop,
127
static struct input_dev kbd_dev = {
128
.ops = &kbd_input_ops,
129
.name = "ps-keyboard",
130
.type = INPUT_DEV_KBD,
133
static irq_return_t ps_kbd_irq_hnd(unsigned int irq_nr, void *data) {
134
struct input_dev *dev = (struct input_dev *) data;
135
struct input_event ev;
138
ret = keyboard_get_input_event(dev, &ev);
140
input_dev_report_event(dev, &ev);
146
static int keyboard_init(void) {
149
res = irq_attach(I8042_KBD_IRQ, ps_kbd_irq_hnd, 0,
150
&kbd_dev, "ps keyboard");
155
keyboard_start(NULL);
157
return input_dev_register(&kbd_dev);