30 #include <linux/module.h>
31 #include <linux/slab.h>
33 #include <linux/input.h>
34 #include <linux/serio.h>
37 #define DRIVER_DESC "Serial mouse driver"
43 static const char *sermouse_protocols[] = {
"None",
"Mouse Systems Mouse",
"Sun Mouse",
"Microsoft Mouse",
44 "Logitech M+ Mouse",
"Microsoft MZ Mouse",
"Logitech MZ+ Mouse",
45 "Logitech MZ++ Mouse"};
48 struct input_dev *
dev;
64 struct input_dev *
dev = sermouse->
dev;
65 signed char *
buf = sermouse->
buf;
67 switch (sermouse->
count) {
70 if ((data & 0xf8) != 0x80)
72 input_report_key(dev,
BTN_LEFT, !(data & 4));
73 input_report_key(dev,
BTN_RIGHT, !(data & 1));
74 input_report_key(dev,
BTN_MIDDLE, !(data & 2));
79 input_report_rel(dev,
REL_X, data / 2);
80 input_report_rel(dev,
REL_Y, -buf[1]);
81 buf[0] = data - data / 2;
86 input_report_rel(dev,
REL_X, buf[0]);
87 input_report_rel(dev,
REL_Y, buf[1] - data);
94 if (++sermouse->
count == 5)
104 static void sermouse_process_ms(
struct sermouse *sermouse,
signed char data)
106 struct input_dev *dev = sermouse->
dev;
107 signed char *buf = sermouse->
buf;
111 else if (sermouse->
count == 0)
114 switch (sermouse->
count) {
118 input_report_key(dev,
BTN_LEFT, (data >> 5) & 1);
119 input_report_key(dev,
BTN_RIGHT, (data >> 4) & 1);
124 data = (
signed char) (((buf[1] << 6) & 0xc0) | (data & 0x3f));
125 input_report_rel(dev,
REL_X, data / 2);
126 input_report_rel(dev,
REL_Y, buf[4]);
127 buf[3] = data - data / 2;
132 if ((sermouse->
type ==
SERIO_MS) && !data && !buf[2] && !((buf[0] & 0xf0) ^ buf[1]))
136 data = (
signed char) (((buf[1] << 4) & 0xc0) | (data & 0x3f));
137 input_report_rel(dev,
REL_X, buf[3]);
138 input_report_rel(dev,
REL_Y, data - buf[4]);
144 switch (sermouse->
type) {
150 if ((data >> 2) & 3)
break;
151 input_report_key(dev,
BTN_MIDDLE, (data >> 5) & 1);
152 input_report_key(dev,
BTN_SIDE, (data >> 4) & 1);
157 input_report_key(dev,
BTN_SIDE, (data >> 5) & 1);
160 input_report_key(dev,
BTN_MIDDLE, (data >> 4) & 1);
161 input_report_rel(dev,
REL_WHEEL, (data & 8) - (data & 7));
169 buf[1] = (data >> 2) & 0x0f;
181 input_report_key(dev,
BTN_SIDE, (data >> 4) & 1);
182 input_report_key(dev,
BTN_EXTRA, (data >> 5) & 1);
190 "sermouse.c: Received MZ++ packet %x, don't know how to handle.\n", buf[1]);
208 unsigned char data,
unsigned int flags)
210 struct sermouse *sermouse = serio_get_drvdata(serio);
218 sermouse_process_ms(sermouse, data);
220 sermouse_process_msc(sermouse, data);
230 static void sermouse_disconnect(
struct serio *serio)
232 struct sermouse *sermouse = serio_get_drvdata(serio);
235 serio_set_drvdata(serio,
NULL);
236 input_unregister_device(sermouse->
dev);
245 static int sermouse_connect(
struct serio *serio,
struct serio_driver *drv)
247 struct sermouse *sermouse;
248 struct input_dev *input_dev;
249 unsigned char c = serio->
id.extra;
252 sermouse = kzalloc(
sizeof(
struct sermouse),
GFP_KERNEL);
253 input_dev = input_allocate_device();
254 if (!sermouse || !input_dev)
257 sermouse->
dev = input_dev;
259 sermouse->
type = serio->
id.proto;
261 input_dev->name = sermouse_protocols[sermouse->
type];
262 input_dev->phys = sermouse->
phys;
264 input_dev->id.vendor = sermouse->
type;
265 input_dev->id.product =
c;
266 input_dev->id.version = 0x0100;
267 input_dev->dev.parent = &serio->
dev;
280 serio_set_drvdata(serio, sermouse);
286 err = input_register_device(sermouse->
dev);
293 fail2: serio_set_drvdata(serio,
NULL);
294 fail1: input_free_device(input_dev);
352 .id_table = sermouse_serio_ids,
353 .interrupt = sermouse_interrupt,
354 .connect = sermouse_connect,
355 .disconnect = sermouse_disconnect,