summaryrefslogtreecommitdiff
path: root/hel
diff options
context:
space:
mode:
Diffstat (limited to 'hel')
-rw-r--r--hel/wacom.patch206
1 files changed, 206 insertions, 0 deletions
diff --git a/hel/wacom.patch b/hel/wacom.patch
new file mode 100644
index 00000000..61500efc
--- /dev/null
+++ b/hel/wacom.patch
@@ -0,0 +1,206 @@
1From 326ea2a90500fe4add86c5fb95d914d46910e780 Mon Sep 17 00:00:00 2001
2From: Jason Gerecke <killertofu@gmail.com>
3Date: Mon, 4 Apr 2016 11:26:52 -0700
4Subject: [PATCH] HID: wacom: Support switching from vendor-defined device mode
5 on G9 and G11
6
7A tablet PC booted into Windows may have its pen/touch hardware switched
8into "Wacom mode" similar to what we do with explicitly-supported hardware.
9Some devices appear to maintain this state across reboots, preventing their
10use with the generic HID driver. This patch adds support for detecting the
11presence of the mode switch feature report used by devices based on the G9
12and G11 chips and has the HID codepath always attempt to reset the device
13back to sending standard HID reports.
14
15Fixes: https://sourceforge.net/p/linuxwacom/bugs/307/
16Fixes: https://sourceforge.net/p/linuxwacom/bugs/310/
17Fixes: https://github.com/linuxwacom/input-wacom/issues/15
18
19Co-authored-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
20Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
21Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
22Signed-off-by: Jiri Kosina <jkosina@suse.cz>
23---
24 drivers/hid/wacom_sys.c | 100 ++++++++++++++++++++++++++++++++++--------------
25 drivers/hid/wacom_wac.h | 8 ++++
26 2 files changed, 80 insertions(+), 28 deletions(-)
27
28diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
29index b338bbf..ccf1883 100644
30--- a/drivers/hid/wacom_sys.c
31+++ b/drivers/hid/wacom_sys.c
32@@ -152,6 +152,25 @@ static void wacom_feature_mapping(struct hid_device *hdev,
33 hid_data->inputmode = field->report->id;
34 hid_data->inputmode_index = usage->usage_index;
35 break;
36+
37+ case HID_UP_DIGITIZER:
38+ if (field->report->id == 0x0B &&
39+ (field->application == WACOM_G9_DIGITIZER ||
40+ field->application == WACOM_G11_DIGITIZER)) {
41+ wacom->wacom_wac.mode_report = field->report->id;
42+ wacom->wacom_wac.mode_value = 0;
43+ }
44+ break;
45+
46+ case WACOM_G9_PAGE:
47+ case WACOM_G11_PAGE:
48+ if (field->report->id == 0x03 &&
49+ (field->application == WACOM_G9_TOUCHSCREEN ||
50+ field->application == WACOM_G11_TOUCHSCREEN)) {
51+ wacom->wacom_wac.mode_report = field->report->id;
52+ wacom->wacom_wac.mode_value = 0;
53+ }
54+ break;
55 }
56 }
57
58@@ -322,26 +341,41 @@ static int wacom_hid_set_device_mode(struct hid_device *hdev)
59 return 0;
60 }
61
62-static int wacom_set_device_mode(struct hid_device *hdev, int report_id,
63- int length, int mode)
64+static int wacom_set_device_mode(struct hid_device *hdev,
65+ struct wacom_wac *wacom_wac)
66 {
67- unsigned char *rep_data;
68+ u8 *rep_data;
69+ struct hid_report *r;
70+ struct hid_report_enum *re;
71+ int length;
72 int error = -ENOMEM, limit = 0;
73
74- rep_data = kzalloc(length, GFP_KERNEL);
75+ if (wacom_wac->mode_report < 0)
76+ return 0;
77+
78+ re = &(hdev->report_enum[HID_FEATURE_REPORT]);
79+ r = re->report_id_hash[wacom_wac->mode_report];
80+ if (!r)
81+ return -EINVAL;
82+
83+ rep_data = hid_alloc_report_buf(r, GFP_KERNEL);
84 if (!rep_data)
85- return error;
86+ return -ENOMEM;
87+
88+ length = hid_report_len(r);
89
90 do {
91- rep_data[0] = report_id;
92- rep_data[1] = mode;
93+ rep_data[0] = wacom_wac->mode_report;
94+ rep_data[1] = wacom_wac->mode_value;
95
96 error = wacom_set_report(hdev, HID_FEATURE_REPORT, rep_data,
97 length, 1);
98 if (error >= 0)
99 error = wacom_get_report(hdev, HID_FEATURE_REPORT,
100 rep_data, length, 1);
101- } while (error >= 0 && rep_data[1] != mode && limit++ < WAC_MSG_RETRIES);
102+ } while (error >= 0 &&
103+ rep_data[1] != wacom_wac->mode_report &&
104+ limit++ < WAC_MSG_RETRIES);
105
106 kfree(rep_data);
107
108@@ -411,32 +445,41 @@ static int wacom_bt_query_tablet_data(struct hid_device *hdev, u8 speed,
109 static int wacom_query_tablet_data(struct hid_device *hdev,
110 struct wacom_features *features)
111 {
112+ struct wacom *wacom = hid_get_drvdata(hdev);
113+ struct wacom_wac *wacom_wac = &wacom->wacom_wac;
114+
115 if (hdev->bus == BUS_BLUETOOTH)
116 return wacom_bt_query_tablet_data(hdev, 1, features);
117
118- if (features->type == HID_GENERIC)
119- return wacom_hid_set_device_mode(hdev);
120-
121- if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
122- if (features->type > TABLETPC) {
123- /* MT Tablet PC touch */
124- return wacom_set_device_mode(hdev, 3, 4, 4);
125- }
126- else if (features->type == WACOM_24HDT) {
127- return wacom_set_device_mode(hdev, 18, 3, 2);
128- }
129- else if (features->type == WACOM_27QHDT) {
130- return wacom_set_device_mode(hdev, 131, 3, 2);
131- }
132- else if (features->type == BAMBOO_PAD) {
133- return wacom_set_device_mode(hdev, 2, 2, 2);
134- }
135- } else if (features->device_type & WACOM_DEVICETYPE_PEN) {
136- if (features->type <= BAMBOO_PT) {
137- return wacom_set_device_mode(hdev, 2, 2, 2);
138+ if (features->type != HID_GENERIC) {
139+ if (features->device_type & WACOM_DEVICETYPE_TOUCH) {
140+ if (features->type > TABLETPC) {
141+ /* MT Tablet PC touch */
142+ wacom_wac->mode_report = 3;
143+ wacom_wac->mode_value = 4;
144+ } else if (features->type == WACOM_24HDT) {
145+ wacom_wac->mode_report = 18;
146+ wacom_wac->mode_value = 2;
147+ } else if (features->type == WACOM_27QHDT) {
148+ wacom_wac->mode_report = 131;
149+ wacom_wac->mode_value = 2;
150+ } else if (features->type == BAMBOO_PAD) {
151+ wacom_wac->mode_report = 2;
152+ wacom_wac->mode_value = 2;
153+ }
154+ } else if (features->device_type & WACOM_DEVICETYPE_PEN) {
155+ if (features->type <= BAMBOO_PT) {
156+ wacom_wac->mode_report = 2;
157+ wacom_wac->mode_value = 2;
158+ }
159 }
160 }
161
162+ wacom_set_device_mode(hdev, wacom_wac);
163+
164+ if (features->type == HID_GENERIC)
165+ return wacom_hid_set_device_mode(hdev);
166+
167 return 0;
168 }
169
170@@ -1818,6 +1861,7 @@ static int wacom_probe(struct hid_device *hdev,
171 }
172
173 wacom_wac->hid_data.inputmode = -1;
174+ wacom_wac->mode_report = -1;
175
176 wacom->usbdev = dev;
177 wacom->intf = intf;
178diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
179index 25baa7f..e2084d9 100644
180--- a/drivers/hid/wacom_wac.h
181+++ b/drivers/hid/wacom_wac.h
182@@ -84,6 +84,12 @@
183 #define WACOM_DEVICETYPE_WL_MONITOR 0x0008
184
185 #define WACOM_VENDORDEFINED_PEN 0xff0d0001
186+#define WACOM_G9_PAGE 0xff090000
187+#define WACOM_G9_DIGITIZER (WACOM_G9_PAGE | 0x02)
188+#define WACOM_G9_TOUCHSCREEN (WACOM_G9_PAGE | 0x11)
189+#define WACOM_G11_PAGE 0xff110000
190+#define WACOM_G11_DIGITIZER (WACOM_G11_PAGE | 0x02)
191+#define WACOM_G11_TOUCHSCREEN (WACOM_G11_PAGE | 0x11)
192
193 #define WACOM_PEN_FIELD(f) (((f)->logical == HID_DG_STYLUS) || \
194 ((f)->physical == HID_DG_STYLUS) || \
195@@ -238,6 +244,8 @@ struct wacom_wac {
196 int ps_connected;
197 u8 bt_features;
198 u8 bt_high_speed;
199+ int mode_report;
200+ int mode_value;
201 struct hid_data hid_data;
202 };
203
204--
2052.1.4
206