aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse/elantech.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse/elantech.c')
-rw-r--r--drivers/input/mouse/elantech.c56
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 */
1138static 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 */
1125static int elantech_set_input_params(struct psmouse *psmouse) 1154static 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);
1299ELANTECH_INT_ATTR(reg_26, 0x26); 1330ELANTECH_INT_ATTR(reg_26, 0x26);
1300ELANTECH_INT_ATTR(debug, 0); 1331ELANTECH_INT_ATTR(debug, 0);
1301ELANTECH_INT_ATTR(paritycheck, 0); 1332ELANTECH_INT_ATTR(paritycheck, 0);
1333ELANTECH_INT_ATTR(crc_enabled, 0);
1302 1334
1303static struct attribute *elantech_attrs[] = { 1335static 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 */
1477static 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);