aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/elantech.c
diff options
context:
space:
mode:
authorArjan Opmeer <arjan@opmeer.net>2009-04-18 22:05:40 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-04-18 22:11:51 -0400
commit3f8c0df43dec51fbdfb2627f7574aa00a5fce98c (patch)
treeb3d3f433d6542ce2f94b05d1ca77be226fe637d0 /drivers/input/mouse/elantech.c
parent3deb649e654ff87b87de9e415ac43ca8afbdff07 (diff)
Input: elantech - provide a workaround for jumpy cursor on firmware 2.34
It seems that Elantech touchpad firmware version 2.34 on the Hercules eCAFÉ suffers from a problem where bogus coordinates get reported at the beginning of a touch action. This causes the mouse cursor or the scrolled page to jump. Included patch provides a workaround that discards mouse packets that are likely to contain bogus coordinates. The workaround is activated when we detect touchpad with fimware version 2.34. Signed-off-by: Arjan Opmeer <arjan@opmeer.net> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/mouse/elantech.c')
-rw-r--r--drivers/input/mouse/elantech.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 6ab0eb1ada1c..d3b591673792 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Elantech Touchpad driver (v5) 2 * Elantech Touchpad driver (v6)
3 * 3 *
4 * Copyright (C) 2007-2008 Arjan Opmeer <arjan@opmeer.net> 4 * Copyright (C) 2007-2009 Arjan Opmeer <arjan@opmeer.net>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published 7 * under the terms of the GNU General Public License version 2 as published
@@ -178,6 +178,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
178 struct elantech_data *etd = psmouse->private; 178 struct elantech_data *etd = psmouse->private;
179 unsigned char *packet = psmouse->packet; 179 unsigned char *packet = psmouse->packet;
180 int fingers; 180 int fingers;
181 static int old_fingers;
181 182
182 if (etd->fw_version_maj == 0x01) { 183 if (etd->fw_version_maj == 0x01) {
183 /* byte 0: D U p1 p2 1 p3 R L 184 /* byte 0: D U p1 p2 1 p3 R L
@@ -190,6 +191,14 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
190 fingers = (packet[0] & 0xc0) >> 6; 191 fingers = (packet[0] & 0xc0) >> 6;
191 } 192 }
192 193
194 if (etd->jumpy_cursor) {
195 /* Discard packets that are likely to have bogus coordinates */
196 if (fingers > old_fingers) {
197 elantech_debug("elantech.c: discarding packet\n");
198 goto discard_packet_v1;
199 }
200 }
201
193 input_report_key(dev, BTN_TOUCH, fingers != 0); 202 input_report_key(dev, BTN_TOUCH, fingers != 0);
194 203
195 /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 204 /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0
@@ -216,6 +225,9 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
216 } 225 }
217 226
218 input_sync(dev); 227 input_sync(dev);
228
229 discard_packet_v1:
230 old_fingers = fingers;
219} 231}
220 232
221/* 233/*
@@ -662,6 +674,17 @@ int elantech_init(struct psmouse *psmouse)
662 param[0], param[1], param[2]); 674 param[0], param[1], param[2]);
663 etd->capabilities = param[0]; 675 etd->capabilities = param[0];
664 676
677 /*
678 * This firmware seems to suffer from misreporting coordinates when
679 * a touch action starts causing the mouse cursor or scrolled page
680 * to jump. Enable a workaround.
681 */
682 if (etd->fw_version_maj == 0x02 && etd->fw_version_min == 0x22) {
683 pr_info("elantech.c: firmware version 2.34 detected, "
684 "enabling jumpy cursor workaround\n");
685 etd->jumpy_cursor = 1;
686 }
687
665 if (elantech_set_absolute_mode(psmouse)) { 688 if (elantech_set_absolute_mode(psmouse)) {
666 pr_err("elantech.c: failed to put touchpad into absolute mode.\n"); 689 pr_err("elantech.c: failed to put touchpad into absolute mode.\n");
667 goto init_fail; 690 goto init_fail;