aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFlorian Ragwitz <rafl@debian.org>2010-05-04 02:29:37 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-05-04 02:35:11 -0400
commite938fbfd4a7ac829d48b767c4dc365535d5c4f97 (patch)
tree894caf195dce009b114aa2c87297071009f8af8a /drivers
parentf81bc788ff91d4efd4baf88b2c29713838caa8e5 (diff)
Input: elantech - ignore high bits in the position coordinates
In older versions of the elantech hardware/firmware those bits always were unset, so it didn't actually matter, but newer versions seem to use those high bits for something else, screwing up the coordinates we report to the input layer for those devices. Signed-off-by: Florian Ragwitz <rafl@debian.org> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/mouse/elantech.c69
1 files changed, 44 insertions, 25 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 095bd388c6dd..2cbf3fc4729a 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -185,13 +185,17 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
185 static int old_fingers; 185 static int old_fingers;
186 186
187 if (etd->fw_version_maj == 0x01) { 187 if (etd->fw_version_maj == 0x01) {
188 /* byte 0: D U p1 p2 1 p3 R L 188 /*
189 byte 1: f 0 th tw x9 x8 y9 y8 */ 189 * byte 0: D U p1 p2 1 p3 R L
190 * byte 1: f 0 th tw x9 x8 y9 y8
191 */
190 fingers = ((packet[1] & 0x80) >> 7) + 192 fingers = ((packet[1] & 0x80) >> 7) +
191 ((packet[1] & 0x30) >> 4); 193 ((packet[1] & 0x30) >> 4);
192 } else { 194 } else {
193 /* byte 0: n1 n0 p2 p1 1 p3 R L 195 /*
194 byte 1: 0 0 0 0 x9 x8 y9 y8 */ 196 * byte 0: n1 n0 p2 p1 1 p3 R L
197 * byte 1: 0 0 0 0 x9 x8 y9 y8
198 */
195 fingers = (packet[0] & 0xc0) >> 6; 199 fingers = (packet[0] & 0xc0) >> 6;
196 } 200 }
197 201
@@ -205,13 +209,15 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse)
205 209
206 input_report_key(dev, BTN_TOUCH, fingers != 0); 210 input_report_key(dev, BTN_TOUCH, fingers != 0);
207 211
208 /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 212 /*
209 byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ 213 * byte 2: x7 x6 x5 x4 x3 x2 x1 x0
214 * byte 3: y7 y6 y5 y4 y3 y2 y1 y0
215 */
210 if (fingers) { 216 if (fingers) {
211 input_report_abs(dev, ABS_X, 217 input_report_abs(dev, ABS_X,
212 ((packet[1] & 0x0c) << 6) | packet[2]); 218 ((packet[1] & 0x0c) << 6) | packet[2]);
213 input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - 219 input_report_abs(dev, ABS_Y,
214 (((packet[1] & 0x03) << 8) | packet[3])); 220 ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3]));
215 } 221 }
216 222
217 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); 223 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
@@ -250,34 +256,47 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse)
250 256
251 switch (fingers) { 257 switch (fingers) {
252 case 1: 258 case 1:
253 /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 259 /*
254 byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ 260 * byte 1: . . . . . x10 x9 x8
255 input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); 261 * byte 2: x7 x6 x5 x4 x4 x2 x1 x0
256 /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 262 */
257 byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ 263 input_report_abs(dev, ABS_X,
258 input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - 264 ((packet[1] & 0x07) << 8) | packet[2]);
259 ((packet[4] << 8) | packet[5])); 265 /*
266 * byte 4: . . . . . . y9 y8
267 * byte 5: y7 y6 y5 y4 y3 y2 y1 y0
268 */
269 input_report_abs(dev, ABS_Y,
270 ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]));
260 break; 271 break;
261 272
262 case 2: 273 case 2:
263 /* The coordinate of each finger is reported separately with 274 /*
264 a lower resolution for two finger touches */ 275 * The coordinate of each finger is reported separately
265 /* byte 0: . . ay8 ax8 . . . . 276 * with a lower resolution for two finger touches:
266 byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ 277 * byte 0: . . ay8 ax8 . . . .
278 * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
279 */
267 x1 = ((packet[0] & 0x10) << 4) | packet[1]; 280 x1 = ((packet[0] & 0x10) << 4) | packet[1];
268 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ 281 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */
269 y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); 282 y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]);
270 /* byte 3: . . by8 bx8 . . . . 283 /*
271 byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ 284 * byte 3: . . by8 bx8 . . . .
285 * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
286 */
272 x2 = ((packet[3] & 0x10) << 4) | packet[4]; 287 x2 = ((packet[3] & 0x10) << 4) | packet[4];
273 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ 288 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */
274 y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); 289 y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]);
275 /* For compatibility with the X Synaptics driver scale up one 290 /*
276 coordinate and report as ordinary mouse movent */ 291 * For compatibility with the X Synaptics driver scale up
292 * one coordinate and report as ordinary mouse movent
293 */
277 input_report_abs(dev, ABS_X, x1 << 2); 294 input_report_abs(dev, ABS_X, x1 << 2);
278 input_report_abs(dev, ABS_Y, y1 << 2); 295 input_report_abs(dev, ABS_Y, y1 << 2);
279 /* For compatibility with the proprietary X Elantech driver 296 /*
280 report both coordinates as hat coordinates */ 297 * For compatibility with the proprietary X Elantech driver
298 * report both coordinates as hat coordinates
299 */
281 input_report_abs(dev, ABS_HAT0X, x1); 300 input_report_abs(dev, ABS_HAT0X, x1);
282 input_report_abs(dev, ABS_HAT0Y, y1); 301 input_report_abs(dev, ABS_HAT0Y, y1);
283 input_report_abs(dev, ABS_HAT1X, x2); 302 input_report_abs(dev, ABS_HAT1X, x2);