aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2016-10-19 21:03:50 -0400
committerJiri Kosina <jkosina@suse.cz>2016-10-20 03:54:00 -0400
commit345857bb493fbff15632a6bdf04713163ccd6fe6 (patch)
tree7075631dd1dec30497cbcda00612e1f15d9b0eae
parente779ef23104869d74f56fbd199a90e76699eb699 (diff)
HID: wacom: generic: Add support for sensor offsets
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.gerecke@wacom.com> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/wacom_sys.c38
-rw-r--r--drivers/hid/wacom_wac.c40
-rw-r--r--drivers/hid/wacom_wac.h4
3 files changed, 74 insertions, 8 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index b2e2471bbef6..b9779bcbd140 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -122,6 +122,7 @@ static void wacom_feature_mapping(struct hid_device *hdev,
122 struct hid_data *hid_data = &wacom->wacom_wac.hid_data; 122 struct hid_data *hid_data = &wacom->wacom_wac.hid_data;
123 u8 *data; 123 u8 *data;
124 int ret; 124 int ret;
125 int n;
125 126
126 switch (usage->hid) { 127 switch (usage->hid) {
127 case HID_DG_CONTACTMAX: 128 case HID_DG_CONTACTMAX:
@@ -180,6 +181,27 @@ static void wacom_feature_mapping(struct hid_device *hdev,
180 wacom->wacom_wac.mode_value = 0; 181 wacom->wacom_wac.mode_value = 0;
181 } 182 }
182 break; 183 break;
184 case WACOM_HID_WD_OFFSETLEFT:
185 case WACOM_HID_WD_OFFSETTOP:
186 case WACOM_HID_WD_OFFSETRIGHT:
187 case WACOM_HID_WD_OFFSETBOTTOM:
188 /* read manually */
189 n = hid_report_len(field->report);
190 data = hid_alloc_report_buf(field->report, GFP_KERNEL);
191 if (!data)
192 break;
193 data[0] = field->report->id;
194 ret = wacom_get_report(hdev, HID_FEATURE_REPORT,
195 data, n, WAC_CMD_RETRIES);
196 if (ret == n) {
197 ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT,
198 data, n, 0);
199 } else {
200 hid_warn(hdev, "%s: could not retrieve sensor offsets\n",
201 __func__);
202 }
203 kfree(data);
204 break;
183 } 205 }
184} 206}
185 207
@@ -718,11 +740,6 @@ static int wacom_add_shared_data(struct hid_device *hdev)
718 return retval; 740 return retval;
719 } 741 }
720 742
721 if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
722 wacom_wac->shared->touch = hdev;
723 else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
724 wacom_wac->shared->pen = hdev;
725
726out: 743out:
727 mutex_unlock(&wacom_udev_list_lock); 744 mutex_unlock(&wacom_udev_list_lock);
728 return retval; 745 return retval;
@@ -2019,6 +2036,10 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
2019 if (error) 2036 if (error)
2020 goto fail; 2037 goto fail;
2021 2038
2039 error = wacom_add_shared_data(hdev);
2040 if (error)
2041 goto fail;
2042
2022 /* 2043 /*
2023 * Bamboo Pad has a generic hid handling for the Pen, and we switch it 2044 * Bamboo Pad has a generic hid handling for the Pen, and we switch it
2024 * into debug mode for the touch part. 2045 * into debug mode for the touch part.
@@ -2059,9 +2080,10 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless)
2059 2080
2060 wacom_update_name(wacom, wireless ? " (WL)" : ""); 2081 wacom_update_name(wacom, wireless ? " (WL)" : "");
2061 2082
2062 error = wacom_add_shared_data(hdev); 2083 if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)
2063 if (error) 2084 wacom_wac->shared->touch = hdev;
2064 goto fail; 2085 else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN)
2086 wacom_wac->shared->pen = hdev;
2065 2087
2066 if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) && 2088 if (!(features->device_type & WACOM_DEVICETYPE_WL_MONITOR) &&
2067 (features->quirks & WACOM_QUIRK_BATTERY)) { 2089 (features->quirks & WACOM_QUIRK_BATTERY)) {
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 5046071f2e9e..3bb6dd6e4eea 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1468,6 +1468,9 @@ static int wacom_equivalent_usage(int usage)
1468static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, 1468static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
1469 struct hid_field *field, __u8 type, __u16 code, int fuzz) 1469 struct hid_field *field, __u8 type, __u16 code, int fuzz)
1470{ 1470{
1471 struct wacom *wacom = input_get_drvdata(input);
1472 struct wacom_wac *wacom_wac = &wacom->wacom_wac;
1473 struct wacom_features *features = &wacom_wac->features;
1471 int fmin = field->logical_minimum; 1474 int fmin = field->logical_minimum;
1472 int fmax = field->logical_maximum; 1475 int fmax = field->logical_maximum;
1473 unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); 1476 unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
@@ -1477,6 +1480,15 @@ static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
1477 resolution_code = ABS_RZ; 1480 resolution_code = ABS_RZ;
1478 } 1481 }
1479 1482
1483 if (equivalent_usage == HID_GD_X) {
1484 fmin += features->offset_left;
1485 fmax -= features->offset_right;
1486 }
1487 if (equivalent_usage == HID_GD_Y) {
1488 fmin += features->offset_top;
1489 fmax -= features->offset_bottom;
1490 }
1491
1480 usage->type = type; 1492 usage->type = type;
1481 usage->code = code; 1493 usage->code = code;
1482 1494
@@ -1629,6 +1641,34 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
1629 */ 1641 */
1630 wacom_wac->id[0] |= value; 1642 wacom_wac->id[0] |= value;
1631 return 0; 1643 return 0;
1644 case WACOM_HID_WD_OFFSETLEFT:
1645 if (features->offset_left && value != features->offset_left)
1646 hid_warn(hdev, "%s: overriding exising left offset "
1647 "%d -> %d\n", __func__, value,
1648 features->offset_left);
1649 features->offset_left = value;
1650 return 0;
1651 case WACOM_HID_WD_OFFSETRIGHT:
1652 if (features->offset_right && value != features->offset_right)
1653 hid_warn(hdev, "%s: overriding exising right offset "
1654 "%d -> %d\n", __func__, value,
1655 features->offset_right);
1656 features->offset_right = value;
1657 return 0;
1658 case WACOM_HID_WD_OFFSETTOP:
1659 if (features->offset_top && value != features->offset_top)
1660 hid_warn(hdev, "%s: overriding exising top offset "
1661 "%d -> %d\n", __func__, value,
1662 features->offset_top);
1663 features->offset_top = value;
1664 return 0;
1665 case WACOM_HID_WD_OFFSETBOTTOM:
1666 if (features->offset_bottom && value != features->offset_bottom)
1667 hid_warn(hdev, "%s: overriding exising bottom offset "
1668 "%d -> %d\n", __func__, value,
1669 features->offset_bottom);
1670 features->offset_bottom = value;
1671 return 0;
1632 } 1672 }
1633 1673
1634 /* send pen events only when touch is up or forced out 1674 /* send pen events only when touch is up or forced out
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 5c5c6891b832..b4c3c6425b85 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -94,6 +94,10 @@
94#define WACOM_HID_WD_TOOLTYPE (WACOM_HID_UP_WACOMDIGITIZER | 0x77) 94#define WACOM_HID_WD_TOOLTYPE (WACOM_HID_UP_WACOMDIGITIZER | 0x77)
95#define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132) 95#define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132)
96#define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03) 96#define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03)
97#define WACOM_HID_WD_OFFSETLEFT (WACOM_HID_UP_WACOMDIGITIZER | 0x0d30)
98#define WACOM_HID_WD_OFFSETTOP (WACOM_HID_UP_WACOMDIGITIZER | 0x0d31)
99#define WACOM_HID_WD_OFFSETRIGHT (WACOM_HID_UP_WACOMDIGITIZER | 0x0d32)
100#define WACOM_HID_WD_OFFSETBOTTOM (WACOM_HID_UP_WACOMDIGITIZER | 0x0d33)
97#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002) 101#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002)
98#define WACOM_HID_UP_G9 0xff090000 102#define WACOM_HID_UP_G9 0xff090000
99#define WACOM_HID_G9_PEN (WACOM_HID_UP_G9 | 0x02) 103#define WACOM_HID_G9_PEN (WACOM_HID_UP_G9 | 0x02)