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 /drivers/hid | |
| 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>
Diffstat (limited to 'drivers/hid')
| -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 | /* |
