Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Florian Ragwitz and committed by
Dmitry Torokhov
e938fbfd f81bc788

+48 -29
+4 -4
Documentation/input/elantech.txt
··· 333 333 byte 1: 334 334 335 335 bit 7 6 5 4 3 2 1 0 336 - x15 x14 x13 x12 x11 x10 x9 x8 336 + . . . . . x10 x9 x8 337 337 338 338 byte 2: 339 339 340 340 bit 7 6 5 4 3 2 1 0 341 341 x7 x6 x5 x4 x4 x2 x1 x0 342 342 343 - x15..x0 = absolute x value (horizontal) 343 + x10..x0 = absolute x value (horizontal) 344 344 345 345 byte 3: 346 346 ··· 350 350 byte 4: 351 351 352 352 bit 7 6 5 4 3 2 1 0 353 - y15 y14 y13 y12 y11 y10 y8 y8 353 + . . . . . . y9 y8 354 354 355 355 byte 5: 356 356 357 357 bit 7 6 5 4 3 2 1 0 358 358 y7 y6 y5 y4 y3 y2 y1 y0 359 359 360 - y15..y0 = absolute y value (vertical) 360 + y9..y0 = absolute y value (vertical) 361 361 362 362 363 363 4.2.2 Two finger touch
+44 -25
drivers/input/mouse/elantech.c
··· 185 185 static int old_fingers; 186 186 187 187 if (etd->fw_version_maj == 0x01) { 188 - /* byte 0: D U p1 p2 1 p3 R L 189 - byte 1: f 0 th tw x9 x8 y9 y8 */ 188 + /* 189 + * byte 0: D U p1 p2 1 p3 R L 190 + * byte 1: f 0 th tw x9 x8 y9 y8 191 + */ 190 192 fingers = ((packet[1] & 0x80) >> 7) + 191 193 ((packet[1] & 0x30) >> 4); 192 194 } else { 193 - /* byte 0: n1 n0 p2 p1 1 p3 R L 194 - byte 1: 0 0 0 0 x9 x8 y9 y8 */ 195 + /* 196 + * byte 0: n1 n0 p2 p1 1 p3 R L 197 + * byte 1: 0 0 0 0 x9 x8 y9 y8 198 + */ 195 199 fingers = (packet[0] & 0xc0) >> 6; 196 200 } 197 201 ··· 209 205 210 206 input_report_key(dev, BTN_TOUCH, fingers != 0); 211 207 212 - /* byte 2: x7 x6 x5 x4 x3 x2 x1 x0 213 - byte 3: y7 y6 y5 y4 y3 y2 y1 y0 */ 208 + /* 209 + * byte 2: x7 x6 x5 x4 x3 x2 x1 x0 210 + * byte 3: y7 y6 y5 y4 y3 y2 y1 y0 211 + */ 214 212 if (fingers) { 215 213 input_report_abs(dev, ABS_X, 216 214 ((packet[1] & 0x0c) << 6) | packet[2]); 217 - input_report_abs(dev, ABS_Y, ETP_YMAX_V1 - 218 - (((packet[1] & 0x03) << 8) | packet[3])); 215 + input_report_abs(dev, ABS_Y, 216 + ETP_YMAX_V1 - (((packet[1] & 0x03) << 8) | packet[3])); 219 217 } 220 218 221 219 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); ··· 256 250 257 251 switch (fingers) { 258 252 case 1: 259 - /* byte 1: x15 x14 x13 x12 x11 x10 x9 x8 260 - byte 2: x7 x6 x5 x4 x4 x2 x1 x0 */ 261 - input_report_abs(dev, ABS_X, (packet[1] << 8) | packet[2]); 262 - /* byte 4: y15 y14 y13 y12 y11 y10 y8 y8 263 - byte 5: y7 y6 y5 y4 y3 y2 y1 y0 */ 264 - input_report_abs(dev, ABS_Y, ETP_YMAX_V2 - 265 - ((packet[4] << 8) | packet[5])); 253 + /* 254 + * byte 1: . . . . . x10 x9 x8 255 + * byte 2: x7 x6 x5 x4 x4 x2 x1 x0 256 + */ 257 + input_report_abs(dev, ABS_X, 258 + ((packet[1] & 0x07) << 8) | packet[2]); 259 + /* 260 + * byte 4: . . . . . . y9 y8 261 + * byte 5: y7 y6 y5 y4 y3 y2 y1 y0 262 + */ 263 + input_report_abs(dev, ABS_Y, 264 + ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5])); 266 265 break; 267 266 268 267 case 2: 269 - /* The coordinate of each finger is reported separately with 270 - a lower resolution for two finger touches */ 271 - /* byte 0: . . ay8 ax8 . . . . 272 - byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 */ 268 + /* 269 + * The coordinate of each finger is reported separately 270 + * with a lower resolution for two finger touches: 271 + * byte 0: . . ay8 ax8 . . . . 272 + * byte 1: ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0 273 + */ 273 274 x1 = ((packet[0] & 0x10) << 4) | packet[1]; 274 275 /* byte 2: ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0 */ 275 276 y1 = ETP_2FT_YMAX - (((packet[0] & 0x20) << 3) | packet[2]); 276 - /* byte 3: . . by8 bx8 . . . . 277 - byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 */ 277 + /* 278 + * byte 3: . . by8 bx8 . . . . 279 + * byte 4: bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0 280 + */ 278 281 x2 = ((packet[3] & 0x10) << 4) | packet[4]; 279 282 /* byte 5: by7 by8 by5 by4 by3 by2 by1 by0 */ 280 283 y2 = ETP_2FT_YMAX - (((packet[3] & 0x20) << 3) | packet[5]); 281 - /* For compatibility with the X Synaptics driver scale up one 282 - coordinate and report as ordinary mouse movent */ 284 + /* 285 + * For compatibility with the X Synaptics driver scale up 286 + * one coordinate and report as ordinary mouse movent 287 + */ 283 288 input_report_abs(dev, ABS_X, x1 << 2); 284 289 input_report_abs(dev, ABS_Y, y1 << 2); 285 - /* For compatibility with the proprietary X Elantech driver 286 - report both coordinates as hat coordinates */ 290 + /* 291 + * For compatibility with the proprietary X Elantech driver 292 + * report both coordinates as hat coordinates 293 + */ 287 294 input_report_abs(dev, ABS_HAT0X, x1); 288 295 input_report_abs(dev, ABS_HAT0Y, y1); 289 296 input_report_abs(dev, ABS_HAT1X, x2);