diff options
Diffstat (limited to 'drivers/input/mouse/elantech.c')
-rw-r--r-- | drivers/input/mouse/elantech.c | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 06fc6e76ffbe..3fcb6b3cb0bd 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -563,6 +563,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) | |||
563 | } else { | 563 | } else { |
564 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 564 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); |
565 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 565 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); |
566 | input_report_key(dev, BTN_MIDDLE, packet[0] & 0x04); | ||
566 | } | 567 | } |
567 | 568 | ||
568 | input_mt_report_pointer_emulation(dev, true); | 569 | input_mt_report_pointer_emulation(dev, true); |
@@ -792,6 +793,9 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) | |||
792 | unsigned char packet_type = packet[3] & 0x03; | 793 | unsigned char packet_type = packet[3] & 0x03; |
793 | bool sanity_check; | 794 | bool sanity_check; |
794 | 795 | ||
796 | if ((packet[3] & 0x0f) == 0x06) | ||
797 | return PACKET_TRACKPOINT; | ||
798 | |||
795 | /* | 799 | /* |
796 | * Sanity check based on the constant bits of a packet. | 800 | * Sanity check based on the constant bits of a packet. |
797 | * The constant bits change depending on the value of | 801 | * The constant bits change depending on the value of |
@@ -877,10 +881,19 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
877 | 881 | ||
878 | case 4: | 882 | case 4: |
879 | packet_type = elantech_packet_check_v4(psmouse); | 883 | packet_type = elantech_packet_check_v4(psmouse); |
880 | if (packet_type == PACKET_UNKNOWN) | 884 | switch (packet_type) { |
885 | case PACKET_UNKNOWN: | ||
881 | return PSMOUSE_BAD_DATA; | 886 | return PSMOUSE_BAD_DATA; |
882 | 887 | ||
883 | elantech_report_absolute_v4(psmouse, packet_type); | 888 | case PACKET_TRACKPOINT: |
889 | elantech_report_trackpoint(psmouse, packet_type); | ||
890 | break; | ||
891 | |||
892 | default: | ||
893 | elantech_report_absolute_v4(psmouse, packet_type); | ||
894 | break; | ||
895 | } | ||
896 | |||
884 | break; | 897 | break; |
885 | } | 898 | } |
886 | 899 | ||
@@ -1120,6 +1133,22 @@ static void elantech_set_buttonpad_prop(struct psmouse *psmouse) | |||
1120 | } | 1133 | } |
1121 | 1134 | ||
1122 | /* | 1135 | /* |
1136 | * Some hw_version 4 models do have a middle button | ||
1137 | */ | ||
1138 | static const struct dmi_system_id elantech_dmi_has_middle_button[] = { | ||
1139 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1140 | { | ||
1141 | /* Fujitsu H730 has a middle button */ | ||
1142 | .matches = { | ||
1143 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
1144 | DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), | ||
1145 | }, | ||
1146 | }, | ||
1147 | #endif | ||
1148 | { } | ||
1149 | }; | ||
1150 | |||
1151 | /* | ||
1123 | * Set the appropriate event bits for the input subsystem | 1152 | * Set the appropriate event bits for the input subsystem |
1124 | */ | 1153 | */ |
1125 | static int elantech_set_input_params(struct psmouse *psmouse) | 1154 | static int elantech_set_input_params(struct psmouse *psmouse) |
@@ -1138,6 +1167,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
1138 | __clear_bit(EV_REL, dev->evbit); | 1167 | __clear_bit(EV_REL, dev->evbit); |
1139 | 1168 | ||
1140 | __set_bit(BTN_LEFT, dev->keybit); | 1169 | __set_bit(BTN_LEFT, dev->keybit); |
1170 | if (dmi_check_system(elantech_dmi_has_middle_button)) | ||
1171 | __set_bit(BTN_MIDDLE, dev->keybit); | ||
1141 | __set_bit(BTN_RIGHT, dev->keybit); | 1172 | __set_bit(BTN_RIGHT, dev->keybit); |
1142 | 1173 | ||
1143 | __set_bit(BTN_TOUCH, dev->keybit); | 1174 | __set_bit(BTN_TOUCH, dev->keybit); |
@@ -1299,6 +1330,7 @@ ELANTECH_INT_ATTR(reg_25, 0x25); | |||
1299 | ELANTECH_INT_ATTR(reg_26, 0x26); | 1330 | ELANTECH_INT_ATTR(reg_26, 0x26); |
1300 | ELANTECH_INT_ATTR(debug, 0); | 1331 | ELANTECH_INT_ATTR(debug, 0); |
1301 | ELANTECH_INT_ATTR(paritycheck, 0); | 1332 | ELANTECH_INT_ATTR(paritycheck, 0); |
1333 | ELANTECH_INT_ATTR(crc_enabled, 0); | ||
1302 | 1334 | ||
1303 | static struct attribute *elantech_attrs[] = { | 1335 | static struct attribute *elantech_attrs[] = { |
1304 | &psmouse_attr_reg_07.dattr.attr, | 1336 | &psmouse_attr_reg_07.dattr.attr, |
@@ -1313,6 +1345,7 @@ static struct attribute *elantech_attrs[] = { | |||
1313 | &psmouse_attr_reg_26.dattr.attr, | 1345 | &psmouse_attr_reg_26.dattr.attr, |
1314 | &psmouse_attr_debug.dattr.attr, | 1346 | &psmouse_attr_debug.dattr.attr, |
1315 | &psmouse_attr_paritycheck.dattr.attr, | 1347 | &psmouse_attr_paritycheck.dattr.attr, |
1348 | &psmouse_attr_crc_enabled.dattr.attr, | ||
1316 | NULL | 1349 | NULL |
1317 | }; | 1350 | }; |
1318 | 1351 | ||
@@ -1439,6 +1472,22 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1439 | } | 1472 | } |
1440 | 1473 | ||
1441 | /* | 1474 | /* |
1475 | * Some hw_version 4 models do not work with crc_disabled | ||
1476 | */ | ||
1477 | static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { | ||
1478 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1479 | { | ||
1480 | /* Fujitsu H730 does not work with crc_enabled == 0 */ | ||
1481 | .matches = { | ||
1482 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
1483 | DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"), | ||
1484 | }, | ||
1485 | }, | ||
1486 | #endif | ||
1487 | { } | ||
1488 | }; | ||
1489 | |||
1490 | /* | ||
1442 | * Some hw_version 3 models go into error state when we try to set | 1491 | * Some hw_version 3 models go into error state when we try to set |
1443 | * bit 3 and/or bit 1 of r10. | 1492 | * bit 3 and/or bit 1 of r10. |
1444 | */ | 1493 | */ |
@@ -1513,7 +1562,8 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1513 | * The signatures of v3 and v4 packets change depending on the | 1562 | * The signatures of v3 and v4 packets change depending on the |
1514 | * value of this hardware flag. | 1563 | * value of this hardware flag. |
1515 | */ | 1564 | */ |
1516 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); | 1565 | etd->crc_enabled = (etd->fw_version & 0x4000) == 0x4000 || |
1566 | dmi_check_system(elantech_dmi_force_crc_enabled); | ||
1517 | 1567 | ||
1518 | /* Enable real hardware resolution on hw_version 3 ? */ | 1568 | /* Enable real hardware resolution on hw_version 3 ? */ |
1519 | etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); | 1569 | etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); |