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

Input: elantech - deal with clickpads reporting right button events

At least the Dell Vostro 5470 elantech *clickpad* reports right button
clicks when clicked in the right bottom area:

https://bugzilla.redhat.com/show_bug.cgi?id=1103528

This is different from how (elantech) clickpads normally operate, normally
no matter where the user clicks on the pad the pad always reports a left
button event, since there is only 1 hardware button beneath the path.

It looks like Dell has put 2 buttons under the pad, one under each bottom
corner, causing this.

Since this however still clearly is a real clickpad hardware-wise, we still
want to report it as such to userspace, so that things like finger movement
in the bottom area can be properly ignored as it should be on clickpads.

So deal with this weirdness by simply mapping a right click to a left click
on elantech clickpads. As an added advantage this is something which we can
simply do on all elantech clickpads, so no need to add special quirks for
this weird model.

Reported-and-tested-by: Elder Marco <eldermarco@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Hans de Goede and committed by
Dmitry Torokhov
cd9e83e2 cc071aca

+18 -4
+18 -4
drivers/input/mouse/elantech.c
··· 473 473 input_report_key(dev, BTN_TOOL_FINGER, fingers == 1); 474 474 input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2); 475 475 input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); 476 - input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 477 - input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 476 + 477 + /* For clickpads map both buttons to BTN_LEFT */ 478 + if (etd->fw_version & 0x001000) { 479 + input_report_key(dev, BTN_LEFT, packet[0] & 0x03); 480 + } else { 481 + input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 482 + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 483 + } 484 + 478 485 input_report_abs(dev, ABS_PRESSURE, pres); 479 486 input_report_abs(dev, ABS_TOOL_WIDTH, width); 480 487 ··· 491 484 static void elantech_input_sync_v4(struct psmouse *psmouse) 492 485 { 493 486 struct input_dev *dev = psmouse->dev; 487 + struct elantech_data *etd = psmouse->private; 494 488 unsigned char *packet = psmouse->packet; 495 489 496 - input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 497 - input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 490 + /* For clickpads map both buttons to BTN_LEFT */ 491 + if (etd->fw_version & 0x001000) { 492 + input_report_key(dev, BTN_LEFT, packet[0] & 0x03); 493 + } else { 494 + input_report_key(dev, BTN_LEFT, packet[0] & 0x01); 495 + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); 496 + } 497 + 498 498 input_mt_report_pointer_emulation(dev, true); 499 499 input_sync(dev); 500 500 }