aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/Makefile2
-rw-r--r--drivers/input/mouse/alps.c52
-rw-r--r--drivers/input/mouse/amimouse.c8
-rw-r--r--drivers/input/mouse/inport.c38
-rw-r--r--drivers/input/mouse/lifebook.c134
-rw-r--r--drivers/input/mouse/lifebook.h17
-rw-r--r--drivers/input/mouse/logibm.c17
-rw-r--r--drivers/input/mouse/maplemouse.c75
-rw-r--r--drivers/input/mouse/pc110pad.c21
-rw-r--r--drivers/input/mouse/psmouse-base.c351
-rw-r--r--drivers/input/mouse/psmouse.h4
-rw-r--r--drivers/input/mouse/rpcmouse.c2
-rw-r--r--drivers/input/mouse/vsxxxaa.c4
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
15obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o 15obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
16obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o 16obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
17 17
18psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o 18psmouse-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
38static struct alps_model_info alps_model_data[] = { 39static 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
257static int alps_passthrough_mode(struct psmouse *psmouse, int enable) 270static 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:
461int alps_detect(struct psmouse *psmouse, int set_properties) 473int 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>");
33MODULE_DESCRIPTION("Amiga mouse driver"); 33MODULE_DESCRIPTION("Amiga mouse driver");
34MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35 35
36static int amimouse_used = 0;
37static int amimouse_lastx, amimouse_lasty; 36static int amimouse_lastx, amimouse_lasty;
38static struct input_dev amimouse_dev; 37static 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
101static void amimouse_close(struct input_dev *dev) 96static 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
107static int __init amimouse_init(void) 101static 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
90static int inport_used;
91
92static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs); 90static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
93 91
94static int inport_open(struct input_dev *dev) 92static 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
106static void inport_close(struct input_dev *dev) 102static 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
115static struct input_dev inport_dev = { 109static 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
23static 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
34static 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
66static 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, &param, PSMOUSE_CMD_SETRES);
81
82 return 0;
83}
84
85static 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, &params[resolution / 100], PSMOUSE_CMD_SETRES);
93 psmouse->resolution = 50 << params[resolution / 100];
94}
95
96static void lifebook_disconnect(struct psmouse *psmouse)
97{
98 psmouse_reset(psmouse);
99}
100
101int 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
114int 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
14int lifebook_detect(struct psmouse *psmouse, int set_properties);
15int 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
80static int logibm_used = 0;
81
82static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs); 80static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
83 81
84static int logibm_open(struct input_dev *dev) 82static 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
97static void logibm_close(struct input_dev *dev) 92static 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 @@
15MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>"); 15MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>");
16MODULE_DESCRIPTION("SEGA Dreamcast mouse driver"); 16MODULE_DESCRIPTION("SEGA Dreamcast mouse driver");
17 17
18struct dc_mouse {
19 struct input_dev dev;
20 int open;
21};
22
23
24static void dc_mouse_callback(struct mapleq *mq) 18static 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
47static 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
55static void dc_mouse_close(struct input_dev *dev)
56{
57 struct dc_mouse *mouse = dev->private;
58 mouse->open--;
59}
60
61
62static int dc_mouse_connect(struct maple_device *dev) 39static 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
97static void dc_mouse_disconnect(struct maple_device *dev) 68static 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;
56static struct input_dev pc110pad_dev; 56static struct input_dev pc110pad_dev;
57static int pc110pad_data[3]; 57static int pc110pad_data[3];
58static int pc110pad_count; 58static int pc110pad_count;
59static int pc110pad_used;
60 59
61static char *pc110pad_name = "IBM PC110 TouchPad"; 60static char *pc110pad_name = "IBM PC110 TouchPad";
62static char *pc110pad_phys = "isa15e0/input0"; 61static 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
91static void pc110pad_close(struct input_dev *dev) 90static 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
97static int pc110pad_open(struct input_dev *dev) 95static 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
167static void __exit pc110pad_exit(void) 162static 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>");
31MODULE_DESCRIPTION(DRIVER_DESC); 32MODULE_DESCRIPTION(DRIVER_DESC);
32MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
33 34
34static unsigned int psmouse_max_proto = -1U; 35static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
35static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); 36static int psmouse_set_maxproto(const char *val, struct kernel_param *kp);
36static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); 37static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp);
37static 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;
57module_param_named(resetafter, psmouse_resetafter, uint, 0644); 57module_param_named(resetafter, psmouse_resetafter, uint, 0644);
58MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never)."); 58MODULE_PARM_DESC(resetafter, "Reset device after so many bad packets (0 = never).");
59 59
60PSMOUSE_DEFINE_ATTR(protocol);
60PSMOUSE_DEFINE_ATTR(rate); 61PSMOUSE_DEFINE_ATTR(rate);
61PSMOUSE_DEFINE_ATTR(resolution); 62PSMOUSE_DEFINE_ATTR(resolution);
62PSMOUSE_DEFINE_ATTR(resetafter); 63PSMOUSE_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
70static 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 */
78static DECLARE_MUTEX(psmouse_sem);
79
80struct 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 */
408static int ps2bare_detect(struct psmouse *psmouse, int set_properties) 425static 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
540static 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
608static 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
620static 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
654static void psmouse_disconnect(struct serio *serio) 782static 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
821static 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
773out: 937out:
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
911out: 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
1098static 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
1103static 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
916static ssize_t psmouse_attr_show_rate(struct psmouse *psmouse, char *buf) 1167static 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
970static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) 1221static 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
995static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) 1238static 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
1002static int __init psmouse_init(void) 1245static 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
82int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command); 84int 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} \
102static struct device_attribute psmouse_attr_##_name = \ 104static 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 *