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

Input: elantech - detect new ICs and setup Host Notify for them

New ICs are using a different scheme for the alternate bus parameter.
Given that they are new and are only using either PS2 only or PS2 + SMBus
Host Notify, we force those new ICs to use the SMBus solution for enhanced
reporting.

This allows the touchpad found on the Lenovo T480s to report 5 fingers
every 8 ms, instead of having a limit of 2 every 8 ms.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Acked-by: KT Liao <kt.liao@emc.com.tw>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Benjamin Tissoires and committed by
Dmitry Torokhov
df077237 21c48dbd

+22 -4
+7 -4
drivers/input/mouse/elantech.c
··· 1793 1793 1794 1794 if (elantech_smbus == ELANTECH_SMBUS_NOT_SET) { 1795 1795 /* 1796 - * FIXME: 1797 - * constraint the I2C capable devices by using FW version, 1798 - * board version, or by using DMI matching 1796 + * New ICs are enabled by default. 1797 + * Old ICs are up to the user to decide. 1799 1798 */ 1800 - return -ENXIO; 1799 + if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) 1800 + return -ENXIO; 1801 1801 } 1802 1802 1803 1803 psmouse_info(psmouse, "Trying to set up SMBus access\n"); ··· 1818 1818 static bool elantech_use_host_notify(struct psmouse *psmouse, 1819 1819 struct elantech_device_info *info) 1820 1820 { 1821 + if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) 1822 + return true; 1823 + 1821 1824 switch (info->bus) { 1822 1825 case ETP_BUS_PS2_ONLY: 1823 1826 /* expected case */
+15
drivers/input/mouse/elantech.h
··· 116 116 #define ETP_BUS_PS2_SMB_HST_NTFY 4 117 117 118 118 /* 119 + * New ICs are either using SMBus Host Notify or just plain PS2. 120 + * 121 + * ETP_FW_VERSION_QUERY is: 122 + * Byte 1: 123 + * - bit 0..3: IC BODY 124 + * Byte 2: 125 + * - bit 4: HiddenButton 126 + * - bit 5: PS2_SMBUS_NOTIFY 127 + * - bit 6: PS2CRCCheck 128 + */ 129 + #define ETP_NEW_IC_SMBUS_HOST_NOTIFY(fw_version) \ 130 + ((((fw_version) & 0x0f2000) == 0x0f2000) && \ 131 + ((fw_version) & 0x0000ff) > 0) 132 + 133 + /* 119 134 * The base position for one finger, v4 hardware 120 135 */ 121 136 struct finger_pos {