From 6797b39e6f6f34c74177736e146406e894b9482b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 26 Mar 2014 13:30:52 -0700 Subject: Input: cypress_ps2 - don't report as a button pads The cypress PS/2 trackpad models supported by the cypress_ps2 driver emulate BTN_RIGHT events in firmware based on the finger position, as part of this no motion events are sent when the finger is in the button area. The INPUT_PROP_BUTTONPAD property is there to indicate to userspace that BTN_RIGHT events should be emulated in userspace, which is not necessary in this case. When INPUT_PROP_BUTTONPAD is advertised userspace will wait for a motion event before propagating the button event higher up the stack, as it needs current abs x + y data for its BTN_RIGHT emulation. Since in the cypress_ps2 pads don't report motion events in the button area, this means that clicks in the button area end up being ignored, so INPUT_PROP_BUTTONPAD actually causes problems for these touchpads, and removing it fixes: https://bugs.freedesktop.org/show_bug.cgi?id=76341 Reported-by: Adam Williamson Tested-by: Adam Williamson Reviewed-by: Peter Hutterer Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 87095e2f5153..8af34ffe208b 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -409,7 +409,6 @@ static int cypress_set_input_params(struct input_dev *input, __clear_bit(REL_X, input->relbit); __clear_bit(REL_Y, input->relbit); - __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); __set_bit(EV_KEY, input->evbit); __set_bit(BTN_LEFT, input->keybit); __set_bit(BTN_RIGHT, input->keybit); -- cgit v1.2.3 From 421e08c41fda1f0c2ff6af81a67b491389b653a5 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Fri, 28 Mar 2014 00:43:00 -0700 Subject: Input: synaptics - add manual min/max quirk The new Lenovo Haswell series (-40's) contains a new Synaptics touchpad. However, these new Synaptics devices report bad axis ranges. Under Windows, it is not a problem because the Windows driver uses RMI4 over SMBus to talk to the device. Under Linux, we are using the PS/2 fallback interface and it occurs the reported ranges are wrong. Of course, it would be too easy to have only one range for the whole series, each touchpad seems to be calibrated in a different way. We can not use SMBus to get the actual range because I suspect the firmware will switch into the SMBus mode and stop talking through PS/2 (this is the case for hybrid HID over I2C / PS/2 Synaptics touchpads). So as a temporary solution (until RMI4 land into upstream), start a new list of quirks with the min/max manually set. Signed-off-by: Benjamin Tissoires CC: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 26386f9d2569..ef148f997c84 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -265,11 +265,22 @@ static int synaptics_identify(struct psmouse *psmouse) * Read touchpad resolution and maximum reported coordinates * Resolution is left zero if touchpad does not support the query */ + +static const int *quirk_min_max; + static int synaptics_resolution(struct psmouse *psmouse) { struct synaptics_data *priv = psmouse->private; unsigned char resp[3]; + if (quirk_min_max) { + priv->x_min = quirk_min_max[0]; + priv->x_max = quirk_min_max[1]; + priv->y_min = quirk_min_max[2]; + priv->y_max = quirk_min_max[3]; + return 0; + } + if (SYN_ID_MAJOR(priv->identity) < 4) return 0; @@ -1485,10 +1496,46 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { { } }; +static const struct dmi_system_id min_max_dmi_table[] __initconst = { +#if defined(CONFIG_DMI) + { + /* Lenovo ThinkPad Helix */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), + }, + .driver_data = (int []){1024, 5052, 2258, 4832}, + }, + { + /* Lenovo ThinkPad T440s */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, + { + /* Lenovo ThinkPad T540p */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"), + }, + .driver_data = (int []){1024, 5056, 2058, 4832}, + }, +#endif + { } +}; + void __init synaptics_module_init(void) { + const struct dmi_system_id *min_max_dmi; + impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); broken_olpc_ec = dmi_check_system(olpc_dmi_table); + + min_max_dmi = dmi_first_match(min_max_dmi_table); + if (min_max_dmi) + quirk_min_max = min_max_dmi->driver_data; } static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) -- cgit v1.2.3 From 8a0435d958fb36d93b8df610124a0e91e5675c82 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 28 Mar 2014 01:01:38 -0700 Subject: Input: synaptics - add manual min/max quirk for ThinkPad X240 This extends Benjamin Tissoires manual min/max quirk table with support for the ThinkPad X240. Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ef148f997c84..d8d49d10f9bb 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1506,6 +1506,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1024, 5052, 2258, 4832}, }, + { + /* Lenovo ThinkPad X240 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"), + }, + .driver_data = (int []){1232, 5710, 1156, 4696}, + }, { /* Lenovo ThinkPad T440s */ .matches = { -- cgit v1.2.3 From 43e19888b1fe2a3e8a5543030c5b286cde38b3f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 22:26:41 -0700 Subject: Input: synaptics - report INPUT_PROP_TOPBUTTONPAD property Check PNP ID of the PS/2 AUX port and report INPUT_PROP_TOPBUTTONPAD property for for touchpads with top button areas. Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 55 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d8d49d10f9bb..9d754103337d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -117,6 +117,44 @@ void synaptics_reset(struct psmouse *psmouse) } #ifdef CONFIG_MOUSE_PS2_SYNAPTICS +/* This list has been kindly provided by Synaptics. */ +static const char * const topbuttonpad_pnp_ids[] = { + "LEN0017", + "LEN0018", + "LEN0019", + "LEN0023", + "LEN002A", + "LEN002B", + "LEN002C", + "LEN002D", + "LEN002E", + "LEN0033", /* Helix */ + "LEN0034", /* T431s, T540, X1 Carbon 2nd */ + "LEN0035", /* X240 */ + "LEN0036", /* T440 */ + "LEN0037", + "LEN0038", + "LEN0041", + "LEN0042", /* Yoga */ + "LEN0045", + "LEN0046", + "LEN0047", + "LEN0048", + "LEN0049", + "LEN2000", + "LEN2001", + "LEN2002", + "LEN2003", + "LEN2004", /* L440 */ + "LEN2005", + "LEN2006", + "LEN2007", + "LEN2008", + "LEN2009", + "LEN200A", + "LEN200B", + NULL +}; /***************************************************************************** * Synaptics communications functions @@ -1255,8 +1293,10 @@ static void set_abs_position_params(struct input_dev *dev, input_abs_set_res(dev, y_code, priv->y_res); } -static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) +static void set_input_params(struct psmouse *psmouse, + struct synaptics_data *priv) { + struct input_dev *dev = psmouse->dev; int i; /* Things that apply to both modes */ @@ -1325,6 +1365,17 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); + /* See if this buttonpad has a top button area */ + if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) { + for (i = 0; topbuttonpad_pnp_ids[i]; i++) { + if (strstr(psmouse->ps2dev.serio->firmware_id, + topbuttonpad_pnp_ids[i])) { + __set_bit(INPUT_PROP_TOPBUTTONPAD, + dev->propbit); + break; + } + } + } /* Clickpads report only left button */ __clear_bit(BTN_RIGHT, dev->keybit); __clear_bit(BTN_MIDDLE, dev->keybit); @@ -1593,7 +1644,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) priv->capabilities, priv->ext_cap, priv->ext_cap_0c, priv->board_id, priv->firmware_id); - set_input_params(psmouse->dev, priv); + set_input_params(psmouse, priv); /* * Encode touchpad model so that it can be used to set -- cgit v1.2.3 From 46a2986ebbe18757c2d8c352f8fb6e0f4f0754e3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 22:31:18 -0700 Subject: Input: synaptics - add min/max quirk for ThinkPad T431s, L440, L540, S1 Yoga and X1 We expect that all the Haswell series will need such quirks, sigh. The T431s seems to be T430 hardware in a T440s case, using the T440s touchpad, with the same min/max issue. The X1 Carbon 3rd generation name says 2nd while it is a 3rd generation. The X1 and T431s share a PnPID with the T540p, but the reported ranges are closer to those of the T440s. HdG: Squashed 5 quirk patches into one. T431s + L440 + L540 are written by me, S1 Yoga and X1 are written by Benjamin Tissoires. Hdg: Standardized S1 Yoga and X1 values, Yoga uses the same touchpad as the X240, X1 uses the same touchpad as the T440. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 42 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 9d754103337d..ef9f4913450d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1565,6 +1565,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1232, 5710, 1156, 4696}, }, + { + /* Lenovo ThinkPad T431s */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, { /* Lenovo ThinkPad T440s */ .matches = { @@ -1573,6 +1581,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1024, 5112, 2024, 4832}, }, + { + /* Lenovo ThinkPad L440 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, { /* Lenovo ThinkPad T540p */ .matches = { @@ -1581,6 +1597,32 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1024, 5056, 2058, 4832}, }, + { + /* Lenovo ThinkPad L540 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, + { + /* Lenovo Yoga S1 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "ThinkPad S1 Yoga"), + }, + .driver_data = (int []){1232, 5710, 1156, 4696}, + }, + { + /* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, + "ThinkPad X1 Carbon 2nd"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, #endif { } }; -- cgit v1.2.3 From ae4bedf0679d99f0a9b80a7ea9b8dd205de05d06 Mon Sep 17 00:00:00 2001 From: Jordan Rife Date: Tue, 22 Apr 2014 17:44:51 -0700 Subject: Input: elantech - add support for newer elantech touchpads Newer elantech touchpads are not recognized by the current driver, since it fails to detect their firmware version number. This prevents more advanced touchpad features from being usable such as two-finger scrolling. This patch allows newer touchpads to be detected and be fully functional. Tested on Sony Vaio SVF13N17PXB. Signed-off-by: Jordan Rife Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ef1cf52f8bb9..088d3541c7d3 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1353,6 +1353,7 @@ static int elantech_set_properties(struct elantech_data *etd) case 6: case 7: case 8: + case 9: etd->hw_version = 4; break; default: -- cgit v1.2.3 From 27a38856a948c3e8de30dc71647ff9e1778c99fc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Apr 2014 13:02:35 -0700 Subject: Input: synaptics - add min/max quirk for ThinkPad Edge E431 Cc: stable@vger.kernel.org Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/input/mouse') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ef9f4913450d..d68d33fb5ac2 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1565,6 +1565,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1232, 5710, 1156, 4696}, }, + { + /* Lenovo ThinkPad Edge E431 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"), + }, + .driver_data = (int []){1024, 5022, 2508, 4832}, + }, { /* Lenovo ThinkPad T431s */ .matches = { -- cgit v1.2.3 From 36189cc3cd57ab0f1cd75241f93fe01de928ac06 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 5 May 2014 09:36:43 -0700 Subject: Input: elantech - fix touchpad initialization on Gigabyte U2442 The hw_version 3 Elantech touchpad on the Gigabyte U2442 does not accept 0x0b as initialization value for r10, this stand-alone version of the driver: http://planet76.com/drivers/elantech/psmouse-elantech-v6.tar.bz2 Uses 0x03 which does work, so this means not setting bit 3 of r10 which sets: "Enable Real H/W Resolution In Absolute mode" Which will result in half the x and y resolution we get with that bit set, so simply not setting it everywhere is not a solution. We've been unable to find a way to identify touchpads where setting the bit will fail, so this patch uses a dmi based blacklist for this. https://bugzilla.kernel.org/show_bug.cgi?id=61151 Cc: stable@vger.kernel.org Reported-by: Philipp Wolfer Tested-by: Philipp Wolfer Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- Documentation/input/elantech.txt | 5 ++++- drivers/input/mouse/elantech.c | 26 +++++++++++++++++++++++++- drivers/input/mouse/elantech.h | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'drivers/input/mouse') diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt index 5602eb71ad5d..e1ae127ed099 100644 --- a/Documentation/input/elantech.txt +++ b/Documentation/input/elantech.txt @@ -504,9 +504,12 @@ byte 5: * reg_10 bit 7 6 5 4 3 2 1 0 - 0 0 0 0 0 0 0 A + 0 0 0 0 R F T A A: 1 = enable absolute tracking + T: 1 = enable two finger mode auto correct + F: 1 = disable ABS Position Filter + R: 1 = enable real hardware resolution 6.2 Native absolute mode 6 byte packet format ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 088d3541c7d3..b96e978a37b7 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -831,7 +832,11 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) break; case 3: - etd->reg_10 = 0x0b; + if (etd->set_hw_resolution) + etd->reg_10 = 0x0b; + else + etd->reg_10 = 0x03; + if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) rc = -1; @@ -1330,6 +1335,22 @@ static int elantech_reconnect(struct psmouse *psmouse) return 0; } +/* + * Some hw_version 3 models go into error state when we try to set bit 3 of r10 + */ +static const struct dmi_system_id no_hw_res_dmi_table[] = { +#if defined(CONFIG_DMI) && defined(CONFIG_X86) + { + /* Gigabyte U2442 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "U2442"), + }, + }, +#endif + { } +}; + /* * determine hardware version and set some properties according to it. */ @@ -1390,6 +1411,9 @@ static int elantech_set_properties(struct elantech_data *etd) */ etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); + /* Enable real hardware resolution on hw_version 3 ? */ + etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); + return 0; } diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 036a04abaef7..9e0e2a1f340d 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h @@ -130,6 +130,7 @@ struct elantech_data { bool jumpy_cursor; bool reports_pressure; bool crc_enabled; + bool set_hw_resolution; unsigned char hw_version; unsigned int fw_version; unsigned int single_finger_reports; -- cgit v1.2.3