2 * OLPC touchpad PS/2 mouse driver
4 * Copyright (c) 2006 One Laptop Per Child, inc.
5 * Authors Zephaniah E. Hull and Andres Salomon <dilinger@laptop.org>
7 * This driver is partly based on the ALPS driver, which is:
9 * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
10 * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
11 * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
12 * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
20 * The touchpad on the OLPC is fairly wide, with the entire area usable
21 * as a tablet ("PT mode"), and the center 1/3rd also usable as a touchpad
24 * Earlier version of the device had simultaneous reporting; however, that
25 * was removed. Instead, the device now reports packets in one mode, and
26 * tells the driver when a mode switch needs to happen.
29 #include <linux/input.h>
30 #include <linux/serio.h>
31 #include <linux/libps2.h>
32 #include <linux/delay.h>
39 module_param(tpdebug, int, 0644);
41 #define OLPC_GS 1 /* The GS sensor. */
42 #define OLPC_PT 2 /* The PT sensor. */
44 static struct olpc_model_info olpc_model_data[] = {
45 { { 0x67, 0x00, 0x00 }, OLPC_GS | OLPC_PT }, /* unknown ID */
46 { { 0x67, 0x00, 0x0a }, OLPC_GS | OLPC_PT }, /* pre-B1 */
47 { { 0x67, 0x00, 0x14 }, OLPC_GS }, /* B1.*/
48 { { 0x67, 0x00, 0x28 }, OLPC_GS | OLPC_PT }, /* B2 */
49 { { 0x67, 0x00, 0x3c }, OLPC_GS | OLPC_PT }, /* B2-2 */
50 { { 0x67, 0x00, 0x50 }, OLPC_GS | OLPC_PT }, /* C1 */
53 #define OLPC_PKT_PT 0xcf
54 #define OLPC_PKT_GS 0xff
56 static int olpc_absolute_mode(struct psmouse *psmouse, int mode);
59 * OLPC absolute Mode - single-mode format
61 * byte 0: 1 1 0 0 1 1 1 1
62 * byte 1: 0 x6 x5 x4 x3 x2 x1 x0
63 * byte 2(PT): 0 0 x9 x8 x7 ? pt-dsw gs-dsw
64 * byte 2(GS): 0 x10 x9 x8 x7 ? gs-dsw pt-dsw
65 * byte 3: 0 y9 y8 y7 1 0 swr swl
66 * byte 4: 0 y6 y5 y4 y3 y2 y1 y0
67 * byte 5: 0 z6 z5 z4 z3 z2 z1 z0
69 * ?'s are not defined in the protocol spec, may vary between models.
71 * swr/swl are the left/right buttons.
73 * pt-dsw/gs-dsw indicate that the pt/gs sensor is detecting a
77 static void olpc_process_packet_gspt(struct psmouse *psmouse)
79 struct olpc_data *priv = psmouse->private;
80 unsigned char *packet = psmouse->packet;
81 struct input_dev *dev = psmouse->dev;
82 struct input_dev *dev2 = priv->dev2;
83 int x, y, z, gs_down = 0, pt_down = 0, left, right;
84 struct timeval now_tv;
88 right = packet[3] & 2;
89 x = packet[1] | ((packet[2] & 0x78) << 4);
90 y = packet[4] | ((packet[3] & 0x70) << 3);
93 if (psmouse->packet[0] == OLPC_PKT_GS) {
94 pt_down = !!(packet[2] & 1);
95 gs_down = !!(packet[2] & 2);
96 } else if (psmouse->packet[0] == OLPC_PKT_PT) {
97 gs_down = !!(packet[2] & 1);
98 pt_down = !!(packet[2] & 2);
103 * If it's been more than 30ms since the last packet,
104 * assume that there was a lift we were never told about.
106 do_gettimeofday(&now_tv);
107 now_ns = timeval_to_ns (&now_tv);
108 if (now_ns >= priv->late) {
109 input_report_key(dev, BTN_TOUCH, 0);
110 input_report_key(dev, BTN_TOOL_PEN, 0);
111 input_report_key(dev2, BTN_TOUCH, 0);
112 input_report_key(dev2, BTN_TOOL_FINGER, 0);
118 priv->late = now_ns + (30 * NSEC_PER_MSEC);
122 printk(KERN_DEBUG "%s %02x %02x %02x %02x %02x %02x\n",
123 __FUNCTION__, psmouse->packet[0], psmouse->packet[1],
124 psmouse->packet[2], psmouse->packet[3], psmouse->packet[4],
126 printk(KERN_DEBUG "l=%d r=%d p=%d g=%d x=%d y=%d z=%d\n",
127 left, right, pt_down, gs_down, x, y, z);
130 if (psmouse->packet[0] == OLPC_PKT_PT) {
131 input_report_key(dev, BTN_LEFT, left);
132 input_report_key(dev, BTN_RIGHT, right);
133 } else if (psmouse->packet[0] == OLPC_PKT_GS) {
134 input_report_key(dev, BTN_LEFT, left);
135 input_report_key(dev, BTN_RIGHT, right);
136 input_report_key(dev2, BTN_LEFT, left);
137 input_report_key(dev2, BTN_RIGHT, right);
140 input_report_key(dev, BTN_TOUCH, pt_down);
141 input_report_key(dev, BTN_TOOL_PEN, pt_down);
142 input_report_key(dev2, BTN_TOUCH, gs_down);
143 input_report_key(dev2, BTN_TOOL_FINGER, gs_down);
145 input_report_abs(dev2, ABS_PRESSURE, z);
147 if (psmouse->packet[0] == OLPC_PKT_PT && pt_down) {
148 input_report_abs(dev, ABS_X, x);
149 input_report_abs(dev, ABS_Y, y);
150 } else if (psmouse->packet[0] == OLPC_PKT_GS && gs_down) {
151 input_report_abs(dev2, ABS_X, x);
152 input_report_abs(dev2, ABS_Y, y);
158 if (priv->pending_mode == OLPC_GS &&
159 psmouse->packet[0] == OLPC_PKT_PT && pt_down) {
160 priv->pending_mode = 0;
161 cancel_delayed_work(&priv->mode_switch);
164 if (priv->i->flags & (OLPC_PT|OLPC_GS)) {
166 if (psmouse->packet[0] == OLPC_PKT_PT && !pt_down)
168 else if (psmouse->packet[0] == OLPC_PKT_GS && pt_down)
171 if (priv->current_mode == pending) {
172 priv->pending_mode = 0;
173 pending = priv->current_mode;
175 else if (priv->pending_mode != pending) {
176 priv->pending_mode = pending;
178 printk(KERN_WARNING "Scheduling mode switch to %s.\n",
179 pending == OLPC_GS ? "GS" : "PT");
182 * Apply a de-bounce when switching from PT to GS, to allow for
183 * spurious PT-up packets.
185 if (priv->pending_mode == OLPC_GS)
186 queue_delayed_work(kpsmoused_wq, &priv->mode_switch, msecs_to_jiffies(50));
188 queue_delayed_work(kpsmoused_wq, &priv->mode_switch, 0);
193 static psmouse_ret_t olpc_process_byte(struct psmouse *psmouse)
195 psmouse_ret_t ret = PSMOUSE_BAD_DATA;
197 if (psmouse->packet[0] != OLPC_PKT_PT &&
198 psmouse->packet[0] != OLPC_PKT_GS)
201 /* Bytes 2 - 6 should have 0 in the highest bit */
202 if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= 6 &&
203 (psmouse->packet[psmouse->pktcnt - 1] & 0x80))
206 if (psmouse->pktcnt == 6) {
207 olpc_process_packet_gspt(psmouse);
208 ret = PSMOUSE_FULL_PACKET;
212 ret = PSMOUSE_GOOD_DATA;
214 if (ret != PSMOUSE_GOOD_DATA && ret != PSMOUSE_FULL_PACKET)
215 printk(KERN_DEBUG "%s: (%d) %02x %02x %02x %02x %02x %02x\n",
216 __FUNCTION__, psmouse->pktcnt, psmouse->packet[0],
217 psmouse->packet[1], psmouse->packet[2],
218 psmouse->packet[3], psmouse->packet[4],
223 static struct olpc_model_info *olpc_get_model(struct psmouse *psmouse)
225 struct ps2dev *ps2dev = &psmouse->ps2dev;
226 unsigned char param[4];
230 * Now try "E7 report". Allowed responses are in
231 * olpc_model_data[].signature
233 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
234 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
235 ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21))
238 param[0] = param[1] = param[2] = 0xff;
239 if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO))
242 pr_debug("olpc.c(%d): E7 report: %2.2x %2.2x %2.2x",
243 __LINE__, param[0], param[1], param[2]);
245 for (i = 0; i < ARRAY_SIZE(olpc_model_data); i++) {
246 if (!memcmp(param, olpc_model_data[i].signature,
247 sizeof(olpc_model_data[i].signature))) {
248 printk(KERN_INFO __FILE__ ": OLPC touchpad revision 0x%x.\n", param[2]);
249 return olpc_model_data + i;
254 * ALPS creates new IDs pretty frequently; rather than listing them
255 * all, just assume they support the defaults. We've set aside the
256 * first entry of olpc_model_data as the catch-all.
258 if (!memcmp(param, olpc_model_data[0].signature, 2)) {
259 printk(KERN_INFO __FILE__ ": unknown ALPS revision %x, assuming default flags.\n", param[2]);
260 return &olpc_model_data[0];
266 static int olpc_find_mode(struct psmouse *psmouse)
268 struct olpc_data *priv = psmouse->private;
269 int mode = priv->i->flags;
273 else if (mode & OLPC_PT)
282 * Touchpad should be disabled before calling this!
284 static int olpc_new_mode(struct psmouse *psmouse, int mode)
286 struct ps2dev *ps2dev = &psmouse->ps2dev;
287 struct olpc_data *priv = psmouse->private;
292 printk(KERN_WARNING __FILE__ ": Switching to %d. [%lu]\n", mode, jiffies);
294 if ((ret = ps2_command(ps2dev, ¶m, 0x01F2)))
296 if ((ret = ps2_command(ps2dev, ¶m, 0x01F2)))
298 if ((ret = ps2_command(ps2dev, ¶m, 0x01F2)))
303 printk(KERN_WARNING __FILE__ ": Invalid mode %d. Defaulting to OLPC_GS.\n", mode);
305 ret = ps2_command(ps2dev, NULL, 0xE6);
308 ret = ps2_command(ps2dev, NULL, 0xE7);
314 /* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
315 psmouse->pktcnt = psmouse->out_of_sync = 0;
316 psmouse->last = jiffies;
317 psmouse->state = PSMOUSE_ACTIVATED;
319 if ((ret = ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE)))
322 priv->current_mode = mode;
323 priv->pending_mode = 0;
325 printk(KERN_WARNING __FILE__ ": Switched to mode %d successful.\n", mode);
329 printk(KERN_WARNING __FILE__ ": Mode switch to %d failed! (%d) [%lu]\n", mode, ret, jiffies);
333 static int olpc_absolute_mode(struct psmouse *psmouse, int mode)
335 struct ps2dev *ps2dev = &psmouse->ps2dev;
337 /* Switch to 'Advanced mode.', four disables in a row. */
338 if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
339 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
340 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) ||
341 ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE))
344 return olpc_new_mode(psmouse, mode);
348 * olpc_poll() - poll the touchpad for current motion packet.
350 * Note: We can't poll, so always return failure.
352 static int olpc_poll(struct psmouse *psmouse)
357 static int olpc_reconnect(struct psmouse *psmouse)
359 struct olpc_data *priv = psmouse->private;
362 if (olpc_rev_after(OLPC_REV_B2))
363 if (psmouse->ps2dev.serio->dev.power.power_state.event != PM_EVENT_ON)
366 psmouse_reset(psmouse);
368 if (!(priv->i = olpc_get_model(psmouse)))
371 mode = olpc_find_mode(psmouse);
375 if (olpc_absolute_mode(psmouse, mode)) {
376 printk(KERN_ERR __FILE__ ": Failed to reenable absolute mode.\n");
383 static void olpc_disconnect(struct psmouse *psmouse)
385 struct olpc_data *priv = psmouse->private;
387 psmouse_reset(psmouse);
388 input_unregister_device(priv->dev2);
392 static void olpc_mode_switch(struct work_struct *w)
394 struct delayed_work *work = container_of(w, struct delayed_work, work);
395 struct olpc_data *priv = container_of(work, struct olpc_data, mode_switch);
396 struct psmouse *psmouse = priv->psmouse;
397 struct ps2dev *ps2dev = &psmouse->ps2dev;
398 int pending_mode, ret;
400 if (priv->pending_mode == priv->current_mode) {
401 priv->pending_mode = 0;
402 printk (KERN_DEBUG __FILE__ ": In switch_mode, no target mode.\n");
407 printk(KERN_WARNING __FILE__ ": Disable for switch to %d. [%lu]\n", priv->pending_mode, jiffies);
409 /* XXX: This is a bit hacky, make sure this isn't screwing stuff up. */
410 psmouse->state = PSMOUSE_INITIALIZING;
412 ret = ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE);
414 /* XXX: if this ever fails, we need to do a full reset! */
415 printk(KERN_WARNING __FILE__ ": Disable failed for switch to %d. (%d) [%lu]\n", priv->pending_mode, ret, jiffies);
420 * ALPS tells us that it may take up to 20msec for the disable to
421 * take effect; however, ps2_command() will wait up to 200msec for
422 * the ACK to come back (and I'm assuming that by the time the
423 * hardware sends back its ACK, it has stopped sending bytes).
425 pending_mode = priv->pending_mode;
427 if (olpc_new_mode(psmouse, priv->pending_mode))
431 * Deal with a potential race condition.
433 * If there is a brief tap of a stylus or a fingernail that
434 * triggers a mode switch to PT mode, and the stylus/fingernail is
435 * lifted after the DISABLE above, but before we reenable in the new mode,
436 * then we can get stuck in PT mode.
438 if (pending_mode == OLPC_PT) {
439 priv->pending_mode = OLPC_GS;
440 queue_delayed_work(kpsmoused_wq, &priv->mode_switch, msecs_to_jiffies(50));
446 printk(KERN_WARNING __FILE__ ": Failure to switch modes, resetting device...\n");
447 olpc_reconnect(psmouse);
450 int olpc_init(struct psmouse *psmouse)
452 struct olpc_data *priv;
453 struct input_dev *dev = psmouse->dev;
454 struct input_dev *dev2;
457 priv = kzalloc(sizeof(struct olpc_data), GFP_KERNEL);
458 dev2 = input_allocate_device();
462 psmouse->private = priv;
464 priv->psmouse = psmouse;
466 psmouse_reset(psmouse);
467 if (!(priv->i = olpc_get_model(psmouse)))
470 mode = olpc_find_mode(psmouse);
472 printk(KERN_ERR __FILE__ ": Failed to identify proper mode\n");
476 if (olpc_absolute_mode(psmouse, mode)) {
477 printk(KERN_ERR __FILE__ ": Failed to enable absolute mode\n");
482 * Unset some of the default bits for things we don't have.
484 dev->evbit[LONG(EV_REL)] &= ~BIT(EV_REL);
485 dev->relbit[LONG(REL_X)] &= ~(BIT(REL_X) | BIT(REL_Y));
486 dev->keybit[LONG(BTN_MIDDLE)] &= ~BIT(BTN_MIDDLE);
488 dev->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
489 dev->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
490 dev->keybit[LONG(BTN_TOOL_PEN)] |= BIT(BTN_TOOL_PEN);
491 dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT);
493 dev->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
494 input_set_abs_params(dev, ABS_X, 2, 1000, 0, 0);
495 input_set_abs_params(dev, ABS_Y, 0, 717, 0, 0);
497 snprintf(priv->phys, sizeof(priv->phys),
498 "%s/input1", psmouse->ps2dev.serio->phys);
499 dev2->phys = priv->phys;
500 dev2->name = "OLPC ALPS GlideSensor";
501 dev2->id.bustype = BUS_I8042;
502 dev2->id.vendor = 0x0002;
503 dev2->id.product = PSMOUSE_OLPC;
504 dev2->id.version = 0x0000;
506 dev2->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
507 dev2->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
508 dev2->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
509 dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT);
511 dev2->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
512 input_set_abs_params(dev2, ABS_X, 350, 512, 0, 0);
513 input_set_abs_params(dev2, ABS_Y, 70, 325, 0, 0);
514 input_set_abs_params(dev2, ABS_PRESSURE, 0, 63, 0, 0);
516 if (input_register_device(dev2)) {
517 printk(KERN_ERR __FILE__ ": Failed to register GlideSensor\n");
521 psmouse->protocol_handler = olpc_process_byte;
522 psmouse->poll = olpc_poll;
523 psmouse->disconnect = olpc_disconnect;
524 psmouse->reconnect = olpc_reconnect;
525 psmouse->pktsize = 6;
527 /* Disable the idle resync. */
528 psmouse->resync_time = 0;
529 /* Reset after a lot of bad bytes. */
530 psmouse->resetafter = 1024;
532 INIT_DELAYED_WORK(&priv->mode_switch, olpc_mode_switch);
537 input_free_device(dev2);
542 int olpc_detect(struct psmouse *psmouse, int set_properties)
544 if (!olpc_get_model(psmouse))
547 if (set_properties) {
548 psmouse->vendor = "ALPS";
549 psmouse->name = "PenTablet";