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