diff options
author | Jason Gerecke <killertofu@gmail.com> | 2018-06-25 16:24:35 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-07-03 06:07:52 -0400 |
commit | 578325120ec122db98b3d57e833d16c1bdac6ec6 (patch) | |
tree | 90361f0498356e82d432cb9a141885a8b42ea366 | |
parent | 29b9e14846f1ff201c4c1ba4fdb868dcdce6c760 (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.c | 92 |
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 | ||
213 | static 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 | |||
213 | static void wacom_feature_mapping(struct hid_device *hdev, | 264 | static 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: |