Many of Wacom's display tablets include an "outbound" area where pen
digitizing is possible but outside of the display area. To accommodate
such sensors in the HID_GENERIC codepath, we add support for the
necessary vendor-defined HID feature usages and adjust the min/max
values of the X and Y axes accordingly, similar to what is done in
the non-generic codepath.

Signed-off-by: Jason Gerecke <jason.gere...@wacom.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com>
[jason.gere...@wacom.com: Imported into input-wacom repository (345857b)]
Signed-off-by: Jason Gerecke <jason.gere...@wacom.com>
[jason.gere...@wacom.com: backported from input-wacom repository (e388fb1)]
Signed-off-by: Jason Gerecke <jason.gere...@wacom.com>
---
 3.17/wacom_sys.c | 47 +++++++++++++++++++++++++++++++++++++----------
 3.17/wacom_wac.c | 40 ++++++++++++++++++++++++++++++++++++++++
 3.17/wacom_wac.h |  4 ++++
 3 files changed, 81 insertions(+), 10 deletions(-)

diff --git a/3.17/wacom_sys.c b/3.17/wacom_sys.c
index 2c34297..80f07ee 100644
--- a/3.17/wacom_sys.c
+++ b/3.17/wacom_sys.c
@@ -122,6 +122,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
        struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
        u8 *data;
        int ret;
+       int n;
 
        switch (usage->hid) {
        case HID_DG_CONTACTMAX:
@@ -180,6 +181,31 @@ static void wacom_feature_mapping(struct hid_device *hdev,
                        wacom->wacom_wac.mode_value = 0;
                }
                break;
+       case WACOM_HID_WD_OFFSETLEFT:
+       case WACOM_HID_WD_OFFSETTOP:
+       case WACOM_HID_WD_OFFSETRIGHT:
+       case WACOM_HID_WD_OFFSETBOTTOM:
+               /* read manually */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
+               n = wacom_hid_report_len(field->report);
+#else
+               n = hid_report_len(field->report);
+#endif
+               data = hid_alloc_report_buf(field->report, GFP_KERNEL);
+               if (!data)
+                       break;
+               data[0] = field->report->id;
+               ret = wacom_get_report(hdev, HID_FEATURE_REPORT,
+                                       data, n, WAC_CMD_RETRIES);
+               if (ret == n) {
+                       ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT,
+                                                  data, n, 0);
+               } else {
+                       hid_warn(hdev, "%s: could not retrieve sensor 
offsets\n",
+                                __func__);
+               }
+               kfree(data);
+               break;
        }
 }
 
@@ -722,11 +748,6 @@ static int wacom_add_shared_data(struct hid_device *hdev)
                return retval;
        }
 
-       if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
-               wacom_wac->shared->touch = hdev;
-       else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
-               wacom_wac->shared->pen = hdev;
-
 out:
        mutex_unlock(&wacom_udev_list_lock);
        return retval;
@@ -1844,6 +1865,10 @@ static int wacom_parse_and_register(struct wacom *wacom, 
bool wireless)
        if (error)
                goto fail_open_group;
 
+       error = wacom_add_shared_data(hdev);
+       if (error)
+               goto fail_allocate_inputs;
+
        /*
         * Bamboo Pad has a generic hid handling for the Pen, and we switch it
         * into debug mode for the touch part.
@@ -1855,7 +1880,7 @@ static int wacom_parse_and_register(struct wacom *wacom, 
bool wireless)
                } else if ((features->pktlen != WACOM_PKGLEN_BPAD_TOUCH) &&
                           (features->pktlen != WACOM_PKGLEN_BPAD_TOUCH_USB)) {
                        error = -ENODEV;
-                       goto fail_allocate_inputs;
+                       goto fail_shared_data;
                }
        }
 
@@ -1884,9 +1909,10 @@ static int wacom_parse_and_register(struct wacom *wacom, 
bool wireless)
 
        wacom_update_name(wacom, wireless ? " (WL)" : "");
 
-       error = wacom_add_shared_data(hdev);
-       if (error)
-               goto fail_shared_data;
+       if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
+               wacom_wac->shared->touch = hdev;
+       else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
+               wacom_wac->shared->pen = hdev;
 
        if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
             (features->quirks & WACOM_QUIRK_BATTERY)) {
@@ -1967,8 +1993,9 @@ fail_register_inputs:
        wacom_destroy_battery(wacom);
 #endif
 fail_battery:
-fail_shared_data:
 fail_parsed:
+fail_shared_data:
+       wacom_remove_shared_data(wacom);
 fail_allocate_inputs:
 fail_open_group:
        wacom_release_resources(wacom);
diff --git a/3.17/wacom_wac.c b/3.17/wacom_wac.c
index 7a2fb19..07482f5 100644
--- a/3.17/wacom_wac.c
+++ b/3.17/wacom_wac.c
@@ -1475,6 +1475,9 @@ static int wacom_equivalent_usage(int usage)
 static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
                struct hid_field *field, __u8 type, __u16 code, int fuzz)
 {
+       struct wacom *wacom = input_get_drvdata(input);
+       struct wacom_wac *wacom_wac = &wacom->wacom_wac;
+       struct wacom_features *features = &wacom_wac->features;
        int fmin = field->logical_minimum;
        int fmax = field->logical_maximum;
        unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
@@ -1484,6 +1487,15 @@ static void wacom_map_usage(struct input_dev *input, 
struct hid_usage *usage,
                resolution_code = ABS_RZ;
        }
 
+       if (equivalent_usage == HID_GD_X) {
+               fmin += features->offset_left;
+               fmax -= features->offset_right;
+       }
+       if (equivalent_usage == HID_GD_Y) {
+               fmin += features->offset_top;
+               fmax -= features->offset_bottom;
+       }
+
        usage->type = type;
        usage->code = code;
 
@@ -1636,6 +1648,34 @@ static int wacom_wac_pen_event(struct hid_device *hdev, 
struct hid_field *field,
                 */
                wacom_wac->id[0] |= value;
                return 0;
+       case WACOM_HID_WD_OFFSETLEFT:
+               if (features->offset_left && value != features->offset_left)
+                       hid_warn(hdev, "%s: overriding exising left offset "
+                                "%d -> %d\n", __func__, value,
+                                features->offset_left);
+               features->offset_left = value;
+               return 0;
+       case WACOM_HID_WD_OFFSETRIGHT:
+               if (features->offset_right && value != features->offset_right)
+                       hid_warn(hdev, "%s: overriding exising right offset "
+                                "%d -> %d\n", __func__, value,
+                                features->offset_right);
+               features->offset_right = value;
+               return 0;
+       case WACOM_HID_WD_OFFSETTOP:
+               if (features->offset_top && value != features->offset_top)
+                       hid_warn(hdev, "%s: overriding exising top offset "
+                                "%d -> %d\n", __func__, value,
+                                features->offset_top);
+               features->offset_top = value;
+               return 0;
+       case WACOM_HID_WD_OFFSETBOTTOM:
+               if (features->offset_bottom && value != features->offset_bottom)
+                       hid_warn(hdev, "%s: overriding exising bottom offset "
+                                "%d -> %d\n", __func__, value,
+                                features->offset_bottom);
+               features->offset_bottom = value;
+               return 0;
        }
 
        /* send pen events only when touch is up or forced out
diff --git a/3.17/wacom_wac.h b/3.17/wacom_wac.h
index bd7a84f..ae695a6 100644
--- a/3.17/wacom_wac.h
+++ b/3.17/wacom_wac.h
@@ -106,6 +106,10 @@
 #define WACOM_HID_WD_TOOLTYPE           (WACOM_HID_UP_WACOMDIGITIZER | 0x77)
 #define WACOM_HID_WD_DISTANCE           (WACOM_HID_UP_WACOMDIGITIZER | 0x0132)
 #define WACOM_HID_WD_FINGERWHEEL        (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03)
+#define WACOM_HID_WD_OFFSETLEFT         (WACOM_HID_UP_WACOMDIGITIZER | 0x0d30)
+#define WACOM_HID_WD_OFFSETTOP          (WACOM_HID_UP_WACOMDIGITIZER | 0x0d31)
+#define WACOM_HID_WD_OFFSETRIGHT        (WACOM_HID_UP_WACOMDIGITIZER | 0x0d32)
+#define WACOM_HID_WD_OFFSETBOTTOM       (WACOM_HID_UP_WACOMDIGITIZER | 0x0d33)
 #define WACOM_HID_WD_DATAMODE           (WACOM_HID_UP_WACOMDIGITIZER | 0x1002)
 #define WACOM_HID_UP_G9                 0xff090000
 #define WACOM_HID_G9_PEN                (WACOM_HID_UP_G9 | 0x02)
-- 
2.10.2


------------------------------------------------------------------------------
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to