Root/drivers/hid/hid-uclogic.c

1/*
2 * HID driver for UC-Logic devices not fully compliant with HID standard
3 *
4 * Copyright (c) 2010 Nikolai Kondrashov
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/module.h>
17#include <linux/usb.h>
18
19#include "hid-ids.h"
20
21/*
22 * See WPXXXXU model descriptions, device and HID report descriptors at
23 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP4030U
24 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP5540U
25 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP8060U
26 */
27
28/* Size of the original descriptor of WPXXXXU tablets */
29#define WPXXXXU_RDESC_ORIG_SIZE 212
30
31/* Fixed WP4030U report descriptor */
32static __u8 wp4030u_rdesc_fixed[] = {
33    0x05, 0x0D, /* Usage Page (Digitizer), */
34    0x09, 0x02, /* Usage (Pen), */
35    0xA1, 0x01, /* Collection (Application), */
36    0x85, 0x09, /* Report ID (9), */
37    0x09, 0x20, /* Usage (Stylus), */
38    0xA0, /* Collection (Physical), */
39    0x75, 0x01, /* Report Size (1), */
40    0x09, 0x42, /* Usage (Tip Switch), */
41    0x09, 0x44, /* Usage (Barrel Switch), */
42    0x09, 0x46, /* Usage (Tablet Pick), */
43    0x14, /* Logical Minimum (0), */
44    0x25, 0x01, /* Logical Maximum (1), */
45    0x95, 0x03, /* Report Count (3), */
46    0x81, 0x02, /* Input (Variable), */
47    0x95, 0x05, /* Report Count (5), */
48    0x81, 0x01, /* Input (Constant), */
49    0x75, 0x10, /* Report Size (16), */
50    0x95, 0x01, /* Report Count (1), */
51    0x14, /* Logical Minimum (0), */
52    0xA4, /* Push, */
53    0x05, 0x01, /* Usage Page (Desktop), */
54    0x55, 0xFD, /* Unit Exponent (-3), */
55    0x65, 0x13, /* Unit (Inch), */
56    0x34, /* Physical Minimum (0), */
57    0x09, 0x30, /* Usage (X), */
58    0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
59    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
60    0x81, 0x02, /* Input (Variable), */
61    0x09, 0x31, /* Usage (Y), */
62    0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
63    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
64    0x81, 0x02, /* Input (Variable), */
65    0xB4, /* Pop, */
66    0x09, 0x30, /* Usage (Tip Pressure), */
67    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
68    0x81, 0x02, /* Input (Variable), */
69    0xC0, /* End Collection, */
70    0xC0 /* End Collection */
71};
72
73/* Fixed WP5540U report descriptor */
74static __u8 wp5540u_rdesc_fixed[] = {
75    0x05, 0x0D, /* Usage Page (Digitizer), */
76    0x09, 0x02, /* Usage (Pen), */
77    0xA1, 0x01, /* Collection (Application), */
78    0x85, 0x09, /* Report ID (9), */
79    0x09, 0x20, /* Usage (Stylus), */
80    0xA0, /* Collection (Physical), */
81    0x75, 0x01, /* Report Size (1), */
82    0x09, 0x42, /* Usage (Tip Switch), */
83    0x09, 0x44, /* Usage (Barrel Switch), */
84    0x09, 0x46, /* Usage (Tablet Pick), */
85    0x14, /* Logical Minimum (0), */
86    0x25, 0x01, /* Logical Maximum (1), */
87    0x95, 0x03, /* Report Count (3), */
88    0x81, 0x02, /* Input (Variable), */
89    0x95, 0x05, /* Report Count (5), */
90    0x81, 0x01, /* Input (Constant), */
91    0x75, 0x10, /* Report Size (16), */
92    0x95, 0x01, /* Report Count (1), */
93    0x14, /* Logical Minimum (0), */
94    0xA4, /* Push, */
95    0x05, 0x01, /* Usage Page (Desktop), */
96    0x55, 0xFD, /* Unit Exponent (-3), */
97    0x65, 0x13, /* Unit (Inch), */
98    0x34, /* Physical Minimum (0), */
99    0x09, 0x30, /* Usage (X), */
100    0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
101    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
102    0x81, 0x02, /* Input (Variable), */
103    0x09, 0x31, /* Usage (Y), */
104    0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
105    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
106    0x81, 0x02, /* Input (Variable), */
107    0xB4, /* Pop, */
108    0x09, 0x30, /* Usage (Tip Pressure), */
109    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
110    0x81, 0x02, /* Input (Variable), */
111    0xC0, /* End Collection, */
112    0xC0, /* End Collection, */
113    0x05, 0x01, /* Usage Page (Desktop), */
114    0x09, 0x02, /* Usage (Mouse), */
115    0xA1, 0x01, /* Collection (Application), */
116    0x85, 0x08, /* Report ID (8), */
117    0x09, 0x01, /* Usage (Pointer), */
118    0xA0, /* Collection (Physical), */
119    0x75, 0x01, /* Report Size (1), */
120    0x05, 0x09, /* Usage Page (Button), */
121    0x19, 0x01, /* Usage Minimum (01h), */
122    0x29, 0x03, /* Usage Maximum (03h), */
123    0x14, /* Logical Minimum (0), */
124    0x25, 0x01, /* Logical Maximum (1), */
125    0x95, 0x03, /* Report Count (3), */
126    0x81, 0x02, /* Input (Variable), */
127    0x95, 0x05, /* Report Count (5), */
128    0x81, 0x01, /* Input (Constant), */
129    0x05, 0x01, /* Usage Page (Desktop), */
130    0x75, 0x08, /* Report Size (8), */
131    0x09, 0x30, /* Usage (X), */
132    0x09, 0x31, /* Usage (Y), */
133    0x15, 0x81, /* Logical Minimum (-127), */
134    0x25, 0x7F, /* Logical Maximum (127), */
135    0x95, 0x02, /* Report Count (2), */
136    0x81, 0x06, /* Input (Variable, Relative), */
137    0x09, 0x38, /* Usage (Wheel), */
138    0x15, 0xFF, /* Logical Minimum (-1), */
139    0x25, 0x01, /* Logical Maximum (1), */
140    0x95, 0x01, /* Report Count (1), */
141    0x81, 0x06, /* Input (Variable, Relative), */
142    0x81, 0x01, /* Input (Constant), */
143    0xC0, /* End Collection, */
144    0xC0 /* End Collection */
145};
146
147/* Fixed WP8060U report descriptor */
148static __u8 wp8060u_rdesc_fixed[] = {
149    0x05, 0x0D, /* Usage Page (Digitizer), */
150    0x09, 0x02, /* Usage (Pen), */
151    0xA1, 0x01, /* Collection (Application), */
152    0x85, 0x09, /* Report ID (9), */
153    0x09, 0x20, /* Usage (Stylus), */
154    0xA0, /* Collection (Physical), */
155    0x75, 0x01, /* Report Size (1), */
156    0x09, 0x42, /* Usage (Tip Switch), */
157    0x09, 0x44, /* Usage (Barrel Switch), */
158    0x09, 0x46, /* Usage (Tablet Pick), */
159    0x14, /* Logical Minimum (0), */
160    0x25, 0x01, /* Logical Maximum (1), */
161    0x95, 0x03, /* Report Count (3), */
162    0x81, 0x02, /* Input (Variable), */
163    0x95, 0x05, /* Report Count (5), */
164    0x81, 0x01, /* Input (Constant), */
165    0x75, 0x10, /* Report Size (16), */
166    0x95, 0x01, /* Report Count (1), */
167    0x14, /* Logical Minimum (0), */
168    0xA4, /* Push, */
169    0x05, 0x01, /* Usage Page (Desktop), */
170    0x55, 0xFD, /* Unit Exponent (-3), */
171    0x65, 0x13, /* Unit (Inch), */
172    0x34, /* Physical Minimum (0), */
173    0x09, 0x30, /* Usage (X), */
174    0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
175    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
176    0x81, 0x02, /* Input (Variable), */
177    0x09, 0x31, /* Usage (Y), */
178    0x46, 0x70, 0x17, /* Physical Maximum (6000), */
179    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
180    0x81, 0x02, /* Input (Variable), */
181    0xB4, /* Pop, */
182    0x09, 0x30, /* Usage (Tip Pressure), */
183    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
184    0x81, 0x02, /* Input (Variable), */
185    0xC0, /* End Collection, */
186    0xC0, /* End Collection, */
187    0x05, 0x01, /* Usage Page (Desktop), */
188    0x09, 0x02, /* Usage (Mouse), */
189    0xA1, 0x01, /* Collection (Application), */
190    0x85, 0x08, /* Report ID (8), */
191    0x09, 0x01, /* Usage (Pointer), */
192    0xA0, /* Collection (Physical), */
193    0x75, 0x01, /* Report Size (1), */
194    0x05, 0x09, /* Usage Page (Button), */
195    0x19, 0x01, /* Usage Minimum (01h), */
196    0x29, 0x03, /* Usage Maximum (03h), */
197    0x14, /* Logical Minimum (0), */
198    0x25, 0x01, /* Logical Maximum (1), */
199    0x95, 0x03, /* Report Count (3), */
200    0x81, 0x02, /* Input (Variable), */
201    0x95, 0x05, /* Report Count (5), */
202    0x81, 0x01, /* Input (Constant), */
203    0x05, 0x01, /* Usage Page (Desktop), */
204    0x75, 0x08, /* Report Size (8), */
205    0x09, 0x30, /* Usage (X), */
206    0x09, 0x31, /* Usage (Y), */
207    0x15, 0x81, /* Logical Minimum (-127), */
208    0x25, 0x7F, /* Logical Maximum (127), */
209    0x95, 0x02, /* Report Count (2), */
210    0x81, 0x06, /* Input (Variable, Relative), */
211    0x09, 0x38, /* Usage (Wheel), */
212    0x15, 0xFF, /* Logical Minimum (-1), */
213    0x25, 0x01, /* Logical Maximum (1), */
214    0x95, 0x01, /* Report Count (1), */
215    0x81, 0x06, /* Input (Variable, Relative), */
216    0x81, 0x01, /* Input (Constant), */
217    0xC0, /* End Collection, */
218    0xC0 /* End Collection */
219};
220
221/*
222 * See WP1062 description, device and HID report descriptors at
223 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_WP1062
224 */
225
226/* Size of the original descriptor of WP1062 tablet */
227#define WP1062_RDESC_ORIG_SIZE 254
228
229/* Fixed WP1062 report descriptor */
230static __u8 wp1062_rdesc_fixed[] = {
231    0x05, 0x0D, /* Usage Page (Digitizer), */
232    0x09, 0x02, /* Usage (Pen), */
233    0xA1, 0x01, /* Collection (Application), */
234    0x85, 0x09, /* Report ID (9), */
235    0x09, 0x20, /* Usage (Stylus), */
236    0xA0, /* Collection (Physical), */
237    0x75, 0x01, /* Report Size (1), */
238    0x09, 0x42, /* Usage (Tip Switch), */
239    0x09, 0x44, /* Usage (Barrel Switch), */
240    0x09, 0x46, /* Usage (Tablet Pick), */
241    0x14, /* Logical Minimum (0), */
242    0x25, 0x01, /* Logical Maximum (1), */
243    0x95, 0x03, /* Report Count (3), */
244    0x81, 0x02, /* Input (Variable), */
245    0x95, 0x04, /* Report Count (4), */
246    0x81, 0x01, /* Input (Constant), */
247    0x09, 0x32, /* Usage (In Range), */
248    0x95, 0x01, /* Report Count (1), */
249    0x81, 0x02, /* Input (Variable), */
250    0x75, 0x10, /* Report Size (16), */
251    0x95, 0x01, /* Report Count (1), */
252    0x14, /* Logical Minimum (0), */
253    0xA4, /* Push, */
254    0x05, 0x01, /* Usage Page (Desktop), */
255    0x55, 0xFD, /* Unit Exponent (-3), */
256    0x65, 0x13, /* Unit (Inch), */
257    0x34, /* Physical Minimum (0), */
258    0x09, 0x30, /* Usage (X), */
259    0x46, 0x10, 0x27, /* Physical Maximum (10000), */
260    0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
261    0x81, 0x02, /* Input (Variable), */
262    0x09, 0x31, /* Usage (Y), */
263    0x46, 0xB7, 0x19, /* Physical Maximum (6583), */
264    0x26, 0x6E, 0x33, /* Logical Maximum (13166), */
265    0x81, 0x02, /* Input (Variable), */
266    0xB4, /* Pop, */
267    0x09, 0x30, /* Usage (Tip Pressure), */
268    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
269    0x81, 0x02, /* Input (Variable), */
270    0xC0, /* End Collection, */
271    0xC0 /* End Collection */
272};
273
274/*
275 * See PF1209 description, device and HID report descriptors at
276 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Tablet_PF1209
277 */
278
279/* Size of the original descriptor of PF1209 tablet */
280#define PF1209_RDESC_ORIG_SIZE 234
281
282/* Fixed PF1209 report descriptor */
283static __u8 pf1209_rdesc_fixed[] = {
284    0x05, 0x0D, /* Usage Page (Digitizer), */
285    0x09, 0x02, /* Usage (Pen), */
286    0xA1, 0x01, /* Collection (Application), */
287    0x85, 0x09, /* Report ID (9), */
288    0x09, 0x20, /* Usage (Stylus), */
289    0xA0, /* Collection (Physical), */
290    0x75, 0x01, /* Report Size (1), */
291    0x09, 0x42, /* Usage (Tip Switch), */
292    0x09, 0x44, /* Usage (Barrel Switch), */
293    0x09, 0x46, /* Usage (Tablet Pick), */
294    0x14, /* Logical Minimum (0), */
295    0x25, 0x01, /* Logical Maximum (1), */
296    0x95, 0x03, /* Report Count (3), */
297    0x81, 0x02, /* Input (Variable), */
298    0x95, 0x05, /* Report Count (5), */
299    0x81, 0x01, /* Input (Constant), */
300    0x75, 0x10, /* Report Size (16), */
301    0x95, 0x01, /* Report Count (1), */
302    0x14, /* Logical Minimum (0), */
303    0xA4, /* Push, */
304    0x05, 0x01, /* Usage Page (Desktop), */
305    0x55, 0xFD, /* Unit Exponent (-3), */
306    0x65, 0x13, /* Unit (Inch), */
307    0x34, /* Physical Minimum (0), */
308    0x09, 0x30, /* Usage (X), */
309    0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
310    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
311    0x81, 0x02, /* Input (Variable), */
312    0x09, 0x31, /* Usage (Y), */
313    0x46, 0x28, 0x23, /* Physical Maximum (9000), */
314    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
315    0x81, 0x02, /* Input (Variable), */
316    0xB4, /* Pop, */
317    0x09, 0x30, /* Usage (Tip Pressure), */
318    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
319    0x81, 0x02, /* Input (Variable), */
320    0xC0, /* End Collection, */
321    0xC0, /* End Collection, */
322    0x05, 0x01, /* Usage Page (Desktop), */
323    0x09, 0x02, /* Usage (Mouse), */
324    0xA1, 0x01, /* Collection (Application), */
325    0x85, 0x08, /* Report ID (8), */
326    0x09, 0x01, /* Usage (Pointer), */
327    0xA0, /* Collection (Physical), */
328    0x75, 0x01, /* Report Size (1), */
329    0x05, 0x09, /* Usage Page (Button), */
330    0x19, 0x01, /* Usage Minimum (01h), */
331    0x29, 0x03, /* Usage Maximum (03h), */
332    0x14, /* Logical Minimum (0), */
333    0x25, 0x01, /* Logical Maximum (1), */
334    0x95, 0x03, /* Report Count (3), */
335    0x81, 0x02, /* Input (Variable), */
336    0x95, 0x05, /* Report Count (5), */
337    0x81, 0x01, /* Input (Constant), */
338    0x05, 0x01, /* Usage Page (Desktop), */
339    0x75, 0x08, /* Report Size (8), */
340    0x09, 0x30, /* Usage (X), */
341    0x09, 0x31, /* Usage (Y), */
342    0x15, 0x81, /* Logical Minimum (-127), */
343    0x25, 0x7F, /* Logical Maximum (127), */
344    0x95, 0x02, /* Report Count (2), */
345    0x81, 0x06, /* Input (Variable, Relative), */
346    0x09, 0x38, /* Usage (Wheel), */
347    0x15, 0xFF, /* Logical Minimum (-1), */
348    0x25, 0x01, /* Logical Maximum (1), */
349    0x95, 0x01, /* Report Count (1), */
350    0x81, 0x06, /* Input (Variable, Relative), */
351    0x81, 0x01, /* Input (Constant), */
352    0xC0, /* End Collection, */
353    0xC0 /* End Collection */
354};
355
356/*
357 * See TWHL850 description, device and HID report descriptors at
358 * http://sf.net/apps/mediawiki/digimend/?title=UC-Logic_Wireless_Tablet_TWHL850
359 */
360
361/* Size of the original descriptors of TWHL850 tablet */
362#define TWHL850_RDESC_ORIG_SIZE0 182
363#define TWHL850_RDESC_ORIG_SIZE1 161
364#define TWHL850_RDESC_ORIG_SIZE2 92
365
366/* Fixed PID 0522 tablet report descriptor, interface 0 (stylus) */
367static __u8 twhl850_rdesc_fixed0[] = {
368    0x05, 0x0D, /* Usage Page (Digitizer), */
369    0x09, 0x02, /* Usage (Pen), */
370    0xA1, 0x01, /* Collection (Application), */
371    0x85, 0x09, /* Report ID (9), */
372    0x09, 0x20, /* Usage (Stylus), */
373    0xA0, /* Collection (Physical), */
374    0x14, /* Logical Minimum (0), */
375    0x25, 0x01, /* Logical Maximum (1), */
376    0x75, 0x01, /* Report Size (1), */
377    0x95, 0x03, /* Report Count (3), */
378    0x09, 0x42, /* Usage (Tip Switch), */
379    0x09, 0x44, /* Usage (Barrel Switch), */
380    0x09, 0x46, /* Usage (Tablet Pick), */
381    0x81, 0x02, /* Input (Variable), */
382    0x81, 0x03, /* Input (Constant, Variable), */
383    0x95, 0x01, /* Report Count (1), */
384    0x09, 0x32, /* Usage (In Range), */
385    0x81, 0x02, /* Input (Variable), */
386    0x81, 0x03, /* Input (Constant, Variable), */
387    0x75, 0x10, /* Report Size (16), */
388    0xA4, /* Push, */
389    0x05, 0x01, /* Usage Page (Desktop), */
390    0x65, 0x13, /* Unit (Inch), */
391    0x55, 0xFD, /* Unit Exponent (-3), */
392    0x34, /* Physical Minimum (0), */
393    0x09, 0x30, /* Usage (X), */
394    0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
395    0x26, 0x00, 0x7D, /* Logical Maximum (32000), */
396    0x81, 0x02, /* Input (Variable), */
397    0x09, 0x31, /* Usage (Y), */
398    0x46, 0x88, 0x13, /* Physical Maximum (5000), */
399    0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
400    0x81, 0x02, /* Input (Variable), */
401    0xB4, /* Pop, */
402    0x09, 0x30, /* Usage (Tip Pressure), */
403    0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
404    0x81, 0x02, /* Input (Variable), */
405    0xC0, /* End Collection, */
406    0xC0 /* End Collection */
407};
408
409/* Fixed PID 0522 tablet report descriptor, interface 1 (mouse) */
410static __u8 twhl850_rdesc_fixed1[] = {
411    0x05, 0x01, /* Usage Page (Desktop), */
412    0x09, 0x02, /* Usage (Mouse), */
413    0xA1, 0x01, /* Collection (Application), */
414    0x85, 0x01, /* Report ID (1), */
415    0x09, 0x01, /* Usage (Pointer), */
416    0xA0, /* Collection (Physical), */
417    0x05, 0x09, /* Usage Page (Button), */
418    0x75, 0x01, /* Report Size (1), */
419    0x95, 0x03, /* Report Count (3), */
420    0x19, 0x01, /* Usage Minimum (01h), */
421    0x29, 0x03, /* Usage Maximum (03h), */
422    0x14, /* Logical Minimum (0), */
423    0x25, 0x01, /* Logical Maximum (1), */
424    0x81, 0x02, /* Input (Variable), */
425    0x95, 0x05, /* Report Count (5), */
426    0x81, 0x03, /* Input (Constant, Variable), */
427    0x05, 0x01, /* Usage Page (Desktop), */
428    0x09, 0x30, /* Usage (X), */
429    0x09, 0x31, /* Usage (Y), */
430    0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
431    0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
432    0x75, 0x10, /* Report Size (16), */
433    0x95, 0x02, /* Report Count (2), */
434    0x81, 0x06, /* Input (Variable, Relative), */
435    0x09, 0x38, /* Usage (Wheel), */
436    0x15, 0xFF, /* Logical Minimum (-1), */
437    0x25, 0x01, /* Logical Maximum (1), */
438    0x95, 0x01, /* Report Count (1), */
439    0x75, 0x08, /* Report Size (8), */
440    0x81, 0x06, /* Input (Variable, Relative), */
441    0x81, 0x03, /* Input (Constant, Variable), */
442    0xC0, /* End Collection, */
443    0xC0 /* End Collection */
444};
445
446/* Fixed PID 0522 tablet report descriptor, interface 2 (frame buttons) */
447static __u8 twhl850_rdesc_fixed2[] = {
448    0x05, 0x01, /* Usage Page (Desktop), */
449    0x09, 0x06, /* Usage (Keyboard), */
450    0xA1, 0x01, /* Collection (Application), */
451    0x85, 0x03, /* Report ID (3), */
452    0x05, 0x07, /* Usage Page (Keyboard), */
453    0x14, /* Logical Minimum (0), */
454    0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */
455    0x29, 0xE7, /* Usage Maximum (KB Right GUI), */
456    0x25, 0x01, /* Logical Maximum (1), */
457    0x75, 0x01, /* Report Size (1), */
458    0x95, 0x08, /* Report Count (8), */
459    0x81, 0x02, /* Input (Variable), */
460    0x18, /* Usage Minimum (None), */
461    0x29, 0xFF, /* Usage Maximum (FFh), */
462    0x26, 0xFF, 0x00, /* Logical Maximum (255), */
463    0x75, 0x08, /* Report Size (8), */
464    0x95, 0x06, /* Report Count (6), */
465    0x80, /* Input, */
466    0xC0 /* End Collection */
467};
468
469static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
470                    unsigned int *rsize)
471{
472    struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
473    __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
474
475    switch (hdev->product) {
476    case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209:
477        if (*rsize == PF1209_RDESC_ORIG_SIZE) {
478            rdesc = pf1209_rdesc_fixed;
479            *rsize = sizeof(pf1209_rdesc_fixed);
480        }
481        break;
482    case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U:
483        if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
484            rdesc = wp4030u_rdesc_fixed;
485            *rsize = sizeof(wp4030u_rdesc_fixed);
486        }
487        break;
488    case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U:
489        if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
490            rdesc = wp5540u_rdesc_fixed;
491            *rsize = sizeof(wp5540u_rdesc_fixed);
492        }
493        break;
494    case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U:
495        if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
496            rdesc = wp8060u_rdesc_fixed;
497            *rsize = sizeof(wp8060u_rdesc_fixed);
498        }
499        break;
500    case USB_DEVICE_ID_UCLOGIC_TABLET_WP1062:
501        if (*rsize == WP1062_RDESC_ORIG_SIZE) {
502            rdesc = wp1062_rdesc_fixed;
503            *rsize = sizeof(wp1062_rdesc_fixed);
504        }
505        break;
506    case USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850:
507        switch (iface_num) {
508        case 0:
509            if (*rsize == TWHL850_RDESC_ORIG_SIZE0) {
510                rdesc = twhl850_rdesc_fixed0;
511                *rsize = sizeof(twhl850_rdesc_fixed0);
512            }
513            break;
514        case 1:
515            if (*rsize == TWHL850_RDESC_ORIG_SIZE1) {
516                rdesc = twhl850_rdesc_fixed1;
517                *rsize = sizeof(twhl850_rdesc_fixed1);
518            }
519            break;
520        case 2:
521            if (*rsize == TWHL850_RDESC_ORIG_SIZE2) {
522                rdesc = twhl850_rdesc_fixed2;
523                *rsize = sizeof(twhl850_rdesc_fixed2);
524            }
525            break;
526        }
527        break;
528    }
529
530    return rdesc;
531}
532
533static const struct hid_device_id uclogic_devices[] = {
534    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
535                USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
536    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
537                USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
538    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
539                USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
540    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
541                USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
542    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
543                USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
544    { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
545                USB_DEVICE_ID_UCLOGIC_WIRELESS_TABLET_TWHL850) },
546    { }
547};
548MODULE_DEVICE_TABLE(hid, uclogic_devices);
549
550static struct hid_driver uclogic_driver = {
551    .name = "uclogic",
552    .id_table = uclogic_devices,
553    .report_fixup = uclogic_report_fixup,
554};
555
556static int __init uclogic_init(void)
557{
558    return hid_register_driver(&uclogic_driver);
559}
560
561static void __exit uclogic_exit(void)
562{
563    hid_unregister_driver(&uclogic_driver);
564}
565
566module_init(uclogic_init);
567module_exit(uclogic_exit);
568MODULE_LICENSE("GPL");
569

Archive Download this file



interactive