aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2017-04-04 15:32:07 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-12 06:41:16 -0400
commitc6e3c6628dfbb9950f829e3f2803476f486abf17 (patch)
tree940c210f3a806b35484289af80dcb5a89464536d
parent68a83be3813507da97024decc4a48d347524bfd6 (diff)
HID: multitouch: do not retrieve all reports for all devices
[ Upstream commit b897f6db3ae2cd9a42377f8b1865450f34ceff0e ] We already have in place a quirk for Windows 8 devices, but it looks like the Surface Cover are not conforming to it. Given that we are only interested in 3 feature reports (the ones that the Windows driver retrieves), we should be safe to unconditionally apply the quirk to everybody. In case there is an issue with a controller, we can always mark it as such in the transport driver, and hid-multitouch won't try to retrieve the feature report. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz> Signed-off-by: Sasha Levin <alexander.levin@verizon.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/hid/hid-multitouch.c76
1 files changed, 40 insertions, 36 deletions
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 84c56e645fe8..89e9032ab1e7 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -108,6 +108,7 @@ struct mt_device {
108 int cc_value_index; /* contact count value index in the field */ 108 int cc_value_index; /* contact count value index in the field */
109 unsigned last_slot_field; /* the last field of a slot */ 109 unsigned last_slot_field; /* the last field of a slot */
110 unsigned mt_report_id; /* the report ID of the multitouch device */ 110 unsigned mt_report_id; /* the report ID of the multitouch device */
111 unsigned long initial_quirks; /* initial quirks state */
111 __s16 inputmode; /* InputMode HID feature, -1 if non-existent */ 112 __s16 inputmode; /* InputMode HID feature, -1 if non-existent */
112 __s16 inputmode_index; /* InputMode HID feature index in the report */ 113 __s16 inputmode_index; /* InputMode HID feature index in the report */
113 __s16 maxcontact_report_id; /* Maximum Contact Number HID feature, 114 __s16 maxcontact_report_id; /* Maximum Contact Number HID feature,
@@ -318,13 +319,10 @@ static void mt_get_feature(struct hid_device *hdev, struct hid_report *report)
318 u8 *buf; 319 u8 *buf;
319 320
320 /* 321 /*
321 * Only fetch the feature report if initial reports are not already 322 * Do not fetch the feature report if the device has been explicitly
322 * been retrieved. Currently this is only done for Windows 8 touch 323 * marked as non-capable.
323 * devices.
324 */ 324 */
325 if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) 325 if (td->initial_quirks & HID_QUIRK_NO_INIT_REPORTS)
326 return;
327 if (td->mtclass.name != MT_CLS_WIN_8)
328 return; 326 return;
329 327
330 buf = hid_alloc_report_buf(report, GFP_KERNEL); 328 buf = hid_alloc_report_buf(report, GFP_KERNEL);
@@ -1085,36 +1083,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
1085 } 1083 }
1086 } 1084 }
1087 1085
1088 /* This allows the driver to correctly support devices
1089 * that emit events over several HID messages.
1090 */
1091 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
1092
1093 /*
1094 * This allows the driver to handle different input sensors
1095 * that emits events through different reports on the same HID
1096 * device.
1097 */
1098 hdev->quirks |= HID_QUIRK_MULTI_INPUT;
1099 hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
1100
1101 /*
1102 * Handle special quirks for Windows 8 certified devices.
1103 */
1104 if (id->group == HID_GROUP_MULTITOUCH_WIN_8)
1105 /*
1106 * Some multitouch screens do not like to be polled for input
1107 * reports. Fortunately, the Win8 spec says that all touches
1108 * should be sent during each report, making the initialization
1109 * of input reports unnecessary.
1110 *
1111 * In addition some touchpads do not behave well if we read
1112 * all feature reports from them. Instead we prevent
1113 * initial report fetching and then selectively fetch each
1114 * report we are interested in.
1115 */
1116 hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
1117
1118 td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); 1086 td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL);
1119 if (!td) { 1087 if (!td) {
1120 dev_err(&hdev->dev, "cannot allocate multitouch data\n"); 1088 dev_err(&hdev->dev, "cannot allocate multitouch data\n");
@@ -1138,6 +1106,39 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
1138 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID) 1106 if (id->vendor == HID_ANY_ID && id->product == HID_ANY_ID)
1139 td->serial_maybe = true; 1107 td->serial_maybe = true;
1140 1108
1109 /*
1110 * Store the initial quirk state
1111 */
1112 td->initial_quirks = hdev->quirks;
1113
1114 /* This allows the driver to correctly support devices
1115 * that emit events over several HID messages.
1116 */
1117 hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
1118
1119 /*
1120 * This allows the driver to handle different input sensors
1121 * that emits events through different reports on the same HID
1122 * device.
1123 */
1124 hdev->quirks |= HID_QUIRK_MULTI_INPUT;
1125 hdev->quirks |= HID_QUIRK_NO_EMPTY_INPUT;
1126
1127 /*
1128 * Some multitouch screens do not like to be polled for input
1129 * reports. Fortunately, the Win8 spec says that all touches
1130 * should be sent during each report, making the initialization
1131 * of input reports unnecessary. For Win7 devices, well, let's hope
1132 * they will still be happy (this is only be a problem if a touch
1133 * was already there while probing the device).
1134 *
1135 * In addition some touchpads do not behave well if we read
1136 * all feature reports from them. Instead we prevent
1137 * initial report fetching and then selectively fetch each
1138 * report we are interested in.
1139 */
1140 hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
1141
1141 ret = hid_parse(hdev); 1142 ret = hid_parse(hdev);
1142 if (ret != 0) 1143 if (ret != 0)
1143 return ret; 1144 return ret;
@@ -1206,8 +1207,11 @@ static int mt_resume(struct hid_device *hdev)
1206 1207
1207static void mt_remove(struct hid_device *hdev) 1208static void mt_remove(struct hid_device *hdev)
1208{ 1209{
1210 struct mt_device *td = hid_get_drvdata(hdev);
1211
1209 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 1212 sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
1210 hid_hw_stop(hdev); 1213 hid_hw_stop(hdev);
1214 hdev->quirks = td->initial_quirks;
1211} 1215}
1212 1216
1213/* 1217/*