aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2018-06-25 16:24:35 -0400
committerJiri Kosina <jkosina@suse.cz>2018-07-03 06:07:52 -0400
commit578325120ec122db98b3d57e833d16c1bdac6ec6 (patch)
tree90361f0498356e82d432cb9a141885a8b42ea366
parent29b9e14846f1ff201c4c1ba4fdb868dcdce6c760 (diff)
HID: wacom: Move handling of HID quirks into a dedicated function
We want to keep device-specific quirks as contained as possible so that the the code remains maintainable. Our 'wacom_setup_device_quirks' function is the usual place for this, but some quirks need to be applied to the HID descriptor as it is parsed. This commit introduces a new function which is called for each usage so that any HID-specific quirks can be applied. The function now houses quirks that were being done in 'wacom_feature_mapping' and 'wacom_usage_mapping'. Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com> Reviewed-by: Ping Cheng <ping.cheng@wacom.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/wacom_sys.c92
1 files changed, 54 insertions, 38 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 6b67c6907caa..3a4cf2666a7c 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -210,6 +210,57 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents,
210 return hidinput_calc_abs_res(&field, ABS_X); 210 return hidinput_calc_abs_res(&field, ABS_X);
211} 211}
212 212
213static void wacom_hid_usage_quirk(struct hid_device *hdev,
214 struct hid_field *field, struct hid_usage *usage)
215{
216 struct wacom *wacom = hid_get_drvdata(hdev);
217 struct wacom_features *features = &wacom->wacom_wac.features;
218 unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
219
220 /*
221 * The Dell Canvas 27 needs to be switched to its vendor-defined
222 * report to provide the best resolution.
223 */
224 if (hdev->vendor == USB_VENDOR_ID_WACOM &&
225 hdev->product == 0x4200 &&
226 field->application == HID_UP_MSVENDOR) {
227 wacom->wacom_wac.mode_report = field->report->id;
228 wacom->wacom_wac.mode_value = 2;
229 }
230
231 /*
232 * ISDv4 devices which predate HID's adoption of the
233 * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its
234 * position instead. We can accurately detect if a
235 * usage with that value should be HID_DG_BARRELSWITCH2
236 * based on the surrounding usages, which have remained
237 * constant across generations.
238 */
239 if (features->type == HID_GENERIC &&
240 usage->hid == 0x000D0000 &&
241 field->application == HID_DG_PEN &&
242 field->physical == HID_DG_STYLUS) {
243 int i = usage->usage_index;
244
245 if (i-4 >= 0 && i+1 < field->maxusage &&
246 field->usage[i-4].hid == HID_DG_TIPSWITCH &&
247 field->usage[i-3].hid == HID_DG_BARRELSWITCH &&
248 field->usage[i-2].hid == HID_DG_ERASER &&
249 field->usage[i-1].hid == HID_DG_INVERT &&
250 field->usage[i+1].hid == HID_DG_INRANGE) {
251 usage->hid = HID_DG_BARRELSWITCH2;
252 }
253 }
254
255 /* 2nd-generation Intuos Pro Large has incorrect Y maximum */
256 if (hdev->vendor == USB_VENDOR_ID_WACOM &&
257 hdev->product == 0x0358 &&
258 WACOM_PEN_FIELD(field) &&
259 equivalent_usage == HID_GD_Y) {
260 field->logical_maximum = 43200;
261 }
262}
263
213static void wacom_feature_mapping(struct hid_device *hdev, 264static void wacom_feature_mapping(struct hid_device *hdev,
214 struct hid_field *field, struct hid_usage *usage) 265 struct hid_field *field, struct hid_usage *usage)
215{ 266{
@@ -221,6 +272,8 @@ static void wacom_feature_mapping(struct hid_device *hdev,
221 int ret; 272 int ret;
222 u32 n; 273 u32 n;
223 274
275 wacom_hid_usage_quirk(hdev, field, usage);
276
224 switch (equivalent_usage) { 277 switch (equivalent_usage) {
225 case HID_DG_CONTACTMAX: 278 case HID_DG_CONTACTMAX:
226 /* leave touch_max as is if predefined */ 279 /* leave touch_max as is if predefined */
@@ -300,13 +353,6 @@ static void wacom_feature_mapping(struct hid_device *hdev,
300 kfree(data); 353 kfree(data);
301 break; 354 break;
302 } 355 }
303
304 if (hdev->vendor == USB_VENDOR_ID_WACOM &&
305 hdev->product == 0x4200 /* Dell Canvas 27 */ &&
306 field->application == HID_UP_MSVENDOR) {
307 wacom->wacom_wac.mode_report = field->report->id;
308 wacom->wacom_wac.mode_value = 2;
309 }
310} 356}
311 357
312/* 358/*
@@ -361,37 +407,7 @@ static void wacom_usage_mapping(struct hid_device *hdev,
361 else 407 else
362 return; 408 return;
363 409
364 /* 410 wacom_hid_usage_quirk(hdev, field, usage);
365 * ISDv4 devices which predate HID's adoption of the
366 * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its
367 * position instead. We can accurately detect if a
368 * usage with that value should be HID_DG_BARRELSWITCH2
369 * based on the surrounding usages, which have remained
370 * constant across generations.
371 */
372 if (features->type == HID_GENERIC &&
373 usage->hid == 0x000D0000 &&
374 field->application == HID_DG_PEN &&
375 field->physical == HID_DG_STYLUS) {
376 int i = usage->usage_index;
377
378 if (i-4 >= 0 && i+1 < field->maxusage &&
379 field->usage[i-4].hid == HID_DG_TIPSWITCH &&
380 field->usage[i-3].hid == HID_DG_BARRELSWITCH &&
381 field->usage[i-2].hid == HID_DG_ERASER &&
382 field->usage[i-1].hid == HID_DG_INVERT &&
383 field->usage[i+1].hid == HID_DG_INRANGE) {
384 usage->hid = HID_DG_BARRELSWITCH2;
385 }
386 }
387
388 /* 2nd-generation Intuos Pro Large has incorrect Y maximum */
389 if (hdev->vendor == USB_VENDOR_ID_WACOM &&
390 hdev->product == 0x0358 &&
391 WACOM_PEN_FIELD(field) &&
392 wacom_equivalent_usage(usage->hid) == HID_GD_Y) {
393 field->logical_maximum = 43200;
394 }
395 411
396 switch (usage->hid) { 412 switch (usage->hid) {
397 case HID_GD_X: 413 case HID_GD_X: