aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/hgpk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/hgpk.c')
-rw-r--r--drivers/input/mouse/hgpk.c695
1 files changed, 614 insertions, 81 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}