HID: waltop: comment on tablet modes
[pandora-kernel.git] / drivers / hid / hid-waltop.c
1 /*
2  *  HID driver for Waltop 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
18 #include "hid-ids.h"
19
20 /*
21  * There exists an official driver on the manufacturer's website, which
22  * wasn't submitted to the kernel, for some reason. The official driver
23  * doesn't seem to support extra features of some tablets, like wheels.
24  *
25  * It shows that the feature report ID 2 could be used to control any waltop
26  * tablet input mode, switching it between "default", "tablet" and "ink".
27  *
28  * This driver only uses "default" mode for all the supported tablets. This
29  * mode tries to be HID-compatible (not very successfully), but cripples the
30  * resolution of some tablets.
31  *
32  * The "tablet" mode uses some proprietary, yet decipherable protocol, which
33  * represents the correct resolution, but is possibly HID-incompatible (i.e.
34  * indescribable by a report descriptor).
35  *
36  * The purpose of the "ink" mode is unknown.
37  *
38  * The feature reports needed for switching to each mode are these:
39  *
40  * 02 16 00     default
41  * 02 16 01     tablet
42  * 02 16 02     ink
43  */
44
45 /*
46  * Original Slim Tablet 5.8 inch report descriptor.
47  *
48  * All the reports except the report with ID 16 (the stylus) are unused,
49  * possibly because the tablet is not configured to, or because they were
50  * just copied from a more capable model. The full purpose of features
51  * described for report ID 2 is unknown.
52  *
53  * The stylus buttons are described as three bit fields, whereas actually
54  * it's an "array", i.e. they're reported as button numbers (1, 2 and 3).
55  * The "eraser" field is not used. There is also a "push" without a "pop" in
56  * the stylus description.
57  *
58  *  Usage Page (Desktop),           ; Generic desktop controls (01h)
59  *  Usage (Mouse),                  ; Mouse (02h, application collection)
60  *  Collection (Application),
61  *    Report ID (1),
62  *    Usage (Pointer),              ; Pointer (01h, physical collection)
63  *    Collection (Physical),
64  *      Usage Page (Button),        ; Button (09h)
65  *      Usage Minimum (01h),
66  *      Usage Maximum (05h),
67  *      Logical Minimum (0),
68  *      Logical Maximum (1),
69  *      Report Size (1),
70  *      Report Count (5),
71  *      Input (Variable),
72  *      Report Size (3),
73  *      Report Count (1),
74  *      Input (Constant, Variable),
75  *      Usage Page (Desktop),       ; Generic desktop controls (01h)
76  *      Usage (X),                  ; X (30h, dynamic value)
77  *      Usage (Y),                  ; Y (31h, dynamic value)
78  *      Usage (Wheel),              ; Wheel (38h, dynamic value)
79  *      Logical Minimum (-127),
80  *      Logical Maximum (127),
81  *      Report Size (8),
82  *      Report Count (3),
83  *      Input (Variable, Relative),
84  *    End Collection,
85  *  End Collection,
86  *  Usage Page (Digitizer),         ; Digitizer (0Dh)
87  *  Usage (Pen),                    ; Pen (02h, application collection)
88  *  Collection (Application),
89  *    Report ID (2),
90  *    Usage (Stylus),               ; Stylus (20h, logical collection)
91  *    Collection (Physical),
92  *      Usage (00h),
93  *      Logical Minimum (0),
94  *      Logical Maximum (255),
95  *      Report Size (8),
96  *      Report Count (7),
97  *      Input (Variable),
98  *      Usage (Azimuth),            ; Azimuth (3Fh, dynamic value)
99  *      Usage (Altitude),           ; Altitude (40h, dynamic value)
100  *      Logical Minimum (0),
101  *      Logical Maximum (255),
102  *      Report Size (8),
103  *      Report Count (2),
104  *      Feature (Variable),
105  *    End Collection,
106  *    Report ID (5),
107  *    Usage Page (Digitizer),       ; Digitizer (0Dh)
108  *    Usage (Stylus),               ; Stylus (20h, logical collection)
109  *    Collection (Physical),
110  *      Usage (00h),
111  *      Logical Minimum (0),
112  *      Logical Maximum (255),
113  *      Report Size (8),
114  *      Report Count (7),
115  *      Input (Variable),
116  *    End Collection,
117  *    Report ID (10),
118  *    Usage Page (Digitizer),       ; Digitizer (0Dh)
119  *    Usage (Stylus),               ; Stylus (20h, logical collection)
120  *    Collection (Physical),
121  *      Usage (00h),
122  *      Logical Minimum (0),
123  *      Logical Maximum (255),
124  *      Report Size (8),
125  *      Report Count (3),
126  *      Input (Variable),
127  *    End Collection,
128  *    Report ID (16),
129  *    Usage (Stylus),               ; Stylus (20h, logical collection)
130  *    Collection (Physical),
131  *      Usage (Tip Switch),         ; Tip switch (42h, momentary control)
132  *      Usage (Barrel Switch),      ; Barrel switch (44h, momentary control)
133  *      Usage (Invert),             ; Invert (3Ch, momentary control)
134  *      Usage (Eraser),             ; Eraser (45h, momentary control)
135  *      Usage (In Range),           ; In range (32h, momentary control)
136  *      Logical Minimum (0),
137  *      Logical Maximum (1),
138  *      Report Size (1),
139  *      Report Count (5),
140  *      Input (Variable),
141  *      Report Count (3),
142  *      Input (Constant, Variable),
143  *      Usage Page (Desktop),       ; Generic desktop controls (01h)
144  *      Usage (X),                  ; X (30h, dynamic value)
145  *      Report Size (16),
146  *      Report Count (1),
147  *      Push,
148  *      Unit Exponent (13),
149  *      Unit (Inch^3),
150  *      Logical Minimum (0),
151  *      Logical Maximum (10000),
152  *      Physical Minimum (0),
153  *      Physical Maximum (10000),
154  *      Input (Variable),
155  *      Usage (Y),                  ; Y (31h, dynamic value)
156  *      Logical Maximum (6000),
157  *      Physical Maximum (6000),
158  *      Input (Variable),
159  *      Usage Page (Digitizer),     ; Digitizer (0Dh)
160  *      Usage (Tip Pressure),       ; Tip pressure (30h, dynamic value)
161  *      Logical Minimum (0),
162  *      Logical Maximum (1023),
163  *      Physical Minimum (0),
164  *      Physical Maximum (1023),
165  *      Input (Variable),
166  *    End Collection,
167  *  End Collection
168  */
169
170 /* Size of the original report descriptor of Slim Tablet 5.8 inch */
171 #define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE    222
172
173 /*
174  * Fixed Slim Tablet 5.8 inch descriptor.
175  *
176  * All the reports except the stylus report (ID 16) were removed as unused.
177  * The stylus buttons description was fixed.
178  */
179 static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {
180         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
181         0x09, 0x02,         /*  Usage (Pen),                        */
182         0xA1, 0x01,         /*  Collection (Application),           */
183         0x85, 0x10,         /*      Report ID (16),                 */
184         0x09, 0x20,         /*      Usage (Stylus),                 */
185         0xA0,               /*      Collection (Physical),          */
186         0x09, 0x42,         /*          Usage (Tip Switch),         */
187         0x09, 0x44,         /*          Usage (Barrel Switch),      */
188         0x09, 0x46,         /*          Usage (Tablet Pick),        */
189         0x15, 0x01,         /*          Logical Minimum (1),        */
190         0x25, 0x03,         /*          Logical Maximum (3),        */
191         0x75, 0x04,         /*          Report Size (4),            */
192         0x95, 0x01,         /*          Report Count (1),           */
193         0x80,               /*          Input,                      */
194         0x09, 0x32,         /*          Usage (In Range),           */
195         0x14,               /*          Logical Minimum (0),        */
196         0x25, 0x01,         /*          Logical Maximum (1),        */
197         0x75, 0x01,         /*          Report Size (1),            */
198         0x95, 0x01,         /*          Report Count (1),           */
199         0x81, 0x02,         /*          Input (Variable),           */
200         0x95, 0x03,         /*          Report Count (3),           */
201         0x81, 0x03,         /*          Input (Constant, Variable), */
202         0x75, 0x10,         /*          Report Size (16),           */
203         0x95, 0x01,         /*          Report Count (1),           */
204         0x14,               /*          Logical Minimum (0),        */
205         0xA4,               /*          Push,                       */
206         0x05, 0x01,         /*          Usage Page (Desktop),       */
207         0x65, 0x13,         /*          Unit (Inch),                */
208         0x55, 0xFD,         /*          Unit Exponent (-3),         */
209         0x34,               /*          Physical Minimum (0),       */
210         0x09, 0x30,         /*          Usage (X),                  */
211         0x46, 0x88, 0x13,   /*          Physical Maximum (5000),    */
212         0x26, 0x10, 0x27,   /*          Logical Maximum (10000),    */
213         0x81, 0x02,         /*          Input (Variable),           */
214         0x09, 0x31,         /*          Usage (Y),                  */
215         0x46, 0xB8, 0x0B,   /*          Physical Maximum (3000),    */
216         0x26, 0x70, 0x17,   /*          Logical Maximum (6000),     */
217         0x81, 0x02,         /*          Input (Variable),           */
218         0xB4,               /*          Pop,                        */
219         0x09, 0x30,         /*          Usage (Tip Pressure),       */
220         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
221         0x81, 0x02,         /*          Input (Variable),           */
222         0xC0,               /*      End Collection,                 */
223         0xC0                /*  End Collection                      */
224 };
225
226 /*
227  * Original Media Tablet 10.6 inch report descriptor.
228  *
229  * There are at least two versions of this model in the wild. They are
230  * represented by Genius G-Pen M609 (older version) and Genius G-Pen M609X
231  * (newer version).
232  *
233  * Both versions have the usual pen with two barrel buttons and two
234  * identical wheels with center buttons in the top corners of the tablet
235  * base. They also have buttons on the top, between the wheels, for
236  * selecting the wheels' functions and wide/standard mode. In the wide mode
237  * the whole working surface is sensed, in the standard mode a narrower area
238  * is sensed, but the logical report extents remain the same. These modes
239  * correspond roughly to 16:9 and 4:3 aspect ratios respectively.
240  *
241  * The older version has three wheel function buttons ("scroll", "zoom" and
242  * "volume") and two separate buttons for wide and standard mode. The newer
243  * version has four wheel function buttons (plus "brush") and only one
244  * button is used for selecting wide/standard mode. So, the total number of
245  * buttons remains the same, but one of the mode buttons is repurposed as a
246  * wheels' function button in the newer version.
247  *
248  * The wheel functions are:
249  * scroll   - the wheels act as scroll wheels, the center buttons switch
250  *            between vertical and horizontal scrolling;
251  * zoom     - the wheels zoom in/out, the buttons supposedly reset to 100%;
252  * volume   - the wheels control the sound volume, the buttons mute;
253  * brush    - the wheels are supposed to control brush width in a graphics
254  *            editor, the buttons do nothing.
255  *
256  * Below is the newer version's report descriptor. It may very well be that
257  * the older version's descriptor is different and thus it won't be
258  * supported.
259  *
260  * The mouse report (ID 1) only uses the wheel field for reporting the tablet
261  * wheels' scroll mode. The keyboard report (ID 13) is used to report the
262  * wheels' zoom and brush control functions as key presses. The report ID 12
263  * is used to report the wheels' volume control functions. The stylus report
264  * (ID 16) has the same problems as the Slim Tablet 5.8 inch report has.
265  *
266  * The rest of the reports are unused, at least in the default configuration.
267  * The purpose of the features is unknown.
268  *
269  *  Usage Page (Desktop),
270  *  Usage (Mouse),
271  *  Collection (Application),
272  *    Report ID (1),
273  *    Usage (Pointer),
274  *    Collection (Physical),
275  *      Usage Page (Button),
276  *      Usage Minimum (01h),
277  *      Usage Maximum (05h),
278  *      Logical Minimum (0),
279  *      Logical Maximum (1),
280  *      Report Size (1),
281  *      Report Count (5),
282  *      Input (Variable),
283  *      Report Size (3),
284  *      Report Count (1),
285  *      Input (Constant, Variable),
286  *      Usage Page (Desktop),
287  *      Usage (X),
288  *      Usage (Y),
289  *      Usage (Wheel),
290  *      Logical Minimum (-127),
291  *      Logical Maximum (127),
292  *      Report Size (8),
293  *      Report Count (3),
294  *      Input (Variable, Relative),
295  *    End Collection,
296  *  End Collection,
297  *  Usage Page (Digitizer),
298  *  Usage (Pen),
299  *  Collection (Application),
300  *    Report ID (2),
301  *    Usage (Stylus),
302  *    Collection (Physical),
303  *      Usage (00h),
304  *      Logical Minimum (0),
305  *      Logical Maximum (255),
306  *      Report Size (8),
307  *      Report Count (7),
308  *      Input (Variable),
309  *      Usage (Azimuth),
310  *      Usage (Altitude),
311  *      Logical Minimum (0),
312  *      Logical Maximum (255),
313  *      Report Size (8),
314  *      Report Count (2),
315  *      Feature (Variable),
316  *    End Collection,
317  *    Report ID (5),
318  *    Usage Page (Digitizer),
319  *    Usage (Stylus),
320  *    Collection (Physical),
321  *      Usage (00h),
322  *      Logical Minimum (0),
323  *      Logical Maximum (255),
324  *      Report Size (8),
325  *      Report Count (7),
326  *      Input (Variable),
327  *    End Collection,
328  *    Report ID (10),
329  *    Usage Page (Digitizer),
330  *    Usage (Stylus),
331  *    Collection (Physical),
332  *      Usage (00h),
333  *      Logical Minimum (0),
334  *      Logical Maximum (255),
335  *      Report Size (8),
336  *      Report Count (7),
337  *      Input (Variable),
338  *    End Collection,
339  *    Report ID (16),
340  *    Usage (Stylus),
341  *    Collection (Physical),
342  *      Usage (Tip Switch),
343  *      Usage (Barrel Switch),
344  *      Usage (Invert),
345  *      Usage (Eraser),
346  *      Usage (In Range),
347  *      Logical Minimum (0),
348  *      Logical Maximum (1),
349  *      Report Size (1),
350  *      Report Count (5),
351  *      Input (Variable),
352  *      Report Count (3),
353  *      Input (Constant, Variable),
354  *      Usage Page (Desktop),
355  *      Usage (X),
356  *      Report Size (16),
357  *      Report Count (1),
358  *      Push,
359  *      Unit Exponent (13),
360  *      Unit (Inch^3),
361  *      Logical Minimum (0),
362  *      Logical Maximum (18000),
363  *      Physical Minimum (0),
364  *      Physical Maximum (18000),
365  *      Input (Variable),
366  *      Usage (Y),
367  *      Logical Maximum (11000),
368  *      Physical Maximum (11000),
369  *      Input (Variable),
370  *      Usage Page (Digitizer),
371  *      Usage (Tip Pressure),
372  *      Logical Minimum (0),
373  *      Logical Maximum (1023),
374  *      Physical Minimum (0),
375  *      Physical Maximum (1023),
376  *      Input (Variable),
377  *    End Collection,
378  *  End Collection,
379  *  Usage Page (Desktop),
380  *  Usage (Keyboard),
381  *  Collection (Application),
382  *    Report ID (13),
383  *    Usage Page (Keyboard),
384  *    Usage Minimum (KB Leftcontrol),
385  *    Usage Maximum (KB Right GUI),
386  *    Logical Minimum (0),
387  *    Logical Maximum (1),
388  *    Report Size (1),
389  *    Report Count (8),
390  *    Input (Variable),
391  *    Report Size (8),
392  *    Report Count (1),
393  *    Input (Constant),
394  *    Usage Page (Keyboard),
395  *    Usage Minimum (None),
396  *    Usage Maximum (KB Application),
397  *    Logical Minimum (0),
398  *    Logical Maximum (101),
399  *    Report Size (8),
400  *    Report Count (5),
401  *    Input,
402  *  End Collection,
403  *  Usage Page (Consumer),
404  *  Usage (Consumer Control),
405  *  Collection (Application),
406  *    Report ID (12),
407  *    Usage (Volume Inc),
408  *    Usage (Volume Dec),
409  *    Usage (Mute),
410  *    Logical Minimum (0),
411  *    Logical Maximum (1),
412  *    Report Size (1),
413  *    Report Count (3),
414  *    Input (Variable, Relative),
415  *    Report Size (5),
416  *    Report Count (1),
417  *    Input (Constant, Variable, Relative),
418  *  End Collection
419  */
420
421 /* Size of the original report descriptor of Media Tablet 10.6 inch */
422 #define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE  300
423
424 /*
425  * Fixed Media Tablet 10.6 inch descriptor.
426  *
427  * The descriptions of reports unused in the default configuration are
428  * removed. The stylus report (ID 16) is fixed similarly to Slim Tablet 5.8
429  * inch.  The unused mouse report (ID 1) fields are replaced with constant
430  * padding.
431  *
432  * The keyboard report (ID 13) is hacked to instead have an "array" field
433  * reporting consumer page controls, and all the unused bits are masked out
434  * with constant padding. The "brush" wheels' function is represented as "Scan
435  * Previous/Next Track" controls due to the lack of brush controls in the
436  * usage tables specification.
437  */
438 static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
439         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
440         0x09, 0x02,         /*  Usage (Pen),                        */
441         0xA1, 0x01,         /*  Collection (Application),           */
442         0x85, 0x10,         /*      Report ID (16),                 */
443         0x09, 0x20,         /*      Usage (Stylus),                 */
444         0xA0,               /*      Collection (Physical),          */
445         0x09, 0x42,         /*          Usage (Tip Switch),         */
446         0x09, 0x44,         /*          Usage (Barrel Switch),      */
447         0x09, 0x46,         /*          Usage (Tablet Pick),        */
448         0x15, 0x01,         /*          Logical Minimum (1),        */
449         0x25, 0x03,         /*          Logical Maximum (3),        */
450         0x75, 0x04,         /*          Report Size (4),            */
451         0x95, 0x01,         /*          Report Count (1),           */
452         0x80,               /*          Input,                      */
453         0x75, 0x01,         /*          Report Size (1),            */
454         0x09, 0x32,         /*          Usage (In Range),           */
455         0x14,               /*          Logical Minimum (0),        */
456         0x25, 0x01,         /*          Logical Maximum (1),        */
457         0x95, 0x01,         /*          Report Count (1),           */
458         0x81, 0x02,         /*          Input (Variable),           */
459         0x95, 0x03,         /*          Report Count (3),           */
460         0x81, 0x03,         /*          Input (Constant, Variable), */
461         0x75, 0x10,         /*          Report Size (16),           */
462         0x95, 0x01,         /*          Report Count (1),           */
463         0x14,               /*          Logical Minimum (0),        */
464         0xA4,               /*          Push,                       */
465         0x05, 0x01,         /*          Usage Page (Desktop),       */
466         0x65, 0x13,         /*          Unit (Inch),                */
467         0x55, 0xFD,         /*          Unit Exponent (-3),         */
468         0x34,               /*          Physical Minimum (0),       */
469         0x09, 0x30,         /*          Usage (X),                  */
470         0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */
471         0x26, 0x50, 0x46,   /*          Logical Maximum (18000),    */
472         0x81, 0x02,         /*          Input (Variable),           */
473         0x09, 0x31,         /*          Usage (Y),                  */
474         0x46, 0x7C, 0x15,   /*          Physical Maximum (5500),    */
475         0x26, 0xF8, 0x2A,   /*          Logical Maximum (11000),    */
476         0x81, 0x02,         /*          Input (Variable),           */
477         0xB4,               /*          Pop,                        */
478         0x09, 0x30,         /*          Usage (Tip Pressure),       */
479         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
480         0x81, 0x02,         /*          Input (Variable),           */
481         0xC0,               /*      End Collection,                 */
482         0xC0,               /*  End Collection,                     */
483         0x05, 0x01,         /*  Usage Page (Desktop),               */
484         0x09, 0x02,         /*  Usage (Mouse),                      */
485         0xA1, 0x01,         /*  Collection (Application),           */
486         0x85, 0x01,         /*      Report ID (1),                  */
487         0x09, 0x01,         /*      Usage (Pointer),                */
488         0xA0,               /*      Collection (Physical),          */
489         0x75, 0x08,         /*          Report Size (8),            */
490         0x95, 0x03,         /*          Report Count (3),           */
491         0x81, 0x03,         /*          Input (Constant, Variable), */
492         0x95, 0x02,         /*          Report Count (2),           */
493         0x15, 0xFF,         /*          Logical Minimum (-1),       */
494         0x25, 0x01,         /*          Logical Maximum (1),        */
495         0x09, 0x38,         /*          Usage (Wheel),              */
496         0x0B, 0x38, 0x02,   /*          Usage (Consumer AC Pan),    */
497                 0x0C, 0x00,
498         0x81, 0x06,         /*          Input (Variable, Relative), */
499         0x95, 0x02,         /*          Report Count (2),           */
500         0x81, 0x03,         /*          Input (Constant, Variable), */
501         0xC0,               /*      End Collection,                 */
502         0xC0,               /*  End Collection,                     */
503         0x05, 0x0C,         /*  Usage Page (Consumer),              */
504         0x09, 0x01,         /*  Usage (Consumer Control),           */
505         0xA1, 0x01,         /*  Collection (Application),           */
506         0x85, 0x0D,         /*      Report ID (13),                 */
507         0x95, 0x01,         /*      Report Count (1),               */
508         0x75, 0x10,         /*      Report Size (16),               */
509         0x81, 0x03,         /*      Input (Constant, Variable),     */
510         0x0A, 0x2F, 0x02,   /*      Usage (AC Zoom),                */
511         0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */
512         0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */
513         0x09, 0xB6,         /*      Usage (Scan Previous Track),    */
514         0x09, 0xB5,         /*      Usage (Scan Next Track),        */
515         0x08,               /*      Usage (00h),                    */
516         0x08,               /*      Usage (00h),                    */
517         0x08,               /*      Usage (00h),                    */
518         0x08,               /*      Usage (00h),                    */
519         0x08,               /*      Usage (00h),                    */
520         0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */
521         0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */
522         0x15, 0x0C,         /*      Logical Minimum (12),           */
523         0x25, 0x17,         /*      Logical Maximum (23),           */
524         0x75, 0x05,         /*      Report Size (5),                */
525         0x80,               /*      Input,                          */
526         0x75, 0x03,         /*      Report Size (3),                */
527         0x81, 0x03,         /*      Input (Constant, Variable),     */
528         0x75, 0x20,         /*      Report Size (32),               */
529         0x81, 0x03,         /*      Input (Constant, Variable),     */
530         0xC0,               /*  End Collection,                     */
531         0x09, 0x01,         /*  Usage (Consumer Control),           */
532         0xA1, 0x01,         /*  Collection (Application),           */
533         0x85, 0x0C,         /*      Report ID (12),                 */
534         0x75, 0x01,         /*      Report Size (1),                */
535         0x09, 0xE9,         /*      Usage (Volume Inc),             */
536         0x09, 0xEA,         /*      Usage (Volume Dec),             */
537         0x09, 0xE2,         /*      Usage (Mute),                   */
538         0x14,               /*      Logical Minimum (0),            */
539         0x25, 0x01,         /*      Logical Maximum (1),            */
540         0x95, 0x03,         /*      Report Count (3),               */
541         0x81, 0x06,         /*      Input (Variable, Relative),     */
542         0x95, 0x35,         /*      Report Count (53),              */
543         0x81, 0x03,         /*      Input (Constant, Variable),     */
544         0xC0                /*  End Collection                      */
545 };
546
547 /*
548  * Original Media Tablet 14.1 inch report descriptor.
549  *
550  * There are at least two versions of this model in the wild. They are
551  * represented by Genius G-Pen M712 (older version) and Genius G-Pen M712X
552  * (newer version). The hardware difference between these versions is the same
553  * as between older and newer versions of Media Tablet 10.6 inch. The report
554  * descriptors are identical for both versions.
555  *
556  * The function, behavior and report descriptor of this tablet is similar to
557  * that of Media Tablet 10.6 inch. However, there is one more field (with
558  * Consumer AC Pan usage) in the mouse description. Then the tablet X and Y
559  * logical extents both get scaled to 0..16383 range (a hardware limit?),
560  * which kind of defeats the advertised 4000 LPI resolution, considering the
561  * physical extents of 12x7.25 inches. Plus, reports 5, 10 and 255 are used
562  * sometimes (while moving the pen) with unknown purpose. Also, the key codes
563  * generated for zoom in/out are different.
564  *
565  *  Usage Page (Desktop),
566  *  Usage (Mouse),
567  *  Collection (Application),
568  *    Report ID (1),
569  *    Usage (Pointer),
570  *    Collection (Physical),
571  *      Usage Page (Button),
572  *      Usage Minimum (01h),
573  *      Usage Maximum (05h),
574  *      Logical Minimum (0),
575  *      Logical Maximum (1),
576  *      Report Size (1),
577  *      Report Count (5),
578  *      Input (Variable),
579  *      Report Size (3),
580  *      Report Count (1),
581  *      Input (Constant, Variable),
582  *      Usage Page (Desktop),
583  *      Usage (X),
584  *      Usage (Y),
585  *      Usage (Wheel),
586  *      Logical Minimum (-127),
587  *      Logical Maximum (127),
588  *      Report Size (8),
589  *      Report Count (3),
590  *      Input (Variable, Relative),
591  *      Usage Page (Consumer),
592  *      Logical Minimum (-127),
593  *      Logical Maximum (127),
594  *      Report Size (8),
595  *      Report Count (1),
596  *      Usage (AC Pan),
597  *      Input (Variable, Relative),
598  *    End Collection,
599  *  End Collection,
600  *  Usage Page (Digitizer),
601  *  Usage (Pen),
602  *  Collection (Application),
603  *    Report ID (2),
604  *    Usage (Stylus),
605  *    Collection (Physical),
606  *      Usage (00h),
607  *      Logical Minimum (0),
608  *      Logical Maximum (255),
609  *      Report Size (8),
610  *      Report Count (7),
611  *      Input (Variable),
612  *      Usage (Azimuth),
613  *      Usage (Altitude),
614  *      Logical Minimum (0),
615  *      Logical Maximum (255),
616  *      Report Size (8),
617  *      Report Count (2),
618  *      Feature (Variable),
619  *    End Collection,
620  *    Report ID (5),
621  *    Usage Page (Digitizer),
622  *    Usage (Stylus),
623  *    Collection (Physical),
624  *      Usage (00h),
625  *      Logical Minimum (0),
626  *      Logical Maximum (255),
627  *      Report Size (8),
628  *      Report Count (7),
629  *      Input (Variable),
630  *    End Collection,
631  *    Report ID (10),
632  *    Usage Page (Digitizer),
633  *    Usage (Stylus),
634  *    Collection (Physical),
635  *      Usage (00h),
636  *      Logical Minimum (0),
637  *      Logical Maximum (255),
638  *      Report Size (8),
639  *      Report Count (7),
640  *      Input (Variable),
641  *    End Collection,
642  *    Report ID (16),
643  *    Usage (Stylus),
644  *    Collection (Physical),
645  *      Usage (Tip Switch),
646  *      Usage (Barrel Switch),
647  *      Usage (Invert),
648  *      Usage (Eraser),
649  *      Usage (In Range),
650  *      Logical Minimum (0),
651  *      Logical Maximum (1),
652  *      Report Size (1),
653  *      Report Count (5),
654  *      Input (Variable),
655  *      Report Count (3),
656  *      Input (Constant, Variable),
657  *      Usage Page (Desktop),
658  *      Usage (X),
659  *      Report Size (16),
660  *      Report Count (1),
661  *      Push,
662  *      Unit Exponent (13),
663  *      Unit (Inch^3),
664  *      Logical Minimum (0),
665  *      Logical Maximum (16383),
666  *      Physical Minimum (0),
667  *      Physical Maximum (16383),
668  *      Input (Variable),
669  *      Usage (Y),
670  *      Input (Variable),
671  *      Usage Page (Digitizer),
672  *      Usage (Tip Pressure),
673  *      Logical Minimum (0),
674  *      Logical Maximum (1023),
675  *      Physical Minimum (0),
676  *      Physical Maximum (1023),
677  *      Input (Variable),
678  *    End Collection,
679  *  End Collection,
680  *  Usage Page (Desktop),
681  *  Usage (Keyboard),
682  *  Collection (Application),
683  *    Report ID (13),
684  *    Usage Page (Keyboard),
685  *    Usage Minimum (KB Leftcontrol),
686  *    Usage Maximum (KB Right GUI),
687  *    Logical Minimum (0),
688  *    Logical Maximum (1),
689  *    Report Size (1),
690  *    Report Count (8),
691  *    Input (Variable),
692  *    Report Size (8),
693  *    Report Count (1),
694  *    Input (Constant),
695  *    Usage Page (Keyboard),
696  *    Usage Minimum (None),
697  *    Usage Maximum (KB Application),
698  *    Logical Minimum (0),
699  *    Logical Maximum (101),
700  *    Report Size (8),
701  *    Report Count (5),
702  *    Input,
703  *  End Collection,
704  *  Usage Page (Consumer),
705  *  Usage (Consumer Control),
706  *  Collection (Application),
707  *    Report ID (12),
708  *    Usage (Volume Inc),
709  *    Usage (Volume Dec),
710  *    Usage (Mute),
711  *    Logical Minimum (0),
712  *    Logical Maximum (1),
713  *    Report Size (1),
714  *    Report Count (3),
715  *    Input (Variable, Relative),
716  *    Report Size (5),
717  *    Report Count (1),
718  *    Input (Constant, Variable, Relative),
719  *  End Collection
720  */
721
722 /* Size of the original report descriptor of Media Tablet 14.1 inch */
723 #define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE  309
724
725 /*
726  * Fixed Media Tablet 14.1 inch descriptor.
727  * It is fixed similarly to the Media Tablet 10.6 inch descriptor.
728  */
729 static __u8 media_tablet_14_1_inch_rdesc_fixed[] = {
730         0x05, 0x0D,         /*  Usage Page (Digitizer),             */
731         0x09, 0x02,         /*  Usage (Pen),                        */
732         0xA1, 0x01,         /*  Collection (Application),           */
733         0x85, 0x10,         /*      Report ID (16),                 */
734         0x09, 0x20,         /*      Usage (Stylus),                 */
735         0xA0,               /*      Collection (Physical),          */
736         0x09, 0x42,         /*          Usage (Tip Switch),         */
737         0x09, 0x44,         /*          Usage (Barrel Switch),      */
738         0x09, 0x46,         /*          Usage (Tablet Pick),        */
739         0x15, 0x01,         /*          Logical Minimum (1),        */
740         0x25, 0x03,         /*          Logical Maximum (3),        */
741         0x75, 0x04,         /*          Report Size (4),            */
742         0x95, 0x01,         /*          Report Count (1),           */
743         0x80,               /*          Input,                      */
744         0x75, 0x01,         /*          Report Size (1),            */
745         0x09, 0x32,         /*          Usage (In Range),           */
746         0x14,               /*          Logical Minimum (0),        */
747         0x25, 0x01,         /*          Logical Maximum (1),        */
748         0x95, 0x01,         /*          Report Count (1),           */
749         0x81, 0x02,         /*          Input (Variable),           */
750         0x95, 0x03,         /*          Report Count (3),           */
751         0x81, 0x03,         /*          Input (Constant, Variable), */
752         0x75, 0x10,         /*          Report Size (16),           */
753         0x95, 0x01,         /*          Report Count (1),           */
754         0x14,               /*          Logical Minimum (0),        */
755         0xA4,               /*          Push,                       */
756         0x05, 0x01,         /*          Usage Page (Desktop),       */
757         0x65, 0x13,         /*          Unit (Inch),                */
758         0x55, 0xFD,         /*          Unit Exponent (-3),         */
759         0x34,               /*          Physical Minimum (0),       */
760         0x09, 0x30,         /*          Usage (X),                  */
761         0x46, 0xE0, 0x2E,   /*          Physical Maximum (12000),   */
762         0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),    */
763         0x81, 0x02,         /*          Input (Variable),           */
764         0x09, 0x31,         /*          Usage (Y),                  */
765         0x46, 0x52, 0x1C,   /*          Physical Maximum (7250),    */
766         0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),    */
767         0x81, 0x02,         /*          Input (Variable),           */
768         0xB4,               /*          Pop,                        */
769         0x09, 0x30,         /*          Usage (Tip Pressure),       */
770         0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
771         0x81, 0x02,         /*          Input (Variable),           */
772         0xC0,               /*      End Collection,                 */
773         0xC0,               /*  End Collection,                     */
774         0x05, 0x01,         /*  Usage Page (Desktop),               */
775         0x09, 0x02,         /*  Usage (Mouse),                      */
776         0xA1, 0x01,         /*  Collection (Application),           */
777         0x85, 0x01,         /*      Report ID (1),                  */
778         0x09, 0x01,         /*      Usage (Pointer),                */
779         0xA0,               /*      Collection (Physical),          */
780         0x75, 0x08,         /*          Report Size (8),            */
781         0x95, 0x03,         /*          Report Count (3),           */
782         0x81, 0x03,         /*          Input (Constant, Variable), */
783         0x95, 0x02,         /*          Report Count (2),           */
784         0x15, 0xFF,         /*          Logical Minimum (-1),       */
785         0x25, 0x01,         /*          Logical Maximum (1),        */
786         0x09, 0x38,         /*          Usage (Wheel),              */
787         0x0B, 0x38, 0x02,   /*          Usage (Consumer AC Pan),    */
788                 0x0C, 0x00,
789         0x81, 0x06,         /*          Input (Variable, Relative), */
790         0xC0,               /*      End Collection,                 */
791         0xC0,               /*  End Collection,                     */
792         0x05, 0x0C,         /*  Usage Page (Consumer),              */
793         0x09, 0x01,         /*  Usage (Consumer Control),           */
794         0xA1, 0x01,         /*  Collection (Application),           */
795         0x85, 0x0D,         /*      Report ID (13),                 */
796         0x95, 0x01,         /*      Report Count (1),               */
797         0x75, 0x10,         /*      Report Size (16),               */
798         0x81, 0x03,         /*      Input (Constant, Variable),     */
799         0x0A, 0x2F, 0x02,   /*      Usage (AC Zoom),                */
800         0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */
801         0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */
802         0x09, 0xB6,         /*      Usage (Scan Previous Track),    */
803         0x09, 0xB5,         /*      Usage (Scan Next Track),        */
804         0x08,               /*      Usage (00h),                    */
805         0x08,               /*      Usage (00h),                    */
806         0x08,               /*      Usage (00h),                    */
807         0x08,               /*      Usage (00h),                    */
808         0x08,               /*      Usage (00h),                    */
809         0x0A, 0x2E, 0x02,   /*      Usage (AC Zoom Out),            */
810         0x0A, 0x2D, 0x02,   /*      Usage (AC Zoom In),             */
811         0x15, 0x0C,         /*      Logical Minimum (12),           */
812         0x25, 0x17,         /*      Logical Maximum (23),           */
813         0x75, 0x05,         /*      Report Size (5),                */
814         0x80,               /*      Input,                          */
815         0x75, 0x03,         /*      Report Size (3),                */
816         0x81, 0x03,         /*      Input (Constant, Variable),     */
817         0x75, 0x20,         /*      Report Size (32),               */
818         0x81, 0x03,         /*      Input (Constant, Variable),     */
819         0xC0,               /*  End Collection,                     */
820         0x09, 0x01,         /*  Usage (Consumer Control),           */
821         0xA1, 0x01,         /*  Collection (Application),           */
822         0x85, 0x0C,         /*      Report ID (12),                 */
823         0x75, 0x01,         /*      Report Size (1),                */
824         0x09, 0xE9,         /*      Usage (Volume Inc),             */
825         0x09, 0xEA,         /*      Usage (Volume Dec),             */
826         0x09, 0xE2,         /*      Usage (Mute),                   */
827         0x14,               /*      Logical Minimum (0),            */
828         0x25, 0x01,         /*      Logical Maximum (1),            */
829         0x95, 0x03,         /*      Report Count (3),               */
830         0x81, 0x06,         /*      Input (Variable, Relative),     */
831         0x75, 0x05,         /*      Report Size (5),                */
832         0x81, 0x03,         /*      Input (Constant, Variable),     */
833         0xC0                /*  End Collection                      */
834 };
835
836 static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
837                 unsigned int *rsize)
838 {
839         switch (hdev->product) {
840         case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
841                 if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
842                         rdesc = slim_tablet_5_8_inch_rdesc_fixed;
843                         *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
844                 }
845                 break;
846         case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
847                 if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
848                         rdesc = media_tablet_10_6_inch_rdesc_fixed;
849                         *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
850                 }
851                 break;
852         case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:
853                 if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {
854                         rdesc = media_tablet_14_1_inch_rdesc_fixed;
855                         *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);
856                 }
857                 break;
858         }
859         return rdesc;
860 }
861
862 static const struct hid_device_id waltop_devices[] = {
863         { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
864                                 USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
865         { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
866                                 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
867         { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
868                                 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
869         { }
870 };
871 MODULE_DEVICE_TABLE(hid, waltop_devices);
872
873 static struct hid_driver waltop_driver = {
874         .name = "waltop",
875         .id_table = waltop_devices,
876         .report_fixup = waltop_report_fixup,
877 };
878
879 static int __init waltop_init(void)
880 {
881         return hid_register_driver(&waltop_driver);
882 }
883
884 static void __exit waltop_exit(void)
885 {
886         hid_unregister_driver(&waltop_driver);
887 }
888
889 module_init(waltop_init);
890 module_exit(waltop_exit);
891 MODULE_LICENSE("GPL");