blob: b3a4163f2e67c1211a5b8cf7f6221cbad425493a [file] [log] [blame]
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001/*
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/*
Nikolai Kondrashovcdd49a82010-08-30 14:06:38 +040021 * 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/*
Nikolai Kondrashov72a46342010-08-20 19:21:11 +040046 * 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
Nikolai Kondrashovcdd49a82010-08-30 14:06:38 +040050 * just copied from a more capable model. The full purpose of features
51 * described for report ID 2 is unknown.
Nikolai Kondrashov72a46342010-08-20 19:21:11 +040052 *
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 */
179static __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/*
Nikolai Kondrashov00e7f962010-09-25 23:16:58 +0400227 * Original Slim Tablet 12.1 inch report descriptor.
228 *
229 * The descriptor is similar to the Slim Tablet 5.8 inch descriptor with the
230 * addition of a keyboard report, seemingly unused. It may have get here
231 * from a Media Tablet - probably an unimplemented feature.
232 *
233 * Usage Page (Desktop), ; Generic desktop controls (01h)
234 * Usage (Mouse), ; Mouse (02h, application collection)
235 * Collection (Application),
236 * Report ID (1),
237 * Usage (Pointer), ; Pointer (01h, physical collection)
238 * Collection (Physical),
239 * Usage Page (Button), ; Button (09h)
240 * Usage Minimum (01h),
241 * Usage Maximum (05h),
242 * Logical Minimum (0),
243 * Logical Maximum (1),
244 * Report Size (1),
245 * Report Count (5),
246 * Input (Variable),
247 * Report Size (3),
248 * Report Count (1),
249 * Input (Constant, Variable),
250 * Usage Page (Desktop), ; Generic desktop controls (01h)
251 * Usage (X), ; X (30h, dynamic value)
252 * Usage (Y), ; Y (31h, dynamic value)
253 * Usage (Wheel), ; Wheel (38h, dynamic value)
254 * Logical Minimum (-127),
255 * Logical Maximum (127),
256 * Report Size (8),
257 * Report Count (3),
258 * Input (Variable, Relative),
259 * End Collection,
260 * End Collection,
261 * Usage Page (Digitizer), ; Digitizer (0Dh)
262 * Usage (Pen), ; Pen (02h, application collection)
263 * Collection (Application),
264 * Report ID (2),
265 * Usage (Stylus), ; Stylus (20h, logical collection)
266 * Collection (Physical),
267 * Usage (00h),
268 * Logical Minimum (0),
269 * Logical Maximum (255),
270 * Report Size (8),
271 * Report Count (7),
272 * Input (Variable),
273 * Usage (Azimuth), ; Azimuth (3Fh, dynamic value)
274 * Usage (Altitude), ; Altitude (40h, dynamic value)
275 * Logical Minimum (0),
276 * Logical Maximum (255),
277 * Report Size (8),
278 * Report Count (2),
279 * Feature (Variable),
280 * End Collection,
281 * Report ID (5),
282 * Usage Page (Digitizer), ; Digitizer (0Dh)
283 * Usage (Stylus), ; Stylus (20h, logical collection)
284 * Collection (Physical),
285 * Usage (00h),
286 * Logical Minimum (0),
287 * Logical Maximum (255),
288 * Report Size (8),
289 * Report Count (7),
290 * Input (Variable),
291 * End Collection,
292 * Report ID (10),
293 * Usage Page (Digitizer), ; Digitizer (0Dh)
294 * Usage (Stylus), ; Stylus (20h, logical collection)
295 * Collection (Physical),
296 * Usage (00h),
297 * Logical Minimum (0),
298 * Logical Maximum (255),
299 * Report Size (8),
300 * Report Count (3),
301 * Input (Variable),
302 * End Collection,
303 * Report ID (16),
304 * Usage (Stylus), ; Stylus (20h, logical collection)
305 * Collection (Physical),
306 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
307 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
308 * Usage (Invert), ; Invert (3Ch, momentary control)
309 * Usage (Eraser), ; Eraser (45h, momentary control)
310 * Usage (In Range), ; In range (32h, momentary control)
311 * Logical Minimum (0),
312 * Logical Maximum (1),
313 * Report Size (1),
314 * Report Count (5),
315 * Input (Variable),
316 * Report Count (3),
317 * Input (Constant, Variable),
318 * Usage Page (Desktop), ; Generic desktop controls (01h)
319 * Usage (X), ; X (30h, dynamic value)
320 * Report Size (16),
321 * Report Count (1),
322 * Push,
323 * Unit Exponent (13),
324 * Unit (Inch^3),
325 * Logical Minimum (0),
326 * Logical Maximum (20000),
327 * Physical Minimum (0),
328 * Physical Maximum (20000),
329 * Input (Variable),
330 * Usage (Y), ; Y (31h, dynamic value)
331 * Logical Maximum (12500),
332 * Physical Maximum (12500),
333 * Input (Variable),
334 * Usage Page (Digitizer), ; Digitizer (0Dh)
335 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
336 * Logical Minimum (0),
337 * Logical Maximum (1023),
338 * Physical Minimum (0),
339 * Physical Maximum (1023),
340 * Input (Variable),
341 * End Collection,
342 * End Collection,
343 * Usage Page (Desktop), ; Generic desktop controls (01h)
344 * Usage (Keyboard), ; Keyboard (06h, application collection)
345 * Collection (Application),
346 * Report ID (13),
347 * Usage Page (Keyboard), ; Keyboard/keypad (07h)
348 * Usage Minimum (KB Leftcontrol), ; Keyboard left control
349 * ; (E0h, dynamic value)
350 * Usage Maximum (KB Right GUI), ; Keyboard right GUI (E7h, dynamic value)
351 * Logical Minimum (0),
352 * Logical Maximum (1),
353 * Report Size (1),
354 * Report Count (8),
355 * Input (Variable),
356 * Report Size (8),
357 * Report Count (1),
358 * Input (Constant),
359 * Usage Page (Keyboard), ; Keyboard/keypad (07h)
360 * Usage Minimum (None), ; No event (00h, selector)
361 * Usage Maximum (KB Application), ; Keyboard Application (65h, selector)
362 * Logical Minimum (0),
363 * Logical Maximum (101),
364 * Report Size (8),
365 * Report Count (5),
366 * Input,
367 * End Collection
368 */
369
370/* Size of the original report descriptor of Slim Tablet 12.1 inch */
371#define SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE 269
372
373/*
374 * Fixed Slim Tablet 12.1 inch descriptor.
375 *
376 * All the reports except the stylus report (ID 16) were removed as unused.
377 * The stylus buttons description was fixed.
378 */
379static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = {
380 0x05, 0x0D, /* Usage Page (Digitizer), */
381 0x09, 0x02, /* Usage (Pen), */
382 0xA1, 0x01, /* Collection (Application), */
383 0x85, 0x10, /* Report ID (16), */
384 0x09, 0x20, /* Usage (Stylus), */
385 0xA0, /* Collection (Physical), */
386 0x09, 0x42, /* Usage (Tip Switch), */
387 0x09, 0x44, /* Usage (Barrel Switch), */
388 0x09, 0x46, /* Usage (Tablet Pick), */
389 0x15, 0x01, /* Logical Minimum (1), */
390 0x25, 0x03, /* Logical Maximum (3), */
391 0x75, 0x04, /* Report Size (4), */
392 0x95, 0x01, /* Report Count (1), */
393 0x80, /* Input, */
394 0x09, 0x32, /* Usage (In Range), */
395 0x14, /* Logical Minimum (0), */
396 0x25, 0x01, /* Logical Maximum (1), */
397 0x75, 0x01, /* Report Size (1), */
398 0x95, 0x01, /* Report Count (1), */
399 0x81, 0x02, /* Input (Variable), */
400 0x95, 0x03, /* Report Count (3), */
401 0x81, 0x03, /* Input (Constant, Variable), */
402 0x75, 0x10, /* Report Size (16), */
403 0x95, 0x01, /* Report Count (1), */
404 0x14, /* Logical Minimum (0), */
405 0xA4, /* Push, */
406 0x05, 0x01, /* Usage Page (Desktop), */
407 0x65, 0x13, /* Unit (Inch), */
408 0x55, 0xFD, /* Unit Exponent (-3), */
409 0x34, /* Physical Minimum (0), */
410 0x09, 0x30, /* Usage (X), */
411 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
412 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
413 0x81, 0x02, /* Input (Variable), */
414 0x09, 0x31, /* Usage (Y), */
415 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */
416 0x26, 0xD4, 0x30, /* Logical Maximum (12500), */
417 0x81, 0x02, /* Input (Variable), */
418 0xB4, /* Pop, */
419 0x09, 0x30, /* Usage (Tip Pressure), */
420 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
421 0x81, 0x02, /* Input (Variable), */
422 0xC0, /* End Collection, */
423 0xC0 /* End Collection */
424};
425
426/*
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400427 * Original Media Tablet 10.6 inch report descriptor.
428 *
429 * There are at least two versions of this model in the wild. They are
430 * represented by Genius G-Pen M609 (older version) and Genius G-Pen M609X
431 * (newer version).
432 *
433 * Both versions have the usual pen with two barrel buttons and two
434 * identical wheels with center buttons in the top corners of the tablet
435 * base. They also have buttons on the top, between the wheels, for
436 * selecting the wheels' functions and wide/standard mode. In the wide mode
437 * the whole working surface is sensed, in the standard mode a narrower area
438 * is sensed, but the logical report extents remain the same. These modes
439 * correspond roughly to 16:9 and 4:3 aspect ratios respectively.
440 *
441 * The older version has three wheel function buttons ("scroll", "zoom" and
442 * "volume") and two separate buttons for wide and standard mode. The newer
443 * version has four wheel function buttons (plus "brush") and only one
444 * button is used for selecting wide/standard mode. So, the total number of
445 * buttons remains the same, but one of the mode buttons is repurposed as a
446 * wheels' function button in the newer version.
447 *
448 * The wheel functions are:
Nikolai Kondrashov4b5b45752010-08-30 14:06:35 +0400449 * scroll - the wheels act as scroll wheels, the center buttons switch
450 * between vertical and horizontal scrolling;
451 * zoom - the wheels zoom in/out, the buttons supposedly reset to 100%;
452 * volume - the wheels control the sound volume, the buttons mute;
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400453 * brush - the wheels are supposed to control brush width in a graphics
454 * editor, the buttons do nothing.
455 *
456 * Below is the newer version's report descriptor. It may very well be that
457 * the older version's descriptor is different and thus it won't be
458 * supported.
459 *
460 * The mouse report (ID 1) only uses the wheel field for reporting the tablet
461 * wheels' scroll mode. The keyboard report (ID 13) is used to report the
462 * wheels' zoom and brush control functions as key presses. The report ID 12
463 * is used to report the wheels' volume control functions. The stylus report
464 * (ID 16) has the same problems as the Slim Tablet 5.8 inch report has.
465 *
466 * The rest of the reports are unused, at least in the default configuration.
467 * The purpose of the features is unknown.
468 *
469 * Usage Page (Desktop),
470 * Usage (Mouse),
471 * Collection (Application),
472 * Report ID (1),
473 * Usage (Pointer),
474 * Collection (Physical),
475 * Usage Page (Button),
476 * Usage Minimum (01h),
477 * Usage Maximum (05h),
478 * Logical Minimum (0),
479 * Logical Maximum (1),
480 * Report Size (1),
481 * Report Count (5),
482 * Input (Variable),
483 * Report Size (3),
484 * Report Count (1),
485 * Input (Constant, Variable),
486 * Usage Page (Desktop),
487 * Usage (X),
488 * Usage (Y),
489 * Usage (Wheel),
490 * Logical Minimum (-127),
491 * Logical Maximum (127),
492 * Report Size (8),
493 * Report Count (3),
494 * Input (Variable, Relative),
495 * End Collection,
496 * End Collection,
497 * Usage Page (Digitizer),
498 * Usage (Pen),
499 * Collection (Application),
500 * Report ID (2),
501 * Usage (Stylus),
502 * Collection (Physical),
503 * Usage (00h),
504 * Logical Minimum (0),
505 * Logical Maximum (255),
506 * Report Size (8),
507 * Report Count (7),
508 * Input (Variable),
509 * Usage (Azimuth),
510 * Usage (Altitude),
511 * Logical Minimum (0),
512 * Logical Maximum (255),
513 * Report Size (8),
514 * Report Count (2),
515 * Feature (Variable),
516 * End Collection,
517 * Report ID (5),
518 * Usage Page (Digitizer),
519 * Usage (Stylus),
520 * Collection (Physical),
521 * Usage (00h),
522 * Logical Minimum (0),
523 * Logical Maximum (255),
524 * Report Size (8),
525 * Report Count (7),
526 * Input (Variable),
527 * End Collection,
528 * Report ID (10),
529 * Usage Page (Digitizer),
530 * Usage (Stylus),
531 * Collection (Physical),
532 * Usage (00h),
533 * Logical Minimum (0),
534 * Logical Maximum (255),
535 * Report Size (8),
536 * Report Count (7),
537 * Input (Variable),
538 * End Collection,
539 * Report ID (16),
540 * Usage (Stylus),
541 * Collection (Physical),
542 * Usage (Tip Switch),
543 * Usage (Barrel Switch),
544 * Usage (Invert),
545 * Usage (Eraser),
546 * Usage (In Range),
547 * Logical Minimum (0),
548 * Logical Maximum (1),
549 * Report Size (1),
550 * Report Count (5),
551 * Input (Variable),
552 * Report Count (3),
553 * Input (Constant, Variable),
554 * Usage Page (Desktop),
555 * Usage (X),
556 * Report Size (16),
557 * Report Count (1),
558 * Push,
559 * Unit Exponent (13),
560 * Unit (Inch^3),
561 * Logical Minimum (0),
562 * Logical Maximum (18000),
563 * Physical Minimum (0),
564 * Physical Maximum (18000),
565 * Input (Variable),
566 * Usage (Y),
567 * Logical Maximum (11000),
568 * Physical Maximum (11000),
569 * Input (Variable),
570 * Usage Page (Digitizer),
571 * Usage (Tip Pressure),
572 * Logical Minimum (0),
573 * Logical Maximum (1023),
574 * Physical Minimum (0),
575 * Physical Maximum (1023),
576 * Input (Variable),
577 * End Collection,
578 * End Collection,
579 * Usage Page (Desktop),
580 * Usage (Keyboard),
581 * Collection (Application),
582 * Report ID (13),
583 * Usage Page (Keyboard),
584 * Usage Minimum (KB Leftcontrol),
585 * Usage Maximum (KB Right GUI),
586 * Logical Minimum (0),
587 * Logical Maximum (1),
588 * Report Size (1),
589 * Report Count (8),
590 * Input (Variable),
591 * Report Size (8),
592 * Report Count (1),
593 * Input (Constant),
594 * Usage Page (Keyboard),
595 * Usage Minimum (None),
596 * Usage Maximum (KB Application),
597 * Logical Minimum (0),
598 * Logical Maximum (101),
599 * Report Size (8),
600 * Report Count (5),
601 * Input,
602 * End Collection,
603 * Usage Page (Consumer),
604 * Usage (Consumer Control),
605 * Collection (Application),
606 * Report ID (12),
607 * Usage (Volume Inc),
608 * Usage (Volume Dec),
609 * Usage (Mute),
610 * Logical Minimum (0),
611 * Logical Maximum (1),
612 * Report Size (1),
613 * Report Count (3),
614 * Input (Variable, Relative),
615 * Report Size (5),
616 * Report Count (1),
617 * Input (Constant, Variable, Relative),
618 * End Collection
619 */
620
621/* Size of the original report descriptor of Media Tablet 10.6 inch */
622#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300
623
624/*
625 * Fixed Media Tablet 10.6 inch descriptor.
626 *
627 * The descriptions of reports unused in the default configuration are
628 * removed. The stylus report (ID 16) is fixed similarly to Slim Tablet 5.8
629 * inch. The unused mouse report (ID 1) fields are replaced with constant
630 * padding.
631 *
632 * The keyboard report (ID 13) is hacked to instead have an "array" field
633 * reporting consumer page controls, and all the unused bits are masked out
634 * with constant padding. The "brush" wheels' function is represented as "Scan
635 * Previous/Next Track" controls due to the lack of brush controls in the
636 * usage tables specification.
637 */
638static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
639 0x05, 0x0D, /* Usage Page (Digitizer), */
640 0x09, 0x02, /* Usage (Pen), */
641 0xA1, 0x01, /* Collection (Application), */
642 0x85, 0x10, /* Report ID (16), */
643 0x09, 0x20, /* Usage (Stylus), */
644 0xA0, /* Collection (Physical), */
645 0x09, 0x42, /* Usage (Tip Switch), */
646 0x09, 0x44, /* Usage (Barrel Switch), */
647 0x09, 0x46, /* Usage (Tablet Pick), */
648 0x15, 0x01, /* Logical Minimum (1), */
649 0x25, 0x03, /* Logical Maximum (3), */
650 0x75, 0x04, /* Report Size (4), */
651 0x95, 0x01, /* Report Count (1), */
652 0x80, /* Input, */
653 0x75, 0x01, /* Report Size (1), */
654 0x09, 0x32, /* Usage (In Range), */
655 0x14, /* Logical Minimum (0), */
656 0x25, 0x01, /* Logical Maximum (1), */
657 0x95, 0x01, /* Report Count (1), */
658 0x81, 0x02, /* Input (Variable), */
659 0x95, 0x03, /* Report Count (3), */
660 0x81, 0x03, /* Input (Constant, Variable), */
661 0x75, 0x10, /* Report Size (16), */
662 0x95, 0x01, /* Report Count (1), */
663 0x14, /* Logical Minimum (0), */
664 0xA4, /* Push, */
665 0x05, 0x01, /* Usage Page (Desktop), */
666 0x65, 0x13, /* Unit (Inch), */
667 0x55, 0xFD, /* Unit Exponent (-3), */
668 0x34, /* Physical Minimum (0), */
669 0x09, 0x30, /* Usage (X), */
670 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
671 0x26, 0x50, 0x46, /* Logical Maximum (18000), */
672 0x81, 0x02, /* Input (Variable), */
673 0x09, 0x31, /* Usage (Y), */
674 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
675 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */
676 0x81, 0x02, /* Input (Variable), */
677 0xB4, /* Pop, */
678 0x09, 0x30, /* Usage (Tip Pressure), */
679 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
680 0x81, 0x02, /* Input (Variable), */
681 0xC0, /* End Collection, */
682 0xC0, /* End Collection, */
683 0x05, 0x01, /* Usage Page (Desktop), */
684 0x09, 0x02, /* Usage (Mouse), */
685 0xA1, 0x01, /* Collection (Application), */
686 0x85, 0x01, /* Report ID (1), */
687 0x09, 0x01, /* Usage (Pointer), */
688 0xA0, /* Collection (Physical), */
Nikolai Kondrashov4b5b45752010-08-30 14:06:35 +0400689 0x75, 0x08, /* Report Size (8), */
690 0x95, 0x03, /* Report Count (3), */
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400691 0x81, 0x03, /* Input (Constant, Variable), */
Nikolai Kondrashov4b5b45752010-08-30 14:06:35 +0400692 0x95, 0x02, /* Report Count (2), */
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400693 0x15, 0xFF, /* Logical Minimum (-1), */
694 0x25, 0x01, /* Logical Maximum (1), */
Nikolai Kondrashov4b5b45752010-08-30 14:06:35 +0400695 0x09, 0x38, /* Usage (Wheel), */
696 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
697 0x0C, 0x00,
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400698 0x81, 0x06, /* Input (Variable, Relative), */
Nikolai Kondrashov4b5b45752010-08-30 14:06:35 +0400699 0x95, 0x02, /* Report Count (2), */
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400700 0x81, 0x03, /* Input (Constant, Variable), */
701 0xC0, /* End Collection, */
702 0xC0, /* End Collection, */
703 0x05, 0x0C, /* Usage Page (Consumer), */
704 0x09, 0x01, /* Usage (Consumer Control), */
705 0xA1, 0x01, /* Collection (Application), */
706 0x85, 0x0D, /* Report ID (13), */
707 0x95, 0x01, /* Report Count (1), */
708 0x75, 0x10, /* Report Size (16), */
709 0x81, 0x03, /* Input (Constant, Variable), */
710 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
711 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
712 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
713 0x09, 0xB6, /* Usage (Scan Previous Track), */
714 0x09, 0xB5, /* Usage (Scan Next Track), */
Nikolai Kondrashov30311542010-08-30 14:06:37 +0400715 0x08, /* Usage (00h), */
716 0x08, /* Usage (00h), */
717 0x08, /* Usage (00h), */
718 0x08, /* Usage (00h), */
719 0x08, /* Usage (00h), */
720 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
721 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
722 0x15, 0x0C, /* Logical Minimum (12), */
723 0x25, 0x17, /* Logical Maximum (23), */
724 0x75, 0x05, /* Report Size (5), */
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400725 0x80, /* Input, */
Nikolai Kondrashov30311542010-08-30 14:06:37 +0400726 0x75, 0x03, /* Report Size (3), */
727 0x81, 0x03, /* Input (Constant, Variable), */
Nikolai Kondrashov72a46342010-08-20 19:21:11 +0400728 0x75, 0x20, /* Report Size (32), */
729 0x81, 0x03, /* Input (Constant, Variable), */
730 0xC0, /* End Collection, */
731 0x09, 0x01, /* Usage (Consumer Control), */
732 0xA1, 0x01, /* Collection (Application), */
733 0x85, 0x0C, /* Report ID (12), */
734 0x75, 0x01, /* Report Size (1), */
735 0x09, 0xE9, /* Usage (Volume Inc), */
736 0x09, 0xEA, /* Usage (Volume Dec), */
737 0x09, 0xE2, /* Usage (Mute), */
738 0x14, /* Logical Minimum (0), */
739 0x25, 0x01, /* Logical Maximum (1), */
740 0x95, 0x03, /* Report Count (3), */
741 0x81, 0x06, /* Input (Variable, Relative), */
742 0x95, 0x35, /* Report Count (53), */
743 0x81, 0x03, /* Input (Constant, Variable), */
744 0xC0 /* End Collection */
745};
746
Nikolai Kondrashov8f1acc32010-08-30 14:06:36 +0400747/*
748 * Original Media Tablet 14.1 inch report descriptor.
749 *
750 * There are at least two versions of this model in the wild. They are
751 * represented by Genius G-Pen M712 (older version) and Genius G-Pen M712X
752 * (newer version). The hardware difference between these versions is the same
753 * as between older and newer versions of Media Tablet 10.6 inch. The report
754 * descriptors are identical for both versions.
755 *
756 * The function, behavior and report descriptor of this tablet is similar to
757 * that of Media Tablet 10.6 inch. However, there is one more field (with
758 * Consumer AC Pan usage) in the mouse description. Then the tablet X and Y
759 * logical extents both get scaled to 0..16383 range (a hardware limit?),
760 * which kind of defeats the advertised 4000 LPI resolution, considering the
761 * physical extents of 12x7.25 inches. Plus, reports 5, 10 and 255 are used
762 * sometimes (while moving the pen) with unknown purpose. Also, the key codes
763 * generated for zoom in/out are different.
764 *
765 * Usage Page (Desktop),
766 * Usage (Mouse),
767 * Collection (Application),
768 * Report ID (1),
769 * Usage (Pointer),
770 * Collection (Physical),
771 * Usage Page (Button),
772 * Usage Minimum (01h),
773 * Usage Maximum (05h),
774 * Logical Minimum (0),
775 * Logical Maximum (1),
776 * Report Size (1),
777 * Report Count (5),
778 * Input (Variable),
779 * Report Size (3),
780 * Report Count (1),
781 * Input (Constant, Variable),
782 * Usage Page (Desktop),
783 * Usage (X),
784 * Usage (Y),
785 * Usage (Wheel),
786 * Logical Minimum (-127),
787 * Logical Maximum (127),
788 * Report Size (8),
789 * Report Count (3),
790 * Input (Variable, Relative),
791 * Usage Page (Consumer),
792 * Logical Minimum (-127),
793 * Logical Maximum (127),
794 * Report Size (8),
795 * Report Count (1),
796 * Usage (AC Pan),
797 * Input (Variable, Relative),
798 * End Collection,
799 * End Collection,
800 * Usage Page (Digitizer),
801 * Usage (Pen),
802 * Collection (Application),
803 * Report ID (2),
804 * Usage (Stylus),
805 * Collection (Physical),
806 * Usage (00h),
807 * Logical Minimum (0),
808 * Logical Maximum (255),
809 * Report Size (8),
810 * Report Count (7),
811 * Input (Variable),
812 * Usage (Azimuth),
813 * Usage (Altitude),
814 * Logical Minimum (0),
815 * Logical Maximum (255),
816 * Report Size (8),
817 * Report Count (2),
818 * Feature (Variable),
819 * End Collection,
820 * Report ID (5),
821 * Usage Page (Digitizer),
822 * Usage (Stylus),
823 * Collection (Physical),
824 * Usage (00h),
825 * Logical Minimum (0),
826 * Logical Maximum (255),
827 * Report Size (8),
828 * Report Count (7),
829 * Input (Variable),
830 * End Collection,
831 * Report ID (10),
832 * Usage Page (Digitizer),
833 * Usage (Stylus),
834 * Collection (Physical),
835 * Usage (00h),
836 * Logical Minimum (0),
837 * Logical Maximum (255),
838 * Report Size (8),
839 * Report Count (7),
840 * Input (Variable),
841 * End Collection,
842 * Report ID (16),
843 * Usage (Stylus),
844 * Collection (Physical),
845 * Usage (Tip Switch),
846 * Usage (Barrel Switch),
847 * Usage (Invert),
848 * Usage (Eraser),
849 * Usage (In Range),
850 * Logical Minimum (0),
851 * Logical Maximum (1),
852 * Report Size (1),
853 * Report Count (5),
854 * Input (Variable),
855 * Report Count (3),
856 * Input (Constant, Variable),
857 * Usage Page (Desktop),
858 * Usage (X),
859 * Report Size (16),
860 * Report Count (1),
861 * Push,
862 * Unit Exponent (13),
863 * Unit (Inch^3),
864 * Logical Minimum (0),
865 * Logical Maximum (16383),
866 * Physical Minimum (0),
867 * Physical Maximum (16383),
868 * Input (Variable),
869 * Usage (Y),
870 * Input (Variable),
871 * Usage Page (Digitizer),
872 * Usage (Tip Pressure),
873 * Logical Minimum (0),
874 * Logical Maximum (1023),
875 * Physical Minimum (0),
876 * Physical Maximum (1023),
877 * Input (Variable),
878 * End Collection,
879 * End Collection,
880 * Usage Page (Desktop),
881 * Usage (Keyboard),
882 * Collection (Application),
883 * Report ID (13),
884 * Usage Page (Keyboard),
885 * Usage Minimum (KB Leftcontrol),
886 * Usage Maximum (KB Right GUI),
887 * Logical Minimum (0),
888 * Logical Maximum (1),
889 * Report Size (1),
890 * Report Count (8),
891 * Input (Variable),
892 * Report Size (8),
893 * Report Count (1),
894 * Input (Constant),
895 * Usage Page (Keyboard),
896 * Usage Minimum (None),
897 * Usage Maximum (KB Application),
898 * Logical Minimum (0),
899 * Logical Maximum (101),
900 * Report Size (8),
901 * Report Count (5),
902 * Input,
903 * End Collection,
904 * Usage Page (Consumer),
905 * Usage (Consumer Control),
906 * Collection (Application),
907 * Report ID (12),
908 * Usage (Volume Inc),
909 * Usage (Volume Dec),
910 * Usage (Mute),
911 * Logical Minimum (0),
912 * Logical Maximum (1),
913 * Report Size (1),
914 * Report Count (3),
915 * Input (Variable, Relative),
916 * Report Size (5),
917 * Report Count (1),
918 * Input (Constant, Variable, Relative),
919 * End Collection
920 */
921
922/* Size of the original report descriptor of Media Tablet 14.1 inch */
923#define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE 309
924
925/*
926 * Fixed Media Tablet 14.1 inch descriptor.
927 * It is fixed similarly to the Media Tablet 10.6 inch descriptor.
928 */
929static __u8 media_tablet_14_1_inch_rdesc_fixed[] = {
930 0x05, 0x0D, /* Usage Page (Digitizer), */
931 0x09, 0x02, /* Usage (Pen), */
932 0xA1, 0x01, /* Collection (Application), */
933 0x85, 0x10, /* Report ID (16), */
934 0x09, 0x20, /* Usage (Stylus), */
935 0xA0, /* Collection (Physical), */
936 0x09, 0x42, /* Usage (Tip Switch), */
937 0x09, 0x44, /* Usage (Barrel Switch), */
938 0x09, 0x46, /* Usage (Tablet Pick), */
939 0x15, 0x01, /* Logical Minimum (1), */
940 0x25, 0x03, /* Logical Maximum (3), */
941 0x75, 0x04, /* Report Size (4), */
942 0x95, 0x01, /* Report Count (1), */
943 0x80, /* Input, */
944 0x75, 0x01, /* Report Size (1), */
945 0x09, 0x32, /* Usage (In Range), */
946 0x14, /* Logical Minimum (0), */
947 0x25, 0x01, /* Logical Maximum (1), */
948 0x95, 0x01, /* Report Count (1), */
949 0x81, 0x02, /* Input (Variable), */
950 0x95, 0x03, /* Report Count (3), */
951 0x81, 0x03, /* Input (Constant, Variable), */
952 0x75, 0x10, /* Report Size (16), */
953 0x95, 0x01, /* Report Count (1), */
954 0x14, /* Logical Minimum (0), */
955 0xA4, /* Push, */
956 0x05, 0x01, /* Usage Page (Desktop), */
957 0x65, 0x13, /* Unit (Inch), */
958 0x55, 0xFD, /* Unit Exponent (-3), */
959 0x34, /* Physical Minimum (0), */
960 0x09, 0x30, /* Usage (X), */
961 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
962 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
963 0x81, 0x02, /* Input (Variable), */
964 0x09, 0x31, /* Usage (Y), */
965 0x46, 0x52, 0x1C, /* Physical Maximum (7250), */
966 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
967 0x81, 0x02, /* Input (Variable), */
968 0xB4, /* Pop, */
969 0x09, 0x30, /* Usage (Tip Pressure), */
970 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
971 0x81, 0x02, /* Input (Variable), */
972 0xC0, /* End Collection, */
973 0xC0, /* End Collection, */
974 0x05, 0x01, /* Usage Page (Desktop), */
975 0x09, 0x02, /* Usage (Mouse), */
976 0xA1, 0x01, /* Collection (Application), */
977 0x85, 0x01, /* Report ID (1), */
978 0x09, 0x01, /* Usage (Pointer), */
979 0xA0, /* Collection (Physical), */
980 0x75, 0x08, /* Report Size (8), */
981 0x95, 0x03, /* Report Count (3), */
982 0x81, 0x03, /* Input (Constant, Variable), */
983 0x95, 0x02, /* Report Count (2), */
984 0x15, 0xFF, /* Logical Minimum (-1), */
985 0x25, 0x01, /* Logical Maximum (1), */
986 0x09, 0x38, /* Usage (Wheel), */
987 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
988 0x0C, 0x00,
989 0x81, 0x06, /* Input (Variable, Relative), */
990 0xC0, /* End Collection, */
991 0xC0, /* End Collection, */
992 0x05, 0x0C, /* Usage Page (Consumer), */
993 0x09, 0x01, /* Usage (Consumer Control), */
994 0xA1, 0x01, /* Collection (Application), */
995 0x85, 0x0D, /* Report ID (13), */
996 0x95, 0x01, /* Report Count (1), */
997 0x75, 0x10, /* Report Size (16), */
998 0x81, 0x03, /* Input (Constant, Variable), */
999 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
1000 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
1001 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
1002 0x09, 0xB6, /* Usage (Scan Previous Track), */
1003 0x09, 0xB5, /* Usage (Scan Next Track), */
1004 0x08, /* Usage (00h), */
1005 0x08, /* Usage (00h), */
1006 0x08, /* Usage (00h), */
1007 0x08, /* Usage (00h), */
1008 0x08, /* Usage (00h), */
1009 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
1010 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
1011 0x15, 0x0C, /* Logical Minimum (12), */
1012 0x25, 0x17, /* Logical Maximum (23), */
1013 0x75, 0x05, /* Report Size (5), */
1014 0x80, /* Input, */
1015 0x75, 0x03, /* Report Size (3), */
1016 0x81, 0x03, /* Input (Constant, Variable), */
1017 0x75, 0x20, /* Report Size (32), */
1018 0x81, 0x03, /* Input (Constant, Variable), */
1019 0xC0, /* End Collection, */
1020 0x09, 0x01, /* Usage (Consumer Control), */
1021 0xA1, 0x01, /* Collection (Application), */
1022 0x85, 0x0C, /* Report ID (12), */
1023 0x75, 0x01, /* Report Size (1), */
1024 0x09, 0xE9, /* Usage (Volume Inc), */
1025 0x09, 0xEA, /* Usage (Volume Dec), */
1026 0x09, 0xE2, /* Usage (Mute), */
1027 0x14, /* Logical Minimum (0), */
1028 0x25, 0x01, /* Logical Maximum (1), */
1029 0x95, 0x03, /* Report Count (3), */
1030 0x81, 0x06, /* Input (Variable, Relative), */
1031 0x75, 0x05, /* Report Size (5), */
1032 0x81, 0x03, /* Input (Constant, Variable), */
1033 0xC0 /* End Collection */
1034};
1035
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001036static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
1037 unsigned int *rsize)
1038{
1039 switch (hdev->product) {
1040 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
1041 if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
1042 rdesc = slim_tablet_5_8_inch_rdesc_fixed;
1043 *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
1044 }
1045 break;
Nikolai Kondrashov00e7f962010-09-25 23:16:58 +04001046 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH:
1047 if (*rsize == SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE) {
1048 rdesc = slim_tablet_12_1_inch_rdesc_fixed;
1049 *rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed);
1050 }
1051 break;
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001052 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
1053 if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
1054 rdesc = media_tablet_10_6_inch_rdesc_fixed;
1055 *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
1056 }
1057 break;
Nikolai Kondrashov8f1acc32010-08-30 14:06:36 +04001058 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:
1059 if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {
1060 rdesc = media_tablet_14_1_inch_rdesc_fixed;
1061 *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);
1062 }
1063 break;
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001064 }
1065 return rdesc;
1066}
1067
1068static const struct hid_device_id waltop_devices[] = {
1069 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1070 USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
1071 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
Nikolai Kondrashov00e7f962010-09-25 23:16:58 +04001072 USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
1073 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001074 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
Nikolai Kondrashov8f1acc32010-08-30 14:06:36 +04001075 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1076 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
Nikolai Kondrashov72a46342010-08-20 19:21:11 +04001077 { }
1078};
1079MODULE_DEVICE_TABLE(hid, waltop_devices);
1080
1081static struct hid_driver waltop_driver = {
1082 .name = "waltop",
1083 .id_table = waltop_devices,
1084 .report_fixup = waltop_report_fixup,
1085};
1086
1087static int __init waltop_init(void)
1088{
1089 return hid_register_driver(&waltop_driver);
1090}
1091
1092static void __exit waltop_exit(void)
1093{
1094 hid_unregister_driver(&waltop_driver);
1095}
1096
1097module_init(waltop_init);
1098module_exit(waltop_exit);
1099MODULE_LICENSE("GPL");