[go: nahoru, domu]

1/*
2 * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
3 *
4 * Copyright (c) 2006-2008 One Laptop Per Child
5 * Authors:
6 *   Zephaniah E. Hull
7 *   Andres Salomon <dilinger@debian.org>
8 *
9 * This driver is partly based on the ALPS driver, which is:
10 *
11 * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
12 * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
13 * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
14 * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21/*
22 * The spec from ALPS is available from
23 * <http://wiki.laptop.org/go/Touch_Pad/Tablet>.  It refers to this
24 * device as HGPK (Hybrid GS, PT, and Keymatrix).
25 *
26 * The earliest versions of the device had simultaneous reporting; that
27 * was removed.  After that, the device used the Advanced Mode GS/PT streaming
28 * stuff.  That turned out to be too buggy to support, so we've finally
29 * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).
30 */
31
32#define DEBUG
33#include <linux/slab.h>
34#include <linux/input.h>
35#include <linux/module.h>
36#include <linux/serio.h>
37#include <linux/libps2.h>
38#include <linux/delay.h>
39#include <asm/olpc.h>
40
41#include "psmouse.h"
42#include "hgpk.h"
43
44#define ILLEGAL_XY 999999
45
46static bool tpdebug;
47module_param(tpdebug, bool, 0644);
48MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
49
50static int recalib_delta = 100;
51module_param(recalib_delta, int, 0644);
52MODULE_PARM_DESC(recalib_delta,
53	"packets containing a delta this large will be discarded, and a "
54	"recalibration may be scheduled.");
55
56static int jumpy_delay = 20;
57module_param(jumpy_delay, int, 0644);
58MODULE_PARM_DESC(jumpy_delay,
59	"delay (ms) before recal after jumpiness detected");
60
61static int spew_delay = 1;
62module_param(spew_delay, int, 0644);
63MODULE_PARM_DESC(spew_delay,
64	"delay (ms) before recal after packet spew detected");
65
66static int recal_guard_time;
67module_param(recal_guard_time, int, 0644);
68MODULE_PARM_DESC(recal_guard_time,
69	"interval (ms) during which recal will be restarted if packet received");
70
71static int post_interrupt_delay = 40;
72module_param(post_interrupt_delay, int, 0644);
73MODULE_PARM_DESC(post_interrupt_delay,
74	"delay (ms) before recal after recal interrupt detected");
75
76static bool autorecal = true;
77module_param(autorecal, bool, 0644);
78MODULE_PARM_DESC(autorecal, "enable recalibration in the driver");
79
80static char hgpk_mode_name[16];
81module_param_string(hgpk_mode, hgpk_mode_name, sizeof(hgpk_mode_name), 0644);
82MODULE_PARM_DESC(hgpk_mode,
83	"default hgpk mode: mouse, glidesensor or pentablet");
84
85static int hgpk_default_mode = HGPK_MODE_MOUSE;
86
87static const char * const hgpk_mode_names[] = {
88	[HGPK_MODE_MOUSE] = "Mouse",
89	[HGPK_MODE_GLIDESENSOR] = "GlideSensor",
90	[HGPK_MODE_PENTABLET] = "PenTablet",
91};
92
93static int hgpk_mode_from_name(const char *buf, int len)
94{
95	int i;
96
97	for (i = 0; i < ARRAY_SIZE(hgpk_mode_names); i++) {
98		const char *name = hgpk_mode_names[i];
99		if (strlen(name) == len && !strncasecmp(name, buf, len))
100			return i;
101	}
102
103	return HGPK_MODE_INVALID;
104}
105
106/*
107 * see if new value is within 20% of half of old value
108 */
109static int approx_half(int curr, int prev)
110{
111	int belowhalf, abovehalf;
112
113	if (curr < 5 || prev < 5)
114		return 0;
115
116	belowhalf = (prev * 8) / 20;
117	abovehalf = (prev * 12) / 20;
118
119	return belowhalf < curr && curr <= abovehalf;
120}
121
122/*
123 * Throw out oddly large delta packets, and any that immediately follow whose
124 * values are each approximately half of the previous.  It seems that the ALPS
125 * firmware emits errant packets, and they get averaged out slowly.
126 */
127static int hgpk_discard_decay_hack(struct psmouse *psmouse, int x, int y)
128{
129	struct hgpk_data *priv = psmouse->private;
130	int avx, avy;
131	bool do_recal = false;
132
133	avx = abs(x);
134	avy = abs(y);
135
136	/* discard if too big, or half that but > 4 times the prev delta */
137	if (avx > recalib_delta ||
138		(avx > recalib_delta / 2 && ((avx / 4) > priv->xlast))) {
139		psmouse_warn(psmouse, "detected %dpx jump in x\n", x);
140		priv->xbigj = avx;
141	} else if (approx_half(avx, priv->xbigj)) {
142		psmouse_warn(psmouse, "detected secondary %dpx jump in x\n", x);
143		priv->xbigj = avx;
144		priv->xsaw_secondary++;
145	} else {
146		if (priv->xbigj && priv->xsaw_secondary > 1)
147			do_recal = true;
148		priv->xbigj = 0;
149		priv->xsaw_secondary = 0;
150	}
151
152	if (avy > recalib_delta ||
153		(avy > recalib_delta / 2 && ((avy / 4) > priv->ylast))) {
154		psmouse_warn(psmouse, "detected %dpx jump in y\n", y);
155		priv->ybigj = avy;
156	} else if (approx_half(avy, priv->ybigj)) {
157		psmouse_warn(psmouse, "detected secondary %dpx jump in y\n", y);
158		priv->ybigj = avy;
159		priv->ysaw_secondary++;
160	} else {
161		if (priv->ybigj && priv->ysaw_secondary > 1)
162			do_recal = true;
163		priv->ybigj = 0;
164		priv->ysaw_secondary = 0;
165	}
166
167	priv->xlast = avx;
168	priv->ylast = avy;
169
170	if (do_recal && jumpy_delay) {
171		psmouse_warn(psmouse, "scheduling recalibration\n");
172		psmouse_queue_work(psmouse, &priv->recalib_wq,
173				msecs_to_jiffies(jumpy_delay));
174	}
175
176	return priv->xbigj || priv->ybigj;
177}
178
179static void hgpk_reset_spew_detection(struct hgpk_data *priv)
180{
181	priv->spew_count = 0;
182	priv->dupe_count = 0;
183	priv->x_tally = 0;
184	priv->y_tally = 0;
185	priv->spew_flag = NO_SPEW;
186}
187
188static void hgpk_reset_hack_state(struct psmouse *psmouse)
189{
190	struct hgpk_data *priv = psmouse->private;
191
192	priv->abs_x = priv->abs_y = -1;
193	priv->xlast = priv->ylast = ILLEGAL_XY;
194	priv->xbigj = priv->ybigj = 0;
195	priv->xsaw_secondary = priv->ysaw_secondary = 0;
196	hgpk_reset_spew_detection(priv);
197}
198
199/*
200 * We have no idea why this particular hardware bug occurs.  The touchpad
201 * will randomly start spewing packets without anything touching the
202 * pad.  This wouldn't necessarily be bad, but it's indicative of a
203 * severely miscalibrated pad; attempting to use the touchpad while it's
204 * spewing means the cursor will jump all over the place, and act "drunk".
205 *
206 * The packets that are spewed tend to all have deltas between -2 and 2, and
207 * the cursor will move around without really going very far.  It will
208 * tend to end up in the same location; if we tally up the changes over
209 * 100 packets, we end up w/ a final delta of close to 0.  This happens
210 * pretty regularly when the touchpad is spewing, and is pretty hard to
211 * manually trigger (at least for *my* fingers).  So, it makes a perfect
212 * scheme for detecting spews.
213 */
214static void hgpk_spewing_hack(struct psmouse *psmouse,
215			      int l, int r, int x, int y)
216{
217	struct hgpk_data *priv = psmouse->private;
218
219	/* ignore button press packets; many in a row could trigger
220	 * a false-positive! */
221	if (l || r)
222		return;
223
224	/* don't track spew if the workaround feature has been turned off */
225	if (!spew_delay)
226		return;
227
228	if (abs(x) > 3 || abs(y) > 3) {
229		/* no spew, or spew ended */
230		hgpk_reset_spew_detection(priv);
231		return;
232	}
233
234	/* Keep a tally of the overall delta to the cursor position caused by
235	 * the spew */
236	priv->x_tally += x;
237	priv->y_tally += y;
238
239	switch (priv->spew_flag) {
240	case NO_SPEW:
241		/* we're not spewing, but this packet might be the start */
242		priv->spew_flag = MAYBE_SPEWING;
243
244		/* fall-through */
245
246	case MAYBE_SPEWING:
247		priv->spew_count++;
248
249		if (priv->spew_count < SPEW_WATCH_COUNT)
250			break;
251
252		/* excessive spew detected, request recalibration */
253		priv->spew_flag = SPEW_DETECTED;
254
255		/* fall-through */
256
257	case SPEW_DETECTED:
258		/* only recalibrate when the overall delta to the cursor
259		 * is really small. if the spew is causing significant cursor
260		 * movement, it is probably a case of the user moving the
261		 * cursor very slowly across the screen. */
262		if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
263			psmouse_warn(psmouse, "packet spew detected (%d,%d)\n",
264				     priv->x_tally, priv->y_tally);
265			priv->spew_flag = RECALIBRATING;
266			psmouse_queue_work(psmouse, &priv->recalib_wq,
267					   msecs_to_jiffies(spew_delay));
268		}
269
270		break;
271	case RECALIBRATING:
272		/* we already detected a spew and requested a recalibration,
273		 * just wait for the queue to kick into action. */
274		break;
275	}
276}
277
278/*
279 * HGPK Mouse Mode format (standard mouse format, sans middle button)
280 *
281 * byte 0:	y-over	x-over	y-neg	x-neg	1	0	swr	swl
282 * byte 1:	x7	x6	x5	x4	x3	x2	x1	x0
283 * byte 2:	y7	y6	y5	y4	y3	y2	y1	y0
284 *
285 * swr/swl are the left/right buttons.
286 * x-neg/y-neg are the x and y delta negative bits
287 * x-over/y-over are the x and y overflow bits
288 *
289 * ---
290 *
291 * HGPK Advanced Mode - single-mode format
292 *
293 * byte 0(PT):  1    1    0    0    1    1     1     1
294 * byte 0(GS):  1    1    1    1    1    1     1     1
295 * byte 1:      0   x6   x5   x4   x3   x2    x1    x0
296 * byte 2(PT):  0    0   x9   x8   x7    ? pt-dsw    0
297 * byte 2(GS):  0  x10   x9   x8   x7    ? gs-dsw pt-dsw
298 * byte 3:      0   y9   y8   y7    1    0   swr   swl
299 * byte 4:      0   y6   y5   y4   y3   y2    y1    y0
300 * byte 5:      0   z6   z5   z4   z3   z2    z1    z0
301 *
302 * ?'s are not defined in the protocol spec, may vary between models.
303 *
304 * swr/swl are the left/right buttons.
305 *
306 * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
307 * pen/finger
308 */
309static bool hgpk_is_byte_valid(struct psmouse *psmouse, unsigned char *packet)
310{
311	struct hgpk_data *priv = psmouse->private;
312	int pktcnt = psmouse->pktcnt;
313	bool valid;
314
315	switch (priv->mode) {
316	case HGPK_MODE_MOUSE:
317		valid = (packet[0] & 0x0C) == 0x08;
318		break;
319
320	case HGPK_MODE_GLIDESENSOR:
321		valid = pktcnt == 1 ?
322			packet[0] == HGPK_GS : !(packet[pktcnt - 1] & 0x80);
323		break;
324
325	case HGPK_MODE_PENTABLET:
326		valid = pktcnt == 1 ?
327			packet[0] == HGPK_PT : !(packet[pktcnt - 1] & 0x80);
328		break;
329
330	default:
331		valid = false;
332		break;
333	}
334
335	if (!valid)
336		psmouse_dbg(psmouse,
337			    "bad data, mode %d (%d) %*ph\n",
338			    priv->mode, pktcnt, 6, psmouse->packet);
339
340	return valid;
341}
342
343static void hgpk_process_advanced_packet(struct psmouse *psmouse)
344{
345	struct hgpk_data *priv = psmouse->private;
346	struct input_dev *idev = psmouse->dev;
347	unsigned char *packet = psmouse->packet;
348	int down = !!(packet[2] & 2);
349	int left = !!(packet[3] & 1);
350	int right = !!(packet[3] & 2);
351	int x = packet[1] | ((packet[2] & 0x78) << 4);
352	int y = packet[4] | ((packet[3] & 0x70) << 3);
353
354	if (priv->mode == HGPK_MODE_GLIDESENSOR) {
355		int pt_down = !!(packet[2] & 1);
356		int finger_down = !!(packet[2] & 2);
357		int z = packet[5];
358
359		input_report_abs(idev, ABS_PRESSURE, z);
360		if (tpdebug)
361			psmouse_dbg(psmouse, "pd=%d fd=%d z=%d",
362				    pt_down, finger_down, z);
363	} else {
364		/*
365		 * PenTablet mode does not report pressure, so we don't
366		 * report it here
367		 */
368		if (tpdebug)
369			psmouse_dbg(psmouse, "pd=%d ", down);
370	}
371
372	if (tpdebug)
373		psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
374			    left, right, x, y);
375
376	input_report_key(idev, BTN_TOUCH, down);
377	input_report_key(idev, BTN_LEFT, left);
378	input_report_key(idev, BTN_RIGHT, right);
379
380	/*
381	 * If this packet says that the finger was removed, reset our position
382	 * tracking so that we don't erroneously detect a jump on next press.
383	 */
384	if (!down) {
385		hgpk_reset_hack_state(psmouse);
386		goto done;
387	}
388
389	/*
390	 * Weed out duplicate packets (we get quite a few, and they mess up
391	 * our jump detection)
392	 */
393	if (x == priv->abs_x && y == priv->abs_y) {
394		if (++priv->dupe_count > SPEW_WATCH_COUNT) {
395			if (tpdebug)
396				psmouse_dbg(psmouse, "hard spew detected\n");
397			priv->spew_flag = RECALIBRATING;
398			psmouse_queue_work(psmouse, &priv->recalib_wq,
399					   msecs_to_jiffies(spew_delay));
400		}
401		goto done;
402	}
403
404	/* not a duplicate, continue with position reporting */
405	priv->dupe_count = 0;
406
407	/* Don't apply hacks in PT mode, it seems reliable */
408	if (priv->mode != HGPK_MODE_PENTABLET && priv->abs_x != -1) {
409		int x_diff = priv->abs_x - x;
410		int y_diff = priv->abs_y - y;
411		if (hgpk_discard_decay_hack(psmouse, x_diff, y_diff)) {
412			if (tpdebug)
413				psmouse_dbg(psmouse, "discarding\n");
414			goto done;
415		}
416		hgpk_spewing_hack(psmouse, left, right, x_diff, y_diff);
417	}
418
419	input_report_abs(idev, ABS_X, x);
420	input_report_abs(idev, ABS_Y, y);
421	priv->abs_x = x;
422	priv->abs_y = y;
423
424done:
425	input_sync(idev);
426}
427
428static void hgpk_process_simple_packet(struct psmouse *psmouse)
429{
430	struct input_dev *dev = psmouse->dev;
431	unsigned char *packet = psmouse->packet;
432	int left = packet[0] & 1;
433	int right = (packet[0] >> 1) & 1;
434	int x = packet[1] - ((packet[0] << 4) & 0x100);
435	int y = ((packet[0] << 3) & 0x100) - packet[2];
436
437	if (packet[0] & 0xc0)
438		psmouse_dbg(psmouse,
439			    "overflow -- 0x%02x 0x%02x 0x%02x\n",
440			    packet[0], packet[1], packet[2]);
441
442	if (hgpk_discard_decay_hack(psmouse, x, y)) {
443		if (tpdebug)
444			psmouse_dbg(psmouse, "discarding\n");
445		return;
446	}
447
448	hgpk_spewing_hack(psmouse, left, right, x, y);
449
450	if (tpdebug)
451		psmouse_dbg(psmouse, "l=%d r=%d x=%d y=%d\n",
452			    left, right, x, y);
453
454	input_report_key(dev, BTN_LEFT, left);
455	input_report_key(dev, BTN_RIGHT, right);
456
457	input_report_rel(dev, REL_X, x);
458	input_report_rel(dev, REL_Y, y);
459
460	input_sync(dev);
461}
462
463static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
464{
465	struct hgpk_data *priv = psmouse->private;
466
467	if (!hgpk_is_byte_valid(psmouse, psmouse->packet))
468		return PSMOUSE_BAD_DATA;
469
470	if (psmouse->pktcnt >= psmouse->pktsize) {
471		if (priv->mode == HGPK_MODE_MOUSE)
472			hgpk_process_simple_packet(psmouse);
473		else
474			hgpk_process_advanced_packet(psmouse);
475		return PSMOUSE_FULL_PACKET;
476	}
477
478	if (priv->recalib_window) {
479		if (time_before(jiffies, priv->recalib_window)) {
480			/*
481			 * ugh, got a packet inside our recalibration
482			 * window, schedule another recalibration.
483			 */
484			psmouse_dbg(psmouse,
485				    "packet inside calibration window, queueing another recalibration\n");
486			psmouse_queue_work(psmouse, &priv->recalib_wq,
487					msecs_to_jiffies(post_interrupt_delay));
488		}
489		priv->recalib_window = 0;
490	}
491
492	return PSMOUSE_GOOD_DATA;
493}
494
495static int hgpk_select_mode(struct psmouse *psmouse)
496{
497	struct ps2dev *ps2dev = &psmouse->ps2dev;
498	struct hgpk_data *priv = psmouse->private;
499	int i;
500	int cmd;
501
502	/*
503	 * 4 disables to enable advanced mode
504	 * then 3 0xf2 bytes as the preamble for GS/PT selection
505	 */
506	const int advanced_init[] = {
507		PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
508		PSMOUSE_CMD_DISABLE, PSMOUSE_CMD_DISABLE,
509		0xf2, 0xf2, 0xf2,
510	};
511
512	switch (priv->mode) {
513	case HGPK_MODE_MOUSE:
514		psmouse->pktsize = 3;
515		break;
516
517	case HGPK_MODE_GLIDESENSOR:
518	case HGPK_MODE_PENTABLET:
519		psmouse->pktsize = 6;
520
521		/* Switch to 'Advanced mode.', four disables in a row. */
522		for (i = 0; i < ARRAY_SIZE(advanced_init); i++)
523			if (ps2_command(ps2dev, NULL, advanced_init[i]))
524				return -EIO;
525
526		/* select between GlideSensor (mouse) or PenTablet */
527		cmd = priv->mode == HGPK_MODE_GLIDESENSOR ?
528			PSMOUSE_CMD_SETSCALE11 : PSMOUSE_CMD_SETSCALE21;
529
530		if (ps2_command(ps2dev, NULL, cmd))
531			return -EIO;
532		break;
533
534	default:
535		return -EINVAL;
536	}
537
538	return 0;
539}
540
541static void hgpk_setup_input_device(struct input_dev *input,
542				    struct input_dev *old_input,
543				    enum hgpk_mode mode)
544{
545	if (old_input) {
546		input->name = old_input->name;
547		input->phys = old_input->phys;
548		input->id = old_input->id;
549		input->dev.parent = old_input->dev.parent;
550	}
551
552	memset(input->evbit, 0, sizeof(input->evbit));
553	memset(input->relbit, 0, sizeof(input->relbit));
554	memset(input->keybit, 0, sizeof(input->keybit));
555
556	/* All modes report left and right buttons */
557	__set_bit(EV_KEY, input->evbit);
558	__set_bit(BTN_LEFT, input->keybit);
559	__set_bit(BTN_RIGHT, input->keybit);
560
561	switch (mode) {
562	case HGPK_MODE_MOUSE:
563		__set_bit(EV_REL, input->evbit);
564		__set_bit(REL_X, input->relbit);
565		__set_bit(REL_Y, input->relbit);
566		break;
567
568	case HGPK_MODE_GLIDESENSOR:
569		__set_bit(BTN_TOUCH, input->keybit);
570		__set_bit(BTN_TOOL_FINGER, input->keybit);
571
572		__set_bit(EV_ABS, input->evbit);
573
574		/* GlideSensor has pressure sensor, PenTablet does not */
575		input_set_abs_params(input, ABS_PRESSURE, 0, 15, 0, 0);
576
577		/* From device specs */
578		input_set_abs_params(input, ABS_X, 0, 399, 0, 0);
579		input_set_abs_params(input, ABS_Y, 0, 290, 0, 0);
580
581		/* Calculated by hand based on usable size (52mm x 38mm) */
582		input_abs_set_res(input, ABS_X, 8);
583		input_abs_set_res(input, ABS_Y, 8);
584		break;
585
586	case HGPK_MODE_PENTABLET:
587		__set_bit(BTN_TOUCH, input->keybit);
588		__set_bit(BTN_TOOL_FINGER, input->keybit);
589
590		__set_bit(EV_ABS, input->evbit);
591
592		/* From device specs */
593		input_set_abs_params(input, ABS_X, 0, 999, 0, 0);
594		input_set_abs_params(input, ABS_Y, 5, 239, 0, 0);
595
596		/* Calculated by hand based on usable size (156mm x 38mm) */
597		input_abs_set_res(input, ABS_X, 6);
598		input_abs_set_res(input, ABS_Y, 8);
599		break;
600
601	default:
602		BUG();
603	}
604}
605
606static int hgpk_reset_device(struct psmouse *psmouse, bool recalibrate)
607{
608	int err;
609
610	psmouse_reset(psmouse);
611
612	if (recalibrate) {
613		struct ps2dev *ps2dev = &psmouse->ps2dev;
614
615		/* send the recalibrate request */
616		if (ps2_command(ps2dev, NULL, 0xf5) ||
617		    ps2_command(ps2dev, NULL, 0xf5) ||
618		    ps2_command(ps2dev, NULL, 0xe6) ||
619		    ps2_command(ps2dev, NULL, 0xf5)) {
620			return -1;
621		}
622
623		/* according to ALPS, 150mS is required for recalibration */
624		msleep(150);
625	}
626
627	err = hgpk_select_mode(psmouse);
628	if (err) {
629		psmouse_err(psmouse, "failed to select mode\n");
630		return err;
631	}
632
633	hgpk_reset_hack_state(psmouse);
634
635	return 0;
636}
637
638static int hgpk_force_recalibrate(struct psmouse *psmouse)
639{
640	struct hgpk_data *priv = psmouse->private;
641	int err;
642
643	/* C-series touchpads added the recalibrate command */
644	if (psmouse->model < HGPK_MODEL_C)
645		return 0;
646
647	if (!autorecal) {
648		psmouse_dbg(psmouse, "recalibration disabled, ignoring\n");
649		return 0;
650	}
651
652	psmouse_dbg(psmouse, "recalibrating touchpad..\n");
653
654	/* we don't want to race with the irq handler, nor with resyncs */
655	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
656
657	/* start by resetting the device */
658	err = hgpk_reset_device(psmouse, true);
659	if (err)
660		return err;
661
662	/*
663	 * XXX: If a finger is down during this delay, recalibration will
664	 * detect capacitance incorrectly.  This is a hardware bug, and
665	 * we don't have a good way to deal with it.  The 2s window stuff
666	 * (below) is our best option for now.
667	 */
668	if (psmouse_activate(psmouse))
669		return -1;
670
671	if (tpdebug)
672		psmouse_dbg(psmouse, "touchpad reactivated\n");
673
674	/*
675	 * If we get packets right away after recalibrating, it's likely
676	 * that a finger was on the touchpad.  If so, it's probably
677	 * miscalibrated, so we optionally schedule another.
678	 */
679	if (recal_guard_time)
680		priv->recalib_window = jiffies +
681			msecs_to_jiffies(recal_guard_time);
682
683	return 0;
684}
685
686/*
687 * This puts the touchpad in a power saving mode; according to ALPS, current
688 * consumption goes down to 50uA after running this.  To turn power back on,
689 * we drive MS-DAT low.  Measuring with a 1mA resolution ammeter says that
690 * the current on the SUS_3.3V rail drops from 3mA or 4mA to 0 when we do this.
691 *
692 * We have no formal spec that details this operation -- the low-power
693 * sequence came from a long-lost email trail.
694 */
695static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable)
696{
697	struct ps2dev *ps2dev = &psmouse->ps2dev;
698	int timeo;
699	int err;
700
701	/* Added on D-series touchpads */
702	if (psmouse->model < HGPK_MODEL_D)
703		return 0;
704
705	if (enable) {
706		psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
707
708		/*
709		 * Sending a byte will drive MS-DAT low; this will wake up
710		 * the controller.  Once we get an ACK back from it, it
711		 * means we can continue with the touchpad re-init.  ALPS
712		 * tells us that 1s should be long enough, so set that as
713		 * the upper bound. (in practice, it takes about 3 loops.)
714		 */
715		for (timeo = 20; timeo > 0; timeo--) {
716			if (!ps2_sendbyte(&psmouse->ps2dev,
717					PSMOUSE_CMD_DISABLE, 20))
718				break;
719			msleep(25);
720		}
721
722		err = hgpk_reset_device(psmouse, false);
723		if (err) {
724			psmouse_err(psmouse, "Failed to reset device!\n");
725			return err;
726		}
727
728		/* should be all set, enable the touchpad */
729		psmouse_activate(psmouse);
730		psmouse_dbg(psmouse, "Touchpad powered up.\n");
731	} else {
732		psmouse_dbg(psmouse, "Powering off touchpad.\n");
733
734		if (ps2_command(ps2dev, NULL, 0xec) ||
735		    ps2_command(ps2dev, NULL, 0xec) ||
736		    ps2_command(ps2dev, NULL, 0xea)) {
737			return -1;
738		}
739
740		psmouse_set_state(psmouse, PSMOUSE_IGNORE);
741
742		/* probably won't see an ACK, the touchpad will be off */
743		ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
744	}
745
746	return 0;
747}
748
749static int hgpk_poll(struct psmouse *psmouse)
750{
751	/* We can't poll, so always return failure. */
752	return -1;
753}
754
755static int hgpk_reconnect(struct psmouse *psmouse)
756{
757	struct hgpk_data *priv = psmouse->private;
758
759	/*
760	 * During suspend/resume the ps2 rails remain powered.  We don't want
761	 * to do a reset because it's flush data out of buffers; however,
762	 * earlier prototypes (B1) had some brokenness that required a reset.
763	 */
764	if (olpc_board_at_least(olpc_board(0xb2)))
765		if (psmouse->ps2dev.serio->dev.power.power_state.event !=
766				PM_EVENT_ON)
767			return 0;
768
769	priv->powered = 1;
770	return hgpk_reset_device(psmouse, false);
771}
772
773static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
774{
775	struct hgpk_data *priv = psmouse->private;
776
777	return sprintf(buf, "%d\n", priv->powered);
778}
779
780static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
781				const char *buf, size_t count)
782{
783	struct hgpk_data *priv = psmouse->private;
784	unsigned int value;
785	int err;
786
787	err = kstrtouint(buf, 10, &value);
788	if (err)
789		return err;
790
791	if (value > 1)
792		return -EINVAL;
793
794	if (value != priv->powered) {
795		/*
796		 * hgpk_toggle_power will deal w/ state so
797		 * we're not racing w/ irq
798		 */
799		err = hgpk_toggle_powersave(psmouse, value);
800		if (!err)
801			priv->powered = value;
802	}
803
804	return err ? err : count;
805}
806
807__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
808		      hgpk_show_powered, hgpk_set_powered, false);
809
810static ssize_t attr_show_mode(struct psmouse *psmouse, void *data, char *buf)
811{
812	struct hgpk_data *priv = psmouse->private;
813
814	return sprintf(buf, "%s\n", hgpk_mode_names[priv->mode]);
815}
816
817static ssize_t attr_set_mode(struct psmouse *psmouse, void *data,
818			     const char *buf, size_t len)
819{
820	struct hgpk_data *priv = psmouse->private;
821	enum hgpk_mode old_mode = priv->mode;
822	enum hgpk_mode new_mode = hgpk_mode_from_name(buf, len);
823	struct input_dev *old_dev = psmouse->dev;
824	struct input_dev *new_dev;
825	int err;
826
827	if (new_mode == HGPK_MODE_INVALID)
828		return -EINVAL;
829
830	if (old_mode == new_mode)
831		return len;
832
833	new_dev = input_allocate_device();
834	if (!new_dev)
835		return -ENOMEM;
836
837	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
838
839	/* Switch device into the new mode */
840	priv->mode = new_mode;
841	err = hgpk_reset_device(psmouse, false);
842	if (err)
843		goto err_try_restore;
844
845	hgpk_setup_input_device(new_dev, old_dev, new_mode);
846
847	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
848
849	err = input_register_device(new_dev);
850	if (err)
851		goto err_try_restore;
852
853	psmouse->dev = new_dev;
854	input_unregister_device(old_dev);
855
856	return len;
857
858err_try_restore:
859	input_free_device(new_dev);
860	priv->mode = old_mode;
861	hgpk_reset_device(psmouse, false);
862
863	return err;
864}
865
866PSMOUSE_DEFINE_ATTR(hgpk_mode, S_IWUSR | S_IRUGO, NULL,
867		    attr_show_mode, attr_set_mode);
868
869static ssize_t hgpk_trigger_recal_show(struct psmouse *psmouse,
870		void *data, char *buf)
871{
872	return -EINVAL;
873}
874
875static ssize_t hgpk_trigger_recal(struct psmouse *psmouse, void *data,
876				const char *buf, size_t count)
877{
878	struct hgpk_data *priv = psmouse->private;
879	unsigned int value;
880	int err;
881
882	err = kstrtouint(buf, 10, &value);
883	if (err)
884		return err;
885
886	if (value != 1)
887		return -EINVAL;
888
889	/*
890	 * We queue work instead of doing recalibration right here
891	 * to avoid adding locking to to hgpk_force_recalibrate()
892	 * since workqueue provides serialization.
893	 */
894	psmouse_queue_work(psmouse, &priv->recalib_wq, 0);
895	return count;
896}
897
898__PSMOUSE_DEFINE_ATTR(recalibrate, S_IWUSR | S_IRUGO, NULL,
899		      hgpk_trigger_recal_show, hgpk_trigger_recal, false);
900
901static void hgpk_disconnect(struct psmouse *psmouse)
902{
903	struct hgpk_data *priv = psmouse->private;
904
905	device_remove_file(&psmouse->ps2dev.serio->dev,
906			   &psmouse_attr_powered.dattr);
907	device_remove_file(&psmouse->ps2dev.serio->dev,
908			   &psmouse_attr_hgpk_mode.dattr);
909
910	if (psmouse->model >= HGPK_MODEL_C)
911		device_remove_file(&psmouse->ps2dev.serio->dev,
912				   &psmouse_attr_recalibrate.dattr);
913
914	psmouse_reset(psmouse);
915	kfree(priv);
916}
917
918static void hgpk_recalib_work(struct work_struct *work)
919{
920	struct delayed_work *w = to_delayed_work(work);
921	struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
922	struct psmouse *psmouse = priv->psmouse;
923
924	if (hgpk_force_recalibrate(psmouse))
925		psmouse_err(psmouse, "recalibration failed!\n");
926}
927
928static int hgpk_register(struct psmouse *psmouse)
929{
930	struct hgpk_data *priv = psmouse->private;
931	int err;
932
933	/* register handlers */
934	psmouse->protocol_handler = hgpk_process_byte;
935	psmouse->poll = hgpk_poll;
936	psmouse->disconnect = hgpk_disconnect;
937	psmouse->reconnect = hgpk_reconnect;
938
939	/* Disable the idle resync. */
940	psmouse->resync_time = 0;
941	/* Reset after a lot of bad bytes. */
942	psmouse->resetafter = 1024;
943
944	hgpk_setup_input_device(psmouse->dev, NULL, priv->mode);
945
946	err = device_create_file(&psmouse->ps2dev.serio->dev,
947				 &psmouse_attr_powered.dattr);
948	if (err) {
949		psmouse_err(psmouse, "Failed creating 'powered' sysfs node\n");
950		return err;
951	}
952
953	err = device_create_file(&psmouse->ps2dev.serio->dev,
954				 &psmouse_attr_hgpk_mode.dattr);
955	if (err) {
956		psmouse_err(psmouse,
957			    "Failed creating 'hgpk_mode' sysfs node\n");
958		goto err_remove_powered;
959	}
960
961	/* C-series touchpads added the recalibrate command */
962	if (psmouse->model >= HGPK_MODEL_C) {
963		err = device_create_file(&psmouse->ps2dev.serio->dev,
964					 &psmouse_attr_recalibrate.dattr);
965		if (err) {
966			psmouse_err(psmouse,
967				    "Failed creating 'recalibrate' sysfs node\n");
968			goto err_remove_mode;
969		}
970	}
971
972	return 0;
973
974err_remove_mode:
975	device_remove_file(&psmouse->ps2dev.serio->dev,
976			   &psmouse_attr_hgpk_mode.dattr);
977err_remove_powered:
978	device_remove_file(&psmouse->ps2dev.serio->dev,
979			   &psmouse_attr_powered.dattr);
980	return err;
981}
982
983int hgpk_init(struct psmouse *psmouse)
984{
985	struct hgpk_data *priv;
986	int err;
987
988	priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
989	if (!priv) {
990		err = -ENOMEM;
991		goto alloc_fail;
992	}
993
994	psmouse->private = priv;
995
996	priv->psmouse = psmouse;
997	priv->powered = true;
998	priv->mode = hgpk_default_mode;
999	INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
1000
1001	err = hgpk_reset_device(psmouse, false);
1002	if (err)
1003		goto init_fail;
1004
1005	err = hgpk_register(psmouse);
1006	if (err)
1007		goto init_fail;
1008
1009	return 0;
1010
1011init_fail:
1012	kfree(priv);
1013alloc_fail:
1014	return err;
1015}
1016
1017static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
1018{
1019	struct ps2dev *ps2dev = &psmouse->ps2dev;
1020	unsigned char param[3];
1021
1022	/* E7, E7, E7, E9 gets us a 3 byte identifier */
1023	if (ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
1024	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
1025	    ps2_command(ps2dev,  NULL, PSMOUSE_CMD_SETSCALE21) ||
1026	    ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
1027		return -EIO;
1028	}
1029
1030	psmouse_dbg(psmouse, "ID: %*ph\n", 3, param);
1031
1032	/* HGPK signature: 0x67, 0x00, 0x<model> */
1033	if (param[0] != 0x67 || param[1] != 0x00)
1034		return -ENODEV;
1035
1036	psmouse_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
1037
1038	return param[2];
1039}
1040
1041int hgpk_detect(struct psmouse *psmouse, bool set_properties)
1042{
1043	int version;
1044
1045	version = hgpk_get_model(psmouse);
1046	if (version < 0)
1047		return version;
1048
1049	if (set_properties) {
1050		psmouse->vendor = "ALPS";
1051		psmouse->name = "HGPK";
1052		psmouse->model = version;
1053	}
1054
1055	return 0;
1056}
1057
1058void hgpk_module_init(void)
1059{
1060	hgpk_default_mode = hgpk_mode_from_name(hgpk_mode_name,
1061						strlen(hgpk_mode_name));
1062	if (hgpk_default_mode == HGPK_MODE_INVALID) {
1063		hgpk_default_mode = HGPK_MODE_MOUSE;
1064		strlcpy(hgpk_mode_name, hgpk_mode_names[HGPK_MODE_MOUSE],
1065			sizeof(hgpk_mode_name));
1066	}
1067}
1068