aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-01-07 01:34:59 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-01-07 01:34:59 -0500
commit554738da71004d96e06fb75f4772dfc3b0f47810 (patch)
tree149a96ce3727025d3b9260961ec94ba8306db278 /drivers/input/mouse
parent7b4b30689d688d9ca2e5c3859db6bbe1c35e6014 (diff)
parenta6d38f889750ed6290728a19d9dad577b147c6d0 (diff)
Merge branch 'next' into for-linus
Conflicts: include/linux/input.h
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/hgpk.c695
-rw-r--r--drivers/input/mouse/hgpk.h31
-rw-r--r--drivers/input/mouse/psmouse-base.c1
-rw-r--r--drivers/input/mouse/synaptics.c129
-rw-r--r--drivers/input/mouse/synaptics.h3
5 files changed, 770 insertions, 89 deletions
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 1d2205b24800..95577c15ae56 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -40,6 +40,8 @@
40#include "psmouse.h" 40#include "psmouse.h"
41#include "hgpk.h" 41#include "hgpk.h"
42 42
43#define ILLEGAL_XY 999999
44
43static bool tpdebug; 45static bool tpdebug;
44module_param(tpdebug, bool, 0644); 46module_param(tpdebug, bool, 0644);
45MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG."); 47MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
@@ -47,48 +49,150 @@ MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
47static int recalib_delta = 100; 49static int recalib_delta = 100;
48module_param(recalib_delta, int, 0644); 50module_param(recalib_delta, int, 0644);
49MODULE_PARM_DESC(recalib_delta, 51MODULE_PARM_DESC(recalib_delta,
50 "packets containing a delta this large will cause a recalibration."); 52 "packets containing a delta this large will be discarded, and a "
53 "recalibration may be scheduled.");
51 54
52static int jumpy_delay = 1000; 55static int jumpy_delay = 20;
53module_param(jumpy_delay, int, 0644); 56module_param(jumpy_delay, int, 0644);
54MODULE_PARM_DESC(jumpy_delay, 57MODULE_PARM_DESC(jumpy_delay,
55 "delay (ms) before recal after jumpiness detected"); 58 "delay (ms) before recal after jumpiness detected");
56 59
57static int spew_delay = 1000; 60static int spew_delay = 1;
58module_param(spew_delay, int, 0644); 61module_param(spew_delay, int, 0644);
59MODULE_PARM_DESC(spew_delay, 62MODULE_PARM_DESC(spew_delay,
60 "delay (ms) before recal after packet spew detected"); 63 "delay (ms) before recal after packet spew detected");
61 64
62static int recal_guard_time = 2000; 65static int recal_guard_time;
63module_param(recal_guard_time, int, 0644); 66module_param(recal_guard_time, int, 0644);
64MODULE_PARM_DESC(recal_guard_time, 67MODULE_PARM_DESC(recal_guard_time,
65 "interval (ms) during which recal will be restarted if packet received"); 68 "interval (ms) during which recal will be restarted if packet received");
66 69
67static int post_interrupt_delay = 1000; 70static int post_interrupt_delay = 40;
68module_param(post_interrupt_delay, int, 0644); 71module_param(post_interrupt_delay, int, 0644);
69MODULE_PARM_DESC(post_interrupt_delay, 72MODULE_PARM_DESC(post_interrupt_delay,
70 "delay (ms) before recal after recal interrupt detected"); 73 "delay (ms) before recal after recal interrupt detected");
71 74
75static bool autorecal = true;
76module_param(autorecal, bool, 0644);
77MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
78
79static char hgpk_mode_name[16];
80module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);
81MODULE_PARM_DESC(hgpk_mode,
82 "default hgpk mode: mouse, glidesensor or pentablet");
83
84static int hgpk_default_mode = HGPK_MODE_MOUSE;
85
86static const char * const hgpk_mode_names[] = {
87 [HGPK_MODE_MOUSE] = "Mouse",
88 [HGPK_MODE_GLIDESENSOR] = "GlideSensor",
89 [HGPK_MODE_PENTABLET] = "PenTablet",
90};
91
92static int hgpk_mode_from_name(const char *buf, int len)
93{
94 int i;
95
96 for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {
97 const char *name = hgpk_mode_names[i];
98 if (strlen(name) == len && !strncasecmp(name, buf, len))
99 return i;
100 }
101
102 return HGPK_MODE_INVALID;
103}
104
105/*
106 * see if new value is within 20% of half of old value
107 */
108static int approx_half(int curr, int prev)
109{
110 int belowhalf, abovehalf;
111
112 if (curr < 5 || prev < 5)
113 return 0;
114
115 belowhalf = (prev * 8) / 20;
116 abovehalf = (prev * 12) / 20;
117
118 return belowhalf < curr && curr <= abovehalf;
119}
120
72/* 121/*
73 * When the touchpad gets ultra-sensitive, one can keep their finger 1/2" 122 * Throw out oddly large delta packets, and any that immediately follow whose
74 * above the pad and still have it send packets. This causes a jump cursor 123 * values are each approximately half of the previous. It seems that the ALPS
75 * when one places their finger on the pad. We can probably detect the 124 * firmware emits errant packets, and they get averaged out slowly.
76 * jump as we see a large deltas (>= 100px). In mouse mode, I've been
77 * unable to even come close to 100px deltas during normal usage, so I think
78 * this threshold is safe. If a large delta occurs, trigger a recalibration.
79 */ 125 */
80static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y) 126static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
81{ 127{
82 struct hgpk_data *priv = psmouse->private; 128 struct hgpk_data *priv = psmouse->private;
129 int avx, avy;
130 bool do_recal = false;
131
132 avx = abs(x);
133 avy = abs(y);
134
135 /* discard if too big, or half that but > 4 times the prev delta */
136 if (avx > recalib_delta ||
137 (avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
138 hgpk_err(psmouse, "detected %dpx jump in x\n", x);
139 priv->xbigj = avx;
140 } else if (approx_half(avx, priv->xbigj)) {
141 hgpk_err(psmouse, "detected secondary %dpx jump in x\n", x);
142 priv->xbigj = avx;
143 priv->xsaw_secondary++;
144 } else {
145 if (priv->xbigj && priv->xsaw_secondary > 1)
146 do_recal = true;
147 priv->xbigj = 0;
148 priv->xsaw_secondary = 0;
149 }
150
151 if (avy > recalib_delta ||
152 (avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
153 hgpk_err(psmouse, "detected %dpx jump in y\n", y);
154 priv->ybigj = avy;
155 } else if (approx_half(avy, priv->ybigj)) {
156 hgpk_err(psmouse, "detected secondary %dpx jump in y\n", y);
157 priv->ybigj = avy;
158 priv->ysaw_secondary++;
159 } else {
160 if (priv->ybigj && priv->ysaw_secondary > 1)
161 do_recal = true;
162 priv->ybigj = 0;
163 priv->ysaw_secondary = 0;
164 }
83 165
84 if (abs(x) > recalib_delta || abs(y) > recalib_delta) { 166 priv->xlast = avx;
85 hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n", 167 priv->ylast = avy;
86 recalib_delta, x, y); 168
87 /* My car gets forty rods to the hogshead and that's the 169 if (do_recal && jumpy_delay) {
88 * way I likes it! */ 170 hgpk_err(psmouse, "scheduling recalibration\n");
89 psmouse_queue_work(psmouse, &priv->recalib_wq, 171 psmouse_queue_work(psmouse, &priv->recalib_wq,
90 msecs_to_jiffies(jumpy_delay)); 172 msecs_to_jiffies(jumpy_delay));
91 } 173 }
174
175 return priv->xbigj || priv->ybigj;
176}
177
178static void hgpk_reset_spew_detection(struct hgpk_data *priv)
179{
180 priv->spew_count = 0;
181 priv->dupe_count = 0;
182 priv->x_tally = 0;
183 priv->y_tally = 0;
184 priv->spew_flag = NO_SPEW;
185}
186
187static void hgpk_reset_hack_state(struct psmouse *psmouse)
188{
189 struct hgpk_data *priv = psmouse->private;
190
191 priv->abs_x = priv->abs_y = -1;
192 priv->xlast = priv->ylast = ILLEGAL_XY;
193 priv->xbigj = priv->ybigj = 0;
194 priv->xsaw_secondary = priv->ysaw_secondary = 0;
195 hgpk_reset_spew_detection(priv);
92} 196}
93 197
94/* 198/*
@@ -116,20 +220,57 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
116 if (l || r) 220 if (l || r)
117 return; 221 return;
118 222
223 /* don't track spew if the workaround feature has been turned off */
224 if (!spew_delay)
225 return;
226
227 if (abs(x) > 3 || abs(y) > 3) {
228 /* no spew, or spew ended */
229 hgpk_reset_spew_detection(priv);
230 return;
231 }
232
233 /* Keep a tally of the overall delta to the cursor position caused by
234 * the spew */
119 priv->x_tally += x; 235 priv->x_tally += x;
120 priv->y_tally += y; 236 priv->y_tally += y;
121 237
122 if (++priv->count > 100) { 238 switch (priv->spew_flag) {
239 case NO_SPEW:
240 /* we're not spewing, but this packet might be the start */
241 priv->spew_flag = MAYBE_SPEWING;
242
243 /* fall-through */
244
245 case MAYBE_SPEWING:
246 priv->spew_count++;
247
248 if (priv->spew_count < SPEW_WATCH_COUNT)
249 break;
250
251 /* excessive spew detected, request recalibration */
252 priv->spew_flag = SPEW_DETECTED;
253
254 /* fall-through */
255
256 case SPEW_DETECTED:
257 /* only recalibrate when the overall delta to the cursor
258 * is really small. if the spew is causing significant cursor
259 * movement, it is probably a case of the user moving the
260 * cursor very slowly across the screen. */
123 if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) { 261 if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
124 hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n", 262 hgpk_err(psmouse, "packet spew detected (%d,%d)\n",
125 priv->x_tally, priv->y_tally); 263 priv->x_tally, priv->y_tally);
264 priv->spew_flag = RECALIBRATING;
126 psmouse_queue_work(psmouse, &priv->recalib_wq, 265 psmouse_queue_work(psmouse, &priv->recalib_wq,
127 msecs_to_jiffies(spew_delay)); 266 msecs_to_jiffies(spew_delay));
128 } 267 }
129 /* reset every 100 packets */ 268
130 priv->count = 0; 269 break;
131 priv->x_tally = 0; 270 case RECALIBRATING:
132 priv->y_tally = 0; 271 /* we already detected a spew and requested a recalibration,
272 * just wait for the queue to kick into action. */
273 break;
133 } 274 }
134} 275}
135 276
@@ -143,25 +284,168 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
143 * swr/swl are the left/right buttons. 284 * swr/swl are the left/right buttons.
144 * x-neg/y-neg are the x and y delta negative bits 285 * x-neg/y-neg are the x and y delta negative bits
145 * x-over/y-over are the x and y overflow bits 286 * x-over/y-over are the x and y overflow bits
287 *
288 * ---
289 *
290 * HGPK Advanced Mode - single-mode format
291 *
292 * byte 0(PT): 1 1 0 0 1 1 1 1
293 * byte 0(GS): 1 1 1 1 1 1 1 1
294 * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
295 * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw 0
296 * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw
297 * byte 3: 0 y9 y8 y7 1 0 swr swl
298 * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
299 * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
300 *
301 * ?'s are not defined in the protocol spec, may vary between models.
302 *
303 * swr/swl are the left/right buttons.
304 *
305 * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
306 * pen/finger
146 */ 307 */
147static int hgpk_validate_byte(unsigned char *packet) 308static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
148{ 309{
149 return (packet[0] & 0x0C) != 0x08; 310 struct hgpk_data *priv = psmouse->private;
311 int pktcnt = psmouse->pktcnt;
312 bool valid;
313
314 switch (priv->mode) {
315 case HGPK_MODE_MOUSE:
316 valid = (packet[0] & 0x0C) == 0x08;
317 break;
318
319 case HGPK_MODE_GLIDESENSOR:
320 valid = pktcnt == 1 ?
321 packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);
322 break;
323
324 case HGPK_MODE_PENTABLET:
325 valid = pktcnt == 1 ?
326 packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);
327 break;
328
329 default:
330 valid = false;
331 break;
332 }
333
334 if (!valid)
335 hgpk_dbg(psmouse,
336 "bad data, mode %d (%d) %02x %02x %02x %02x %02x %02x\n",
337 priv->mode, pktcnt,
338 psmouse->packet[0], psmouse->packet[1],
339 psmouse->packet[2], psmouse->packet[3],
340 psmouse->packet[4], psmouse->packet[5]);
341
342 return valid;
150} 343}
151 344
152static void hgpk_process_packet(struct psmouse *psmouse) 345static void hgpk_process_advanced_packet(struct psmouse *psmouse)
153{ 346{
154 struct input_dev *dev = psmouse->dev; 347 struct hgpk_data *priv = psmouse->private;
348 struct input_dev *idev = psmouse->dev;
155 unsigned char *packet = psmouse->packet; 349 unsigned char *packet = psmouse->packet;
156 int x, y, left, right; 350 int down = !!(packet[2] & 2);
351 int left = !!(packet[3] & 1);
352 int right = !!(packet[3] & 2);
353 int x = packet[1] | ((packet[2] & 0x78) << 4);
354 int y = packet[4] | ((packet[3] & 0x70) << 3);
355
356 if (priv->mode == HGPK_MODE_GLIDESENSOR) {
357 int pt_down = !!(packet[2] & 1);
358 int finger_down = !!(packet[2] & 2);
359 int z = packet[5];
360
361 input_report_abs(idev, ABS_PRESSURE, z);
362 if (tpdebug)
363 hgpk_dbg(psmouse, "pd=%d fd=%d z=%d",
364 pt_down, finger_down, z);
365 } else {
366 /*
367 * PenTablet mode does not report pressure, so we don't
368 * report it here
369 */
370 if (tpdebug)
371 hgpk_dbg(psmouse, "pd=%d ", down);
372 }
373
374 if (tpdebug)
375 hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);
376
377 input_report_key(idev, BTN_TOUCH, down);
378 input_report_key(idev, BTN_LEFT, left);
379 input_report_key(idev, BTN_RIGHT, right);
380
381 /*
382 * If this packet says that the finger was removed, reset our position
383 * tracking so that we don't erroneously detect a jump on next press.
384 */
385 if (!down) {
386 hgpk_reset_hack_state(psmouse);
387 goto done;
388 }
389
390 /*
391 * Weed out duplicate packets (we get quite a few, and they mess up
392 * our jump detection)
393 */
394 if (x == priv->abs_x && y == priv->abs_y) {
395 if (++priv->dupe_count > SPEW_WATCH_COUNT) {
396 if (tpdebug)
397 hgpk_dbg(psmouse, "hard spew detected\n");
398 priv->spew_flag = RECALIBRATING;
399 psmouse_queue_work(psmouse, &priv->recalib_wq,
400 msecs_to_jiffies(spew_delay));
401 }
402 goto done;
403 }
157 404
158 left = packet[0] & 1; 405 /* not a duplicate, continue with position reporting */
159 right = (packet[0] >> 1) & 1; 406 priv->dupe_count = 0;
407
408 /* Don't apply hacks in PT mode, it seems reliable */
409 if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {
410 int x_diff = priv->abs_x - x;
411 int y_diff = priv->abs_y - y;
412 if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
413 if (tpdebug)
414 hgpk_dbg(psmouse, "discarding\n");
415 goto done;
416 }
417 hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
418 }
160 419
161 x = packet[1] - ((packet[0] << 4) & 0x100); 420 input_report_abs(idev, ABS_X, x);
162 y = ((packet[0] << 3) & 0x100) - packet[2]; 421 input_report_abs(idev, ABS_Y, y);
422 priv->abs_x = x;
423 priv->abs_y = y;
424
425done:
426 input_sync(idev);
427}
428
429static void hgpk_process_simple_packet(struct psmouse *psmouse)
430{
431 struct input_dev *dev = psmouse->dev;
432 unsigned char *packet = psmouse->packet;
433 int left = packet[0] & 1;
434 int right = (packet[0] >> 1) & 1;
435 int x = packet[1] - ((packet[0] << 4) & 0x100);
436 int y = ((packet[0] << 3) & 0x100) - packet[2];
437
438 if (packet[0] & 0xc0)
439 hgpk_dbg(psmouse,
440 "overflow -- 0x%02x 0x%02x 0x%02x\n",
441 packet[0], packet[1], packet[2]);
442
443 if (hgpk_discard_decay_hack(psmouse, x, y)) {
444 if (tpdebug)
445 hgpk_dbg(psmouse, "discarding\n");
446 return;
447 }
163 448
164 hgpk_jumpy_hack(psmouse, x, y);
165 hgpk_spewing_hack(psmouse, left, right, x, y); 449 hgpk_spewing_hack(psmouse, left, right, x, y);
166 450
167 if (tpdebug) 451 if (tpdebug)
@@ -180,15 +464,14 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
180{ 464{
181 struct hgpk_data *priv = psmouse->private; 465 struct hgpk_data *priv = psmouse->private;
182 466
183 if (hgpk_validate_byte(psmouse->packet)) { 467 if (!hgpk_is_byte_valid(psmouse, psmouse->packet))
184 hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",
185 __func__, psmouse->pktcnt, psmouse->packet[0],
186 psmouse->packet[1], psmouse->packet[2]);
187 return PSMOUSE_BAD_DATA; 468 return PSMOUSE_BAD_DATA;
188 }
189 469
190 if (psmouse->pktcnt >= psmouse->pktsize) { 470 if (psmouse->pktcnt >= psmouse->pktsize) {
191 hgpk_process_packet(psmouse); 471 if (priv->mode == HGPK_MODE_MOUSE)
472 hgpk_process_simple_packet(psmouse);
473 else
474 hgpk_process_advanced_packet(psmouse);
192 return PSMOUSE_FULL_PACKET; 475 return PSMOUSE_FULL_PACKET;
193 } 476 }
194 477
@@ -210,33 +493,176 @@ static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
210 return PSMOUSE_GOOD_DATA; 493 return PSMOUSE_GOOD_DATA;
211} 494}
212 495
496static int hgpk_select_mode(struct psmouse *psmouse)
497{
498 struct ps2dev *ps2dev = &psmouse->ps2dev;
499 struct hgpk_data *priv = psmouse->private;
500 int i;
501 int cmd;
502
503 /*
504 * 4 disables to enable advanced mode
505 * then 3 0xf2 bytes as the preamble for GS/PT selection
506 */
507 const int advanced_init[] = {
508 PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
509 PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
510 0xf2, 0xf2, 0xf2,
511 };
512
513 switch (priv->mode) {
514 case HGPK_MODE_MOUSE:
515 psmouse->pktsize = 3;
516 break;
517
518 case HGPK_MODE_GLIDESENSOR:
519 case HGPK_MODE_PENTABLET:
520 psmouse->pktsize = 6;
521
522 /* Switch to 'Advanced mode.', four disables in a row. */
523 for (i = 0; i < ARRAY_SIZE(advanced_init); i++)
524 if (ps2_command(ps2dev, NULL, advanced_init[i]))
525 return -EIO;
526
527 /* select between GlideSensor (mouse) or PenTablet */
528 cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?
529 PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;
530
531 if (ps2_command(ps2dev, NULL, cmd))
532 return -EIO;
533 break;
534
535 default:
536 return -EINVAL;
537 }
538
539 return 0;
540}
541
542static void hgpk_setup_input_device(struct input_dev *input,
543 struct input_dev *old_input,
544 enum hgpk_mode mode)
545{
546 if (old_input) {
547 input->name = old_input->name;
548 input->phys = old_input->phys;
549 input->id = old_input->id;
550 input->dev.parent = old_input->dev.parent;
551 }
552
553 memset(input->evbit, 0, sizeof(input->evbit));
554 memset(input->relbit, 0, sizeof(input->relbit));
555 memset(input->keybit, 0, sizeof(input->keybit));
556
557 /* All modes report left and right buttons */
558 __set_bit(EV_KEY, input->evbit);
559 __set_bit(BTN_LEFT, input->keybit);
560 __set_bit(BTN_RIGHT, input->keybit);
561
562 switch (mode) {
563 case HGPK_MODE_MOUSE:
564 __set_bit(EV_REL, input->evbit);
565 __set_bit(REL_X, input->relbit);
566 __set_bit(REL_Y, input->relbit);
567 break;
568
569 case HGPK_MODE_GLIDESENSOR:
570 __set_bit(BTN_TOUCH, input->keybit);
571 __set_bit(BTN_TOOL_FINGER, input->keybit);
572
573 __set_bit(EV_ABS, input->evbit);
574
575 /* GlideSensor has pressure sensor, PenTablet does not */
576 input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);
577
578 /* From device specs */
579 input_set_abs_params(input, ABS_X, 0, 399, 0, 0);
580 input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);
581
582 /* Calculated by hand based on usable size (52mm x 38mm) */
583 input_abs_set_res(input, ABS_X, 8);
584 input_abs_set_res(input, ABS_Y, 8);
585 break;
586
587 case HGPK_MODE_PENTABLET:
588 __set_bit(BTN_TOUCH, input->keybit);
589 __set_bit(BTN_TOOL_FINGER, input->keybit);
590
591 __set_bit(EV_ABS, input->evbit);
592
593 /* From device specs */
594 input_set_abs_params(input, ABS_X, 0, 999, 0, 0);
595 input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);
596
597 /* Calculated by hand based on usable size (156mm x 38mm) */
598 input_abs_set_res(input, ABS_X, 6);
599 input_abs_set_res(input, ABS_Y, 8);
600 break;
601
602 default:
603 BUG();
604 }
605}
606
607static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
608{
609 int err;
610
611 psmouse_reset(psmouse);
612
613 if (recalibrate) {
614 struct ps2dev *ps2dev = &psmouse->ps2dev;
615
616 /* send the recalibrate request */
617 if (ps2_command(ps2dev, NULL, 0xf5) ||
618 ps2_command(ps2dev, NULL, 0xf5) ||
619 ps2_command(ps2dev, NULL, 0xe6) ||
620 ps2_command(ps2dev, NULL, 0xf5)) {
621 return -1;
622 }
623
624 /* according to ALPS, 150mS is required for recalibration */
625 msleep(150);
626 }
627
628 err = hgpk_select_mode(psmouse);
629 if (err) {
630 hgpk_err(psmouse, "failed to select mode\n");
631 return err;
632 }
633
634 hgpk_reset_hack_state(psmouse);
635
636 return 0;
637}
638
213static int hgpk_force_recalibrate(struct psmouse *psmouse) 639static int hgpk_force_recalibrate(struct psmouse *psmouse)
214{ 640{
215 struct ps2dev *ps2dev = &psmouse->ps2dev; 641 struct ps2dev *ps2dev = &psmouse->ps2dev;
216 struct hgpk_data *priv = psmouse->private; 642 struct hgpk_data *priv = psmouse->private;
643 int err;
217 644
218 /* C-series touchpads added the recalibrate command */ 645 /* C-series touchpads added the recalibrate command */
219 if (psmouse->model < HGPK_MODEL_C) 646 if (psmouse->model < HGPK_MODEL_C)
220 return 0; 647 return 0;
221 648
649 if (!autorecal) {
650 hgpk_dbg(psmouse, "recalibrations disabled, ignoring\n");
651 return 0;
652 }
653
654 hgpk_dbg(psmouse, "recalibrating touchpad..\n");
655
222 /* we don't want to race with the irq handler, nor with resyncs */ 656 /* we don't want to race with the irq handler, nor with resyncs */
223 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING); 657 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
224 658
225 /* start by resetting the device */ 659 /* start by resetting the device */
226 psmouse_reset(psmouse); 660 err = hgpk_reset_device(psmouse, true);
227 661 if (err)
228 /* send the recalibrate request */ 662 return err;
229 if (ps2_command(ps2dev, NULL, 0xf5) ||
230 ps2_command(ps2dev, NULL, 0xf5) ||
231 ps2_command(ps2dev, NULL, 0xe6) ||
232 ps2_command(ps2dev, NULL, 0xf5)) {
233 return -1;
234 }
235
236 /* according to ALPS, 150mS is required for recalibration */
237 msleep(150);
238 663
239 /* XXX: If a finger is down during this delay, recalibration will 664 /*
665 * XXX: If a finger is down during this delay, recalibration will
240 * detect capacitance incorrectly. This is a hardware bug, and 666 * detect capacitance incorrectly. This is a hardware bug, and
241 * we don't have a good way to deal with it. The 2s window stuff 667 * we don't have a good way to deal with it. The 2s window stuff
242 * (below) is our best option for now. 668 * (below) is our best option for now.
@@ -247,25 +673,35 @@ static int hgpk_force_recalibrate(struct psmouse *psmouse)
247 673
248 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 674 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
249 675
250 /* After we recalibrate, we shouldn't get any packets for 2s. If 676 if (tpdebug)
251 * we do, it's likely that someone's finger was on the touchpad. 677 hgpk_dbg(psmouse, "touchpad reactivated\n");
252 * If someone's finger *was* on the touchpad, it's probably 678
253 * miscalibrated. So, we should schedule another recalibration 679 /*
680 * If we get packets right away after recalibrating, it's likely
681 * that a finger was on the touchpad. If so, it's probably
682 * miscalibrated, so we optionally schedule another.
254 */ 683 */
255 priv->recalib_window = jiffies + msecs_to_jiffies(recal_guard_time); 684 if (recal_guard_time)
685 priv->recalib_window = jiffies +
686 msecs_to_jiffies(recal_guard_time);
256 687
257 return 0; 688 return 0;
258} 689}
259 690
260/* 691/*
261 * This kills power to the touchpad; according to ALPS, current consumption 692 * This puts the touchpad in a power saving mode; according to ALPS, current
262 * goes down to 50uA after running this. To turn power back on, we drive 693 * consumption goes down to 50uA after running this. To turn power back on,
263 * MS-DAT low. 694 * we drive MS-DAT low. Measuring with a 1mA resolution ammeter says that
695 * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this.
696 *
697 * We have no formal spec that details this operation -- the low-power
698 * sequence came from a long-lost email trail.
264 */ 699 */
265static int hgpk_toggle_power(struct psmouse *psmouse, int enable) 700static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
266{ 701{
267 struct ps2dev *ps2dev = &psmouse->ps2dev; 702 struct ps2dev *ps2dev = &psmouse->ps2dev;
268 int timeo; 703 int timeo;
704 int err;
269 705
270 /* Added on D-series touchpads */ 706 /* Added on D-series touchpads */
271 if (psmouse->model < HGPK_MODEL_D) 707 if (psmouse->model < HGPK_MODEL_D)
@@ -279,24 +715,27 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
279 * the controller. Once we get an ACK back from it, it 715 * the controller. Once we get an ACK back from it, it
280 * means we can continue with the touchpad re-init. ALPS 716 * means we can continue with the touchpad re-init. ALPS
281 * tells us that 1s should be long enough, so set that as 717 * tells us that 1s should be long enough, so set that as
282 * the upper bound. 718 * the upper bound. (in practice, it takes about 3 loops.)
283 */ 719 */
284 for (timeo = 20; timeo > 0; timeo--) { 720 for (timeo = 20; timeo > 0; timeo--) {
285 if (!ps2_sendbyte(&psmouse->ps2dev, 721 if (!ps2_sendbyte(&psmouse->ps2dev,
286 PSMOUSE_CMD_DISABLE, 20)) 722 PSMOUSE_CMD_DISABLE, 20))
287 break; 723 break;
288 msleep(50); 724 msleep(25);
289 } 725 }
290 726
291 psmouse_reset(psmouse); 727 err = hgpk_reset_device(psmouse, false);
728 if (err) {
729 hgpk_err(psmouse, "Failed to reset device!\n");
730 return err;
731 }
292 732
293 /* should be all set, enable the touchpad */ 733 /* should be all set, enable the touchpad */
294 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE); 734 ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
295 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); 735 psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
296 736 hgpk_dbg(psmouse, "Touchpad powered up.\n");
297 } else { 737 } else {
298 hgpk_dbg(psmouse, "Powering off touchpad.\n"); 738 hgpk_dbg(psmouse, "Powering off touchpad.\n");
299 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
300 739
301 if (ps2_command(ps2dev, NULL, 0xec) || 740 if (ps2_command(ps2dev, NULL, 0xec) ||
302 ps2_command(ps2dev, NULL, 0xec) || 741 ps2_command(ps2dev, NULL, 0xec) ||
@@ -304,6 +743,8 @@ static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
304 return -1; 743 return -1;
305 } 744 }
306 745
746 psmouse_set_state(psmouse, PSMOUSE_IGNORE);
747
307 /* probably won't see an ACK, the touchpad will be off */ 748 /* probably won't see an ACK, the touchpad will be off */
308 ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); 749 ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
309 } 750 }
@@ -319,17 +760,20 @@ static int hgpk_poll(struct psmouse *psmouse)
319 760
320static int hgpk_reconnect(struct psmouse *psmouse) 761static int hgpk_reconnect(struct psmouse *psmouse)
321{ 762{
322 /* During suspend/resume the ps2 rails remain powered. We don't want 763 struct hgpk_data *priv = psmouse->private;
764
765 /*
766 * During suspend/resume the ps2 rails remain powered. We don't want
323 * to do a reset because it's flush data out of buffers; however, 767 * to do a reset because it's flush data out of buffers; however,
324 * earlier prototypes (B1) had some brokenness that required a reset. */ 768 * earlier prototypes (B1) had some brokenness that required a reset.
769 */
325 if (olpc_board_at_least(olpc_board(0xb2))) 770 if (olpc_board_at_least(olpc_board(0xb2)))
326 if (psmouse->ps2dev.serio->dev.power.power_state.event != 771 if (psmouse->ps2dev.serio->dev.power.power_state.event !=
327 PM_EVENT_ON) 772 PM_EVENT_ON)
328 return 0; 773 return 0;
329 774
330 psmouse_reset(psmouse); 775 priv->powered = 1;
331 776 return hgpk_reset_device(psmouse, false);
332 return 0;
333} 777}
334 778
335static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf) 779static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
@@ -355,7 +799,7 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
355 * hgpk_toggle_power will deal w/ state so 799 * hgpk_toggle_power will deal w/ state so
356 * we're not racing w/ irq 800 * we're not racing w/ irq
357 */ 801 */
358 err = hgpk_toggle_power(psmouse, value); 802 err = hgpk_toggle_powersave(psmouse, value);
359 if (!err) 803 if (!err)
360 priv->powered = value; 804 priv->powered = value;
361 } 805 }
@@ -366,6 +810,65 @@ static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
366__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL, 810__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
367 hgpk_show_powered, hgpk_set_powered, false); 811 hgpk_show_powered, hgpk_set_powered, false);
368 812
813static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)
814{
815 struct hgpk_data *priv = psmouse->private;
816
817 return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);
818}
819
820static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,
821 const char *buf, size_t len)
822{
823 struct hgpk_data *priv = psmouse->private;
824 enum hgpk_mode old_mode = priv->mode;
825 enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);
826 struct input_dev *old_dev = psmouse->dev;
827 struct input_dev *new_dev;
828 int err;
829
830 if (new_mode == HGPK_MODE_INVALID)
831 return -EINVAL;
832
833 if (old_mode == new_mode)
834 return len;
835
836 new_dev = input_allocate_device();
837 if (!new_dev)
838 return -ENOMEM;
839
840 psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
841
842 /* Switch device into the new mode */
843 priv->mode = new_mode;
844 err = hgpk_reset_device(psmouse, false);
845 if (err)
846 goto err_try_restore;
847
848 hgpk_setup_input_device(new_dev, old_dev, new_mode);
849
850 psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
851
852 err = input_register_device(new_dev);
853 if (err)
854 goto err_try_restore;
855
856 psmouse->dev = new_dev;
857 input_unregister_device(old_dev);
858
859 return len;
860
861err_try_restore:
862 input_free_device(new_dev);
863 priv->mode = old_mode;
864 hgpk_reset_device(psmouse, false);
865
866 return err;
867}
868
869PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,
870 attr_show_mode, attr_set_mode);
871
369static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse, 872static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
370 void *data, char *buf) 873 void *data, char *buf)
371{ 874{
@@ -401,6 +904,8 @@ static void hgpk_disconnect(struct psmouse *psmouse)
401 904
402 device_remove_file(&psmouse->ps2dev.serio->dev, 905 device_remove_file(&psmouse->ps2dev.serio->dev,
403 &psmouse_attr_powered.dattr); 906 &psmouse_attr_powered.dattr);
907 device_remove_file(&psmouse->ps2dev.serio->dev,
908 &psmouse_attr_hgpk_mode.dattr);
404 909
405 if (psmouse->model >= HGPK_MODEL_C) 910 if (psmouse->model >= HGPK_MODEL_C)
406 device_remove_file(&psmouse->ps2dev.serio->dev, 911 device_remove_file(&psmouse->ps2dev.serio->dev,
@@ -416,14 +921,13 @@ static void hgpk_recalib_work(struct work_struct *work)
416 struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq); 921 struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
417 struct psmouse *psmouse = priv->psmouse; 922 struct psmouse *psmouse = priv->psmouse;
418 923
419 hgpk_dbg(psmouse, "recalibrating touchpad..\n");
420
421 if (hgpk_force_recalibrate(psmouse)) 924 if (hgpk_force_recalibrate(psmouse))
422 hgpk_err(psmouse, "recalibration failed!\n"); 925 hgpk_err(psmouse, "recalibration failed!\n");
423} 926}
424 927
425static int hgpk_register(struct psmouse *psmouse) 928static int hgpk_register(struct psmouse *psmouse)
426{ 929{
930 struct hgpk_data *priv = psmouse->private;
427 int err; 931 int err;
428 932
429 /* register handlers */ 933 /* register handlers */
@@ -431,13 +935,14 @@ static int hgpk_register(struct psmouse *psmouse)
431 psmouse->poll = hgpk_poll; 935 psmouse->poll = hgpk_poll;
432 psmouse->disconnect = hgpk_disconnect; 936 psmouse->disconnect = hgpk_disconnect;
433 psmouse->reconnect = hgpk_reconnect; 937 psmouse->reconnect = hgpk_reconnect;
434 psmouse->pktsize = 3;
435 938
436 /* Disable the idle resync. */ 939 /* Disable the idle resync. */
437 psmouse->resync_time = 0; 940 psmouse->resync_time = 0;
438 /* Reset after a lot of bad bytes. */ 941 /* Reset after a lot of bad bytes. */
439 psmouse->resetafter = 1024; 942 psmouse->resetafter = 1024;
440 943
944 hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);
945
441 err = device_create_file(&psmouse->ps2dev.serio->dev, 946 err = device_create_file(&psmouse->ps2dev.serio->dev,
442 &psmouse_attr_powered.dattr); 947 &psmouse_attr_powered.dattr);
443 if (err) { 948 if (err) {
@@ -445,6 +950,13 @@ static int hgpk_register(struct psmouse *psmouse)
445 return err; 950 return err;
446 } 951 }
447 952
953 err = device_create_file(&psmouse->ps2dev.serio->dev,
954 &psmouse_attr_hgpk_mode.dattr);
955 if (err) {
956 hgpk_err(psmouse, "Failed creating 'hgpk_mode' sysfs node\n");
957 goto err_remove_powered;
958 }
959
448 /* C-series touchpads added the recalibrate command */ 960 /* C-series touchpads added the recalibrate command */
449 if (psmouse->model >= HGPK_MODEL_C) { 961 if (psmouse->model >= HGPK_MODEL_C) {
450 err = device_create_file(&psmouse->ps2dev.serio->dev, 962 err = device_create_file(&psmouse->ps2dev.serio->dev,
@@ -452,30 +964,40 @@ static int hgpk_register(struct psmouse *psmouse)
452 if (err) { 964 if (err) {
453 hgpk_err(psmouse, 965 hgpk_err(psmouse,
454 "Failed creating 'recalibrate' sysfs node\n"); 966 "Failed creating 'recalibrate' sysfs node\n");
455 device_remove_file(&psmouse->ps2dev.serio->dev, 967 goto err_remove_mode;
456 &psmouse_attr_powered.dattr);
457 return err;
458 } 968 }
459 } 969 }
460 970
461 return 0; 971 return 0;
972
973err_remove_mode:
974 device_remove_file(&psmouse->ps2dev.serio->dev,
975 &psmouse_attr_hgpk_mode.dattr);
976err_remove_powered:
977 device_remove_file(&psmouse->ps2dev.serio->dev,
978 &psmouse_attr_powered.dattr);
979 return err;
462} 980}
463 981
464int hgpk_init(struct psmouse *psmouse) 982int hgpk_init(struct psmouse *psmouse)
465{ 983{
466 struct hgpk_data *priv; 984 struct hgpk_data *priv;
467 int err = -ENOMEM; 985 int err;
468 986
469 priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL); 987 priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
470 if (!priv) 988 if (!priv) {
989 err = -ENOMEM;
471 goto alloc_fail; 990 goto alloc_fail;
991 }
472 992
473 psmouse->private = priv; 993 psmouse->private = priv;
994
474 priv->psmouse = psmouse; 995 priv->psmouse = psmouse;
475 priv->powered = true; 996 priv->powered = true;
997 priv->mode = hgpk_default_mode;
476 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work); 998 INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
477 999
478 err = psmouse_reset(psmouse); 1000 err = hgpk_reset_device(psmouse, false);
479 if (err) 1001 if (err)
480 goto init_fail; 1002 goto init_fail;
481 1003
@@ -531,3 +1053,14 @@ int hgpk_detect(struct psmouse *psmouse, bool set_properties)
531 1053
532 return 0; 1054 return 0;
533} 1055}
1056
1057void hgpk_module_init(void)
1058{
1059 hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,
1060 strlen(hgpk_mode_name));
1061 if (hgpk_default_mode == HGPK_MODE_INVALID) {
1062 hgpk_default_mode = HGPK_MODE_MOUSE;
1063 strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],
1064 sizeof(hgpk_mode_name));
1065 }
1066}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
index d61cfd3ee9cb..311c0e87fcbf 100644
--- a/drivers/input/mouse/hgpk.h
+++ b/drivers/input/mouse/hgpk.h
@@ -5,6 +5,9 @@
5#ifndef _HGPK_H 5#ifndef _HGPK_H
6#define _HGPK_H 6#define _HGPK_H
7 7
8#define HGPK_GS 0xff /* The GlideSensor */
9#define HGPK_PT 0xcf /* The PenTablet */
10
8enum hgpk_model_t { 11enum hgpk_model_t {
9 HGPK_MODEL_PREA = 0x0a, /* pre-B1s */ 12 HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
10 HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */ 13 HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
@@ -13,12 +16,34 @@ enum hgpk_model_t {
13 HGPK_MODEL_D = 0x50, /* C1, mass production */ 16 HGPK_MODEL_D = 0x50, /* C1, mass production */
14}; 17};
15 18
19enum hgpk_spew_flag {
20 NO_SPEW,
21 MAYBE_SPEWING,
22 SPEW_DETECTED,
23 RECALIBRATING,
24};
25
26#define SPEW_WATCH_COUNT 42 /* at 12ms/packet, this is 1/2 second */
27
28enum hgpk_mode {
29 HGPK_MODE_MOUSE,
30 HGPK_MODE_GLIDESENSOR,
31 HGPK_MODE_PENTABLET,
32 HGPK_MODE_INVALID
33};
34
16struct hgpk_data { 35struct hgpk_data {
17 struct psmouse *psmouse; 36 struct psmouse *psmouse;
37 enum hgpk_mode mode;
18 bool powered; 38 bool powered;
19 int count, x_tally, y_tally; /* hardware workaround stuff */ 39 enum hgpk_spew_flag spew_flag;
40 int spew_count, x_tally, y_tally; /* spew detection */
20 unsigned long recalib_window; 41 unsigned long recalib_window;
21 struct delayed_work recalib_wq; 42 struct delayed_work recalib_wq;
43 int abs_x, abs_y;
44 int dupe_count;
45 int xbigj, ybigj, xlast, ylast; /* jumpiness detection */
46 int xsaw_secondary, ysaw_secondary; /* jumpiness detection */
22}; 47};
23 48
24#define hgpk_dbg(psmouse, format, arg...) \ 49#define hgpk_dbg(psmouse, format, arg...) \
@@ -33,9 +58,13 @@ struct hgpk_data {
33 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg) 58 dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
34 59
35#ifdef CONFIG_MOUSE_PS2_OLPC 60#ifdef CONFIG_MOUSE_PS2_OLPC
61void hgpk_module_init(void);
36int hgpk_detect(struct psmouse *psmouse, bool set_properties); 62int hgpk_detect(struct psmouse *psmouse, bool set_properties);
37int hgpk_init(struct psmouse *psmouse); 63int hgpk_init(struct psmouse *psmouse);
38#else 64#else
65static inline void hgpk_module_init(void)
66{
67}
39static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties) 68static inline int hgpk_detect(struct psmouse *psmouse, bool set_properties)
40{ 69{
41 return -ENODEV; 70 return -ENODEV;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index cd9d0c97e429..3f74baee102b 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -1711,6 +1711,7 @@ static int __init psmouse_init(void)
1711 1711
1712 lifebook_module_init(); 1712 lifebook_module_init();
1713 synaptics_module_init(); 1713 synaptics_module_init();
1714 hgpk_module_init();
1714 1715
1715 kpsmoused_wq = create_singlethread_workqueue("kpsmoused"); 1716 kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
1716 if (!kpsmoused_wq) { 1717 if (!kpsmoused_wq) {
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 2e300a460556..da392c22fc6c 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -25,7 +25,7 @@
25 25
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/dmi.h> 27#include <linux/dmi.h>
28#include <linux/input.h> 28#include <linux/input/mt.h>
29#include <linux/serio.h> 29#include <linux/serio.h>
30#include <linux/libps2.h> 30#include <linux/libps2.h>
31#include <linux/slab.h> 31#include <linux/slab.h>
@@ -279,6 +279,25 @@ static void synaptics_set_rate(struct psmouse *psmouse, unsigned int rate)
279 synaptics_mode_cmd(psmouse, priv->mode); 279 synaptics_mode_cmd(psmouse, priv->mode);
280} 280}
281 281
282static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse)
283{
284 static unsigned char param = 0xc8;
285 struct synaptics_data *priv = psmouse->private;
286
287 if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
288 return 0;
289
290 if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL))
291 return -1;
292 if (ps2_command(&psmouse->ps2dev, &param, PSMOUSE_CMD_SETRATE))
293 return -1;
294
295 /* Advanced gesture mode also sends multi finger data */
296 priv->capabilities |= BIT(1);
297
298 return 0;
299}
300
282/***************************************************************************** 301/*****************************************************************************
283 * Synaptics pass-through PS/2 port support 302 * Synaptics pass-through PS/2 port support
284 ****************************************************************************/ 303 ****************************************************************************/
@@ -380,7 +399,9 @@ static void synaptics_pt_create(struct psmouse *psmouse)
380 * Functions to interpret the absolute mode packets 399 * Functions to interpret the absolute mode packets
381 ****************************************************************************/ 400 ****************************************************************************/
382 401
383static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data *priv, struct synaptics_hw_state *hw) 402static int synaptics_parse_hw_state(const unsigned char buf[],
403 struct synaptics_data *priv,
404 struct synaptics_hw_state *hw)
384{ 405{
385 memset(hw, 0, sizeof(struct synaptics_hw_state)); 406 memset(hw, 0, sizeof(struct synaptics_hw_state));
386 407
@@ -397,6 +418,14 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
397 ((buf[0] & 0x04) >> 1) | 418 ((buf[0] & 0x04) >> 1) |
398 ((buf[3] & 0x04) >> 2)); 419 ((buf[3] & 0x04) >> 2));
399 420
421 if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) && hw->w == 2) {
422 /* Gesture packet: (x, y, z) at half resolution */
423 priv->mt.x = (((buf[4] & 0x0f) << 8) | buf[1]) << 1;
424 priv->mt.y = (((buf[4] & 0xf0) << 4) | buf[2]) << 1;
425 priv->mt.z = ((buf[3] & 0x30) | (buf[5] & 0x0f)) << 1;
426 return 1;
427 }
428
400 hw->left = (buf[0] & 0x01) ? 1 : 0; 429 hw->left = (buf[0] & 0x01) ? 1 : 0;
401 hw->right = (buf[0] & 0x02) ? 1 : 0; 430 hw->right = (buf[0] & 0x02) ? 1 : 0;
402 431
@@ -452,6 +481,36 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
452 hw->left = (buf[0] & 0x01) ? 1 : 0; 481 hw->left = (buf[0] & 0x01) ? 1 : 0;
453 hw->right = (buf[0] & 0x02) ? 1 : 0; 482 hw->right = (buf[0] & 0x02) ? 1 : 0;
454 } 483 }
484
485 return 0;
486}
487
488static void set_slot(struct input_dev *dev, int slot, bool active, int x, int y)
489{
490 input_mt_slot(dev, slot);
491 input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
492 if (active) {
493 input_report_abs(dev, ABS_MT_POSITION_X, x);
494 input_report_abs(dev, ABS_MT_POSITION_Y,
495 YMAX_NOMINAL + YMIN_NOMINAL - y);
496 }
497}
498
499static void synaptics_report_semi_mt_data(struct input_dev *dev,
500 const struct synaptics_hw_state *a,
501 const struct synaptics_hw_state *b,
502 int num_fingers)
503{
504 if (num_fingers >= 2) {
505 set_slot(dev, 0, true, min(a->x, b->x), min(a->y, b->y));
506 set_slot(dev, 1, true, max(a->x, b->x), max(a->y, b->y));
507 } else if (num_fingers == 1) {
508 set_slot(dev, 0, true, a->x, a->y);
509 set_slot(dev, 1, false, 0, 0);
510 } else {
511 set_slot(dev, 0, false, 0, 0);
512 set_slot(dev, 1, false, 0, 0);
513 }
455} 514}
456 515
457/* 516/*
@@ -466,7 +525,8 @@ static void synaptics_process_packet(struct psmouse *psmouse)
466 int finger_width; 525 int finger_width;
467 int i; 526 int i;
468 527
469 synaptics_parse_hw_state(psmouse->packet, priv, &hw); 528 if (synaptics_parse_hw_state(psmouse->packet, priv, &hw))
529 return;
470 530
471 if (hw.scroll) { 531 if (hw.scroll) {
472 priv->scroll += hw.scroll; 532 priv->scroll += hw.scroll;
@@ -488,7 +548,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
488 return; 548 return;
489 } 549 }
490 550
491 if (hw.z > 0) { 551 if (hw.z > 0 && hw.x > 1) {
492 num_fingers = 1; 552 num_fingers = 1;
493 finger_width = 5; 553 finger_width = 5;
494 if (SYN_CAP_EXTENDED(priv->capabilities)) { 554 if (SYN_CAP_EXTENDED(priv->capabilities)) {
@@ -512,6 +572,9 @@ static void synaptics_process_packet(struct psmouse *psmouse)
512 finger_width = 0; 572 finger_width = 0;
513 } 573 }
514 574
575 if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c))
576 synaptics_report_semi_mt_data(dev, &hw, &priv->mt, num_fingers);
577
515 /* Post events 578 /* Post events
516 * BTN_TOUCH has to be first as mousedev relies on it when doing 579 * BTN_TOUCH has to be first as mousedev relies on it when doing
517 * absolute -> relative conversion 580 * absolute -> relative conversion
@@ -519,7 +582,7 @@ static void synaptics_process_packet(struct psmouse *psmouse)
519 if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1); 582 if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
520 if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0); 583 if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
521 584
522 if (hw.z > 0) { 585 if (num_fingers > 0) {
523 input_report_abs(dev, ABS_X, hw.x); 586 input_report_abs(dev, ABS_X, hw.x);
524 input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); 587 input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
525 } 588 }
@@ -622,6 +685,8 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
622{ 685{
623 int i; 686 int i;
624 687
688 __set_bit(INPUT_PROP_POINTER, dev->propbit);
689
625 __set_bit(EV_ABS, dev->evbit); 690 __set_bit(EV_ABS, dev->evbit);
626 input_set_abs_params(dev, ABS_X, 691 input_set_abs_params(dev, ABS_X,
627 XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0); 692 XMIN_NOMINAL, priv->x_max ?: XMAX_NOMINAL, 0, 0);
@@ -629,6 +694,15 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
629 YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0); 694 YMIN_NOMINAL, priv->y_max ?: YMAX_NOMINAL, 0, 0);
630 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); 695 input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
631 696
697 if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
698 __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
699 input_mt_init_slots(dev, 2);
700 input_set_abs_params(dev, ABS_MT_POSITION_X, XMIN_NOMINAL,
701 priv->x_max ?: XMAX_NOMINAL, 0, 0);
702 input_set_abs_params(dev, ABS_MT_POSITION_Y, YMIN_NOMINAL,
703 priv->y_max ?: YMAX_NOMINAL, 0, 0);
704 }
705
632 if (SYN_CAP_PALMDETECT(priv->capabilities)) 706 if (SYN_CAP_PALMDETECT(priv->capabilities))
633 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); 707 input_set_abs_params(dev, ABS_TOOL_WIDTH, 0, 15, 0, 0);
634 708
@@ -663,6 +737,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv)
663 input_abs_set_res(dev, ABS_Y, priv->y_res); 737 input_abs_set_res(dev, ABS_Y, priv->y_res);
664 738
665 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { 739 if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
740 __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit);
666 /* Clickpads report only left button */ 741 /* Clickpads report only left button */
667 __clear_bit(BTN_RIGHT, dev->keybit); 742 __clear_bit(BTN_RIGHT, dev->keybit);
668 __clear_bit(BTN_MIDDLE, dev->keybit); 743 __clear_bit(BTN_MIDDLE, dev->keybit);
@@ -702,6 +777,11 @@ static int synaptics_reconnect(struct psmouse *psmouse)
702 return -1; 777 return -1;
703 } 778 }
704 779
780 if (synaptics_set_advanced_gesture_mode(psmouse)) {
781 printk(KERN_ERR "Advanced gesture mode reconnect failed.\n");
782 return -1;
783 }
784
705 return 0; 785 return 0;
706} 786}
707 787
@@ -744,15 +824,45 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = {
744#endif 824#endif
745}; 825};
746 826
827static bool broken_olpc_ec;
828
829static const struct dmi_system_id __initconst olpc_dmi_table[] = {
830#if defined(CONFIG_DMI) && defined(CONFIG_OLPC)
831 {
832 /* OLPC XO-1 or XO-1.5 */
833 .matches = {
834 DMI_MATCH(DMI_SYS_VENDOR, "OLPC"),
835 DMI_MATCH(DMI_PRODUCT_NAME, "XO"),
836 },
837 },
838 { }
839#endif
840};
841
747void __init synaptics_module_init(void) 842void __init synaptics_module_init(void)
748{ 843{
749 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); 844 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
845 broken_olpc_ec = dmi_check_system(olpc_dmi_table);
750} 846}
751 847
752int synaptics_init(struct psmouse *psmouse) 848int synaptics_init(struct psmouse *psmouse)
753{ 849{
754 struct synaptics_data *priv; 850 struct synaptics_data *priv;
755 851
852 /*
853 * The OLPC XO has issues with Synaptics' absolute mode; similarly to
854 * the HGPK, it quickly degrades and the hardware becomes jumpy and
855 * overly sensitive. Not only that, but the constant packet spew
856 * (even at a lowered 40pps rate) overloads the EC such that key
857 * presses on the keyboard are missed. Given all of that, don't
858 * even attempt to use Synaptics mode. Relative mode seems to work
859 * just fine.
860 */
861 if (broken_olpc_ec) {
862 printk(KERN_INFO "synaptics: OLPC XO detected, not enabling Synaptics protocol.\n");
863 return -ENODEV;
864 }
865
756 psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL); 866 psmouse->private = priv = kzalloc(sizeof(struct synaptics_data), GFP_KERNEL);
757 if (!priv) 867 if (!priv)
758 return -ENOMEM; 868 return -ENOMEM;
@@ -769,6 +879,11 @@ int synaptics_init(struct psmouse *psmouse)
769 goto init_fail; 879 goto init_fail;
770 } 880 }
771 881
882 if (synaptics_set_advanced_gesture_mode(psmouse)) {
883 printk(KERN_ERR "Advanced gesture mode init failed.\n");
884 goto init_fail;
885 }
886
772 priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; 887 priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS;
773 888
774 printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", 889 printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n",
@@ -802,8 +917,8 @@ int synaptics_init(struct psmouse *psmouse)
802 917
803 /* 918 /*
804 * Toshiba's KBC seems to have trouble handling data from 919 * Toshiba's KBC seems to have trouble handling data from
805 * Synaptics as full rate, switch to lower rate which is roughly 920 * Synaptics at full rate. Switch to a lower rate (roughly
806 * thye same as rate of standard PS/2 mouse. 921 * the same rate as a standard PS/2 mouse).
807 */ 922 */
808 if (psmouse->rate >= 80 && impaired_toshiba_kbc) { 923 if (psmouse->rate >= 80 && impaired_toshiba_kbc) {
809 printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n", 924 printk(KERN_INFO "synaptics: Toshiba %s detected, limiting rate to 40pps.\n",
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h
index 0aefaa885871..25e5d042a72c 100644
--- a/drivers/input/mouse/synaptics.h
+++ b/drivers/input/mouse/synaptics.h
@@ -54,6 +54,7 @@
54#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ 54#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */
55#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ 55#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */
56#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) 56#define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000)
57#define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000)
57 58
58/* synaptics modes query bits */ 59/* synaptics modes query bits */
59#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) 60#define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7))
@@ -113,6 +114,8 @@ struct synaptics_data {
113 int scroll; 114 int scroll;
114 115
115 struct serio *pt_port; /* Pass-through serio port */ 116 struct serio *pt_port; /* Pass-through serio port */
117
118 struct synaptics_hw_state mt; /* current gesture packet */
116}; 119};
117 120
118void synaptics_module_init(void); 121void synaptics_module_init(void);