embox

Форк
0
133 строки · 2.6 Кб
1
/*
2
 * @file
3
 *
4
 * @date Feb 14, 2013
5
 * @author: Anton Bondarev
6
 */
7

8
#include <asm/io.h>
9
#include <errno.h>
10
#include <embox/unit.h>
11
#include <drivers/input/input_dev.h>
12
#include <kernel/irq.h>
13

14
#include <drivers/ps_mouse.h>
15
#include <drivers/i8042.h>
16

17
EMBOX_UNIT_INIT(ps_mouse_init);
18

19
struct ps2_mouse_indev {
20
	struct input_dev input_dev;
21
};
22

23
//http://lists.gnu.org/archive/html/qemu-devel/2004-11/msg00082.html
24
static void ps_mouse_get_input_event(struct input_dev *dev) {
25
	uint8_t data;
26
	uint8_t stat;
27
	struct input_event ev;
28

29
	irq_lock();
30
	{
31
		stat = inb(I8042_STS_PORT);
32

33
		if ((stat & (I8042_STS_AUXOBF | I8042_STS_OBF))
34
				!= (I8042_STS_AUXOBF | I8042_STS_OBF)) {
35
			/* this is keyboard scan code */
36
			goto out;
37
		}
38

39
		stat = inb(I8042_DATA_PORT);
40
		if (stat == MOUSE_ACK) {
41
			goto out;
42
		}
43

44
		data = inb(I8042_DATA_PORT);
45

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;
49

50
		ev.type = 0;
51
		if (stat & MSTAT_BUTLEFT) {
52
			ev.type |= MOUSE_BUTTON_LEFT;
53
		}
54
		if (stat & MSTAT_BUTRIGHT) {
55
			ev.type  |= MOUSE_BUTTON_RIGHT;
56
		}
57
		if (stat & MSTAT_BUTMIDDLE) {
58
			ev.type  |= MOUSE_BUTTON_MIDDLE;
59
		}
60
//		ev.type = stat & MSTAT_BUTMASK;
61
		input_dev_report_event(dev, &ev);
62
	}
63
out:
64
	irq_unlock();
65
}
66

67
static int ps_mouse_start(struct input_dev *dev) {
68
	uint8_t mode;
69

70
	irq_lock();
71
	{
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);
76

77
		i8042_wait_write();
78
		outb(I8042_CMD_MOUSE_ENABLE, I8042_CMD_PORT);
79

80
		i8042_write_aux(I8042_AUX_SET_SAMPLE);
81
		i8042_write_aux(100); /* 100 samples/sec */
82

83
		i8042_write_aux(I8042_AUX_SET_RES);
84
		i8042_write_aux(3); /* 8 counts per mm */
85
		i8042_write_aux(I8042_AUX_SET_SCALE21);
86

87
		i8042_write_aux(I8042_AUX_ENABLE_DEV);
88
	}
89
	irq_unlock();
90

91
	return 0;
92
}
93

94
static int ps_mouse_stop(struct input_dev *dev) {
95

96
	/* TODO */
97
	return 0;
98
}
99

100
static const struct input_dev_ops ps_mouse_input_ops = {
101
	/*.start = ps_mouse_start,*/
102
	.stop = ps_mouse_stop,
103
};
104

105
static struct ps2_mouse_indev mouse_dev = {
106
	.input_dev = {
107
		.ops = &ps_mouse_input_ops,
108
		.name = "ps-mouse",
109
		.type = INPUT_DEV_MOUSE,
110
	},
111
};
112

113
static irq_return_t ps_mouse_irq_hnd(unsigned int irq_nr, void *data) {
114
	struct input_dev *dev = (struct input_dev *) data;
115

116
	ps_mouse_get_input_event(dev);
117

118
	return IRQ_HANDLED;
119
}
120

121
static int ps_mouse_init(void) {
122
	int res;
123

124
	res = irq_attach(I8042_MOUSE_IRQ, ps_mouse_irq_hnd, 0,
125
					 &mouse_dev.input_dev, "ps mouse");
126
	if (res < 0) {
127
		return res;
128
	}
129

130
	ps_mouse_start(NULL);
131

132
	return input_dev_register(&mouse_dev.input_dev);
133
}
134

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.