aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2014-03-28 03:43:00 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-03-28 12:02:00 -0400
commit421e08c41fda1f0c2ff6af81a67b491389b653a5 (patch)
treeed7512d06b79fb0f47fa1c4dfba86db2b6f9cdef /drivers/input/mouse
parent6797b39e6f6f34c74177736e146406e894b9482b (diff)
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 <benjamin.tissoires@redhat.com> CC: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/synaptics.c47
1 files changed, 47 insertions, 0 deletions
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)
265 * Read touchpad resolution and maximum reported coordinates 265 * Read touchpad resolution and maximum reported coordinates
266 * Resolution is left zero if touchpad does not support the query 266 * Resolution is left zero if touchpad does not support the query
267 */ 267 */
268
269static const int *quirk_min_max;
270
268static int synaptics_resolution(struct psmouse *psmouse) 271static int synaptics_resolution(struct psmouse *psmouse)
269{ 272{
270 struct synaptics_data *priv = psmouse->private; 273 struct synaptics_data *priv = psmouse->private;
271 unsigned char resp[3]; 274 unsigned char resp[3];
272 275
276 if (quirk_min_max) {
277 priv->x_min = quirk_min_max[0];
278 priv->x_max = quirk_min_max[1];
279 priv->y_min = quirk_min_max[2];
280 priv->y_max = quirk_min_max[3];
281 return 0;
282 }
283
273 if (SYN_ID_MAJOR(priv->identity) < 4) 284 if (SYN_ID_MAJOR(priv->identity) < 4)
274 return 0; 285 return 0;
275 286
@@ -1485,10 +1496,46 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = {
1485 { } 1496 { }
1486}; 1497};
1487 1498
1499static const struct dmi_system_id min_max_dmi_table[] __initconst = {
1500#if defined(CONFIG_DMI)
1501 {
1502 /* Lenovo ThinkPad Helix */
1503 .matches = {
1504 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1505 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"),
1506 },
1507 .driver_data = (int []){1024, 5052, 2258, 4832},
1508 },
1509 {
1510 /* Lenovo ThinkPad T440s */
1511 .matches = {
1512 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1513 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"),
1514 },
1515 .driver_data = (int []){1024, 5112, 2024, 4832},
1516 },
1517 {
1518 /* Lenovo ThinkPad T540p */
1519 .matches = {
1520 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
1521 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"),
1522 },
1523 .driver_data = (int []){1024, 5056, 2058, 4832},
1524 },
1525#endif
1526 { }
1527};
1528
1488void __init synaptics_module_init(void) 1529void __init synaptics_module_init(void)
1489{ 1530{
1531 const struct dmi_system_id *min_max_dmi;
1532
1490 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); 1533 impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table);
1491 broken_olpc_ec = dmi_check_system(olpc_dmi_table); 1534 broken_olpc_ec = dmi_check_system(olpc_dmi_table);
1535
1536 min_max_dmi = dmi_first_match(min_max_dmi_table);
1537 if (min_max_dmi)
1538 quirk_min_max = min_max_dmi->driver_data;
1492} 1539}
1493 1540
1494static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) 1541static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode)