diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/elantech.c | 27 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.h | 1 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 105 |
3 files changed, 130 insertions, 3 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ef1cf52f8bb9..b96e978a37b7 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/dmi.h> | ||
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/input.h> | 17 | #include <linux/input.h> |
@@ -831,7 +832,11 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
831 | break; | 832 | break; |
832 | 833 | ||
833 | case 3: | 834 | case 3: |
834 | etd->reg_10 = 0x0b; | 835 | if (etd->set_hw_resolution) |
836 | etd->reg_10 = 0x0b; | ||
837 | else | ||
838 | etd->reg_10 = 0x03; | ||
839 | |||
835 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) | 840 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) |
836 | rc = -1; | 841 | rc = -1; |
837 | 842 | ||
@@ -1331,6 +1336,22 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1331 | } | 1336 | } |
1332 | 1337 | ||
1333 | /* | 1338 | /* |
1339 | * Some hw_version 3 models go into error state when we try to set bit 3 of r10 | ||
1340 | */ | ||
1341 | static const struct dmi_system_id no_hw_res_dmi_table[] = { | ||
1342 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1343 | { | ||
1344 | /* Gigabyte U2442 */ | ||
1345 | .matches = { | ||
1346 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
1347 | DMI_MATCH(DMI_PRODUCT_NAME, "U2442"), | ||
1348 | }, | ||
1349 | }, | ||
1350 | #endif | ||
1351 | { } | ||
1352 | }; | ||
1353 | |||
1354 | /* | ||
1334 | * determine hardware version and set some properties according to it. | 1355 | * determine hardware version and set some properties according to it. |
1335 | */ | 1356 | */ |
1336 | static int elantech_set_properties(struct elantech_data *etd) | 1357 | static int elantech_set_properties(struct elantech_data *etd) |
@@ -1353,6 +1374,7 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1353 | case 6: | 1374 | case 6: |
1354 | case 7: | 1375 | case 7: |
1355 | case 8: | 1376 | case 8: |
1377 | case 9: | ||
1356 | etd->hw_version = 4; | 1378 | etd->hw_version = 4; |
1357 | break; | 1379 | break; |
1358 | default: | 1380 | default: |
@@ -1389,6 +1411,9 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1389 | */ | 1411 | */ |
1390 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); | 1412 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); |
1391 | 1413 | ||
1414 | /* Enable real hardware resolution on hw_version 3 ? */ | ||
1415 | etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); | ||
1416 | |||
1392 | return 0; | 1417 | return 0; |
1393 | } | 1418 | } |
1394 | 1419 | ||
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 { | |||
130 | bool jumpy_cursor; | 130 | bool jumpy_cursor; |
131 | bool reports_pressure; | 131 | bool reports_pressure; |
132 | bool crc_enabled; | 132 | bool crc_enabled; |
133 | bool set_hw_resolution; | ||
133 | unsigned char hw_version; | 134 | unsigned char hw_version; |
134 | unsigned int fw_version; | 135 | unsigned int fw_version; |
135 | unsigned int single_finger_reports; | 136 | unsigned int single_finger_reports; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d8d49d10f9bb..d68d33fb5ac2 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -117,6 +117,44 @@ void synaptics_reset(struct psmouse *psmouse) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | 119 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS |
120 | /* This list has been kindly provided by Synaptics. */ | ||
121 | static const char * const topbuttonpad_pnp_ids[] = { | ||
122 | "LEN0017", | ||
123 | "LEN0018", | ||
124 | "LEN0019", | ||
125 | "LEN0023", | ||
126 | "LEN002A", | ||
127 | "LEN002B", | ||
128 | "LEN002C", | ||
129 | "LEN002D", | ||
130 | "LEN002E", | ||
131 | "LEN0033", /* Helix */ | ||
132 | "LEN0034", /* T431s, T540, X1 Carbon 2nd */ | ||
133 | "LEN0035", /* X240 */ | ||
134 | "LEN0036", /* T440 */ | ||
135 | "LEN0037", | ||
136 | "LEN0038", | ||
137 | "LEN0041", | ||
138 | "LEN0042", /* Yoga */ | ||
139 | "LEN0045", | ||
140 | "LEN0046", | ||
141 | "LEN0047", | ||
142 | "LEN0048", | ||
143 | "LEN0049", | ||
144 | "LEN2000", | ||
145 | "LEN2001", | ||
146 | "LEN2002", | ||
147 | "LEN2003", | ||
148 | "LEN2004", /* L440 */ | ||
149 | "LEN2005", | ||
150 | "LEN2006", | ||
151 | "LEN2007", | ||
152 | "LEN2008", | ||
153 | "LEN2009", | ||
154 | "LEN200A", | ||
155 | "LEN200B", | ||
156 | NULL | ||
157 | }; | ||
120 | 158 | ||
121 | /***************************************************************************** | 159 | /***************************************************************************** |
122 | * Synaptics communications functions | 160 | * Synaptics communications functions |
@@ -1255,8 +1293,10 @@ static void set_abs_position_params(struct input_dev *dev, | |||
1255 | input_abs_set_res(dev, y_code, priv->y_res); | 1293 | input_abs_set_res(dev, y_code, priv->y_res); |
1256 | } | 1294 | } |
1257 | 1295 | ||
1258 | static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | 1296 | static void set_input_params(struct psmouse *psmouse, |
1297 | struct synaptics_data *priv) | ||
1259 | { | 1298 | { |
1299 | struct input_dev *dev = psmouse->dev; | ||
1260 | int i; | 1300 | int i; |
1261 | 1301 | ||
1262 | /* Things that apply to both modes */ | 1302 | /* Things that apply to both modes */ |
@@ -1325,6 +1365,17 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1325 | 1365 | ||
1326 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { | 1366 | if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { |
1327 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | 1367 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
1368 | /* See if this buttonpad has a top button area */ | ||
1369 | if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) { | ||
1370 | for (i = 0; topbuttonpad_pnp_ids[i]; i++) { | ||
1371 | if (strstr(psmouse->ps2dev.serio->firmware_id, | ||
1372 | topbuttonpad_pnp_ids[i])) { | ||
1373 | __set_bit(INPUT_PROP_TOPBUTTONPAD, | ||
1374 | dev->propbit); | ||
1375 | break; | ||
1376 | } | ||
1377 | } | ||
1378 | } | ||
1328 | /* Clickpads report only left button */ | 1379 | /* Clickpads report only left button */ |
1329 | __clear_bit(BTN_RIGHT, dev->keybit); | 1380 | __clear_bit(BTN_RIGHT, dev->keybit); |
1330 | __clear_bit(BTN_MIDDLE, dev->keybit); | 1381 | __clear_bit(BTN_MIDDLE, dev->keybit); |
@@ -1515,6 +1566,22 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { | |||
1515 | .driver_data = (int []){1232, 5710, 1156, 4696}, | 1566 | .driver_data = (int []){1232, 5710, 1156, 4696}, |
1516 | }, | 1567 | }, |
1517 | { | 1568 | { |
1569 | /* Lenovo ThinkPad Edge E431 */ | ||
1570 | .matches = { | ||
1571 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1572 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"), | ||
1573 | }, | ||
1574 | .driver_data = (int []){1024, 5022, 2508, 4832}, | ||
1575 | }, | ||
1576 | { | ||
1577 | /* Lenovo ThinkPad T431s */ | ||
1578 | .matches = { | ||
1579 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1580 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"), | ||
1581 | }, | ||
1582 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
1583 | }, | ||
1584 | { | ||
1518 | /* Lenovo ThinkPad T440s */ | 1585 | /* Lenovo ThinkPad T440s */ |
1519 | .matches = { | 1586 | .matches = { |
1520 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 1587 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -1523,6 +1590,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { | |||
1523 | .driver_data = (int []){1024, 5112, 2024, 4832}, | 1590 | .driver_data = (int []){1024, 5112, 2024, 4832}, |
1524 | }, | 1591 | }, |
1525 | { | 1592 | { |
1593 | /* Lenovo ThinkPad L440 */ | ||
1594 | .matches = { | ||
1595 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1596 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"), | ||
1597 | }, | ||
1598 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
1599 | }, | ||
1600 | { | ||
1526 | /* Lenovo ThinkPad T540p */ | 1601 | /* Lenovo ThinkPad T540p */ |
1527 | .matches = { | 1602 | .matches = { |
1528 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 1603 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
@@ -1530,6 +1605,32 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { | |||
1530 | }, | 1605 | }, |
1531 | .driver_data = (int []){1024, 5056, 2058, 4832}, | 1606 | .driver_data = (int []){1024, 5056, 2058, 4832}, |
1532 | }, | 1607 | }, |
1608 | { | ||
1609 | /* Lenovo ThinkPad L540 */ | ||
1610 | .matches = { | ||
1611 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1612 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"), | ||
1613 | }, | ||
1614 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
1615 | }, | ||
1616 | { | ||
1617 | /* Lenovo Yoga S1 */ | ||
1618 | .matches = { | ||
1619 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1620 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, | ||
1621 | "ThinkPad S1 Yoga"), | ||
1622 | }, | ||
1623 | .driver_data = (int []){1232, 5710, 1156, 4696}, | ||
1624 | }, | ||
1625 | { | ||
1626 | /* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */ | ||
1627 | .matches = { | ||
1628 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1629 | DMI_MATCH(DMI_PRODUCT_VERSION, | ||
1630 | "ThinkPad X1 Carbon 2nd"), | ||
1631 | }, | ||
1632 | .driver_data = (int []){1024, 5112, 2024, 4832}, | ||
1633 | }, | ||
1533 | #endif | 1634 | #endif |
1534 | { } | 1635 | { } |
1535 | }; | 1636 | }; |
@@ -1593,7 +1694,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | |||
1593 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c, | 1694 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c, |
1594 | priv->board_id, priv->firmware_id); | 1695 | priv->board_id, priv->firmware_id); |
1595 | 1696 | ||
1596 | set_input_params(psmouse->dev, priv); | 1697 | set_input_params(psmouse, priv); |
1597 | 1698 | ||
1598 | /* | 1699 | /* |
1599 | * Encode touchpad model so that it can be used to set | 1700 | * Encode touchpad model so that it can be used to set |