diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2017-04-04 15:32:07 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-04-12 06:41:16 -0400 |
commit | c6e3c6628dfbb9950f829e3f2803476f486abf17 (patch) | |
tree | 940c210f3a806b35484289af80dcb5a89464536d | |
parent | 68a83be3813507da97024decc4a48d347524bfd6 (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.c | 76 |
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 | ||
1207 | static void mt_remove(struct hid_device *hdev) | 1208 | static 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 | /* |