1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * USB Hanwang tablet support |
4 | * |
5 | * Copyright (c) 2010 Xing Wei <weixing@hanwang.com.cn> |
6 | */ |
7 | |
8 | #include <linux/types.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/slab.h> |
11 | #include <linux/module.h> |
12 | #include <linux/usb/input.h> |
13 | |
14 | MODULE_AUTHOR("Xing Wei <weixing@hanwang.com.cn>" ); |
15 | MODULE_DESCRIPTION("USB Hanwang tablet driver" ); |
16 | MODULE_LICENSE("GPL" ); |
17 | |
18 | #define USB_VENDOR_ID_HANWANG 0x0b57 |
19 | #define HANWANG_TABLET_INT_CLASS 0x0003 |
20 | #define HANWANG_TABLET_INT_SUB_CLASS 0x0001 |
21 | #define HANWANG_TABLET_INT_PROTOCOL 0x0002 |
22 | |
23 | #define ART_MASTER_PKGLEN_MAX 10 |
24 | |
25 | /* device IDs */ |
26 | #define STYLUS_DEVICE_ID 0x02 |
27 | #define TOUCH_DEVICE_ID 0x03 |
28 | #define CURSOR_DEVICE_ID 0x06 |
29 | #define ERASER_DEVICE_ID 0x0A |
30 | #define PAD_DEVICE_ID 0x0F |
31 | |
32 | /* match vendor and interface info */ |
33 | #define HANWANG_TABLET_DEVICE(vend, cl, sc, pr) \ |
34 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR \ |
35 | | USB_DEVICE_ID_MATCH_INT_INFO, \ |
36 | .idVendor = (vend), \ |
37 | .bInterfaceClass = (cl), \ |
38 | .bInterfaceSubClass = (sc), \ |
39 | .bInterfaceProtocol = (pr) |
40 | |
41 | enum hanwang_tablet_type { |
42 | HANWANG_ART_MASTER_III, |
43 | HANWANG_ART_MASTER_HD, |
44 | HANWANG_ART_MASTER_II, |
45 | }; |
46 | |
47 | struct hanwang { |
48 | unsigned char *data; |
49 | dma_addr_t data_dma; |
50 | struct input_dev *dev; |
51 | struct usb_device *usbdev; |
52 | struct urb *irq; |
53 | const struct hanwang_features *features; |
54 | unsigned int current_tool; |
55 | unsigned int current_id; |
56 | char name[64]; |
57 | char phys[32]; |
58 | }; |
59 | |
60 | struct hanwang_features { |
61 | unsigned short pid; |
62 | char *name; |
63 | enum hanwang_tablet_type type; |
64 | int pkg_len; |
65 | int max_x; |
66 | int max_y; |
67 | int max_tilt_x; |
68 | int max_tilt_y; |
69 | int max_pressure; |
70 | }; |
71 | |
72 | static const struct hanwang_features features_array[] = { |
73 | { 0x8528, "Hanwang Art Master III 0906" , HANWANG_ART_MASTER_III, |
74 | ART_MASTER_PKGLEN_MAX, 0x5757, 0x3692, 0x3f, 0x7f, 2048 }, |
75 | { 0x8529, "Hanwang Art Master III 0604" , HANWANG_ART_MASTER_III, |
76 | ART_MASTER_PKGLEN_MAX, 0x3d84, 0x2672, 0x3f, 0x7f, 2048 }, |
77 | { 0x852a, "Hanwang Art Master III 1308" , HANWANG_ART_MASTER_III, |
78 | ART_MASTER_PKGLEN_MAX, 0x7f00, 0x4f60, 0x3f, 0x7f, 2048 }, |
79 | { 0x8401, "Hanwang Art Master HD 5012" , HANWANG_ART_MASTER_HD, |
80 | ART_MASTER_PKGLEN_MAX, 0x678e, 0x4150, 0x3f, 0x7f, 1024 }, |
81 | { 0x8503, "Hanwang Art Master II" , HANWANG_ART_MASTER_II, |
82 | ART_MASTER_PKGLEN_MAX, 0x27de, 0x1cfe, 0x3f, 0x7f, 1024 }, |
83 | }; |
84 | |
85 | static const int hw_eventtypes[] = { |
86 | EV_KEY, EV_ABS, EV_MSC, |
87 | }; |
88 | |
89 | static const int hw_absevents[] = { |
90 | ABS_X, ABS_Y, ABS_TILT_X, ABS_TILT_Y, ABS_WHEEL, |
91 | ABS_RX, ABS_RY, ABS_PRESSURE, ABS_MISC, |
92 | }; |
93 | |
94 | static const int hw_btnevents[] = { |
95 | BTN_STYLUS, BTN_STYLUS2, BTN_TOOL_PEN, BTN_TOOL_RUBBER, |
96 | BTN_TOOL_MOUSE, BTN_TOOL_FINGER, |
97 | BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8, |
98 | }; |
99 | |
100 | static const int hw_mscevents[] = { |
101 | MSC_SERIAL, |
102 | }; |
103 | |
104 | static void hanwang_parse_packet(struct hanwang *hanwang) |
105 | { |
106 | unsigned char *data = hanwang->data; |
107 | struct input_dev *input_dev = hanwang->dev; |
108 | struct usb_device *dev = hanwang->usbdev; |
109 | enum hanwang_tablet_type type = hanwang->features->type; |
110 | int i; |
111 | u16 p; |
112 | |
113 | if (type == HANWANG_ART_MASTER_II) { |
114 | hanwang->current_tool = BTN_TOOL_PEN; |
115 | hanwang->current_id = STYLUS_DEVICE_ID; |
116 | } |
117 | |
118 | switch (data[0]) { |
119 | case 0x02: /* data packet */ |
120 | switch (data[1]) { |
121 | case 0x80: /* tool prox out */ |
122 | if (type != HANWANG_ART_MASTER_II) { |
123 | hanwang->current_id = 0; |
124 | input_report_key(dev: input_dev, |
125 | code: hanwang->current_tool, value: 0); |
126 | } |
127 | break; |
128 | |
129 | case 0x00: /* artmaster ii pen leave */ |
130 | if (type == HANWANG_ART_MASTER_II) { |
131 | hanwang->current_id = 0; |
132 | input_report_key(dev: input_dev, |
133 | code: hanwang->current_tool, value: 0); |
134 | } |
135 | break; |
136 | |
137 | case 0xc2: /* first time tool prox in */ |
138 | switch (data[3] & 0xf0) { |
139 | case 0x20: /* art_master III */ |
140 | case 0x30: /* art_master_HD */ |
141 | hanwang->current_id = STYLUS_DEVICE_ID; |
142 | hanwang->current_tool = BTN_TOOL_PEN; |
143 | input_report_key(dev: input_dev, BTN_TOOL_PEN, value: 1); |
144 | break; |
145 | case 0xa0: /* art_master III */ |
146 | case 0xb0: /* art_master_HD */ |
147 | hanwang->current_id = ERASER_DEVICE_ID; |
148 | hanwang->current_tool = BTN_TOOL_RUBBER; |
149 | input_report_key(dev: input_dev, BTN_TOOL_RUBBER, value: 1); |
150 | break; |
151 | default: |
152 | hanwang->current_id = 0; |
153 | dev_dbg(&dev->dev, |
154 | "unknown tablet tool %02x\n" , data[0]); |
155 | break; |
156 | } |
157 | break; |
158 | |
159 | default: /* tool data packet */ |
160 | switch (type) { |
161 | case HANWANG_ART_MASTER_III: |
162 | p = (data[6] << 3) | |
163 | ((data[7] & 0xc0) >> 5) | |
164 | (data[1] & 0x01); |
165 | break; |
166 | |
167 | case HANWANG_ART_MASTER_HD: |
168 | case HANWANG_ART_MASTER_II: |
169 | p = (data[7] >> 6) | (data[6] << 2); |
170 | break; |
171 | |
172 | default: |
173 | p = 0; |
174 | break; |
175 | } |
176 | |
177 | input_report_abs(dev: input_dev, ABS_X, |
178 | be16_to_cpup(p: (__be16 *)&data[2])); |
179 | input_report_abs(dev: input_dev, ABS_Y, |
180 | be16_to_cpup(p: (__be16 *)&data[4])); |
181 | input_report_abs(dev: input_dev, ABS_PRESSURE, value: p); |
182 | input_report_abs(dev: input_dev, ABS_TILT_X, value: data[7] & 0x3f); |
183 | input_report_abs(dev: input_dev, ABS_TILT_Y, value: data[8] & 0x7f); |
184 | input_report_key(dev: input_dev, BTN_STYLUS, value: data[1] & 0x02); |
185 | |
186 | if (type != HANWANG_ART_MASTER_II) |
187 | input_report_key(dev: input_dev, BTN_STYLUS2, |
188 | value: data[1] & 0x04); |
189 | else |
190 | input_report_key(dev: input_dev, BTN_TOOL_PEN, value: 1); |
191 | |
192 | break; |
193 | } |
194 | |
195 | input_report_abs(dev: input_dev, ABS_MISC, value: hanwang->current_id); |
196 | input_event(dev: input_dev, EV_MSC, MSC_SERIAL, |
197 | value: hanwang->features->pid); |
198 | break; |
199 | |
200 | case 0x0c: |
201 | /* roll wheel */ |
202 | hanwang->current_id = PAD_DEVICE_ID; |
203 | |
204 | switch (type) { |
205 | case HANWANG_ART_MASTER_III: |
206 | input_report_key(dev: input_dev, BTN_TOOL_FINGER, |
207 | value: data[1] || data[2] || data[3]); |
208 | input_report_abs(dev: input_dev, ABS_WHEEL, value: data[1]); |
209 | input_report_key(dev: input_dev, BTN_0, value: data[2]); |
210 | for (i = 0; i < 8; i++) |
211 | input_report_key(dev: input_dev, |
212 | BTN_1 + i, value: data[3] & (1 << i)); |
213 | break; |
214 | |
215 | case HANWANG_ART_MASTER_HD: |
216 | input_report_key(dev: input_dev, BTN_TOOL_FINGER, value: data[1] || |
217 | data[2] || data[3] || data[4] || |
218 | data[5] || data[6]); |
219 | input_report_abs(dev: input_dev, ABS_RX, |
220 | value: ((data[1] & 0x1f) << 8) | data[2]); |
221 | input_report_abs(dev: input_dev, ABS_RY, |
222 | value: ((data[3] & 0x1f) << 8) | data[4]); |
223 | input_report_key(dev: input_dev, BTN_0, value: data[5] & 0x01); |
224 | for (i = 0; i < 4; i++) { |
225 | input_report_key(dev: input_dev, |
226 | BTN_1 + i, value: data[5] & (1 << i)); |
227 | input_report_key(dev: input_dev, |
228 | BTN_5 + i, value: data[6] & (1 << i)); |
229 | } |
230 | break; |
231 | |
232 | case HANWANG_ART_MASTER_II: |
233 | dev_dbg(&dev->dev, "error packet %02x\n" , data[0]); |
234 | return; |
235 | } |
236 | |
237 | input_report_abs(dev: input_dev, ABS_MISC, value: hanwang->current_id); |
238 | input_event(dev: input_dev, EV_MSC, MSC_SERIAL, value: 0xffffffff); |
239 | break; |
240 | |
241 | default: |
242 | dev_dbg(&dev->dev, "error packet %02x\n" , data[0]); |
243 | break; |
244 | } |
245 | |
246 | input_sync(dev: input_dev); |
247 | } |
248 | |
249 | static void hanwang_irq(struct urb *urb) |
250 | { |
251 | struct hanwang *hanwang = urb->context; |
252 | struct usb_device *dev = hanwang->usbdev; |
253 | int retval; |
254 | |
255 | switch (urb->status) { |
256 | case 0: |
257 | /* success */; |
258 | hanwang_parse_packet(hanwang); |
259 | break; |
260 | case -ECONNRESET: |
261 | case -ENOENT: |
262 | case -ESHUTDOWN: |
263 | /* this urb is terminated, clean up */ |
264 | dev_err(&dev->dev, "%s - urb shutting down with status: %d" , |
265 | __func__, urb->status); |
266 | return; |
267 | default: |
268 | dev_err(&dev->dev, "%s - nonzero urb status received: %d" , |
269 | __func__, urb->status); |
270 | break; |
271 | } |
272 | |
273 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
274 | if (retval) |
275 | dev_err(&dev->dev, "%s - usb_submit_urb failed with result %d" , |
276 | __func__, retval); |
277 | } |
278 | |
279 | static int hanwang_open(struct input_dev *dev) |
280 | { |
281 | struct hanwang *hanwang = input_get_drvdata(dev); |
282 | |
283 | hanwang->irq->dev = hanwang->usbdev; |
284 | if (usb_submit_urb(urb: hanwang->irq, GFP_KERNEL)) |
285 | return -EIO; |
286 | |
287 | return 0; |
288 | } |
289 | |
290 | static void hanwang_close(struct input_dev *dev) |
291 | { |
292 | struct hanwang *hanwang = input_get_drvdata(dev); |
293 | |
294 | usb_kill_urb(urb: hanwang->irq); |
295 | } |
296 | |
297 | static bool get_features(struct usb_device *dev, struct hanwang *hanwang) |
298 | { |
299 | int i; |
300 | |
301 | for (i = 0; i < ARRAY_SIZE(features_array); i++) { |
302 | if (le16_to_cpu(dev->descriptor.idProduct) == |
303 | features_array[i].pid) { |
304 | hanwang->features = &features_array[i]; |
305 | return true; |
306 | } |
307 | } |
308 | |
309 | return false; |
310 | } |
311 | |
312 | |
313 | static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id *id) |
314 | { |
315 | struct usb_device *dev = interface_to_usbdev(intf); |
316 | struct usb_endpoint_descriptor *endpoint; |
317 | struct hanwang *hanwang; |
318 | struct input_dev *input_dev; |
319 | int error; |
320 | int i; |
321 | |
322 | if (intf->cur_altsetting->desc.bNumEndpoints < 1) |
323 | return -ENODEV; |
324 | |
325 | hanwang = kzalloc(size: sizeof(struct hanwang), GFP_KERNEL); |
326 | input_dev = input_allocate_device(); |
327 | if (!hanwang || !input_dev) { |
328 | error = -ENOMEM; |
329 | goto fail1; |
330 | } |
331 | |
332 | if (!get_features(dev, hanwang)) { |
333 | error = -ENXIO; |
334 | goto fail1; |
335 | } |
336 | |
337 | hanwang->data = usb_alloc_coherent(dev, size: hanwang->features->pkg_len, |
338 | GFP_KERNEL, dma: &hanwang->data_dma); |
339 | if (!hanwang->data) { |
340 | error = -ENOMEM; |
341 | goto fail1; |
342 | } |
343 | |
344 | hanwang->irq = usb_alloc_urb(iso_packets: 0, GFP_KERNEL); |
345 | if (!hanwang->irq) { |
346 | error = -ENOMEM; |
347 | goto fail2; |
348 | } |
349 | |
350 | hanwang->usbdev = dev; |
351 | hanwang->dev = input_dev; |
352 | |
353 | usb_make_path(dev, buf: hanwang->phys, size: sizeof(hanwang->phys)); |
354 | strlcat(p: hanwang->phys, q: "/input0" , avail: sizeof(hanwang->phys)); |
355 | |
356 | strscpy(p: hanwang->name, q: hanwang->features->name, size: sizeof(hanwang->name)); |
357 | input_dev->name = hanwang->name; |
358 | input_dev->phys = hanwang->phys; |
359 | usb_to_input_id(dev, id: &input_dev->id); |
360 | input_dev->dev.parent = &intf->dev; |
361 | |
362 | input_set_drvdata(dev: input_dev, data: hanwang); |
363 | |
364 | input_dev->open = hanwang_open; |
365 | input_dev->close = hanwang_close; |
366 | |
367 | for (i = 0; i < ARRAY_SIZE(hw_eventtypes); ++i) |
368 | __set_bit(hw_eventtypes[i], input_dev->evbit); |
369 | |
370 | for (i = 0; i < ARRAY_SIZE(hw_absevents); ++i) |
371 | __set_bit(hw_absevents[i], input_dev->absbit); |
372 | |
373 | for (i = 0; i < ARRAY_SIZE(hw_btnevents); ++i) |
374 | __set_bit(hw_btnevents[i], input_dev->keybit); |
375 | |
376 | for (i = 0; i < ARRAY_SIZE(hw_mscevents); ++i) |
377 | __set_bit(hw_mscevents[i], input_dev->mscbit); |
378 | |
379 | input_set_abs_params(dev: input_dev, ABS_X, |
380 | min: 0, max: hanwang->features->max_x, fuzz: 4, flat: 0); |
381 | input_set_abs_params(dev: input_dev, ABS_Y, |
382 | min: 0, max: hanwang->features->max_y, fuzz: 4, flat: 0); |
383 | input_set_abs_params(dev: input_dev, ABS_TILT_X, |
384 | min: 0, max: hanwang->features->max_tilt_x, fuzz: 0, flat: 0); |
385 | input_set_abs_params(dev: input_dev, ABS_TILT_Y, |
386 | min: 0, max: hanwang->features->max_tilt_y, fuzz: 0, flat: 0); |
387 | input_set_abs_params(dev: input_dev, ABS_PRESSURE, |
388 | min: 0, max: hanwang->features->max_pressure, fuzz: 0, flat: 0); |
389 | |
390 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
391 | usb_fill_int_urb(urb: hanwang->irq, dev, |
392 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
393 | transfer_buffer: hanwang->data, buffer_length: hanwang->features->pkg_len, |
394 | complete_fn: hanwang_irq, context: hanwang, interval: endpoint->bInterval); |
395 | hanwang->irq->transfer_dma = hanwang->data_dma; |
396 | hanwang->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
397 | |
398 | error = input_register_device(hanwang->dev); |
399 | if (error) |
400 | goto fail3; |
401 | |
402 | usb_set_intfdata(intf, data: hanwang); |
403 | |
404 | return 0; |
405 | |
406 | fail3: usb_free_urb(urb: hanwang->irq); |
407 | fail2: usb_free_coherent(dev, size: hanwang->features->pkg_len, |
408 | addr: hanwang->data, dma: hanwang->data_dma); |
409 | fail1: input_free_device(dev: input_dev); |
410 | kfree(objp: hanwang); |
411 | return error; |
412 | |
413 | } |
414 | |
415 | static void hanwang_disconnect(struct usb_interface *intf) |
416 | { |
417 | struct hanwang *hanwang = usb_get_intfdata(intf); |
418 | |
419 | input_unregister_device(hanwang->dev); |
420 | usb_free_urb(urb: hanwang->irq); |
421 | usb_free_coherent(interface_to_usbdev(intf), |
422 | size: hanwang->features->pkg_len, addr: hanwang->data, |
423 | dma: hanwang->data_dma); |
424 | kfree(objp: hanwang); |
425 | usb_set_intfdata(intf, NULL); |
426 | } |
427 | |
428 | static const struct usb_device_id hanwang_ids[] = { |
429 | { HANWANG_TABLET_DEVICE(USB_VENDOR_ID_HANWANG, HANWANG_TABLET_INT_CLASS, |
430 | HANWANG_TABLET_INT_SUB_CLASS, HANWANG_TABLET_INT_PROTOCOL) }, |
431 | {} |
432 | }; |
433 | |
434 | MODULE_DEVICE_TABLE(usb, hanwang_ids); |
435 | |
436 | static struct usb_driver hanwang_driver = { |
437 | .name = "hanwang" , |
438 | .probe = hanwang_probe, |
439 | .disconnect = hanwang_disconnect, |
440 | .id_table = hanwang_ids, |
441 | }; |
442 | |
443 | module_usb_driver(hanwang_driver); |
444 | |