diff options
| -rw-r--r-- | drivers/input/mouse/synaptics.c | 149 |
1 files changed, 36 insertions, 113 deletions
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 395ec9c5ae9a..c5ec703c727e 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -117,6 +117,31 @@ void synaptics_reset(struct psmouse *psmouse) | |||
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
| 120 | struct min_max_quirk { | ||
| 121 | const char * const *pnp_ids; | ||
| 122 | int x_min, x_max, y_min, y_max; | ||
| 123 | }; | ||
| 124 | |||
| 125 | static const struct min_max_quirk min_max_pnpid_table[] = { | ||
| 126 | { | ||
| 127 | (const char * const []){"LEN0033", NULL}, | ||
| 128 | 1024, 5052, 2258, 4832 | ||
| 129 | }, | ||
| 130 | { | ||
| 131 | (const char * const []){"LEN0035", "LEN0042", NULL}, | ||
| 132 | 1232, 5710, 1156, 4696 | ||
| 133 | }, | ||
| 134 | { | ||
| 135 | (const char * const []){"LEN0034", "LEN0036", "LEN2004", NULL}, | ||
| 136 | 1024, 5112, 2024, 4832 | ||
| 137 | }, | ||
| 138 | { | ||
| 139 | (const char * const []){"LEN2001", NULL}, | ||
| 140 | 1024, 5022, 2508, 4832 | ||
| 141 | }, | ||
| 142 | { } | ||
| 143 | }; | ||
| 144 | |||
| 120 | /* This list has been kindly provided by Synaptics. */ | 145 | /* This list has been kindly provided by Synaptics. */ |
| 121 | static const char * const topbuttonpad_pnp_ids[] = { | 146 | static const char * const topbuttonpad_pnp_ids[] = { |
| 122 | "LEN0017", | 147 | "LEN0017", |
| @@ -129,7 +154,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
| 129 | "LEN002D", | 154 | "LEN002D", |
| 130 | "LEN002E", | 155 | "LEN002E", |
| 131 | "LEN0033", /* Helix */ | 156 | "LEN0033", /* Helix */ |
| 132 | "LEN0034", /* T431s, T540, X1 Carbon 2nd */ | 157 | "LEN0034", /* T431s, L440, L540, T540, W540, X1 Carbon 2nd */ |
| 133 | "LEN0035", /* X240 */ | 158 | "LEN0035", /* X240 */ |
| 134 | "LEN0036", /* T440 */ | 159 | "LEN0036", /* T440 */ |
| 135 | "LEN0037", | 160 | "LEN0037", |
| @@ -142,7 +167,7 @@ static const char * const topbuttonpad_pnp_ids[] = { | |||
| 142 | "LEN0048", | 167 | "LEN0048", |
| 143 | "LEN0049", | 168 | "LEN0049", |
| 144 | "LEN2000", | 169 | "LEN2000", |
| 145 | "LEN2001", | 170 | "LEN2001", /* Edge E431 */ |
| 146 | "LEN2002", | 171 | "LEN2002", |
| 147 | "LEN2003", | 172 | "LEN2003", |
| 148 | "LEN2004", /* L440 */ | 173 | "LEN2004", /* L440 */ |
| @@ -316,20 +341,20 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
| 316 | * Resolution is left zero if touchpad does not support the query | 341 | * Resolution is left zero if touchpad does not support the query |
| 317 | */ | 342 | */ |
| 318 | 343 | ||
| 319 | static const int *quirk_min_max; | ||
| 320 | |||
| 321 | static int synaptics_resolution(struct psmouse *psmouse) | 344 | static int synaptics_resolution(struct psmouse *psmouse) |
| 322 | { | 345 | { |
| 323 | struct synaptics_data *priv = psmouse->private; | 346 | struct synaptics_data *priv = psmouse->private; |
| 324 | unsigned char resp[3]; | 347 | unsigned char resp[3]; |
| 348 | int i; | ||
| 325 | 349 | ||
| 326 | if (quirk_min_max) { | 350 | for (i = 0; min_max_pnpid_table[i].pnp_ids; i++) |
| 327 | priv->x_min = quirk_min_max[0]; | 351 | if (matches_pnp_id(psmouse, min_max_pnpid_table[i].pnp_ids)) { |
| 328 | priv->x_max = quirk_min_max[1]; | 352 | priv->x_min = min_max_pnpid_table[i].x_min; |
| 329 | priv->y_min = quirk_min_max[2]; | 353 | priv->x_max = min_max_pnpid_table[i].x_max; |
| 330 | priv->y_max = quirk_min_max[3]; | 354 | priv->y_min = min_max_pnpid_table[i].y_min; |
| 331 | return 0; | 355 | priv->y_max = min_max_pnpid_table[i].y_max; |
| 332 | } | 356 | return 0; |
| 357 | } | ||
| 333 | 358 | ||
| 334 | if (SYN_ID_MAJOR(priv->identity) < 4) | 359 | if (SYN_ID_MAJOR(priv->identity) < 4) |
| 335 | return 0; | 360 | return 0; |
| @@ -1550,112 +1575,10 @@ static const struct dmi_system_id olpc_dmi_table[] __initconst = { | |||
| 1550 | { } | 1575 | { } |
| 1551 | }; | 1576 | }; |
| 1552 | 1577 | ||
| 1553 | static const struct dmi_system_id min_max_dmi_table[] __initconst = { | ||
| 1554 | #if defined(CONFIG_DMI) | ||
| 1555 | { | ||
| 1556 | /* Lenovo ThinkPad Helix */ | ||
| 1557 | .matches = { | ||
| 1558 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1559 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Helix"), | ||
| 1560 | }, | ||
| 1561 | .driver_data = (int []){1024, 5052, 2258, 4832}, | ||
| 1562 | }, | ||
| 1563 | { | ||
| 1564 | /* Lenovo ThinkPad X240 */ | ||
| 1565 | .matches = { | ||
| 1566 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1567 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X240"), | ||
| 1568 | }, | ||
| 1569 | .driver_data = (int []){1232, 5710, 1156, 4696}, | ||
| 1570 | }, | ||
| 1571 | { | ||
| 1572 | /* Lenovo ThinkPad Edge E431 */ | ||
| 1573 | .matches = { | ||
| 1574 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1575 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"), | ||
| 1576 | }, | ||
| 1577 | .driver_data = (int []){1024, 5022, 2508, 4832}, | ||
| 1578 | }, | ||
| 1579 | { | ||
| 1580 | /* Lenovo ThinkPad T431s */ | ||
| 1581 | .matches = { | ||
| 1582 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1583 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"), | ||
| 1584 | }, | ||
| 1585 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1586 | }, | ||
| 1587 | { | ||
| 1588 | /* Lenovo ThinkPad T440s */ | ||
| 1589 | .matches = { | ||
| 1590 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1591 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T440"), | ||
| 1592 | }, | ||
| 1593 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1594 | }, | ||
| 1595 | { | ||
| 1596 | /* Lenovo ThinkPad L440 */ | ||
| 1597 | .matches = { | ||
| 1598 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1599 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"), | ||
| 1600 | }, | ||
| 1601 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1602 | }, | ||
| 1603 | { | ||
| 1604 | /* Lenovo ThinkPad T540p */ | ||
| 1605 | .matches = { | ||
| 1606 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1607 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T540"), | ||
| 1608 | }, | ||
| 1609 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1610 | }, | ||
| 1611 | { | ||
| 1612 | /* Lenovo ThinkPad L540 */ | ||
| 1613 | .matches = { | ||
| 1614 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1615 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"), | ||
| 1616 | }, | ||
| 1617 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1618 | }, | ||
| 1619 | { | ||
| 1620 | /* Lenovo ThinkPad W540 */ | ||
| 1621 | .matches = { | ||
| 1622 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1623 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W540"), | ||
| 1624 | }, | ||
| 1625 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1626 | }, | ||
| 1627 | { | ||
| 1628 | /* Lenovo Yoga S1 */ | ||
| 1629 | .matches = { | ||
| 1630 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1631 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, | ||
| 1632 | "ThinkPad S1 Yoga"), | ||
| 1633 | }, | ||
| 1634 | .driver_data = (int []){1232, 5710, 1156, 4696}, | ||
| 1635 | }, | ||
| 1636 | { | ||
| 1637 | /* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */ | ||
| 1638 | .matches = { | ||
| 1639 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
| 1640 | DMI_MATCH(DMI_PRODUCT_VERSION, | ||
| 1641 | "ThinkPad X1 Carbon 2nd"), | ||
| 1642 | }, | ||
| 1643 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
| 1644 | }, | ||
| 1645 | #endif | ||
| 1646 | { } | ||
| 1647 | }; | ||
| 1648 | |||
| 1649 | void __init synaptics_module_init(void) | 1578 | void __init synaptics_module_init(void) |
| 1650 | { | 1579 | { |
| 1651 | const struct dmi_system_id *min_max_dmi; | ||
| 1652 | |||
| 1653 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 1580 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
| 1654 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 1581 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
| 1655 | |||
| 1656 | min_max_dmi = dmi_first_match(min_max_dmi_table); | ||
| 1657 | if (min_max_dmi) | ||
| 1658 | quirk_min_max = min_max_dmi->driver_data; | ||
| 1659 | } | 1582 | } |
| 1660 | 1583 | ||
| 1661 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 1584 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) |
