aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2016-10-19 21:03:40 -0400
committerJiri Kosina <jkosina@suse.cz>2016-10-20 03:53:56 -0400
commit6005a13c90a31501f3c21797b567e845c7098f25 (patch)
tree8e38f20d8a260c307311535a7db13e1d46c3088b
parent49005b9fd05249d537363ff86cb41f07f48c847a (diff)
HID: wacom: Detect and correct descriptors missing HID_DG_BARRELSWITCH2
ISDv4 devices have long supported reporting data from each of two barrel switches, but HID_DG_BARRELSWITCH2 itself was only recently standardized. Prior to its adoption, ISDv4 devices would associate the bit indicating the state of the second barrel switch with the "Undefined" 0x000D0000 usage. Although most such devices have explicit support, a few use the HID_GENERIC codepath which ignores the "Undefined" usage. This patch adds code which detects the presence of a pre-standard second barrel switch and corrects the usage value so that the HID_GENERIC code will declare its presence and report its state. 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.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 773fa114b216..033cc032f45c 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -240,6 +240,30 @@ static void wacom_usage_mapping(struct hid_device *hdev,
240 features->touch_max = 1; 240 features->touch_max = 1;
241 } 241 }
242 242
243 /*
244 * ISDv4 devices which predate HID's adoption of the
245 * HID_DG_BARELSWITCH2 usage use 0x000D0000 in its
246 * position instead. We can accurately detect if a
247 * usage with that value should be HID_DG_BARRELSWITCH2
248 * based on the surrounding usages, which have remained
249 * constant across generations.
250 */
251 if (features->type == HID_GENERIC &&
252 usage->hid == 0x000D0000 &&
253 field->application == HID_DG_PEN &&
254 field->physical == HID_DG_STYLUS) {
255 int i = usage->usage_index;
256
257 if (i-4 >= 0 && i+1 < field->maxusage &&
258 field->usage[i-4].hid == HID_DG_TIPSWITCH &&
259 field->usage[i-3].hid == HID_DG_BARRELSWITCH &&
260 field->usage[i-2].hid == HID_DG_ERASER &&
261 field->usage[i-1].hid == HID_DG_INVERT &&
262 field->usage[i+1].hid == HID_DG_INRANGE) {
263 usage->hid = HID_DG_BARRELSWITCH2;
264 }
265 }
266
243 switch (usage->hid) { 267 switch (usage->hid) {
244 case HID_GD_X: 268 case HID_GD_X:
245 features->x_max = field->logical_maximum; 269 features->x_max = field->logical_maximum;