aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:13:17 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-04 21:16:12 -0400
commita3d52136ee8f7399859f9a0824470fd49b1d1a00 (patch)
treeac0fd3d1efc356029cbbc5e413f778f7231cd909 /drivers/input/mouse
parent5b339915762d30b21995aa7263e74081f2f1110a (diff)
parent84767d00a8fd54dd97866561f6e2ee246c8e1cdc (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (65 commits) Input: gpio_keys - add support for switches (EV_SW) Input: cobalt_btns - convert to use polldev library Input: add skeleton for simple polled devices Input: update some documentation Input: wistron - fix typo in keymap for Acer TM610 Input: add input_set_capability() helper Input: i8042 - add Fujitsu touchscreen/touchpad PNP IDs Input: i8042 - add Panasonic CF-29 to nomux list Input: lifebook - split into 2 devices Input: lifebook - add signature of Panasonic CF-29 Input: lifebook - activate 6-byte protocol on select models Input: lifebook - work properly on Panasonic CF-18 Input: cobalt buttons - separate device and driver registration Input: ati_remote - make button repeat sensitivity configurable Input: pxa27x - do not use deprecated SA_INTERRUPT flag Input: ucb1400 - make delays configurable Input: misc devices - switch to using input_dev->dev.parent Input: joysticks - switch to using input_dev->dev.parent Input: touchscreens - switch to using input_dev->dev.parent Input: mice - switch to using input_dev->dev.parent ... Fixed up conflicts with core device model removal of "struct subsystem" manually. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/Kconfig61
-rw-r--r--drivers/input/mouse/Makefile8
-rw-r--r--drivers/input/mouse/alps.c13
-rw-r--r--drivers/input/mouse/alps.h18
-rw-r--r--drivers/input/mouse/hil_ptr.c97
-rw-r--r--drivers/input/mouse/lifebook.c195
-rw-r--r--drivers/input/mouse/lifebook.h11
-rw-r--r--drivers/input/mouse/logips2pp.c7
-rw-r--r--drivers/input/mouse/logips2pp.h7
-rw-r--r--drivers/input/mouse/psmouse-base.c50
-rw-r--r--drivers/input/mouse/psmouse.h1
-rw-r--r--drivers/input/mouse/sermouse.c19
-rw-r--r--drivers/input/mouse/synaptics.c109
-rw-r--r--drivers/input/mouse/synaptics.h18
-rw-r--r--drivers/input/mouse/touchkit_ps2.c100
-rw-r--r--drivers/input/mouse/touchkit_ps2.h24
-rw-r--r--drivers/input/mouse/trackpoint.h9
-rw-r--r--drivers/input/mouse/vsxxxaa.c3
18 files changed, 591 insertions, 159 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index b40784a60aa1..81dd8c7211a7 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -37,6 +37,65 @@ config MOUSE_PS2
37 To compile this driver as a module, choose M here: the 37 To compile this driver as a module, choose M here: the
38 module will be called psmouse. 38 module will be called psmouse.
39 39
40config MOUSE_PS2_ALPS
41 bool "ALPS PS/2 mouse protocol extension" if EMBEDDED
42 default y
43 depends on MOUSE_PS2
44 ---help---
45 Say Y here if you have an ALPS PS/2 touchpad connected to
46 your system.
47
48 If unsure, say Y.
49
50config MOUSE_PS2_LOGIPS2PP
51 bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED
52 default y
53 depends on MOUSE_PS2
54 ---help---
55 Say Y here if you have a Logictech PS/2++ mouse connected to
56 your system.
57
58 If unsure, say Y.
59
60config MOUSE_PS2_SYNAPTICS
61 bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED
62 default y
63 depends on MOUSE_PS2
64 ---help---
65 Say Y here if you have a Synaptics PS/2 TouchPad connected to
66 your system.
67
68 If unsure, say Y.
69
70config MOUSE_PS2_LIFEBOOK
71 bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED
72 default y
73 depends on MOUSE_PS2
74 ---help---
75 Say Y here if you have a Fujitsu B-series Lifebook PS/2
76 TouchScreen connected to your system.
77
78 If unsure, say Y.
79
80config MOUSE_PS2_TRACKPOINT
81 bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED
82 default y
83 depends on MOUSE_PS2
84 ---help---
85 Say Y here if you have an IBM Trackpoint PS/2 mouse connected
86 to your system.
87
88 If unsure, say Y.
89
90config MOUSE_PS2_TOUCHKIT
91 bool "eGalax TouchKit PS/2 protocol extension"
92 depends on MOUSE_PS2
93 ---help---
94 Say Y here if you have an eGalax TouchKit PS/2 touchscreen
95 connected to your system.
96
97 If unsure, say N.
98
40config MOUSE_SERIAL 99config MOUSE_SERIAL
41 tristate "Serial mouse" 100 tristate "Serial mouse"
42 select SERIO 101 select SERIO
@@ -129,7 +188,7 @@ config MOUSE_VSXXXAA
129 digitizer (VSXXX-AB) DEC produced. 188 digitizer (VSXXX-AB) DEC produced.
130 189
131config MOUSE_HIL 190config MOUSE_HIL
132 tristate "HIL pointers (mice etc)." 191 tristate "HIL pointers (mice etc)."
133 depends on GSC || HP300 192 depends on GSC || HP300
134 select HP_SDC 193 select HP_SDC
135 select HIL_MLC 194 select HIL_MLC
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index 700f61200dfc..6a8f622927f2 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -15,4 +15,10 @@ 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 lifebook.o trackpoint.o 18psmouse-objs := psmouse-base.o synaptics.o
19
20psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
21psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
22psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
23psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
24psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4e71a66fc7fc..cf3e4664e72b 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -424,14 +424,15 @@ int alps_init(struct psmouse *psmouse)
424 struct input_dev *dev1 = psmouse->dev, *dev2; 424 struct input_dev *dev1 = psmouse->dev, *dev2;
425 int version; 425 int version;
426 426
427 psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); 427 priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
428 dev2 = input_allocate_device(); 428 dev2 = input_allocate_device();
429 if (!priv || !dev2) 429 if (!priv || !dev2)
430 goto init_fail; 430 goto init_fail;
431 431
432 priv->dev2 = dev2; 432 priv->dev2 = dev2;
433 433
434 if (!(priv->i = alps_get_model(psmouse, &version))) 434 priv->i = alps_get_model(psmouse, &version);
435 if (!priv->i)
435 goto init_fail; 436 goto init_fail;
436 437
437 if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) 438 if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1))
@@ -480,7 +481,8 @@ int alps_init(struct psmouse *psmouse)
480 dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); 481 dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
481 dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 482 dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
482 483
483 input_register_device(priv->dev2); 484 if (input_register_device(priv->dev2))
485 goto init_fail;
484 486
485 psmouse->protocol_handler = alps_process_byte; 487 psmouse->protocol_handler = alps_process_byte;
486 psmouse->poll = alps_poll; 488 psmouse->poll = alps_poll;
@@ -491,9 +493,11 @@ int alps_init(struct psmouse *psmouse)
491 /* We are having trouble resyncing ALPS touchpads so disable it for now */ 493 /* We are having trouble resyncing ALPS touchpads so disable it for now */
492 psmouse->resync_time = 0; 494 psmouse->resync_time = 0;
493 495
496 psmouse->private = priv;
494 return 0; 497 return 0;
495 498
496init_fail: 499init_fail:
500 psmouse_reset(psmouse);
497 input_free_device(dev2); 501 input_free_device(dev2);
498 kfree(priv); 502 kfree(priv);
499 return -1; 503 return -1;
@@ -504,7 +508,8 @@ int alps_detect(struct psmouse *psmouse, int set_properties)
504 int version; 508 int version;
505 const struct alps_model_info *model; 509 const struct alps_model_info *model;
506 510
507 if (!(model = alps_get_model(psmouse, &version))) 511 model = alps_get_model(psmouse, &version);
512 if (!model)
508 return -1; 513 return -1;
509 514
510 if (set_properties) { 515 if (set_properties) {
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index 69db7325a494..4bbddc99962b 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -12,9 +12,6 @@
12#ifndef _ALPS_H 12#ifndef _ALPS_H
13#define _ALPS_H 13#define _ALPS_H
14 14
15int alps_detect(struct psmouse *psmouse, int set_properties);
16int alps_init(struct psmouse *psmouse);
17
18struct alps_model_info { 15struct alps_model_info {
19 unsigned char signature[3]; 16 unsigned char signature[3];
20 unsigned char byte0, mask0; 17 unsigned char byte0, mask0;
@@ -23,10 +20,23 @@ struct alps_model_info {
23 20
24struct alps_data { 21struct alps_data {
25 struct input_dev *dev2; /* Relative device */ 22 struct input_dev *dev2; /* Relative device */
26 char name[32]; /* Name */
27 char phys[32]; /* Phys */ 23 char phys[32]; /* Phys */
28 const struct alps_model_info *i;/* Info */ 24 const struct alps_model_info *i;/* Info */
29 int prev_fin; /* Finger bit from previous packet */ 25 int prev_fin; /* Finger bit from previous packet */
30}; 26};
31 27
28#ifdef CONFIG_MOUSE_PS2_ALPS
29int alps_detect(struct psmouse *psmouse, int set_properties);
30int alps_init(struct psmouse *psmouse);
31#else
32inline int alps_detect(struct psmouse *psmouse, int set_properties)
33{
34 return -ENOSYS;
35}
36inline int alps_init(struct psmouse *psmouse)
37{
38 return -ENOSYS;
39}
40#endif /* CONFIG_MOUSE_PS2_ALPS */
41
32#endif 42#endif
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index bfb174fe3230..449bf4dcbbcc 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -88,10 +88,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
88 idx = ptr->idx4/4; 88 idx = ptr->idx4/4;
89 p = data[idx - 1]; 89 p = data[idx - 1];
90 90
91 if ((p & ~HIL_CMDCT_POL) == 91 if ((p & ~HIL_CMDCT_POL) ==
92 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; 92 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
93 if ((p & ~HIL_CMDCT_RPL) == 93 goto report;
94 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; 94 if ((p & ~HIL_CMDCT_RPL) ==
95 (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
96 goto report;
95 97
96 /* Not a poll response. See if we are loading config records. */ 98 /* Not a poll response. See if we are loading config records. */
97 switch (p & HIL_PKT_DATA_MASK) { 99 switch (p & HIL_PKT_DATA_MASK) {
@@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
101 for (; i < HIL_PTR_MAX_LENGTH; i++) 103 for (; i < HIL_PTR_MAX_LENGTH; i++)
102 ptr->idd[i] = 0; 104 ptr->idd[i] = 0;
103 break; 105 break;
106
104 case HIL_CMD_RSC: 107 case HIL_CMD_RSC:
105 for (i = 0; i < idx; i++) 108 for (i = 0; i < idx; i++)
106 ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 109 ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
107 for (; i < HIL_PTR_MAX_LENGTH; i++) 110 for (; i < HIL_PTR_MAX_LENGTH; i++)
108 ptr->rsc[i] = 0; 111 ptr->rsc[i] = 0;
109 break; 112 break;
113
110 case HIL_CMD_EXD: 114 case HIL_CMD_EXD:
111 for (i = 0; i < idx; i++) 115 for (i = 0; i < idx; i++)
112 ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 116 ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
113 for (; i < HIL_PTR_MAX_LENGTH; i++) 117 for (; i < HIL_PTR_MAX_LENGTH; i++)
114 ptr->exd[i] = 0; 118 ptr->exd[i] = 0;
115 break; 119 break;
120
116 case HIL_CMD_RNM: 121 case HIL_CMD_RNM:
117 for (i = 0; i < idx; i++) 122 for (i = 0; i < idx; i++)
118 ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; 123 ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
119 for (; i < HIL_PTR_MAX_LENGTH + 1; i++) 124 for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
120 ptr->rnm[i] = '\0'; 125 ptr->rnm[i] = 0;
121 break; 126 break;
127
122 default: 128 default:
123 /* These occur when device isn't present */ 129 /* These occur when device isn't present */
124 if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; 130 if (p == (HIL_ERR_INT | HIL_PKT_CMD))
131 break;
125 /* Anything else we'd like to know about. */ 132 /* Anything else we'd like to know about. */
126 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); 133 printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
127 break; 134 break;
@@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
130 137
131 report: 138 report:
132 if ((p & HIL_CMDCT_POL) != idx - 1) { 139 if ((p & HIL_CMDCT_POL) != idx - 1) {
133 printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); 140 printk(KERN_WARNING PREFIX
141 "Malformed poll packet %x (idx = %i)\n", p, idx);
134 goto out; 142 goto out;
135 } 143 }
136 144
@@ -139,7 +147,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
139 laxis += i; 147 laxis += i;
140 148
141 ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ 149 ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
142 absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; 150 absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
143 151
144 for (cnt = 1; i < laxis; i++) { 152 for (cnt = 1; i < laxis; i++) {
145 unsigned int lo,hi,val; 153 unsigned int lo,hi,val;
@@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
157 input_report_abs(dev, ABS_X + i, val); 165 input_report_abs(dev, ABS_X + i, val);
158 } else { 166 } else {
159 val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); 167 val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
160 if (i%3) val *= -1; 168 if (i%3)
169 val *= -1;
161 input_report_rel(dev, REL_X + i, val); 170 input_report_rel(dev, REL_X + i, val);
162 } 171 }
163 } 172 }
@@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
168 btn = ptr->data[cnt++]; 177 btn = ptr->data[cnt++];
169 up = btn & 1; 178 up = btn & 1;
170 btn &= 0xfe; 179 btn &= 0xfe;
171 if (btn == 0x8e) { 180 if (btn == 0x8e)
172 continue; /* TODO: proximity == touch? */ 181 continue; /* TODO: proximity == touch? */
173 } 182 else
174 else if ((btn > 0x8c) || (btn < 0x80)) continue; 183 if ((btn > 0x8c) || (btn < 0x80))
184 continue;
175 btn = (btn - 0x80) >> 1; 185 btn = (btn - 0x80) >> 1;
176 btn = ptr->btnmap[btn]; 186 btn = ptr->btnmap[btn];
177 input_report_key(dev, btn, !up); 187 input_report_key(dev, btn, !up);
@@ -182,14 +192,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr)
182 up(&ptr->sem); 192 up(&ptr->sem);
183} 193}
184 194
185static void hil_ptr_process_err(struct hil_ptr *ptr) { 195static void hil_ptr_process_err(struct hil_ptr *ptr)
196{
186 printk(KERN_WARNING PREFIX "errored HIL packet\n"); 197 printk(KERN_WARNING PREFIX "errored HIL packet\n");
187 ptr->idx4 = 0; 198 ptr->idx4 = 0;
188 up(&ptr->sem); 199 up(&ptr->sem);
189 return;
190} 200}
191 201
192static irqreturn_t hil_ptr_interrupt(struct serio *serio, 202static irqreturn_t hil_ptr_interrupt(struct serio *serio,
193 unsigned char data, unsigned int flags) 203 unsigned char data, unsigned int flags)
194{ 204{
195 struct hil_ptr *ptr; 205 struct hil_ptr *ptr;
@@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio,
197 int idx; 207 int idx;
198 208
199 ptr = serio_get_drvdata(serio); 209 ptr = serio_get_drvdata(serio);
200 if (ptr == NULL) { 210 BUG_ON(ptr == NULL);
201 BUG();
202 return IRQ_HANDLED;
203 }
204 211
205 if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { 212 if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
206 hil_ptr_process_err(ptr); 213 hil_ptr_process_err(ptr);
207 return IRQ_HANDLED; 214 return IRQ_HANDLED;
208 } 215 }
209 idx = ptr->idx4/4; 216 idx = ptr->idx4/4;
210 if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; 217 if (!(ptr->idx4 % 4))
218 ptr->data[idx] = 0;
211 packet = ptr->data[idx]; 219 packet = ptr->data[idx];
212 packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); 220 packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
213 ptr->data[idx] = packet; 221 ptr->data[idx] = packet;
214 222
215 /* Records of N 4-byte hil_packets must terminate with a command. */ 223 /* Records of N 4-byte hil_packets must terminate with a command. */
216 if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; 224 if ((++(ptr->idx4)) % 4)
225 return IRQ_HANDLED;
217 if ((packet & 0xffff0000) != HIL_ERR_INT) { 226 if ((packet & 0xffff0000) != HIL_ERR_INT) {
218 hil_ptr_process_err(ptr); 227 hil_ptr_process_err(ptr);
219 return IRQ_HANDLED; 228 return IRQ_HANDLED;
220 } 229 }
221 if (packet & HIL_PKT_CMD) 230 if (packet & HIL_PKT_CMD)
222 hil_ptr_process_record(ptr); 231 hil_ptr_process_record(ptr);
232
223 return IRQ_HANDLED; 233 return IRQ_HANDLED;
224} 234}
225 235
@@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio)
228 struct hil_ptr *ptr; 238 struct hil_ptr *ptr;
229 239
230 ptr = serio_get_drvdata(serio); 240 ptr = serio_get_drvdata(serio);
231 if (ptr == NULL) { 241 BUG_ON(ptr == NULL);
232 BUG();
233 return;
234 }
235 242
236 serio_close(serio); 243 serio_close(serio);
237 input_unregister_device(ptr->dev); 244 input_unregister_device(ptr->dev);
@@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio)
241static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) 248static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
242{ 249{
243 struct hil_ptr *ptr; 250 struct hil_ptr *ptr;
244 char *txt; 251 const char *txt;
245 unsigned int i, naxsets, btntype; 252 unsigned int i, naxsets, btntype;
246 uint8_t did, *idd; 253 uint8_t did, *idd;
247 254
@@ -252,42 +259,40 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
252 if (!ptr->dev) 259 if (!ptr->dev)
253 goto bail0; 260 goto bail0;
254 261
255 ptr->dev->private = ptr;
256
257 if (serio_open(serio, driver)) 262 if (serio_open(serio, driver))
258 goto bail1; 263 goto bail1;
259 264
260 serio_set_drvdata(serio, ptr); 265 serio_set_drvdata(serio, ptr);
261 ptr->serio = serio; 266 ptr->serio = serio;
262 267
263 init_MUTEX_LOCKED(&(ptr->sem)); 268 init_MUTEX_LOCKED(&ptr->sem);
264 269
265 /* Get device info. MLC driver supplies devid/status/etc. */ 270 /* Get device info. MLC driver supplies devid/status/etc. */
266 serio->write(serio, 0); 271 serio->write(serio, 0);
267 serio->write(serio, 0); 272 serio->write(serio, 0);
268 serio->write(serio, HIL_PKT_CMD >> 8); 273 serio->write(serio, HIL_PKT_CMD >> 8);
269 serio->write(serio, HIL_CMD_IDD); 274 serio->write(serio, HIL_CMD_IDD);
270 down(&(ptr->sem)); 275 down(&ptr->sem);
271 276
272 serio->write(serio, 0); 277 serio->write(serio, 0);
273 serio->write(serio, 0); 278 serio->write(serio, 0);
274 serio->write(serio, HIL_PKT_CMD >> 8); 279 serio->write(serio, HIL_PKT_CMD >> 8);
275 serio->write(serio, HIL_CMD_RSC); 280 serio->write(serio, HIL_CMD_RSC);
276 down(&(ptr->sem)); 281 down(&ptr->sem);
277 282
278 serio->write(serio, 0); 283 serio->write(serio, 0);
279 serio->write(serio, 0); 284 serio->write(serio, 0);
280 serio->write(serio, HIL_PKT_CMD >> 8); 285 serio->write(serio, HIL_PKT_CMD >> 8);
281 serio->write(serio, HIL_CMD_RNM); 286 serio->write(serio, HIL_CMD_RNM);
282 down(&(ptr->sem)); 287 down(&ptr->sem);
283 288
284 serio->write(serio, 0); 289 serio->write(serio, 0);
285 serio->write(serio, 0); 290 serio->write(serio, 0);
286 serio->write(serio, HIL_PKT_CMD >> 8); 291 serio->write(serio, HIL_PKT_CMD >> 8);
287 serio->write(serio, HIL_CMD_EXD); 292 serio->write(serio, HIL_CMD_EXD);
288 down(&(ptr->sem)); 293 down(&ptr->sem);
289 294
290 up(&(ptr->sem)); 295 up(&ptr->sem);
291 296
292 did = ptr->idd[0]; 297 did = ptr->idd[0];
293 idd = ptr->idd + 1; 298 idd = ptr->idd + 1;
@@ -301,12 +306,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
301 ptr->dev->evbit[0] = BIT(EV_ABS); 306 ptr->dev->evbit[0] = BIT(EV_ABS);
302 txt = "absolute"; 307 txt = "absolute";
303 } 308 }
304 if (!ptr->dev->evbit[0]) { 309 if (!ptr->dev->evbit[0])
305 goto bail2; 310 goto bail2;
306 }
307 311
308 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); 312 ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
309 if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); 313 if (ptr->nbtn)
314 ptr->dev->evbit[0] |= BIT(EV_KEY);
310 315
311 naxsets = HIL_IDD_NUM_AXSETS(*idd); 316 naxsets = HIL_IDD_NUM_AXSETS(*idd);
312 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); 317 ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
@@ -315,7 +320,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
315 did, txt); 320 did, txt);
316 printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", 321 printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
317 ptr->nbtn, naxsets, ptr->naxes); 322 ptr->nbtn, naxsets, ptr->naxes);
318 323
319 btntype = BTN_MISC; 324 btntype = BTN_MISC;
320 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) 325 if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
321#ifdef TABLET_SIMULATES_MOUSE 326#ifdef TABLET_SIMULATES_MOUSE
@@ -325,7 +330,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
325#endif 330#endif
326 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) 331 if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
327 btntype = BTN_TOUCH; 332 btntype = BTN_TOUCH;
328 333
329 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) 334 if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
330 btntype = BTN_MOUSE; 335 btntype = BTN_MOUSE;
331 336
@@ -341,12 +346,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
341 } 346 }
342 347
343 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { 348 if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
344 for (i = 0; i < ptr->naxes; i++) { 349 for (i = 0; i < ptr->naxes; i++)
345 set_bit(REL_X + i, ptr->dev->relbit); 350 set_bit(REL_X + i, ptr->dev->relbit);
346 } 351 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++)
347 for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
348 set_bit(REL_X + i, ptr->dev->relbit); 352 set_bit(REL_X + i, ptr->dev->relbit);
349 }
350 } else { 353 } else {
351 for (i = 0; i < ptr->naxes; i++) { 354 for (i = 0; i < ptr->naxes; i++) {
352 set_bit(ABS_X + i, ptr->dev->absbit); 355 set_bit(ABS_X + i, ptr->dev->absbit);
@@ -375,7 +378,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
375 ptr->dev->id.vendor = PCI_VENDOR_ID_HP; 378 ptr->dev->id.vendor = PCI_VENDOR_ID_HP;
376 ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ 379 ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */
377 ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ 380 ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */
378 ptr->dev->cdev.dev = &serio->dev; 381 ptr->dev->dev.parent = &serio->dev;
379 382
380 input_register_device(ptr->dev); 383 input_register_device(ptr->dev);
381 printk(KERN_INFO "input: %s (%s), ID: %d\n", 384 printk(KERN_INFO "input: %s (%s), ID: %d\n",
@@ -419,11 +422,11 @@ static int __init hil_ptr_init(void)
419{ 422{
420 return serio_register_driver(&hil_ptr_serio_driver); 423 return serio_register_driver(&hil_ptr_serio_driver);
421} 424}
422 425
423static void __exit hil_ptr_exit(void) 426static void __exit hil_ptr_exit(void)
424{ 427{
425 serio_unregister_driver(&hil_ptr_serio_driver); 428 serio_unregister_driver(&hil_ptr_serio_driver);
426} 429}
427 430
428module_init(hil_ptr_init); 431module_init(hil_ptr_init);
429module_exit(hil_ptr_exit); 432module_exit(hil_ptr_exit);
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 29542f0631cb..1740cadd9594 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -20,6 +20,27 @@
20#include "psmouse.h" 20#include "psmouse.h"
21#include "lifebook.h" 21#include "lifebook.h"
22 22
23struct lifebook_data {
24 struct input_dev *dev2; /* Relative device */
25 char phys[32];
26};
27
28static const char *desired_serio_phys;
29
30static int lifebook_set_serio_phys(struct dmi_system_id *d)
31{
32 desired_serio_phys = d->driver_data;
33 return 0;
34}
35
36static unsigned char lifebook_use_6byte_proto;
37
38static int lifebook_set_6byte_proto(struct dmi_system_id *d)
39{
40 lifebook_use_6byte_proto = 1;
41 return 0;
42}
43
23static struct dmi_system_id lifebook_dmi_table[] = { 44static struct dmi_system_id lifebook_dmi_table[] = {
24 { 45 {
25 .ident = "FLORA-ie 55mi", 46 .ident = "FLORA-ie 55mi",
@@ -56,6 +77,24 @@ static struct dmi_system_id lifebook_dmi_table[] = {
56 .matches = { 77 .matches = {
57 DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), 78 DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
58 }, 79 },
80 .callback = lifebook_set_serio_phys,
81 .driver_data = "isa0060/serio3",
82 },
83 {
84 .ident = "Panasonic CF-28",
85 .matches = {
86 DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
87 DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"),
88 },
89 .callback = lifebook_set_6byte_proto,
90 },
91 {
92 .ident = "Panasonic CF-29",
93 .matches = {
94 DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
95 DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"),
96 },
97 .callback = lifebook_set_6byte_proto,
59 }, 98 },
60 { 99 {
61 .ident = "Lifebook B142", 100 .ident = "Lifebook B142",
@@ -68,30 +107,70 @@ static struct dmi_system_id lifebook_dmi_table[] = {
68 107
69static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) 108static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
70{ 109{
110 struct lifebook_data *priv = psmouse->private;
111 struct input_dev *dev1 = psmouse->dev;
112 struct input_dev *dev2 = priv->dev2;
71 unsigned char *packet = psmouse->packet; 113 unsigned char *packet = psmouse->packet;
72 struct input_dev *dev = psmouse->dev; 114 int relative_packet = packet[0] & 0x08;
73 115
74 if (psmouse->pktcnt != 3) 116 if (relative_packet || !lifebook_use_6byte_proto) {
75 return PSMOUSE_GOOD_DATA; 117 if (psmouse->pktcnt != 3)
118 return PSMOUSE_GOOD_DATA;
119 } else {
120 switch (psmouse->pktcnt) {
121 case 1:
122 return (packet[0] & 0xf8) == 0x00 ?
123 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
124 case 2:
125 return PSMOUSE_GOOD_DATA;
126 case 3:
127 return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ?
128 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
129 case 4:
130 return (packet[3] & 0xf8) == 0xc0 ?
131 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
132 case 5:
133 return (packet[4] & 0xc0) == (packet[2] & 0xc0) ?
134 PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
135 case 6:
136 if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0))
137 return PSMOUSE_BAD_DATA;
138 if ((packet[5] & 0xc0) != (packet[1] & 0xc0))
139 return PSMOUSE_BAD_DATA;
140 break; /* report data */
141 }
142 }
76 143
77 /* calculate X and Y */ 144 if (relative_packet) {
78 if ((packet[0] & 0x08) == 0x00) { 145 if (!dev2)
79 input_report_abs(dev, ABS_X, 146 printk(KERN_WARNING "lifebook.c: got relative packet "
147 "but no relative device set up\n");
148 } else if (lifebook_use_6byte_proto) {
149 input_report_abs(dev1, ABS_X,
150 ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f));
151 input_report_abs(dev1, ABS_Y,
152 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f)));
153 } else {
154 input_report_abs(dev1, ABS_X,
80 (packet[1] | ((packet[0] & 0x30) << 4))); 155 (packet[1] | ((packet[0] & 0x30) << 4)));
81 input_report_abs(dev, ABS_Y, 156 input_report_abs(dev1, ABS_Y,
82 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); 157 1024 - (packet[2] | ((packet[0] & 0xC0) << 2)));
83 } else {
84 input_report_rel(dev, REL_X,
85 ((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
86 input_report_rel(dev, REL_Y,
87 -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
88 } 158 }
89 159
90 input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 160 input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04);
91 input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 161 input_sync(dev1);
92 input_report_key(dev, BTN_TOUCH, packet[0] & 0x04);
93 162
94 input_sync(dev); 163 if (dev2) {
164 if (relative_packet) {
165 input_report_rel(dev2, REL_X,
166 ((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
167 input_report_rel(dev2, REL_Y,
168 -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
169 }
170 input_report_key(dev2, BTN_LEFT, packet[0] & 0x01);
171 input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02);
172 input_sync(dev2);
173 }
95 174
96 return PSMOUSE_FULL_PACKET; 175 return PSMOUSE_FULL_PACKET;
97} 176}
@@ -109,12 +188,20 @@ static int lifebook_absolute_mode(struct psmouse *psmouse)
109 you leave this call out the touchsreen will never send 188 you leave this call out the touchsreen will never send
110 absolute coordinates 189 absolute coordinates
111 */ 190 */
112 param = 0x07; 191 param = lifebook_use_6byte_proto ? 0x08 : 0x07;
113 ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES); 192 ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
114 193
115 return 0; 194 return 0;
116} 195}
117 196
197static void lifebook_relative_mode(struct psmouse *psmouse)
198{
199 struct ps2dev *ps2dev = &psmouse->ps2dev;
200 unsigned char param = 0x06;
201
202 ps2_command(ps2dev, &param, PSMOUSE_CMD_SETRES);
203}
204
118static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) 205static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution)
119{ 206{
120 static const unsigned char params[] = { 0, 1, 2, 2, 3 }; 207 static const unsigned char params[] = { 0, 1, 2, 2, 3 };
@@ -131,6 +218,8 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu
131static void lifebook_disconnect(struct psmouse *psmouse) 218static void lifebook_disconnect(struct psmouse *psmouse)
132{ 219{
133 psmouse_reset(psmouse); 220 psmouse_reset(psmouse);
221 kfree(psmouse->private);
222 psmouse->private = NULL;
134} 223}
135 224
136int lifebook_detect(struct psmouse *psmouse, int set_properties) 225int lifebook_detect(struct psmouse *psmouse, int set_properties)
@@ -138,6 +227,10 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties)
138 if (!dmi_check_system(lifebook_dmi_table)) 227 if (!dmi_check_system(lifebook_dmi_table))
139 return -1; 228 return -1;
140 229
230 if (desired_serio_phys &&
231 strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys))
232 return -1;
233
141 if (set_properties) { 234 if (set_properties) {
142 psmouse->vendor = "Fujitsu"; 235 psmouse->vendor = "Fujitsu";
143 psmouse->name = "Lifebook TouchScreen"; 236 psmouse->name = "Lifebook TouchScreen";
@@ -146,24 +239,78 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties)
146 return 0; 239 return 0;
147} 240}
148 241
242static int lifebook_create_relative_device(struct psmouse *psmouse)
243{
244 struct input_dev *dev2;
245 struct lifebook_data *priv;
246 int error = -ENOMEM;
247
248 priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL);
249 dev2 = input_allocate_device();
250 if (!priv || !dev2)
251 goto err_out;
252
253 priv->dev2 = dev2;
254 snprintf(priv->phys, sizeof(priv->phys),
255 "%s/input1", psmouse->ps2dev.serio->phys);
256
257 dev2->phys = priv->phys;
258 dev2->name = "PS/2 Touchpad";
259 dev2->id.bustype = BUS_I8042;
260 dev2->id.vendor = 0x0002;
261 dev2->id.product = PSMOUSE_LIFEBOOK;
262 dev2->id.version = 0x0000;
263 dev2->dev.parent = &psmouse->ps2dev.serio->dev;
264
265 dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
266 dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y);
267 dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
268
269 error = input_register_device(priv->dev2);
270 if (error)
271 goto err_out;
272
273 psmouse->private = priv;
274 return 0;
275
276 err_out:
277 input_free_device(dev2);
278 kfree(priv);
279 return error;
280}
281
149int lifebook_init(struct psmouse *psmouse) 282int lifebook_init(struct psmouse *psmouse)
150{ 283{
151 struct input_dev *input_dev = psmouse->dev; 284 struct input_dev *dev1 = psmouse->dev;
285 int max_coord = lifebook_use_6byte_proto ? 1024 : 4096;
152 286
153 if (lifebook_absolute_mode(psmouse)) 287 if (lifebook_absolute_mode(psmouse))
154 return -1; 288 return -1;
155 289
156 input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); 290 dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
157 input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 291 dev1->relbit[0] = 0;
158 input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); 292 dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
159 input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); 293 input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
160 input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); 294 input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
161 input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); 295
296 if (!desired_serio_phys) {
297 if (lifebook_create_relative_device(psmouse)) {
298 lifebook_relative_mode(psmouse);
299 return -1;
300 }
301 }
162 302
163 psmouse->protocol_handler = lifebook_process_byte; 303 psmouse->protocol_handler = lifebook_process_byte;
164 psmouse->set_resolution = lifebook_set_resolution; 304 psmouse->set_resolution = lifebook_set_resolution;
165 psmouse->disconnect = lifebook_disconnect; 305 psmouse->disconnect = lifebook_disconnect;
166 psmouse->reconnect = lifebook_absolute_mode; 306 psmouse->reconnect = lifebook_absolute_mode;
307
308 psmouse->model = lifebook_use_6byte_proto ? 6 : 3;
309
310 /*
311 * Use packet size = 3 even when using 6-byte protocol because
312 * that's what POLL will return on Lifebooks (according to spec).
313 */
167 psmouse->pktsize = 3; 314 psmouse->pktsize = 3;
168 315
169 return 0; 316 return 0;
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h
index be1c0943825d..c1647cf036c2 100644
--- a/drivers/input/mouse/lifebook.h
+++ b/drivers/input/mouse/lifebook.h
@@ -11,7 +11,18 @@
11#ifndef _LIFEBOOK_H 11#ifndef _LIFEBOOK_H
12#define _LIFEBOOK_H 12#define _LIFEBOOK_H
13 13
14#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
14int lifebook_detect(struct psmouse *psmouse, int set_properties); 15int lifebook_detect(struct psmouse *psmouse, int set_properties);
15int lifebook_init(struct psmouse *psmouse); 16int lifebook_init(struct psmouse *psmouse);
17#else
18inline int lifebook_detect(struct psmouse *psmouse, int set_properties)
19{
20 return -ENOSYS;
21}
22inline int lifebook_init(struct psmouse *psmouse)
23{
24 return -ENOSYS;
25}
26#endif
16 27
17#endif 28#endif
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index d3ddea26b8ca..9df74b72e6c4 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -200,6 +200,7 @@ static void ps2pp_disconnect(struct psmouse *psmouse)
200static const struct ps2pp_info *get_model_info(unsigned char model) 200static const struct ps2pp_info *get_model_info(unsigned char model)
201{ 201{
202 static const struct ps2pp_info ps2pp_list[] = { 202 static const struct ps2pp_info ps2pp_list[] = {
203 { 1, 0, 0 }, /* Simple 2-button mouse */
203 { 12, 0, PS2PP_SIDE_BTN}, 204 { 12, 0, PS2PP_SIDE_BTN},
204 { 13, 0, 0 }, 205 { 13, 0, 0 },
205 { 15, PS2PP_KIND_MX, /* MX1000 */ 206 { 15, PS2PP_KIND_MX, /* MX1000 */
@@ -338,12 +339,12 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
338 param[1] = 0; 339 param[1] = 0;
339 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); 340 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
340 341
341 if (!param[1])
342 return -1;
343
344 model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); 342 model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78);
345 buttons = param[1]; 343 buttons = param[1];
346 344
345 if (!model || !buttons)
346 return -1;
347
347 if ((model_info = get_model_info(model)) != NULL) { 348 if ((model_info = get_model_info(model)) != NULL) {
348 349
349/* 350/*
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h
index 64a8ec52ea6d..6e5712525fd6 100644
--- a/drivers/input/mouse/logips2pp.h
+++ b/drivers/input/mouse/logips2pp.h
@@ -11,6 +11,13 @@
11#ifndef _LOGIPS2PP_H 11#ifndef _LOGIPS2PP_H
12#define _LOGIPS2PP_H 12#define _LOGIPS2PP_H
13 13
14#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
14int ps2pp_init(struct psmouse *psmouse, int set_properties); 15int ps2pp_init(struct psmouse *psmouse, int set_properties);
16#else
17inline int ps2pp_init(struct psmouse *psmouse, int set_properties)
18{
19 return -ENOSYS;
20}
21#endif /* CONFIG_MOUSE_PS2_LOGIPS2PP */
15 22
16#endif 23#endif
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 0fe5869d7d4c..f15f695777f8 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -28,6 +28,7 @@
28#include "alps.h" 28#include "alps.h"
29#include "lifebook.h" 29#include "lifebook.h"
30#include "trackpoint.h" 30#include "trackpoint.h"
31#include "touchkit_ps2.h"
31 32
32#define DRIVER_DESC "PS/2 mouse driver" 33#define DRIVER_DESC "PS/2 mouse driver"
33 34
@@ -569,7 +570,9 @@ static int psmouse_extensions(struct psmouse *psmouse,
569 return PSMOUSE_THINKPS; 570 return PSMOUSE_THINKPS;
570 571
571/* 572/*
572 * Try Synaptics TouchPad 573 * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol
574 * support is disabled in config - we need to know if it is synaptics so we
575 * can reset it properly after probing for intellimouse.
573 */ 576 */
574 if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { 577 if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) {
575 synaptics_hardware = 1; 578 synaptics_hardware = 1;
@@ -605,14 +608,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
605 } 608 }
606 } 609 }
607 610
608 if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) 611 if (max_proto > PSMOUSE_IMEX) {
609 return PSMOUSE_GENPS; 612
613 if (genius_detect(psmouse, set_properties) == 0)
614 return PSMOUSE_GENPS;
610 615
611 if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) 616 if (ps2pp_init(psmouse, set_properties) == 0)
612 return PSMOUSE_PS2PP; 617 return PSMOUSE_PS2PP;
613 618
614 if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) 619 if (trackpoint_detect(psmouse, set_properties) == 0)
615 return PSMOUSE_TRACKPOINT; 620 return PSMOUSE_TRACKPOINT;
621
622 if (touchkit_ps2_detect(psmouse, set_properties) == 0)
623 return PSMOUSE_TOUCHKIT_PS2;
624 }
616 625
617/* 626/*
618 * Reset to defaults in case the device got confused by extended 627 * Reset to defaults in case the device got confused by extended
@@ -654,12 +663,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
654 .maxproto = 1, 663 .maxproto = 1,
655 .detect = ps2bare_detect, 664 .detect = ps2bare_detect,
656 }, 665 },
666#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP
657 { 667 {
658 .type = PSMOUSE_PS2PP, 668 .type = PSMOUSE_PS2PP,
659 .name = "PS2++", 669 .name = "PS2++",
660 .alias = "logitech", 670 .alias = "logitech",
661 .detect = ps2pp_init, 671 .detect = ps2pp_init,
662 }, 672 },
673#endif
663 { 674 {
664 .type = PSMOUSE_THINKPS, 675 .type = PSMOUSE_THINKPS,
665 .name = "ThinkPS/2", 676 .name = "ThinkPS/2",
@@ -686,6 +697,7 @@ static const struct psmouse_protocol psmouse_protocols[] = {
686 .maxproto = 1, 697 .maxproto = 1,
687 .detect = im_explorer_detect, 698 .detect = im_explorer_detect,
688 }, 699 },
700#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
689 { 701 {
690 .type = PSMOUSE_SYNAPTICS, 702 .type = PSMOUSE_SYNAPTICS,
691 .name = "SynPS/2", 703 .name = "SynPS/2",
@@ -693,6 +705,8 @@ static const struct psmouse_protocol psmouse_protocols[] = {
693 .detect = synaptics_detect, 705 .detect = synaptics_detect,
694 .init = synaptics_init, 706 .init = synaptics_init,
695 }, 707 },
708#endif
709#ifdef CONFIG_MOUSE_PS2_ALPS
696 { 710 {
697 .type = PSMOUSE_ALPS, 711 .type = PSMOUSE_ALPS,
698 .name = "AlpsPS/2", 712 .name = "AlpsPS/2",
@@ -700,18 +714,31 @@ static const struct psmouse_protocol psmouse_protocols[] = {
700 .detect = alps_detect, 714 .detect = alps_detect,
701 .init = alps_init, 715 .init = alps_init,
702 }, 716 },
717#endif
718#ifdef CONFIG_MOUSE_PS2_LIFEBOOK
703 { 719 {
704 .type = PSMOUSE_LIFEBOOK, 720 .type = PSMOUSE_LIFEBOOK,
705 .name = "LBPS/2", 721 .name = "LBPS/2",
706 .alias = "lifebook", 722 .alias = "lifebook",
707 .init = lifebook_init, 723 .init = lifebook_init,
708 }, 724 },
725#endif
726#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
709 { 727 {
710 .type = PSMOUSE_TRACKPOINT, 728 .type = PSMOUSE_TRACKPOINT,
711 .name = "TPPS/2", 729 .name = "TPPS/2",
712 .alias = "trackpoint", 730 .alias = "trackpoint",
713 .detect = trackpoint_detect, 731 .detect = trackpoint_detect,
714 }, 732 },
733#endif
734#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
735 {
736 .type = PSMOUSE_TOUCHKIT_PS2,
737 .name = "touchkitPS/2",
738 .alias = "touchkit",
739 .detect = touchkit_ps2_detect,
740 },
741#endif
715 { 742 {
716 .type = PSMOUSE_AUTO, 743 .type = PSMOUSE_AUTO,
717 .name = "auto", 744 .name = "auto",
@@ -823,12 +850,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate)
823static void psmouse_initialize(struct psmouse *psmouse) 850static void psmouse_initialize(struct psmouse *psmouse)
824{ 851{
825/* 852/*
826 * We set the mouse into streaming mode.
827 */
828
829 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM);
830
831/*
832 * We set the mouse report rate, resolution and scaling. 853 * We set the mouse report rate, resolution and scaling.
833 */ 854 */
834 855
@@ -1062,8 +1083,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
1062{ 1083{
1063 struct input_dev *input_dev = psmouse->dev; 1084 struct input_dev *input_dev = psmouse->dev;
1064 1085
1065 input_dev->private = psmouse; 1086 input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
1066 input_dev->cdev.dev = &psmouse->ps2dev.serio->dev;
1067 1087
1068 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 1088 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
1069 input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); 1089 input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index cf1de95b6f27..3964e8acbc54 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -87,6 +87,7 @@ enum psmouse_type {
87 PSMOUSE_ALPS, 87 PSMOUSE_ALPS,
88 PSMOUSE_LIFEBOOK, 88 PSMOUSE_LIFEBOOK,
89 PSMOUSE_TRACKPOINT, 89 PSMOUSE_TRACKPOINT,
90 PSMOUSE_TOUCHKIT_PS2,
90 PSMOUSE_AUTO /* This one should always be last */ 91 PSMOUSE_AUTO /* This one should always be last */
91}; 92};
92 93
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index a85d74710b44..77b8ee2b9651 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -69,7 +69,8 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data)
69 switch (sermouse->count) { 69 switch (sermouse->count) {
70 70
71 case 0: 71 case 0:
72 if ((data & 0xf8) != 0x80) return; 72 if ((data & 0xf8) != 0x80)
73 return;
73 input_report_key(dev, BTN_LEFT, !(data & 4)); 74 input_report_key(dev, BTN_LEFT, !(data & 4));
74 input_report_key(dev, BTN_RIGHT, !(data & 1)); 75 input_report_key(dev, BTN_RIGHT, !(data & 1));
75 input_report_key(dev, BTN_MIDDLE, !(data & 2)); 76 input_report_key(dev, BTN_MIDDLE, !(data & 2));
@@ -107,7 +108,10 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
107 struct input_dev *dev = sermouse->dev; 108 struct input_dev *dev = sermouse->dev;
108 signed char *buf = sermouse->buf; 109 signed char *buf = sermouse->buf;
109 110
110 if (data & 0x40) sermouse->count = 0; 111 if (data & 0x40)
112 sermouse->count = 0;
113 else if (sermouse->count == 0)
114 return;
111 115
112 switch (sermouse->count) { 116 switch (sermouse->count) {
113 117
@@ -169,7 +173,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data)
169 173
170 case 5: 174 case 5:
171 case 7: /* Ignore anything besides MZ++ */ 175 case 7: /* Ignore anything besides MZ++ */
172 if (sermouse->type != SERIO_MZPP) break; 176 if (sermouse->type != SERIO_MZPP)
177 break;
173 178
174 switch (buf[1]) { 179 switch (buf[1]) {
175 180
@@ -206,13 +211,16 @@ static irqreturn_t sermouse_interrupt(struct serio *serio,
206{ 211{
207 struct sermouse *sermouse = serio_get_drvdata(serio); 212 struct sermouse *sermouse = serio_get_drvdata(serio);
208 213
209 if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0; 214 if (time_after(jiffies, sermouse->last + HZ/10))
215 sermouse->count = 0;
216
210 sermouse->last = jiffies; 217 sermouse->last = jiffies;
211 218
212 if (sermouse->type > SERIO_SUN) 219 if (sermouse->type > SERIO_SUN)
213 sermouse_process_ms(sermouse, data); 220 sermouse_process_ms(sermouse, data);
214 else 221 else
215 sermouse_process_msc(sermouse, data); 222 sermouse_process_msc(sermouse, data);
223
216 return IRQ_HANDLED; 224 return IRQ_HANDLED;
217} 225}
218 226
@@ -258,12 +266,11 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
258 input_dev->id.vendor = sermouse->type; 266 input_dev->id.vendor = sermouse->type;
259 input_dev->id.product = c; 267 input_dev->id.product = c;
260 input_dev->id.version = 0x0100; 268 input_dev->id.version = 0x0100;
261 input_dev->cdev.dev = &serio->dev; 269 input_dev->dev.parent = &serio->dev;
262 270
263 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); 271 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
264 input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); 272 input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
265 input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); 273 input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
266 input_dev->private = sermouse;
267 274
268 if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); 275 if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
269 if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); 276 if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index f0f9413d762c..c77788bf932d 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -40,33 +40,70 @@
40#define YMIN_NOMINAL 1408 40#define YMIN_NOMINAL 1408
41#define YMAX_NOMINAL 4448 41#define YMAX_NOMINAL 4448
42 42
43
43/***************************************************************************** 44/*****************************************************************************
44 * Synaptics communications functions 45 * Stuff we need even when we do not want native Synaptics support
45 ****************************************************************************/ 46 ****************************************************************************/
46 47
47/* 48/*
48 * Send a command to the synpatics touchpad by special commands 49 * Set the synaptics touchpad mode byte by special commands
49 */ 50 */
50static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) 51static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode)
51{ 52{
52 if (psmouse_sliced_command(psmouse, c)) 53 unsigned char param[1];
54
55 if (psmouse_sliced_command(psmouse, mode))
53 return -1; 56 return -1;
54 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) 57 param[0] = SYN_PS_SET_MODE2;
58 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
55 return -1; 59 return -1;
56 return 0; 60 return 0;
57} 61}
58 62
63int synaptics_detect(struct psmouse *psmouse, int set_properties)
64{
65 struct ps2dev *ps2dev = &psmouse->ps2dev;
66 unsigned char param[4];
67
68 param[0] = 0;
69
70 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
71 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
72 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
73 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
74 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
75
76 if (param[1] != 0x47)
77 return -ENODEV;
78
79 if (set_properties) {
80 psmouse->vendor = "Synaptics";
81 psmouse->name = "TouchPad";
82 }
83
84 return 0;
85}
86
87void synaptics_reset(struct psmouse *psmouse)
88{
89 /* reset touchpad back to relative mode, gestures enabled */
90 synaptics_mode_cmd(psmouse, 0);
91}
92
93#ifdef CONFIG_MOUSE_PS2_SYNAPTICS
94
95/*****************************************************************************
96 * Synaptics communications functions
97 ****************************************************************************/
98
59/* 99/*
60 * Set the synaptics touchpad mode byte by special commands 100 * Send a command to the synpatics touchpad by special commands
61 */ 101 */
62static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) 102static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param)
63{ 103{
64 unsigned char param[1]; 104 if (psmouse_sliced_command(psmouse, c))
65
66 if (psmouse_sliced_command(psmouse, mode))
67 return -1; 105 return -1;
68 param[0] = SYN_PS_SET_MODE2; 106 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO))
69 if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE))
70 return -1; 107 return -1;
71 return 0; 108 return 0;
72} 109}
@@ -529,12 +566,6 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
529 clear_bit(REL_Y, dev->relbit); 566 clear_bit(REL_Y, dev->relbit);
530} 567}
531 568
532void synaptics_reset(struct psmouse *psmouse)
533{
534 /* reset touchpad back to relative mode, gestures enabled */
535 synaptics_mode_cmd(psmouse, 0);
536}
537
538static void synaptics_disconnect(struct psmouse *psmouse) 569static void synaptics_disconnect(struct psmouse *psmouse)
539{ 570{
540 synaptics_reset(psmouse); 571 synaptics_reset(psmouse);
@@ -569,30 +600,6 @@ static int synaptics_reconnect(struct psmouse *psmouse)
569 return 0; 600 return 0;
570} 601}
571 602
572int synaptics_detect(struct psmouse *psmouse, int set_properties)
573{
574 struct ps2dev *ps2dev = &psmouse->ps2dev;
575 unsigned char param[4];
576
577 param[0] = 0;
578
579 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
580 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
581 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
582 ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES);
583 ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO);
584
585 if (param[1] != 0x47)
586 return -1;
587
588 if (set_properties) {
589 psmouse->vendor = "Synaptics";
590 psmouse->name = "TouchPad";
591 }
592
593 return 0;
594}
595
596#if defined(__i386__) 603#if defined(__i386__)
597#include <linux/dmi.h> 604#include <linux/dmi.h>
598static struct dmi_system_id toshiba_dmi_table[] = { 605static struct dmi_system_id toshiba_dmi_table[] = {
@@ -648,6 +655,16 @@ int synaptics_init(struct psmouse *psmouse)
648 655
649 set_input_params(psmouse->dev, priv); 656 set_input_params(psmouse->dev, priv);
650 657
658 /*
659 * Encode touchpad model so that it can be used to set
660 * input device->id.version and be visible to userspace.
661 * Because version is __u16 we have to drop something.
662 * Hardware info bits seem to be good candidates as they
663 * are documented to be for Synaptics corp. internal use.
664 */
665 psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) |
666 (priv->model_id & 0x000000ff);
667
651 psmouse->protocol_handler = synaptics_process_byte; 668 psmouse->protocol_handler = synaptics_process_byte;
652 psmouse->set_rate = synaptics_set_rate; 669 psmouse->set_rate = synaptics_set_rate;
653 psmouse->disconnect = synaptics_disconnect; 670 psmouse->disconnect = synaptics_disconnect;
@@ -680,4 +697,12 @@ int synaptics_init(struct psmouse *psmouse)
680 return -1; 697 return -1;
681} 698}
682 699
700#else /* CONFIG_MOUSE_PS2_SYNAPTICS */
701
702int synaptics_init(struct psmouse *psmouse)
703{
704 return -ENOSYS;
705}
706
707#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */
683 708
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 68fff1dcd7de..02aa4cf7bc77 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -9,10 +9,6 @@
9#ifndef _SYNAPTICS_H 9#ifndef _SYNAPTICS_H
10#define _SYNAPTICS_H 10#define _SYNAPTICS_H
11 11
12extern int synaptics_detect(struct psmouse *psmouse, int set_properties);
13extern int synaptics_init(struct psmouse *psmouse);
14extern void synaptics_reset(struct psmouse *psmouse);
15
16/* synaptics queries */ 12/* synaptics queries */
17#define SYN_QUE_IDENTIFY 0x00 13#define SYN_QUE_IDENTIFY 0x00
18#define SYN_QUE_MODES 0x01 14#define SYN_QUE_MODES 0x01
@@ -62,9 +58,9 @@ extern void synaptics_reset(struct psmouse *psmouse);
62#define SYN_MODE_WMODE(m) ((m) & (1 << 0)) 58#define SYN_MODE_WMODE(m) ((m) & (1 << 0))
63 59
64/* synaptics identify query bits */ 60/* synaptics identify query bits */
65#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) 61#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f)
66#define SYN_ID_MAJOR(i) ((i) & 0x0f) 62#define SYN_ID_MAJOR(i) ((i) & 0x0f)
67#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) 63#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff)
68#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) 64#define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47)
69 65
70/* synaptics special commands */ 66/* synaptics special commands */
@@ -98,8 +94,8 @@ struct synaptics_hw_state {
98struct synaptics_data { 94struct synaptics_data {
99 /* Data read from the touchpad */ 95 /* Data read from the touchpad */
100 unsigned long int model_id; /* Model-ID */ 96 unsigned long int model_id; /* Model-ID */
101 unsigned long int capabilities; /* Capabilities */ 97 unsigned long int capabilities; /* Capabilities */
102 unsigned long int ext_cap; /* Extended Capabilities */ 98 unsigned long int ext_cap; /* Extended Capabilities */
103 unsigned long int identity; /* Identification */ 99 unsigned long int identity; /* Identification */
104 100
105 unsigned char pkt_type; /* packet type - old, new, etc */ 101 unsigned char pkt_type; /* packet type - old, new, etc */
@@ -107,4 +103,8 @@ struct synaptics_data {
107 int scroll; 103 int scroll;
108}; 104};
109 105
106int synaptics_detect(struct psmouse *psmouse, int set_properties);
107int synaptics_init(struct psmouse *psmouse);
108void synaptics_reset(struct psmouse *psmouse);
109
110#endif /* _SYNAPTICS_H */ 110#endif /* _SYNAPTICS_H */
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
new file mode 100644
index 000000000000..7b977fd23571
--- /dev/null
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -0,0 +1,100 @@
1/* ----------------------------------------------------------------------------
2 * touchkit_ps2.c -- Driver for eGalax TouchKit PS/2 Touchscreens
3 *
4 * Copyright (C) 2005 by Stefan Lucke
5 * Copyright (C) 2004 by Daniel Ritz
6 * Copyright (C) by Todd E. Johnson (mtouchusb.c)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * Based upon touchkitusb.c
23 *
24 * Vendor documentation is available in support section of:
25 * http://www.egalax.com.tw/
26 */
27
28#include <linux/kernel.h>
29#include <linux/slab.h>
30
31#include <linux/input.h>
32#include <linux/serio.h>
33#include <linux/libps2.h>
34
35#include "psmouse.h"
36#include "touchkit_ps2.h"
37
38#define TOUCHKIT_MAX_XC 0x07ff
39#define TOUCHKIT_MAX_YC 0x07ff
40
41#define TOUCHKIT_CMD 0x0a
42#define TOUCHKIT_CMD_LENGTH 1
43
44#define TOUCHKIT_CMD_ACTIVE 'A'
45#define TOUCHKIT_CMD_FIRMWARE_VERSION 'D'
46#define TOUCHKIT_CMD_CONTROLLER_TYPE 'E'
47
48#define TOUCHKIT_SEND_PARMS(s, r, c) ((s) << 12 | (r) << 8 | (c))
49
50#define TOUCHKIT_GET_TOUCHED(packet) (((packet)[0]) & 0x01)
51#define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2])
52#define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4])
53
54static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse)
55{
56 unsigned char *packet = psmouse->packet;
57 struct input_dev *dev = psmouse->dev;
58
59 if (psmouse->pktcnt != 5)
60 return PSMOUSE_GOOD_DATA;
61
62 input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet));
63 input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet));
64 input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet));
65 input_sync(dev);
66
67 return PSMOUSE_FULL_PACKET;
68}
69
70int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
71{
72 struct input_dev *dev = psmouse->dev;
73 unsigned char param[3];
74 int command;
75
76 param[0] = TOUCHKIT_CMD_LENGTH;
77 param[1] = TOUCHKIT_CMD_ACTIVE;
78 command = TOUCHKIT_SEND_PARMS(2, 3, TOUCHKIT_CMD);
79
80 if (ps2_command(&psmouse->ps2dev, param, command))
81 return -ENODEV;
82
83 if (param[0] != TOUCHKIT_CMD || param[1] != 0x01 ||
84 param[2] != TOUCHKIT_CMD_ACTIVE)
85 return -ENODEV;
86
87 if (set_properties) {
88 dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
89 set_bit(BTN_TOUCH, dev->keybit);
90 input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
91 input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
92
93 psmouse->vendor = "eGalax";
94 psmouse->name = "Touchscreen";
95 psmouse->protocol_handler = touchkit_ps2_process_byte;
96 psmouse->pktsize = 5;
97 }
98
99 return 0;
100}
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h
new file mode 100644
index 000000000000..61e9dfd8419f
--- /dev/null
+++ b/drivers/input/mouse/touchkit_ps2.h
@@ -0,0 +1,24 @@
1/* ----------------------------------------------------------------------------
2 * touchkit_ps2.h -- Driver for eGalax TouchKit PS/2 Touchscreens
3 *
4 * Copyright (C) 2005 by Stefan Lucke
5 * Copyright (c) 2005 Vojtech Pavlik
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12#ifndef _TOUCHKIT_PS2_H
13#define _TOUCHKIT_PS2_H
14
15#ifdef CONFIG_MOUSE_PS2_TOUCHKIT
16int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties);
17#else
18inline int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
19{
20 return -ENOSYS;
21}
22#endif /* CONFIG_MOUSE_PS2_TOUCHKIT */
23
24#endif
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index 050298b1a09d..c10a6e7d0101 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -142,6 +142,13 @@ struct trackpoint_data
142 unsigned char ext_dev; 142 unsigned char ext_dev;
143}; 143};
144 144
145extern int trackpoint_detect(struct psmouse *psmouse, int set_properties); 145#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
146int trackpoint_detect(struct psmouse *psmouse, int set_properties);
147#else
148inline int trackpoint_detect(struct psmouse *psmouse, int set_properties)
149{
150 return -ENOSYS;
151}
152#endif /* CONFIG_MOUSE_PS2_TRACKPOINT */
146 153
147#endif /* _TRACKPOINT_H */ 154#endif /* _TRACKPOINT_H */
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index c3d64fcc858d..4a321576f345 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -508,8 +508,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
508 input_dev->name = mouse->name; 508 input_dev->name = mouse->name;
509 input_dev->phys = mouse->phys; 509 input_dev->phys = mouse->phys;
510 input_dev->id.bustype = BUS_RS232; 510 input_dev->id.bustype = BUS_RS232;
511 input_dev->cdev.dev = &serio->dev; 511 input_dev->dev.parent = &serio->dev;
512 input_dev->private = mouse;
513 512
514 set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ 513 set_bit (EV_KEY, input_dev->evbit); /* We have buttons */
515 set_bit (EV_REL, input_dev->evbit); 514 set_bit (EV_REL, input_dev->evbit);