diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 17:47:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 17:47:31 -0400 |
commit | 3e0777b8fa96f7073ed5d13d3bc1d573b766bef9 (patch) | |
tree | 3849e8457dd8f038ab7da025c708e275b43ea9c1 /drivers/input/mouse | |
parent | a94130e00038ebeb2f66901a4a4a9e05a03051c1 (diff) | |
parent | e5119885f00874453e837e3407014b73de2f4741 (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/dtor/input.git manually
Some manual fixups required due to clashes with the PF_FREEZE cleanups.
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/Makefile | 2 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 52 | ||||
-rw-r--r-- | drivers/input/mouse/amimouse.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/inport.c | 38 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 134 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.h | 17 | ||||
-rw-r--r-- | drivers/input/mouse/logibm.c | 17 | ||||
-rw-r--r-- | drivers/input/mouse/maplemouse.c | 75 | ||||
-rw-r--r-- | drivers/input/mouse/pc110pad.c | 21 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 351 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 4 | ||||
-rw-r--r-- | drivers/input/mouse/rpcmouse.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/vsxxxaa.c | 4 |
13 files changed, 539 insertions, 186 deletions
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index a7864195806a..c4909b49337d 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -15,4 +15,4 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | |||
15 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | 15 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o |
16 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 16 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
17 | 17 | ||
18 | psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o | 18 | psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7bf4be733e9a..a12e98158a75 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -30,10 +30,11 @@ | |||
30 | 30 | ||
31 | #define ALPS_DUALPOINT 0x01 | 31 | #define ALPS_DUALPOINT 0x01 |
32 | #define ALPS_WHEEL 0x02 | 32 | #define ALPS_WHEEL 0x02 |
33 | #define ALPS_FW_BK 0x04 | 33 | #define ALPS_FW_BK_1 0x04 |
34 | #define ALPS_4BTN 0x08 | 34 | #define ALPS_4BTN 0x08 |
35 | #define ALPS_OLDPROTO 0x10 | 35 | #define ALPS_OLDPROTO 0x10 |
36 | #define ALPS_PASS 0x20 | 36 | #define ALPS_PASS 0x20 |
37 | #define ALPS_FW_BK_2 0x40 | ||
37 | 38 | ||
38 | static struct alps_model_info alps_model_data[] = { | 39 | static struct alps_model_info alps_model_data[] = { |
39 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ | 40 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ |
@@ -43,11 +44,11 @@ static struct alps_model_info alps_model_data[] = { | |||
43 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 44 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
44 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 }, | 45 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, 0 }, |
45 | { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ | 46 | { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ |
46 | { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK }, /* NEC Versa L320 */ | 47 | { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ |
47 | { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, | 48 | { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, |
48 | { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */ | 49 | { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */ |
49 | { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 50 | { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
50 | { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 51 | { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ |
51 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ | 52 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ |
52 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 53 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, |
53 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 54 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ |
@@ -61,11 +62,11 @@ static struct alps_model_info alps_model_data[] = { | |||
61 | 62 | ||
62 | /* | 63 | /* |
63 | * ALPS abolute Mode - new format | 64 | * ALPS abolute Mode - new format |
64 | * | 65 | * |
65 | * byte 0: 1 ? ? ? 1 ? ? ? | 66 | * byte 0: 1 ? ? ? 1 ? ? ? |
66 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 | 67 | * byte 1: 0 x6 x5 x4 x3 x2 x1 x0 |
67 | * byte 2: 0 x10 x9 x8 x7 ? fin ges | 68 | * byte 2: 0 x10 x9 x8 x7 ? fin ges |
68 | * byte 3: 0 y9 y8 y7 1 M R L | 69 | * byte 3: 0 y9 y8 y7 1 M R L |
69 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 | 70 | * byte 4: 0 y6 y5 y4 y3 y2 y1 y0 |
70 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 | 71 | * byte 5: 0 z6 z5 z4 z3 z2 z1 z0 |
71 | * | 72 | * |
@@ -81,11 +82,12 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) | |||
81 | struct input_dev *dev = &psmouse->dev; | 82 | struct input_dev *dev = &psmouse->dev; |
82 | struct input_dev *dev2 = &priv->dev2; | 83 | struct input_dev *dev2 = &priv->dev2; |
83 | int x, y, z, ges, fin, left, right, middle; | 84 | int x, y, z, ges, fin, left, right, middle; |
85 | int back = 0, forward = 0; | ||
84 | 86 | ||
85 | input_regs(dev, regs); | 87 | input_regs(dev, regs); |
86 | 88 | ||
87 | if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ | 89 | if ((packet[0] & 0xc8) == 0x08) { /* 3-byte PS/2 packet */ |
88 | input_report_key(dev2, BTN_LEFT, packet[0] & 1); | 90 | input_report_key(dev2, BTN_LEFT, packet[0] & 1); |
89 | input_report_key(dev2, BTN_RIGHT, packet[0] & 2); | 91 | input_report_key(dev2, BTN_RIGHT, packet[0] & 2); |
90 | input_report_key(dev2, BTN_MIDDLE, packet[0] & 4); | 92 | input_report_key(dev2, BTN_MIDDLE, packet[0] & 4); |
91 | input_report_rel(dev2, REL_X, | 93 | input_report_rel(dev2, REL_X, |
@@ -112,6 +114,18 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) | |||
112 | z = packet[5]; | 114 | z = packet[5]; |
113 | } | 115 | } |
114 | 116 | ||
117 | if (priv->i->flags & ALPS_FW_BK_1) { | ||
118 | back = packet[2] & 4; | ||
119 | forward = packet[0] & 0x10; | ||
120 | } | ||
121 | |||
122 | if (priv->i->flags & ALPS_FW_BK_2) { | ||
123 | back = packet[3] & 4; | ||
124 | forward = packet[2] & 4; | ||
125 | if ((middle = forward && back)) | ||
126 | forward = back = 0; | ||
127 | } | ||
128 | |||
115 | ges = packet[2] & 1; | 129 | ges = packet[2] & 1; |
116 | fin = packet[2] & 2; | 130 | fin = packet[2] & 2; |
117 | 131 | ||
@@ -155,13 +169,12 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs) | |||
155 | input_report_abs(dev, ABS_PRESSURE, z); | 169 | input_report_abs(dev, ABS_PRESSURE, z); |
156 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); | 170 | input_report_key(dev, BTN_TOOL_FINGER, z > 0); |
157 | 171 | ||
158 | |||
159 | if (priv->i->flags & ALPS_WHEEL) | 172 | if (priv->i->flags & ALPS_WHEEL) |
160 | input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08)); | 173 | input_report_rel(dev, REL_WHEEL, ((packet[0] >> 4) & 0x07) | ((packet[2] >> 2) & 0x08)); |
161 | 174 | ||
162 | if (priv->i->flags & ALPS_FW_BK) { | 175 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
163 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x10); | 176 | input_report_key(dev, BTN_FORWARD, forward); |
164 | input_report_key(dev, BTN_BACK, packet[2] & 0x04); | 177 | input_report_key(dev, BTN_BACK, back); |
165 | } | 178 | } |
166 | 179 | ||
167 | input_sync(dev); | 180 | input_sync(dev); |
@@ -257,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers | |||
257 | static int alps_passthrough_mode(struct psmouse *psmouse, int enable) | 270 | static int alps_passthrough_mode(struct psmouse *psmouse, int enable) |
258 | { | 271 | { |
259 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 272 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
260 | unsigned char param[3]; | ||
261 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; | 273 | int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11; |
262 | 274 | ||
263 | if (ps2_command(ps2dev, NULL, cmd) || | 275 | if (ps2_command(ps2dev, NULL, cmd) || |
@@ -267,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable) | |||
267 | return -1; | 279 | return -1; |
268 | 280 | ||
269 | /* we may get 3 more bytes, just ignore them */ | 281 | /* we may get 3 more bytes, just ignore them */ |
270 | ps2_command(ps2dev, param, 0x0300); | 282 | ps2_drain(ps2dev, 3, 100); |
271 | 283 | ||
272 | return 0; | 284 | return 0; |
273 | } | 285 | } |
@@ -425,7 +437,7 @@ int alps_init(struct psmouse *psmouse) | |||
425 | psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); | 437 | psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); |
426 | } | 438 | } |
427 | 439 | ||
428 | if (priv->i->flags & ALPS_FW_BK) { | 440 | if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { |
429 | psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); | 441 | psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); |
430 | psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); | 442 | psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); |
431 | } | 443 | } |
@@ -436,8 +448,8 @@ int alps_init(struct psmouse *psmouse) | |||
436 | priv->dev2.id.bustype = BUS_I8042; | 448 | priv->dev2.id.bustype = BUS_I8042; |
437 | priv->dev2.id.vendor = 0x0002; | 449 | priv->dev2.id.vendor = 0x0002; |
438 | priv->dev2.id.product = PSMOUSE_ALPS; | 450 | priv->dev2.id.product = PSMOUSE_ALPS; |
439 | priv->dev2.id.version = 0x0000; | 451 | priv->dev2.id.version = 0x0000; |
440 | 452 | ||
441 | priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 453 | priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
442 | priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); | 454 | priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); |
443 | priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 455 | priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
@@ -461,17 +473,15 @@ init_fail: | |||
461 | int alps_detect(struct psmouse *psmouse, int set_properties) | 473 | int alps_detect(struct psmouse *psmouse, int set_properties) |
462 | { | 474 | { |
463 | int version; | 475 | int version; |
464 | struct alps_model_info *model; | 476 | struct alps_model_info *model; |
465 | 477 | ||
466 | if (!(model = alps_get_model(psmouse, &version))) | 478 | if (!(model = alps_get_model(psmouse, &version))) |
467 | return -1; | 479 | return -1; |
468 | 480 | ||
469 | if (set_properties) { | 481 | if (set_properties) { |
470 | psmouse->vendor = "ALPS"; | 482 | psmouse->vendor = "ALPS"; |
471 | if (model->flags & ALPS_DUALPOINT) | 483 | psmouse->name = model->flags & ALPS_DUALPOINT ? |
472 | psmouse->name = "DualPoint TouchPad"; | 484 | "DualPoint TouchPad" : "GlidePoint"; |
473 | else | ||
474 | psmouse->name = "GlidePoint"; | ||
475 | psmouse->model = version; | 485 | psmouse->model = version; |
476 | } | 486 | } |
477 | return 0; | 487 | return 0; |
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c index 7baa09cca7c5..e994849efb8f 100644 --- a/drivers/input/mouse/amimouse.c +++ b/drivers/input/mouse/amimouse.c | |||
@@ -33,7 +33,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
33 | MODULE_DESCRIPTION("Amiga mouse driver"); | 33 | MODULE_DESCRIPTION("Amiga mouse driver"); |
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | 35 | ||
36 | static int amimouse_used = 0; | ||
37 | static int amimouse_lastx, amimouse_lasty; | 36 | static int amimouse_lastx, amimouse_lasty; |
38 | static struct input_dev amimouse_dev; | 37 | static struct input_dev amimouse_dev; |
39 | 38 | ||
@@ -81,16 +80,12 @@ static int amimouse_open(struct input_dev *dev) | |||
81 | { | 80 | { |
82 | unsigned short joy0dat; | 81 | unsigned short joy0dat; |
83 | 82 | ||
84 | if (amimouse_used++) | ||
85 | return 0; | ||
86 | |||
87 | joy0dat = custom.joy0dat; | 83 | joy0dat = custom.joy0dat; |
88 | 84 | ||
89 | amimouse_lastx = joy0dat & 0xff; | 85 | amimouse_lastx = joy0dat & 0xff; |
90 | amimouse_lasty = joy0dat >> 8; | 86 | amimouse_lasty = joy0dat >> 8; |
91 | 87 | ||
92 | if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { | 88 | if (request_irq(IRQ_AMIGA_VERTB, amimouse_interrupt, 0, "amimouse", amimouse_interrupt)) { |
93 | amimouse_used--; | ||
94 | printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); | 89 | printk(KERN_ERR "amimouse.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB); |
95 | return -EBUSY; | 90 | return -EBUSY; |
96 | } | 91 | } |
@@ -100,8 +95,7 @@ static int amimouse_open(struct input_dev *dev) | |||
100 | 95 | ||
101 | static void amimouse_close(struct input_dev *dev) | 96 | static void amimouse_close(struct input_dev *dev) |
102 | { | 97 | { |
103 | if (!--amimouse_used) | 98 | free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); |
104 | free_irq(IRQ_AMIGA_VERTB, amimouse_interrupt); | ||
105 | } | 99 | } |
106 | 100 | ||
107 | static int __init amimouse_init(void) | 101 | static int __init amimouse_init(void) |
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c index ca4e96886627..1f62c0134010 100644 --- a/drivers/input/mouse/inport.c +++ b/drivers/input/mouse/inport.c | |||
@@ -17,18 +17,18 @@ | |||
17 | /* | 17 | /* |
18 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
19 | * it under the terms of the GNU General Public License as published by | 19 | * it under the terms of the GNU General Public License as published by |
20 | * the Free Software Foundation; either version 2 of the License, or | 20 | * the Free Software Foundation; either version 2 of the License, or |
21 | * (at your option) any later version. | 21 | * (at your option) any later version. |
22 | * | 22 | * |
23 | * This program is distributed in the hope that it will be useful, | 23 | * This program is distributed in the hope that it will be useful, |
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
26 | * GNU General Public License for more details. | 26 | * GNU General Public License for more details. |
27 | * | 27 | * |
28 | * You should have received a copy of the GNU General Public License | 28 | * You should have received a copy of the GNU General Public License |
29 | * along with this program; if not, write to the Free Software | 29 | * along with this program; if not, write to the Free Software |
30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 30 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
31 | * | 31 | * |
32 | * Should you need to contact me, the author, you can do so either by | 32 | * Should you need to contact me, the author, you can do so either by |
33 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 33 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
34 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 34 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
@@ -87,29 +87,23 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)"); | |||
87 | 87 | ||
88 | __obsolete_setup("inport_irq="); | 88 | __obsolete_setup("inport_irq="); |
89 | 89 | ||
90 | static int inport_used; | ||
91 | |||
92 | static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 90 | static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
93 | 91 | ||
94 | static int inport_open(struct input_dev *dev) | 92 | static int inport_open(struct input_dev *dev) |
95 | { | 93 | { |
96 | if (!inport_used++) { | 94 | if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL)) |
97 | if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL)) | 95 | return -EBUSY; |
98 | return -EBUSY; | 96 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
99 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 97 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); |
100 | outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT); | ||
101 | } | ||
102 | 98 | ||
103 | return 0; | 99 | return 0; |
104 | } | 100 | } |
105 | 101 | ||
106 | static void inport_close(struct input_dev *dev) | 102 | static void inport_close(struct input_dev *dev) |
107 | { | 103 | { |
108 | if (!--inport_used) { | 104 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); |
109 | outb(INPORT_REG_MODE, INPORT_CONTROL_PORT); | 105 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); |
110 | outb(INPORT_MODE_BASE, INPORT_DATA_PORT); | 106 | free_irq(inport_irq, NULL); |
111 | free_irq(inport_irq, NULL); | ||
112 | } | ||
113 | } | 107 | } |
114 | 108 | ||
115 | static struct input_dev inport_dev = { | 109 | static struct input_dev inport_dev = { |
@@ -120,11 +114,11 @@ static struct input_dev inport_dev = { | |||
120 | .close = inport_close, | 114 | .close = inport_close, |
121 | .name = INPORT_NAME, | 115 | .name = INPORT_NAME, |
122 | .phys = "isa023c/input0", | 116 | .phys = "isa023c/input0", |
123 | .id = { | 117 | .id = { |
124 | .bustype = BUS_ISA, | 118 | .bustype = BUS_ISA, |
125 | .vendor = INPORT_VENDOR, | 119 | .vendor = INPORT_VENDOR, |
126 | .product = 0x0001, | 120 | .product = 0x0001, |
127 | .version = 0x0100, | 121 | .version = 0x0100, |
128 | }, | 122 | }, |
129 | }; | 123 | }; |
130 | 124 | ||
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c new file mode 100644 index 000000000000..bd9df9b28325 --- /dev/null +++ b/drivers/input/mouse/lifebook.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Fujitsu B-series Lifebook PS/2 TouchScreen driver | ||
3 | * | ||
4 | * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz> | ||
5 | * Copyright (c) 2005 Kenan Esau <kenan.esau@conan.de> | ||
6 | * | ||
7 | * TouchScreen detection, absolute mode setting and packet layout is taken from | ||
8 | * Harald Hoyer's description of the device. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published by | ||
12 | * the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/input.h> | ||
16 | #include <linux/serio.h> | ||
17 | #include <linux/libps2.h> | ||
18 | #include <linux/dmi.h> | ||
19 | |||
20 | #include "psmouse.h" | ||
21 | #include "lifebook.h" | ||
22 | |||
23 | static struct dmi_system_id lifebook_dmi_table[] = { | ||
24 | { | ||
25 | .ident = "Lifebook B", | ||
26 | .matches = { | ||
27 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"), | ||
28 | }, | ||
29 | }, | ||
30 | { } | ||
31 | }; | ||
32 | |||
33 | |||
34 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs) | ||
35 | { | ||
36 | unsigned char *packet = psmouse->packet; | ||
37 | struct input_dev *dev = &psmouse->dev; | ||
38 | |||
39 | if (psmouse->pktcnt != 3) | ||
40 | return PSMOUSE_GOOD_DATA; | ||
41 | |||
42 | input_regs(dev, regs); | ||
43 | |||
44 | /* calculate X and Y */ | ||
45 | if ((packet[0] & 0x08) == 0x00) { | ||
46 | input_report_abs(dev, ABS_X, | ||
47 | (packet[1] | ((packet[0] & 0x30) << 4))); | ||
48 | input_report_abs(dev, ABS_Y, | ||
49 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); | ||
50 | } else { | ||
51 | input_report_rel(dev, REL_X, | ||
52 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | ||
53 | input_report_rel(dev, REL_Y, | ||
54 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
55 | } | ||
56 | |||
57 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | ||
58 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | ||
59 | input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); | ||
60 | |||
61 | input_sync(dev); | ||
62 | |||
63 | return PSMOUSE_FULL_PACKET; | ||
64 | } | ||
65 | |||
66 | static int lifebook_absolute_mode(struct psmouse *psmouse) | ||
67 | { | ||
68 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
69 | unsigned char param; | ||
70 | |||
71 | if (psmouse_reset(psmouse)) | ||
72 | return -1; | ||
73 | |||
74 | /* | ||
75 | Enable absolute output -- ps2_command fails always but if | ||
76 | you leave this call out the touchsreen will never send | ||
77 | absolute coordinates | ||
78 | */ | ||
79 | param = 0x07; | ||
80 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) | ||
86 | { | ||
87 | unsigned char params[] = { 0, 1, 2, 2, 3 }; | ||
88 | |||
89 | if (resolution == 0 || resolution > 400) | ||
90 | resolution = 400; | ||
91 | |||
92 | ps2_command(&psmouse->ps2dev, ¶ms[resolution / 100], PSMOUSE_CMD_SETRES); | ||
93 | psmouse->resolution = 50 << params[resolution / 100]; | ||
94 | } | ||
95 | |||
96 | static void lifebook_disconnect(struct psmouse *psmouse) | ||
97 | { | ||
98 | psmouse_reset(psmouse); | ||
99 | } | ||
100 | |||
101 | int lifebook_detect(struct psmouse *psmouse, int set_properties) | ||
102 | { | ||
103 | if (!dmi_check_system(lifebook_dmi_table)) | ||
104 | return -1; | ||
105 | |||
106 | if (set_properties) { | ||
107 | psmouse->vendor = "Fujitsu"; | ||
108 | psmouse->name = "Lifebook TouchScreen"; | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int lifebook_init(struct psmouse *psmouse) | ||
115 | { | ||
116 | if (lifebook_absolute_mode(psmouse)) | ||
117 | return -1; | ||
118 | |||
119 | psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); | ||
120 | psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
121 | psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
122 | psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
123 | input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0); | ||
124 | input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0); | ||
125 | |||
126 | psmouse->protocol_handler = lifebook_process_byte; | ||
127 | psmouse->set_resolution = lifebook_set_resolution; | ||
128 | psmouse->disconnect = lifebook_disconnect; | ||
129 | psmouse->reconnect = lifebook_absolute_mode; | ||
130 | psmouse->pktsize = 3; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h new file mode 100644 index 000000000000..be1c0943825d --- /dev/null +++ b/drivers/input/mouse/lifebook.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Fujitsu B-series Lifebook PS/2 TouchScreen driver | ||
3 | * | ||
4 | * Copyright (c) 2005 Vojtech Pavlik | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef _LIFEBOOK_H | ||
12 | #define _LIFEBOOK_H | ||
13 | |||
14 | int lifebook_detect(struct psmouse *psmouse, int set_properties); | ||
15 | int lifebook_init(struct psmouse *psmouse); | ||
16 | |||
17 | #endif | ||
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c index 77eb83e87f61..8b5243167227 100644 --- a/drivers/input/mouse/logibm.c +++ b/drivers/input/mouse/logibm.c | |||
@@ -18,18 +18,18 @@ | |||
18 | /* | 18 | /* |
19 | * This program is free software; you can redistribute it and/or modify | 19 | * This program is free software; you can redistribute it and/or modify |
20 | * it under the terms of the GNU General Public License as published by | 20 | * it under the terms of the GNU General Public License as published by |
21 | * the Free Software Foundation; either version 2 of the License, or | 21 | * the Free Software Foundation; either version 2 of the License, or |
22 | * (at your option) any later version. | 22 | * (at your option) any later version. |
23 | * | 23 | * |
24 | * This program is distributed in the hope that it will be useful, | 24 | * This program is distributed in the hope that it will be useful, |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
27 | * GNU General Public License for more details. | 27 | * GNU General Public License for more details. |
28 | * | 28 | * |
29 | * You should have received a copy of the GNU General Public License | 29 | * You should have received a copy of the GNU General Public License |
30 | * along with this program; if not, write to the Free Software | 30 | * along with this program; if not, write to the Free Software |
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
32 | * | 32 | * |
33 | * Should you need to contact me, the author, you can do so either by | 33 | * Should you need to contact me, the author, you can do so either by |
34 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | 34 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: |
35 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | 35 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic |
@@ -77,16 +77,11 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)"); | |||
77 | 77 | ||
78 | __obsolete_setup("logibm_irq="); | 78 | __obsolete_setup("logibm_irq="); |
79 | 79 | ||
80 | static int logibm_used = 0; | ||
81 | |||
82 | static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 80 | static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
83 | 81 | ||
84 | static int logibm_open(struct input_dev *dev) | 82 | static int logibm_open(struct input_dev *dev) |
85 | { | 83 | { |
86 | if (logibm_used++) | ||
87 | return 0; | ||
88 | if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) { | 84 | if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) { |
89 | logibm_used--; | ||
90 | printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq); | 85 | printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq); |
91 | return -EBUSY; | 86 | return -EBUSY; |
92 | } | 87 | } |
@@ -96,8 +91,6 @@ static int logibm_open(struct input_dev *dev) | |||
96 | 91 | ||
97 | static void logibm_close(struct input_dev *dev) | 92 | static void logibm_close(struct input_dev *dev) |
98 | { | 93 | { |
99 | if (--logibm_used) | ||
100 | return; | ||
101 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); | 94 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); |
102 | free_irq(logibm_irq, NULL); | 95 | free_irq(logibm_irq, NULL); |
103 | } | 96 | } |
@@ -167,7 +160,7 @@ static int __init logibm_init(void) | |||
167 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); | 160 | outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT); |
168 | 161 | ||
169 | input_register_device(&logibm_dev); | 162 | input_register_device(&logibm_dev); |
170 | 163 | ||
171 | printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq); | 164 | printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq); |
172 | 165 | ||
173 | return 0; | 166 | return 0; |
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 12dc0ef5020f..e90c60cbbf05 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: maplemouse.c,v 1.2 2004/03/22 01:18:15 lethal Exp $ | 2 | * $Id: maplemouse.c,v 1.2 2004/03/22 01:18:15 lethal Exp $ |
3 | * SEGA Dreamcast mouse driver | 3 | * SEGA Dreamcast mouse driver |
4 | * Based on drivers/usb/usbmouse.c | 4 | * Based on drivers/usb/usbmouse.c |
5 | */ | 5 | */ |
6 | 6 | ||
@@ -15,80 +15,51 @@ | |||
15 | MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>"); | 15 | MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>"); |
16 | MODULE_DESCRIPTION("SEGA Dreamcast mouse driver"); | 16 | MODULE_DESCRIPTION("SEGA Dreamcast mouse driver"); |
17 | 17 | ||
18 | struct dc_mouse { | ||
19 | struct input_dev dev; | ||
20 | int open; | ||
21 | }; | ||
22 | |||
23 | |||
24 | static void dc_mouse_callback(struct mapleq *mq) | 18 | static void dc_mouse_callback(struct mapleq *mq) |
25 | { | 19 | { |
26 | int buttons, relx, rely, relz; | 20 | int buttons, relx, rely, relz; |
27 | struct maple_device *mapledev = mq->dev; | 21 | struct maple_device *mapledev = mq->dev; |
28 | struct dc_mouse *mouse = mapledev->private_data; | 22 | struct input_dev *dev = mapledev->private_data; |
29 | struct input_dev *dev = &mouse->dev; | ||
30 | unsigned char *res = mq->recvbuf; | 23 | unsigned char *res = mq->recvbuf; |
31 | 24 | ||
32 | buttons = ~res[8]; | 25 | buttons = ~res[8]; |
33 | relx=*(unsigned short *)(res+12)-512; | 26 | relx = *(unsigned short *)(res + 12) - 512; |
34 | rely=*(unsigned short *)(res+14)-512; | 27 | rely = *(unsigned short *)(res + 14) - 512; |
35 | relz=*(unsigned short *)(res+16)-512; | 28 | relz = *(unsigned short *)(res + 16) - 512; |
36 | 29 | ||
37 | input_report_key(dev, BTN_LEFT, buttons&4); | 30 | input_report_key(dev, BTN_LEFT, buttons & 4); |
38 | input_report_key(dev, BTN_MIDDLE, buttons&9); | 31 | input_report_key(dev, BTN_MIDDLE, buttons & 9); |
39 | input_report_key(dev, BTN_RIGHT, buttons&2); | 32 | input_report_key(dev, BTN_RIGHT, buttons & 2); |
40 | input_report_rel(dev, REL_X, relx); | 33 | input_report_rel(dev, REL_X, relx); |
41 | input_report_rel(dev, REL_Y, rely); | 34 | input_report_rel(dev, REL_Y, rely); |
42 | input_report_rel(dev, REL_WHEEL, relz); | 35 | input_report_rel(dev, REL_WHEEL, relz); |
43 | input_sync(dev); | 36 | input_sync(dev); |
44 | } | 37 | } |
45 | 38 | ||
46 | |||
47 | static int dc_mouse_open(struct input_dev *dev) | ||
48 | { | ||
49 | struct dc_mouse *mouse = dev->private; | ||
50 | mouse->open++; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | |||
55 | static void dc_mouse_close(struct input_dev *dev) | ||
56 | { | ||
57 | struct dc_mouse *mouse = dev->private; | ||
58 | mouse->open--; | ||
59 | } | ||
60 | |||
61 | |||
62 | static int dc_mouse_connect(struct maple_device *dev) | 39 | static int dc_mouse_connect(struct maple_device *dev) |
63 | { | 40 | { |
64 | unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); | 41 | unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]); |
65 | struct dc_mouse *mouse; | 42 | struct input_dev *input_dev; |
66 | 43 | ||
67 | if (!(mouse = kmalloc(sizeof(struct dc_mouse), GFP_KERNEL))) | 44 | if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL))) |
68 | return -1; | 45 | return -1; |
69 | memset(mouse, 0, sizeof(struct dc_mouse)); | ||
70 | |||
71 | dev->private_data = mouse; | ||
72 | 46 | ||
73 | mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 47 | dev->private_data = input_dev; |
74 | mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); | ||
75 | mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); | ||
76 | 48 | ||
77 | init_input_dev(&mouse->dev); | 49 | memset(input_dev, 0, sizeof(struct dc_mouse)); |
50 | init_input_dev(input_dev); | ||
51 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
52 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); | ||
53 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL); | ||
78 | 54 | ||
79 | mouse->dev.private = mouse; | 55 | input_dev->name = dev->product_name; |
80 | mouse->dev.open = dc_mouse_open; | 56 | input_dev->id.bustype = BUS_MAPLE; |
81 | mouse->dev.close = dc_mouse_close; | ||
82 | mouse->dev.event = NULL; | ||
83 | 57 | ||
84 | mouse->dev.name = dev->product_name; | 58 | input_register_device(input_dev); |
85 | mouse->dev.id.bustype = BUS_MAPLE; | ||
86 | |||
87 | input_register_device(&mouse->dev); | ||
88 | 59 | ||
89 | maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE); | 60 | maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE); |
90 | 61 | ||
91 | printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, mouse->dev.name); | 62 | printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name); |
92 | 63 | ||
93 | return 0; | 64 | return 0; |
94 | } | 65 | } |
@@ -96,10 +67,10 @@ static int dc_mouse_connect(struct maple_device *dev) | |||
96 | 67 | ||
97 | static void dc_mouse_disconnect(struct maple_device *dev) | 68 | static void dc_mouse_disconnect(struct maple_device *dev) |
98 | { | 69 | { |
99 | struct dc_mouse *mouse = dev->private_data; | 70 | struct input_dev *input_dev = dev->private_data; |
100 | 71 | ||
101 | input_unregister_device(&mouse->dev); | 72 | input_unregister_device(input_dev); |
102 | kfree(mouse); | 73 | kfree(input_dev); |
103 | } | 74 | } |
104 | 75 | ||
105 | 76 | ||
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index 0c74918fe254..93393d5c0078 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | 4 | * Copyright (c) 2000-2001 Vojtech Pavlik |
5 | * | 5 | * |
6 | * Based on the work of: | 6 | * Based on the work of: |
7 | * Alan Cox Robin O'Leary | 7 | * Alan Cox Robin O'Leary |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /* | 10 | /* |
@@ -56,7 +56,6 @@ static int pc110pad_io = 0x15e0; | |||
56 | static struct input_dev pc110pad_dev; | 56 | static struct input_dev pc110pad_dev; |
57 | static int pc110pad_data[3]; | 57 | static int pc110pad_data[3]; |
58 | static int pc110pad_count; | 58 | static int pc110pad_count; |
59 | static int pc110pad_used; | ||
60 | 59 | ||
61 | static char *pc110pad_name = "IBM PC110 TouchPad"; | 60 | static char *pc110pad_name = "IBM PC110 TouchPad"; |
62 | static char *pc110pad_phys = "isa15e0/input0"; | 61 | static char *pc110pad_phys = "isa15e0/input0"; |
@@ -74,7 +73,7 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) | |||
74 | 73 | ||
75 | if (pc110pad_count < 3) | 74 | if (pc110pad_count < 3) |
76 | return IRQ_HANDLED; | 75 | return IRQ_HANDLED; |
77 | 76 | ||
78 | input_regs(&pc110pad_dev, regs); | 77 | input_regs(&pc110pad_dev, regs); |
79 | input_report_key(&pc110pad_dev, BTN_TOUCH, | 78 | input_report_key(&pc110pad_dev, BTN_TOUCH, |
80 | pc110pad_data[0] & 0x01); | 79 | pc110pad_data[0] & 0x01); |
@@ -90,15 +89,11 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs) | |||
90 | 89 | ||
91 | static void pc110pad_close(struct input_dev *dev) | 90 | static void pc110pad_close(struct input_dev *dev) |
92 | { | 91 | { |
93 | if (!--pc110pad_used) | 92 | outb(PC110PAD_OFF, pc110pad_io + 2); |
94 | outb(PC110PAD_OFF, pc110pad_io + 2); | ||
95 | } | 93 | } |
96 | 94 | ||
97 | static int pc110pad_open(struct input_dev *dev) | 95 | static int pc110pad_open(struct input_dev *dev) |
98 | { | 96 | { |
99 | if (pc110pad_used++) | ||
100 | return 0; | ||
101 | |||
102 | pc110pad_interrupt(0,NULL,NULL); | 97 | pc110pad_interrupt(0,NULL,NULL); |
103 | pc110pad_interrupt(0,NULL,NULL); | 98 | pc110pad_interrupt(0,NULL,NULL); |
104 | pc110pad_interrupt(0,NULL,NULL); | 99 | pc110pad_interrupt(0,NULL,NULL); |
@@ -145,7 +140,7 @@ static int __init pc110pad_init(void) | |||
145 | 140 | ||
146 | pc110pad_dev.absmax[ABS_X] = 0x1ff; | 141 | pc110pad_dev.absmax[ABS_X] = 0x1ff; |
147 | pc110pad_dev.absmax[ABS_Y] = 0x0ff; | 142 | pc110pad_dev.absmax[ABS_Y] = 0x0ff; |
148 | 143 | ||
149 | pc110pad_dev.open = pc110pad_open; | 144 | pc110pad_dev.open = pc110pad_open; |
150 | pc110pad_dev.close = pc110pad_close; | 145 | pc110pad_dev.close = pc110pad_close; |
151 | 146 | ||
@@ -156,17 +151,17 @@ static int __init pc110pad_init(void) | |||
156 | pc110pad_dev.id.product = 0x0001; | 151 | pc110pad_dev.id.product = 0x0001; |
157 | pc110pad_dev.id.version = 0x0100; | 152 | pc110pad_dev.id.version = 0x0100; |
158 | 153 | ||
159 | input_register_device(&pc110pad_dev); | 154 | input_register_device(&pc110pad_dev); |
160 | 155 | ||
161 | printk(KERN_INFO "input: %s at %#x irq %d\n", | 156 | printk(KERN_INFO "input: %s at %#x irq %d\n", |
162 | pc110pad_name, pc110pad_io, pc110pad_irq); | 157 | pc110pad_name, pc110pad_io, pc110pad_irq); |
163 | 158 | ||
164 | return 0; | 159 | return 0; |
165 | } | 160 | } |
166 | 161 | ||
167 | static void __exit pc110pad_exit(void) | 162 | static void __exit pc110pad_exit(void) |
168 | { | 163 | { |
169 | input_unregister_device(&pc110pad_dev); | 164 | input_unregister_device(&pc110pad_dev); |
170 | 165 | ||
171 | outb(PC110PAD_OFF, pc110pad_io + 2); | 166 | outb(PC110PAD_OFF, pc110pad_io + 2); |
172 | 167 | ||
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 019034b21a0b..19785a6c5abd 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "synaptics.h" | 24 | #include "synaptics.h" |
25 | #include "logips2pp.h" | 25 | #include "logips2pp.h" |
26 | #include "alps.h" | 26 | #include "alps.h" |
27 | #include "lifebook.h" | ||
27 | 28 | ||
28 | #define DRIVER_DESC "PS/2 mouse driver" | 29 | #define DRIVER_DESC "PS/2 mouse driver" |
29 | 30 | ||
@@ -31,10 +32,9 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | |||
31 | MODULE_DESCRIPTION(DRIVER_DESC); | 32 | MODULE_DESCRIPTION(DRIVER_DESC); |
32 | MODULE_LICENSE("GPL"); | 33 | MODULE_LICENSE("GPL"); |
33 | 34 | ||
34 | static unsigned int psmouse_max_proto = -1U; | 35 | static unsigned int psmouse_max_proto = PSMOUSE_AUTO; |
35 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); | 36 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); |
36 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); | 37 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); |
37 | static char *psmouse_proto_abbrev[] = { NULL, "bare", NULL, NULL, NULL, "imps", "exps", NULL, NULL, NULL }; | ||
38 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) | 38 | #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) |
39 | #define param_set_proto_abbrev psmouse_set_maxproto | 39 | #define param_set_proto_abbrev psmouse_set_maxproto |
40 | #define param_get_proto_abbrev psmouse_get_maxproto | 40 | #define param_get_proto_abbrev psmouse_get_maxproto |
@@ -57,6 +57,7 @@ static unsigned int psmouse_resetafter; | |||
57 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); | 57 | module_param_named(resetafter, psmouse_resetafter, uint, 0644); |
58 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); | 58 | MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); |
59 | 59 | ||
60 | PSMOUSE_DEFINE_ATTR(protocol); | ||
60 | PSMOUSE_DEFINE_ATTR(rate); | 61 | PSMOUSE_DEFINE_ATTR(rate); |
61 | PSMOUSE_DEFINE_ATTR(resolution); | 62 | PSMOUSE_DEFINE_ATTR(resolution); |
62 | PSMOUSE_DEFINE_ATTR(resetafter); | 63 | PSMOUSE_DEFINE_ATTR(resetafter); |
@@ -67,7 +68,23 @@ __obsolete_setup("psmouse_smartscroll="); | |||
67 | __obsolete_setup("psmouse_resetafter="); | 68 | __obsolete_setup("psmouse_resetafter="); |
68 | __obsolete_setup("psmouse_rate="); | 69 | __obsolete_setup("psmouse_rate="); |
69 | 70 | ||
70 | static char *psmouse_protocols[] = { "None", "PS/2", "PS2++", "ThinkPS/2", "GenPS/2", "ImPS/2", "ImExPS/2", "SynPS/2", "AlpsPS/2" }; | 71 | /* |
72 | * psmouse_sem protects all operations changing state of mouse | ||
73 | * (connecting, disconnecting, changing rate or resolution via | ||
74 | * sysfs). We could use a per-device semaphore but since there | ||
75 | * rarely more than one PS/2 mouse connected and since semaphore | ||
76 | * is taken in "slow" paths it is not worth it. | ||
77 | */ | ||
78 | static DECLARE_MUTEX(psmouse_sem); | ||
79 | |||
80 | struct psmouse_protocol { | ||
81 | enum psmouse_type type; | ||
82 | char *name; | ||
83 | char *alias; | ||
84 | int maxproto; | ||
85 | int (*detect)(struct psmouse *, int); | ||
86 | int (*init)(struct psmouse *); | ||
87 | }; | ||
71 | 88 | ||
72 | /* | 89 | /* |
73 | * psmouse_process_byte() analyzes the PS/2 data stream and reports | 90 | * psmouse_process_byte() analyzes the PS/2 data stream and reports |
@@ -407,12 +424,15 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties) | |||
407 | */ | 424 | */ |
408 | static int ps2bare_detect(struct psmouse *psmouse, int set_properties) | 425 | static int ps2bare_detect(struct psmouse *psmouse, int set_properties) |
409 | { | 426 | { |
410 | if (!psmouse->vendor) psmouse->vendor = "Generic"; | 427 | if (set_properties) { |
411 | if (!psmouse->name) psmouse->name = "Mouse"; | 428 | if (!psmouse->vendor) psmouse->vendor = "Generic"; |
429 | if (!psmouse->name) psmouse->name = "Mouse"; | ||
430 | } | ||
412 | 431 | ||
413 | return 0; | 432 | return 0; |
414 | } | 433 | } |
415 | 434 | ||
435 | |||
416 | /* | 436 | /* |
417 | * psmouse_extensions() probes for any extensions to the basic PS/2 protocol | 437 | * psmouse_extensions() probes for any extensions to the basic PS/2 protocol |
418 | * the mouse may have. | 438 | * the mouse may have. |
@@ -424,6 +444,17 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
424 | int synaptics_hardware = 0; | 444 | int synaptics_hardware = 0; |
425 | 445 | ||
426 | /* | 446 | /* |
447 | * We always check for lifebook because it does not disturb mouse | ||
448 | * (it only checks DMI information). | ||
449 | */ | ||
450 | if (lifebook_detect(psmouse, set_properties) == 0) { | ||
451 | if (max_proto > PSMOUSE_IMEX) { | ||
452 | if (!set_properties || lifebook_init(psmouse) == 0) | ||
453 | return PSMOUSE_LIFEBOOK; | ||
454 | } | ||
455 | } | ||
456 | |||
457 | /* | ||
427 | * Try Kensington ThinkingMouse (we try first, because synaptics probe | 458 | * Try Kensington ThinkingMouse (we try first, because synaptics probe |
428 | * upsets the thinkingmouse). | 459 | * upsets the thinkingmouse). |
429 | */ | 460 | */ |
@@ -506,6 +537,103 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
506 | return PSMOUSE_PS2; | 537 | return PSMOUSE_PS2; |
507 | } | 538 | } |
508 | 539 | ||
540 | static struct psmouse_protocol psmouse_protocols[] = { | ||
541 | { | ||
542 | .type = PSMOUSE_PS2, | ||
543 | .name = "PS/2", | ||
544 | .alias = "bare", | ||
545 | .maxproto = 1, | ||
546 | .detect = ps2bare_detect, | ||
547 | }, | ||
548 | { | ||
549 | .type = PSMOUSE_PS2PP, | ||
550 | .name = "PS2++", | ||
551 | .alias = "logitech", | ||
552 | .detect = ps2pp_init, | ||
553 | }, | ||
554 | { | ||
555 | .type = PSMOUSE_THINKPS, | ||
556 | .name = "ThinkPS/2", | ||
557 | .alias = "thinkps", | ||
558 | .detect = thinking_detect, | ||
559 | }, | ||
560 | { | ||
561 | .type = PSMOUSE_GENPS, | ||
562 | .name = "GenPS/2", | ||
563 | .alias = "genius", | ||
564 | .detect = genius_detect, | ||
565 | }, | ||
566 | { | ||
567 | .type = PSMOUSE_IMPS, | ||
568 | .name = "ImPS/2", | ||
569 | .alias = "imps", | ||
570 | .maxproto = 1, | ||
571 | .detect = intellimouse_detect, | ||
572 | }, | ||
573 | { | ||
574 | .type = PSMOUSE_IMEX, | ||
575 | .name = "ImExPS/2", | ||
576 | .alias = "exps", | ||
577 | .maxproto = 1, | ||
578 | .detect = im_explorer_detect, | ||
579 | }, | ||
580 | { | ||
581 | .type = PSMOUSE_SYNAPTICS, | ||
582 | .name = "SynPS/2", | ||
583 | .alias = "synaptics", | ||
584 | .detect = synaptics_detect, | ||
585 | .init = synaptics_init, | ||
586 | }, | ||
587 | { | ||
588 | .type = PSMOUSE_ALPS, | ||
589 | .name = "AlpsPS/2", | ||
590 | .alias = "alps", | ||
591 | .detect = alps_detect, | ||
592 | .init = alps_init, | ||
593 | }, | ||
594 | { | ||
595 | .type = PSMOUSE_LIFEBOOK, | ||
596 | .name = "LBPS/2", | ||
597 | .alias = "lifebook", | ||
598 | .init = lifebook_init, | ||
599 | }, | ||
600 | { | ||
601 | .type = PSMOUSE_AUTO, | ||
602 | .name = "auto", | ||
603 | .alias = "any", | ||
604 | .maxproto = 1, | ||
605 | }, | ||
606 | }; | ||
607 | |||
608 | static struct psmouse_protocol *psmouse_protocol_by_type(enum psmouse_type type) | ||
609 | { | ||
610 | int i; | ||
611 | |||
612 | for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) | ||
613 | if (psmouse_protocols[i].type == type) | ||
614 | return &psmouse_protocols[i]; | ||
615 | |||
616 | WARN_ON(1); | ||
617 | return &psmouse_protocols[0]; | ||
618 | } | ||
619 | |||
620 | static struct psmouse_protocol *psmouse_protocol_by_name(const char *name, size_t len) | ||
621 | { | ||
622 | struct psmouse_protocol *p; | ||
623 | int i; | ||
624 | |||
625 | for (i = 0; i < ARRAY_SIZE(psmouse_protocols); i++) { | ||
626 | p = &psmouse_protocols[i]; | ||
627 | |||
628 | if ((strlen(p->name) == len && !strncmp(p->name, name, len)) || | ||
629 | (strlen(p->alias) == len && !strncmp(p->alias, name, len))) | ||
630 | return &psmouse_protocols[i]; | ||
631 | } | ||
632 | |||
633 | return NULL; | ||
634 | } | ||
635 | |||
636 | |||
509 | /* | 637 | /* |
510 | * psmouse_probe() probes for a PS/2 mouse. | 638 | * psmouse_probe() probes for a PS/2 mouse. |
511 | */ | 639 | */ |
@@ -653,30 +781,84 @@ static void psmouse_cleanup(struct serio *serio) | |||
653 | 781 | ||
654 | static void psmouse_disconnect(struct serio *serio) | 782 | static void psmouse_disconnect(struct serio *serio) |
655 | { | 783 | { |
656 | struct psmouse *psmouse, *parent; | 784 | struct psmouse *psmouse, *parent = NULL; |
657 | 785 | ||
786 | psmouse = serio_get_drvdata(serio); | ||
787 | |||
788 | device_remove_file(&serio->dev, &psmouse_attr_protocol); | ||
658 | device_remove_file(&serio->dev, &psmouse_attr_rate); | 789 | device_remove_file(&serio->dev, &psmouse_attr_rate); |
659 | device_remove_file(&serio->dev, &psmouse_attr_resolution); | 790 | device_remove_file(&serio->dev, &psmouse_attr_resolution); |
660 | device_remove_file(&serio->dev, &psmouse_attr_resetafter); | 791 | device_remove_file(&serio->dev, &psmouse_attr_resetafter); |
661 | 792 | ||
662 | psmouse = serio_get_drvdata(serio); | 793 | down(&psmouse_sem); |
794 | |||
663 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 795 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
664 | 796 | ||
665 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 797 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
666 | parent = serio_get_drvdata(serio->parent); | 798 | parent = serio_get_drvdata(serio->parent); |
667 | if (parent->pt_deactivate) | 799 | psmouse_deactivate(parent); |
668 | parent->pt_deactivate(parent); | ||
669 | } | 800 | } |
670 | 801 | ||
671 | if (psmouse->disconnect) | 802 | if (psmouse->disconnect) |
672 | psmouse->disconnect(psmouse); | 803 | psmouse->disconnect(psmouse); |
673 | 804 | ||
805 | if (parent && parent->pt_deactivate) | ||
806 | parent->pt_deactivate(parent); | ||
807 | |||
674 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 808 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
675 | 809 | ||
676 | input_unregister_device(&psmouse->dev); | 810 | input_unregister_device(&psmouse->dev); |
677 | serio_close(serio); | 811 | serio_close(serio); |
678 | serio_set_drvdata(serio, NULL); | 812 | serio_set_drvdata(serio, NULL); |
679 | kfree(psmouse); | 813 | kfree(psmouse); |
814 | |||
815 | if (parent) | ||
816 | psmouse_activate(parent); | ||
817 | |||
818 | up(&psmouse_sem); | ||
819 | } | ||
820 | |||
821 | static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto) | ||
822 | { | ||
823 | memset(&psmouse->dev, 0, sizeof(struct input_dev)); | ||
824 | |||
825 | init_input_dev(&psmouse->dev); | ||
826 | |||
827 | psmouse->dev.private = psmouse; | ||
828 | psmouse->dev.dev = &psmouse->ps2dev.serio->dev; | ||
829 | |||
830 | psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
831 | psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
832 | psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
833 | |||
834 | psmouse->set_rate = psmouse_set_rate; | ||
835 | psmouse->set_resolution = psmouse_set_resolution; | ||
836 | psmouse->protocol_handler = psmouse_process_byte; | ||
837 | psmouse->pktsize = 3; | ||
838 | |||
839 | if (proto && (proto->detect || proto->init)) { | ||
840 | if (proto->detect && proto->detect(psmouse, 1) < 0) | ||
841 | return -1; | ||
842 | |||
843 | if (proto->init && proto->init(psmouse) < 0) | ||
844 | return -1; | ||
845 | |||
846 | psmouse->type = proto->type; | ||
847 | } | ||
848 | else | ||
849 | psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); | ||
850 | |||
851 | sprintf(psmouse->devname, "%s %s %s", | ||
852 | psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name); | ||
853 | |||
854 | psmouse->dev.name = psmouse->devname; | ||
855 | psmouse->dev.phys = psmouse->phys; | ||
856 | psmouse->dev.id.bustype = BUS_I8042; | ||
857 | psmouse->dev.id.vendor = 0x0002; | ||
858 | psmouse->dev.id.product = psmouse->type; | ||
859 | psmouse->dev.id.version = psmouse->model; | ||
860 | |||
861 | return 0; | ||
680 | } | 862 | } |
681 | 863 | ||
682 | /* | 864 | /* |
@@ -688,6 +870,8 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
688 | struct psmouse *psmouse, *parent = NULL; | 870 | struct psmouse *psmouse, *parent = NULL; |
689 | int retval; | 871 | int retval; |
690 | 872 | ||
873 | down(&psmouse_sem); | ||
874 | |||
691 | /* | 875 | /* |
692 | * If this is a pass-through port deactivate parent so the device | 876 | * If this is a pass-through port deactivate parent so the device |
693 | * connected to this port can be successfully identified | 877 | * connected to this port can be successfully identified |
@@ -697,20 +881,14 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
697 | psmouse_deactivate(parent); | 881 | psmouse_deactivate(parent); |
698 | } | 882 | } |
699 | 883 | ||
700 | if (!(psmouse = kmalloc(sizeof(struct psmouse), GFP_KERNEL))) { | 884 | if (!(psmouse = kcalloc(1, sizeof(struct psmouse), GFP_KERNEL))) { |
701 | retval = -ENOMEM; | 885 | retval = -ENOMEM; |
702 | goto out; | 886 | goto out; |
703 | } | 887 | } |
704 | 888 | ||
705 | memset(psmouse, 0, sizeof(struct psmouse)); | ||
706 | |||
707 | ps2_init(&psmouse->ps2dev, serio); | 889 | ps2_init(&psmouse->ps2dev, serio); |
708 | sprintf(psmouse->phys, "%s/input0", serio->phys); | 890 | sprintf(psmouse->phys, "%s/input0", serio->phys); |
709 | psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 891 | |
710 | psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | ||
711 | psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y); | ||
712 | psmouse->dev.private = psmouse; | ||
713 | psmouse->dev.dev = &serio->dev; | ||
714 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | 892 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); |
715 | 893 | ||
716 | serio_set_drvdata(serio, psmouse); | 894 | serio_set_drvdata(serio, psmouse); |
@@ -734,25 +912,10 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
734 | psmouse->resolution = psmouse_resolution; | 912 | psmouse->resolution = psmouse_resolution; |
735 | psmouse->resetafter = psmouse_resetafter; | 913 | psmouse->resetafter = psmouse_resetafter; |
736 | psmouse->smartscroll = psmouse_smartscroll; | 914 | psmouse->smartscroll = psmouse_smartscroll; |
737 | psmouse->set_rate = psmouse_set_rate; | ||
738 | psmouse->set_resolution = psmouse_set_resolution; | ||
739 | psmouse->protocol_handler = psmouse_process_byte; | ||
740 | psmouse->pktsize = 3; | ||
741 | 915 | ||
742 | psmouse->type = psmouse_extensions(psmouse, psmouse_max_proto, 1); | 916 | psmouse_switch_protocol(psmouse, NULL); |
743 | |||
744 | sprintf(psmouse->devname, "%s %s %s", | ||
745 | psmouse_protocols[psmouse->type], psmouse->vendor, psmouse->name); | ||
746 | |||
747 | psmouse->dev.name = psmouse->devname; | ||
748 | psmouse->dev.phys = psmouse->phys; | ||
749 | psmouse->dev.id.bustype = BUS_I8042; | ||
750 | psmouse->dev.id.vendor = 0x0002; | ||
751 | psmouse->dev.id.product = psmouse->type; | ||
752 | psmouse->dev.id.version = psmouse->model; | ||
753 | 917 | ||
754 | input_register_device(&psmouse->dev); | 918 | input_register_device(&psmouse->dev); |
755 | |||
756 | printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); | 919 | printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); |
757 | 920 | ||
758 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | 921 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); |
@@ -762,6 +925,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
762 | if (parent && parent->pt_activate) | 925 | if (parent && parent->pt_activate) |
763 | parent->pt_activate(parent); | 926 | parent->pt_activate(parent); |
764 | 927 | ||
928 | device_create_file(&serio->dev, &psmouse_attr_protocol); | ||
765 | device_create_file(&serio->dev, &psmouse_attr_rate); | 929 | device_create_file(&serio->dev, &psmouse_attr_rate); |
766 | device_create_file(&serio->dev, &psmouse_attr_resolution); | 930 | device_create_file(&serio->dev, &psmouse_attr_resolution); |
767 | device_create_file(&serio->dev, &psmouse_attr_resetafter); | 931 | device_create_file(&serio->dev, &psmouse_attr_resetafter); |
@@ -771,10 +935,11 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
771 | retval = 0; | 935 | retval = 0; |
772 | 936 | ||
773 | out: | 937 | out: |
774 | /* If this is a pass-through port the parent awaits to be activated */ | 938 | /* If this is a pass-through port the parent needs to be re-activated */ |
775 | if (parent) | 939 | if (parent) |
776 | psmouse_activate(parent); | 940 | psmouse_activate(parent); |
777 | 941 | ||
942 | up(&psmouse_sem); | ||
778 | return retval; | 943 | return retval; |
779 | } | 944 | } |
780 | 945 | ||
@@ -791,6 +956,8 @@ static int psmouse_reconnect(struct serio *serio) | |||
791 | return -1; | 956 | return -1; |
792 | } | 957 | } |
793 | 958 | ||
959 | down(&psmouse_sem); | ||
960 | |||
794 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 961 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
795 | parent = serio_get_drvdata(serio->parent); | 962 | parent = serio_get_drvdata(serio->parent); |
796 | psmouse_deactivate(parent); | 963 | psmouse_deactivate(parent); |
@@ -823,6 +990,7 @@ out: | |||
823 | if (parent) | 990 | if (parent) |
824 | psmouse_activate(parent); | 991 | psmouse_activate(parent); |
825 | 992 | ||
993 | up(&psmouse_sem); | ||
826 | return rc; | 994 | return rc; |
827 | } | 995 | } |
828 | 996 | ||
@@ -893,26 +1061,109 @@ ssize_t psmouse_attr_set_helper(struct device *dev, const char *buf, size_t coun | |||
893 | 1061 | ||
894 | if (serio->drv != &psmouse_drv) { | 1062 | if (serio->drv != &psmouse_drv) { |
895 | retval = -ENODEV; | 1063 | retval = -ENODEV; |
896 | goto out; | 1064 | goto out_unpin; |
1065 | } | ||
1066 | |||
1067 | retval = down_interruptible(&psmouse_sem); | ||
1068 | if (retval) | ||
1069 | goto out_unpin; | ||
1070 | |||
1071 | if (psmouse->state == PSMOUSE_IGNORE) { | ||
1072 | retval = -ENODEV; | ||
1073 | goto out_up; | ||
897 | } | 1074 | } |
898 | 1075 | ||
899 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | 1076 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { |
900 | parent = serio_get_drvdata(serio->parent); | 1077 | parent = serio_get_drvdata(serio->parent); |
901 | psmouse_deactivate(parent); | 1078 | psmouse_deactivate(parent); |
902 | } | 1079 | } |
1080 | |||
903 | psmouse_deactivate(psmouse); | 1081 | psmouse_deactivate(psmouse); |
904 | 1082 | ||
905 | retval = handler(psmouse, buf, count); | 1083 | retval = handler(psmouse, buf, count); |
906 | 1084 | ||
907 | psmouse_activate(psmouse); | 1085 | if (retval != -ENODEV) |
1086 | psmouse_activate(psmouse); | ||
1087 | |||
908 | if (parent) | 1088 | if (parent) |
909 | psmouse_activate(parent); | 1089 | psmouse_activate(parent); |
910 | 1090 | ||
911 | out: | 1091 | out_up: |
1092 | up(&psmouse_sem); | ||
1093 | out_unpin: | ||
912 | serio_unpin_driver(serio); | 1094 | serio_unpin_driver(serio); |
913 | return retval; | 1095 | return retval; |
914 | } | 1096 | } |
915 | 1097 | ||
1098 | static ssize_t psmouse_attr_show_protocol(struct psmouse *psmouse, char *buf) | ||
1099 | { | ||
1100 | return sprintf(buf, "%s\n", psmouse_protocol_by_type(psmouse->type)->name); | ||
1101 | } | ||
1102 | |||
1103 | static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, const char *buf, size_t count) | ||
1104 | { | ||
1105 | struct serio *serio = psmouse->ps2dev.serio; | ||
1106 | struct psmouse *parent = NULL; | ||
1107 | struct psmouse_protocol *proto; | ||
1108 | int retry = 0; | ||
1109 | |||
1110 | if (!(proto = psmouse_protocol_by_name(buf, count))) | ||
1111 | return -EINVAL; | ||
1112 | |||
1113 | if (psmouse->type == proto->type) | ||
1114 | return count; | ||
1115 | |||
1116 | while (serio->child) { | ||
1117 | if (++retry > 3) { | ||
1118 | printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n"); | ||
1119 | return -EIO; | ||
1120 | } | ||
1121 | |||
1122 | up(&psmouse_sem); | ||
1123 | serio_unpin_driver(serio); | ||
1124 | serio_unregister_child_port(serio); | ||
1125 | serio_pin_driver_uninterruptible(serio); | ||
1126 | down(&psmouse_sem); | ||
1127 | |||
1128 | if (serio->drv != &psmouse_drv) | ||
1129 | return -ENODEV; | ||
1130 | |||
1131 | if (psmouse->type == proto->type) | ||
1132 | return count; /* switched by other thread */ | ||
1133 | } | ||
1134 | |||
1135 | if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) { | ||
1136 | parent = serio_get_drvdata(serio->parent); | ||
1137 | if (parent->pt_deactivate) | ||
1138 | parent->pt_deactivate(parent); | ||
1139 | } | ||
1140 | |||
1141 | if (psmouse->disconnect) | ||
1142 | psmouse->disconnect(psmouse); | ||
1143 | |||
1144 | psmouse_set_state(psmouse, PSMOUSE_IGNORE); | ||
1145 | input_unregister_device(&psmouse->dev); | ||
1146 | |||
1147 | psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); | ||
1148 | |||
1149 | if (psmouse_switch_protocol(psmouse, proto) < 0) { | ||
1150 | psmouse_reset(psmouse); | ||
1151 | /* default to PSMOUSE_PS2 */ | ||
1152 | psmouse_switch_protocol(psmouse, &psmouse_protocols[0]); | ||
1153 | } | ||
1154 | |||
1155 | psmouse_initialize(psmouse); | ||
1156 | psmouse_set_state(psmouse, PSMOUSE_CMD_MODE); | ||
1157 | |||
1158 | input_register_device(&psmouse->dev); | ||
1159 | printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys); | ||
1160 | |||
1161 | if (parent && parent->pt_activate) | ||
1162 | parent->pt_activate(parent); | ||
1163 | |||
1164 | return count; | ||
1165 | } | ||
1166 | |||
916 | static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) | 1167 | static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) |
917 | { | 1168 | { |
918 | return sprintf(buf, "%d\n", psmouse->rate); | 1169 | return sprintf(buf, "%d\n", psmouse->rate); |
@@ -969,34 +1220,26 @@ static ssize_t psmouse_attr_set_resetafter(struct psmouse *psmouse, const char * | |||
969 | 1220 | ||
970 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | 1221 | static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) |
971 | { | 1222 | { |
972 | int i; | 1223 | struct psmouse_protocol *proto; |
973 | 1224 | ||
974 | if (!val) | 1225 | if (!val) |
975 | return -EINVAL; | 1226 | return -EINVAL; |
976 | 1227 | ||
977 | if (!strncmp(val, "any", 3)) { | 1228 | proto = psmouse_protocol_by_name(val, strlen(val)); |
978 | *((unsigned int *)kp->arg) = -1U; | ||
979 | return 0; | ||
980 | } | ||
981 | 1229 | ||
982 | for (i = 0; i < ARRAY_SIZE(psmouse_proto_abbrev); i++) { | 1230 | if (!proto || !proto->maxproto) |
983 | if (!psmouse_proto_abbrev[i]) | 1231 | return -EINVAL; |
984 | continue; | ||
985 | 1232 | ||
986 | if (!strncmp(val, psmouse_proto_abbrev[i], strlen(psmouse_proto_abbrev[i]))) { | 1233 | *((unsigned int *)kp->arg) = proto->type; |
987 | *((unsigned int *)kp->arg) = i; | ||
988 | return 0; | ||
989 | } | ||
990 | } | ||
991 | 1234 | ||
992 | return -EINVAL; \ | 1235 | return 0; \ |
993 | } | 1236 | } |
994 | 1237 | ||
995 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) | 1238 | static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) |
996 | { | 1239 | { |
997 | return sprintf(buffer, "%s\n", | 1240 | int type = *((unsigned int *)kp->arg); |
998 | psmouse_max_proto < ARRAY_SIZE(psmouse_proto_abbrev) ? | 1241 | |
999 | psmouse_proto_abbrev[psmouse_max_proto] : "any"); | 1242 | return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name); |
1000 | } | 1243 | } |
1001 | 1244 | ||
1002 | static int __init psmouse_init(void) | 1245 | static int __init psmouse_init(void) |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 79e17a0c4664..86691cf43433 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -77,6 +77,8 @@ enum psmouse_type { | |||
77 | PSMOUSE_IMEX, | 77 | PSMOUSE_IMEX, |
78 | PSMOUSE_SYNAPTICS, | 78 | PSMOUSE_SYNAPTICS, |
79 | PSMOUSE_ALPS, | 79 | PSMOUSE_ALPS, |
80 | PSMOUSE_LIFEBOOK, | ||
81 | PSMOUSE_AUTO /* This one should always be last */ | ||
80 | }; | 82 | }; |
81 | 83 | ||
82 | int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); | 84 | int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); |
@@ -99,7 +101,7 @@ static ssize_t psmouse_do_set_##_name(struct device *d, struct device_attribute | |||
99 | { \ | 101 | { \ |
100 | return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name); \ | 102 | return psmouse_attr_set_helper(d, b, s, psmouse_attr_set_##_name); \ |
101 | } \ | 103 | } \ |
102 | static struct device_attribute psmouse_attr_##_name = \ | 104 | static struct device_attribute psmouse_attr_##_name = \ |
103 | __ATTR(_name, S_IWUSR | S_IRUGO, \ | 105 | __ATTR(_name, S_IWUSR | S_IRUGO, \ |
104 | psmouse_do_show_##_name, psmouse_do_set_##_name); | 106 | psmouse_do_show_##_name, psmouse_do_set_##_name); |
105 | 107 | ||
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 7280f68afcee..8fe1212b8fd7 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
@@ -59,7 +59,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
59 | b = (short) (__raw_readl(0xe0310000) ^ 0x70); | 59 | b = (short) (__raw_readl(0xe0310000) ^ 0x70); |
60 | 60 | ||
61 | dx = x - rpcmouse_lastx; | 61 | dx = x - rpcmouse_lastx; |
62 | dy = y - rpcmouse_lasty; | 62 | dy = y - rpcmouse_lasty; |
63 | 63 | ||
64 | rpcmouse_lastx = x; | 64 | rpcmouse_lastx = x; |
65 | rpcmouse_lasty = y; | 65 | rpcmouse_lasty = y; |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index b2cb101c8110..f024be9b44d2 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Driver for DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers) | 2 | * Driver for DEC VSXXX-AA mouse (hockey-puck mouse, ball or two rollers) |
3 | * DEC VSXXX-GA mouse (rectangular mouse, with ball) | 3 | * DEC VSXXX-GA mouse (rectangular mouse, with ball) |
4 | * DEC VSXXX-AB tablet (digitizer with hair cross or stylus) | 4 | * DEC VSXXX-AB tablet (digitizer with hair cross or stylus) |
5 | * | 5 | * |
6 | * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de> | 6 | * Copyright (C) 2003-2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de> |
7 | * | 7 | * |