]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
HID: wacom: Move handling of HID quirks into a dedicated function
authorJason Gerecke <killertofu@gmail.com>
Mon, 25 Jun 2018 20:24:35 +0000 (13:24 -0700)
committerJiri Kosina <jkosina@suse.cz>
Tue, 3 Jul 2018 10:07:52 +0000 (12:07 +0200)
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>
drivers/hid/wacom_sys.c

index 6b67c6907caa34d25626721924ce6f75e456fe96..3a4cf2666a7c13c662005ce77824906c3bdb92b3 100644 (file)
@@ -210,6 +210,57 @@ static int wacom_calc_hid_res(int logical_extents, int physical_extents,
        return hidinput_calc_abs_res(&field, ABS_X);
 }
 
+static void wacom_hid_usage_quirk(struct hid_device *hdev,
+               struct hid_field *field, struct hid_usage *usage)
+{
+       struct wacom *wacom = hid_get_drvdata(hdev);
+       struct wacom_features *features = &wacom->wacom_wac.features;
+       unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
+
+       /*
+        * The Dell Canvas 27 needs to be switched to its vendor-defined
+        * report to provide the best resolution.
+        */
+       if (hdev->vendor == USB_VENDOR_ID_WACOM &&
+           hdev->product == 0x4200 &&
+           field->application == HID_UP_MSVENDOR) {
+               wacom->wacom_wac.mode_report = field->report->id;
+               wacom->wacom_wac.mode_value = 2;
+       }
+
+       /*
+        * ISDv4 devices which predate HID's adoption of the
+        * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its
+        * position instead. We can accurately detect if a
+        * usage with that value should be HID_DG_BARRELSWITCH2
+        * based on the surrounding usages, which have remained
+        * constant across generations.
+        */
+       if (features->type == HID_GENERIC &&
+           usage->hid == 0x000D0000 &&
+           field->application == HID_DG_PEN &&
+           field->physical == HID_DG_STYLUS) {
+               int i = usage->usage_index;
+
+               if (i-4 >= 0 && i+1 < field->maxusage &&
+                   field->usage[i-4].hid == HID_DG_TIPSWITCH &&
+                   field->usage[i-3].hid == HID_DG_BARRELSWITCH &&
+                   field->usage[i-2].hid == HID_DG_ERASER &&
+                   field->usage[i-1].hid == HID_DG_INVERT &&
+                   field->usage[i+1].hid == HID_DG_INRANGE) {
+                       usage->hid = HID_DG_BARRELSWITCH2;
+               }
+       }
+
+       /* 2nd-generation Intuos Pro Large has incorrect Y maximum */
+       if (hdev->vendor == USB_VENDOR_ID_WACOM &&
+           hdev->product == 0x0358 &&
+           WACOM_PEN_FIELD(field) &&
+           equivalent_usage == HID_GD_Y) {
+               field->logical_maximum = 43200;
+       }
+}
+
 static void wacom_feature_mapping(struct hid_device *hdev,
                struct hid_field *field, struct hid_usage *usage)
 {
@@ -221,6 +272,8 @@ static void wacom_feature_mapping(struct hid_device *hdev,
        int ret;
        u32 n;
 
+       wacom_hid_usage_quirk(hdev, field, usage);
+
        switch (equivalent_usage) {
        case HID_DG_CONTACTMAX:
                /* leave touch_max as is if predefined */
@@ -300,13 +353,6 @@ static void wacom_feature_mapping(struct hid_device *hdev,
                kfree(data);
                break;
        }
-
-       if (hdev->vendor == USB_VENDOR_ID_WACOM &&
-           hdev->product == 0x4200 /* Dell Canvas 27 */ &&
-           field->application == HID_UP_MSVENDOR) {
-               wacom->wacom_wac.mode_report = field->report->id;
-               wacom->wacom_wac.mode_value = 2;
-       }
 }
 
 /*
@@ -361,37 +407,7 @@ static void wacom_usage_mapping(struct hid_device *hdev,
        else
                return;
 
-       /*
-        * ISDv4 devices which predate HID's adoption of the
-        * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its
-        * position instead. We can accurately detect if a
-        * usage with that value should be HID_DG_BARRELSWITCH2
-        * based on the surrounding usages, which have remained
-        * constant across generations.
-        */
-       if (features->type == HID_GENERIC &&
-           usage->hid == 0x000D0000 &&
-           field->application == HID_DG_PEN &&
-           field->physical == HID_DG_STYLUS) {
-               int i = usage->usage_index;
-
-               if (i-4 >= 0 && i+1 < field->maxusage &&
-                   field->usage[i-4].hid == HID_DG_TIPSWITCH &&
-                   field->usage[i-3].hid == HID_DG_BARRELSWITCH &&
-                   field->usage[i-2].hid == HID_DG_ERASER &&
-                   field->usage[i-1].hid == HID_DG_INVERT &&
-                   field->usage[i+1].hid == HID_DG_INRANGE) {
-                       usage->hid = HID_DG_BARRELSWITCH2;
-               }
-       }
-
-       /* 2nd-generation Intuos Pro Large has incorrect Y maximum */
-       if (hdev->vendor == USB_VENDOR_ID_WACOM &&
-           hdev->product == 0x0358 &&
-           WACOM_PEN_FIELD(field) &&
-           wacom_equivalent_usage(usage->hid) == HID_GD_Y) {
-               field->logical_maximum = 43200;
-       }
+       wacom_hid_usage_quirk(hdev, field, usage);
 
        switch (usage->hid) {
        case HID_GD_X: