aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIoan-Adrian Ratiu <adi@adirat.com>2016-09-27 14:41:38 -0400
committerJiri Kosina <jkosina@suse.cz>2016-10-10 04:52:00 -0400
commite15944099870f374ca7efc62f98cf23ba272ef43 (patch)
tree143de2a9a03a73bf91b6fd29ad0e8c157d92b819
parent3d1355b3cfad53feba76a73b052c757a7de7f4de (diff)
HID: hid-dr: add input mapping for axis selection
Commit 79346d620e9d ("HID: input: force generic axis to be mapped to their user space axis") made mapping generic axes to their userspace equivalents mandatory and some lower end gamepads which were depending on the previous behaviour suffered severe regressions because they were reusing axes and expecting hid-input to multiplex their map to the respective userspace axis by always searching for and using the next available axis. One solution is to add a hid quirk for this type of "previous" behaviour in hid-input to bypass the new axes policy in favour of the old one, but since only one hardware vendor seems to be affected negatively we're better off making and exception and mapping in the driver for now; if more vendors or drivers turn out to experience the problem we should reconsider the quirk solution. Signed-off-by: Ioan-Adrian Ratiu <adi@adirat.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-dr.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c
index 8fd4bf77f264..0ed843939b2c 100644
--- a/drivers/hid/hid-dr.c
+++ b/drivers/hid/hid-dr.c
@@ -306,6 +306,30 @@ static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
306 return rdesc; 306 return rdesc;
307} 307}
308 308
309#define map_abs(c) hid_map_usage(hi, usage, bit, max, EV_ABS, (c))
310#define map_rel(c) hid_map_usage(hi, usage, bit, max, EV_REL, (c))
311
312static int dr_input_mapping(struct hid_device *hdev, struct hid_input *hi,
313 struct hid_field *field, struct hid_usage *usage,
314 unsigned long **bit, int *max)
315{
316 switch (usage->hid) {
317 /*
318 * revert to the old hid-input behavior where axes
319 * can be randomly assigned when hid->usage is reused.
320 */
321 case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
322 case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ:
323 if (field->flags & HID_MAIN_ITEM_RELATIVE)
324 map_rel(usage->hid & 0xf);
325 else
326 map_abs(usage->hid & 0xf);
327 return 1;
328 }
329
330 return 0;
331}
332
309static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) 333static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
310{ 334{
311 int ret; 335 int ret;
@@ -352,6 +376,7 @@ static struct hid_driver dr_driver = {
352 .id_table = dr_devices, 376 .id_table = dr_devices,
353 .report_fixup = dr_report_fixup, 377 .report_fixup = dr_report_fixup,
354 .probe = dr_probe, 378 .probe = dr_probe,
379 .input_mapping = dr_input_mapping,
355}; 380};
356module_hid_driver(dr_driver); 381module_hid_driver(dr_driver);
357 382