10
#include <embox/unit.h>
11
#include <drivers/input/input_dev.h>
12
#include <kernel/irq.h>
14
#include <drivers/ps_mouse.h>
15
#include <drivers/i8042.h>
17
EMBOX_UNIT_INIT(ps_mouse_init);
19
struct ps2_mouse_indev {
20
struct input_dev input_dev;
24
static void ps_mouse_get_input_event(struct input_dev *dev) {
27
struct input_event ev;
31
stat = inb(I8042_STS_PORT);
33
if ((stat & (I8042_STS_AUXOBF | I8042_STS_OBF))
34
!= (I8042_STS_AUXOBF | I8042_STS_OBF)) {
39
stat = inb(I8042_DATA_PORT);
40
if (stat == MOUSE_ACK) {
44
data = inb(I8042_DATA_PORT);
46
ev.value = ((stat & MSTAT_XSIGN ? 0xff00 : 0) | data) << 16;
47
data = inb(I8042_DATA_PORT);
48
ev.value |= (stat & MSTAT_YSIGN ? 0xff00 : 0) | data;
51
if (stat & MSTAT_BUTLEFT) {
52
ev.type |= MOUSE_BUTTON_LEFT;
54
if (stat & MSTAT_BUTRIGHT) {
55
ev.type |= MOUSE_BUTTON_RIGHT;
57
if (stat & MSTAT_BUTMIDDLE) {
58
ev.type |= MOUSE_BUTTON_MIDDLE;
61
input_dev_report_event(dev, &ev);
67
static int ps_mouse_start(struct input_dev *dev) {
72
mode = i8042_read_mode();
73
mode |= I8042_MODE_XLATE | I8042_MODE_SYS | I8042_MODE_MOUSE_INT;
74
mode &= ~I8042_MODE_DISABLE_MOUSE;
75
i8042_write_mode(mode);
78
outb(I8042_CMD_MOUSE_ENABLE, I8042_CMD_PORT);
80
i8042_write_aux(I8042_AUX_SET_SAMPLE);
83
i8042_write_aux(I8042_AUX_SET_RES);
85
i8042_write_aux(I8042_AUX_SET_SCALE21);
87
i8042_write_aux(I8042_AUX_ENABLE_DEV);
94
static int ps_mouse_stop(struct input_dev *dev) {
100
static const struct input_dev_ops ps_mouse_input_ops = {
102
.stop = ps_mouse_stop,
105
static struct ps2_mouse_indev mouse_dev = {
107
.ops = &ps_mouse_input_ops,
109
.type = INPUT_DEV_MOUSE,
113
static irq_return_t ps_mouse_irq_hnd(unsigned int irq_nr, void *data) {
114
struct input_dev *dev = (struct input_dev *) data;
116
ps_mouse_get_input_event(dev);
121
static int ps_mouse_init(void) {
124
res = irq_attach(I8042_MOUSE_IRQ, ps_mouse_irq_hnd, 0,
125
&mouse_dev.input_dev, "ps mouse");
130
ps_mouse_start(NULL);
132
return input_dev_register(&mouse_dev.input_dev);