aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-waltop.c
diff options
context:
space:
mode:
authorNikolai Kondrashov <spbnick@gmail.com>2010-08-20 11:21:11 -0400
committerJiri Kosina <jkosina@suse.cz>2010-08-23 09:01:55 -0400
commit72a46344867111c3e019b169ddfa9e1a1f55c759 (patch)
treed2a134a2c7fe193b1f68d640c73de78f0636bef8 /drivers/hid/hid-waltop.c
parentf36ee074d5d563a832fbfc378207739db3a0a205 (diff)
HID: add support for two Waltop tablets
Add support for Waltop Slim Tablet 5.8 inch and Media Tablet 10.6 inch. These (and other Waltop) tablets are usually sold by different companies (such as Genius and Trust) and with different names, but with the same USB vendor/product IDs. Slim Tablet 5.8 inch is known to also be sold as Genius G-Pen F350 and Trust Widescreen Mini Tablet (item no 16485). Media Tablet 10.6 inch is known to also be sold as Genius G-Pen M609 and M609X. Of these only the latter is known to be supported. Signed-off-by: Nikolai Kondrashov <spbnick@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-waltop.c')
-rw-r--r--drivers/hid/hid-waltop.c558
1 files changed, 558 insertions, 0 deletions
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c
new file mode 100644
index 000000000000..81cb4edb6b6b
--- /dev/null
+++ b/drivers/hid/hid-waltop.c
@@ -0,0 +1,558 @@
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 * Original Slim Tablet 5.8 inch report descriptor.
22 *
23 * All the reports except the report with ID 16 (the stylus) are unused,
24 * possibly because the tablet is not configured to, or because they were
25 * just copied from a more capable model. The purpose of features described
26 * for report ID 2 is unknown.
27 *
28 * The stylus buttons are described as three bit fields, whereas actually
29 * it's an "array", i.e. they're reported as button numbers (1, 2 and 3).
30 * The "eraser" field is not used. There is also a "push" without a "pop" in
31 * the stylus description.
32 *
33 * Usage Page (Desktop), ; Generic desktop controls (01h)
34 * Usage (Mouse), ; Mouse (02h, application collection)
35 * Collection (Application),
36 * Report ID (1),
37 * Usage (Pointer), ; Pointer (01h, physical collection)
38 * Collection (Physical),
39 * Usage Page (Button), ; Button (09h)
40 * Usage Minimum (01h),
41 * Usage Maximum (05h),
42 * Logical Minimum (0),
43 * Logical Maximum (1),
44 * Report Size (1),
45 * Report Count (5),
46 * Input (Variable),
47 * Report Size (3),
48 * Report Count (1),
49 * Input (Constant, Variable),
50 * Usage Page (Desktop), ; Generic desktop controls (01h)
51 * Usage (X), ; X (30h, dynamic value)
52 * Usage (Y), ; Y (31h, dynamic value)
53 * Usage (Wheel), ; Wheel (38h, dynamic value)
54 * Logical Minimum (-127),
55 * Logical Maximum (127),
56 * Report Size (8),
57 * Report Count (3),
58 * Input (Variable, Relative),
59 * End Collection,
60 * End Collection,
61 * Usage Page (Digitizer), ; Digitizer (0Dh)
62 * Usage (Pen), ; Pen (02h, application collection)
63 * Collection (Application),
64 * Report ID (2),
65 * Usage (Stylus), ; Stylus (20h, logical collection)
66 * Collection (Physical),
67 * Usage (00h),
68 * Logical Minimum (0),
69 * Logical Maximum (255),
70 * Report Size (8),
71 * Report Count (7),
72 * Input (Variable),
73 * Usage (Azimuth), ; Azimuth (3Fh, dynamic value)
74 * Usage (Altitude), ; Altitude (40h, dynamic value)
75 * Logical Minimum (0),
76 * Logical Maximum (255),
77 * Report Size (8),
78 * Report Count (2),
79 * Feature (Variable),
80 * End Collection,
81 * Report ID (5),
82 * Usage Page (Digitizer), ; Digitizer (0Dh)
83 * Usage (Stylus), ; Stylus (20h, logical collection)
84 * Collection (Physical),
85 * Usage (00h),
86 * Logical Minimum (0),
87 * Logical Maximum (255),
88 * Report Size (8),
89 * Report Count (7),
90 * Input (Variable),
91 * End Collection,
92 * Report ID (10),
93 * Usage Page (Digitizer), ; Digitizer (0Dh)
94 * Usage (Stylus), ; Stylus (20h, logical collection)
95 * Collection (Physical),
96 * Usage (00h),
97 * Logical Minimum (0),
98 * Logical Maximum (255),
99 * Report Size (8),
100 * Report Count (3),
101 * Input (Variable),
102 * End Collection,
103 * Report ID (16),
104 * Usage (Stylus), ; Stylus (20h, logical collection)
105 * Collection (Physical),
106 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
107 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
108 * Usage (Invert), ; Invert (3Ch, momentary control)
109 * Usage (Eraser), ; Eraser (45h, momentary control)
110 * Usage (In Range), ; In range (32h, momentary control)
111 * Logical Minimum (0),
112 * Logical Maximum (1),
113 * Report Size (1),
114 * Report Count (5),
115 * Input (Variable),
116 * Report Count (3),
117 * Input (Constant, Variable),
118 * Usage Page (Desktop), ; Generic desktop controls (01h)
119 * Usage (X), ; X (30h, dynamic value)
120 * Report Size (16),
121 * Report Count (1),
122 * Push,
123 * Unit Exponent (13),
124 * Unit (Inch^3),
125 * Logical Minimum (0),
126 * Logical Maximum (10000),
127 * Physical Minimum (0),
128 * Physical Maximum (10000),
129 * Input (Variable),
130 * Usage (Y), ; Y (31h, dynamic value)
131 * Logical Maximum (6000),
132 * Physical Maximum (6000),
133 * Input (Variable),
134 * Usage Page (Digitizer), ; Digitizer (0Dh)
135 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
136 * Logical Minimum (0),
137 * Logical Maximum (1023),
138 * Physical Minimum (0),
139 * Physical Maximum (1023),
140 * Input (Variable),
141 * End Collection,
142 * End Collection
143 */
144
145/* Size of the original report descriptor of Slim Tablet 5.8 inch */
146#define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE 222
147
148/*
149 * Fixed Slim Tablet 5.8 inch descriptor.
150 *
151 * All the reports except the stylus report (ID 16) were removed as unused.
152 * The stylus buttons description was fixed.
153 */
154static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {
155 0x05, 0x0D, /* Usage Page (Digitizer), */
156 0x09, 0x02, /* Usage (Pen), */
157 0xA1, 0x01, /* Collection (Application), */
158 0x85, 0x10, /* Report ID (16), */
159 0x09, 0x20, /* Usage (Stylus), */
160 0xA0, /* Collection (Physical), */
161 0x09, 0x42, /* Usage (Tip Switch), */
162 0x09, 0x44, /* Usage (Barrel Switch), */
163 0x09, 0x46, /* Usage (Tablet Pick), */
164 0x15, 0x01, /* Logical Minimum (1), */
165 0x25, 0x03, /* Logical Maximum (3), */
166 0x75, 0x04, /* Report Size (4), */
167 0x95, 0x01, /* Report Count (1), */
168 0x80, /* Input, */
169 0x09, 0x32, /* Usage (In Range), */
170 0x14, /* Logical Minimum (0), */
171 0x25, 0x01, /* Logical Maximum (1), */
172 0x75, 0x01, /* Report Size (1), */
173 0x95, 0x01, /* Report Count (1), */
174 0x81, 0x02, /* Input (Variable), */
175 0x95, 0x03, /* Report Count (3), */
176 0x81, 0x03, /* Input (Constant, Variable), */
177 0x75, 0x10, /* Report Size (16), */
178 0x95, 0x01, /* Report Count (1), */
179 0x14, /* Logical Minimum (0), */
180 0xA4, /* Push, */
181 0x05, 0x01, /* Usage Page (Desktop), */
182 0x65, 0x13, /* Unit (Inch), */
183 0x55, 0xFD, /* Unit Exponent (-3), */
184 0x34, /* Physical Minimum (0), */
185 0x09, 0x30, /* Usage (X), */
186 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
187 0x26, 0x10, 0x27, /* Logical Maximum (10000), */
188 0x81, 0x02, /* Input (Variable), */
189 0x09, 0x31, /* Usage (Y), */
190 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
191 0x26, 0x70, 0x17, /* Logical Maximum (6000), */
192 0x81, 0x02, /* Input (Variable), */
193 0xB4, /* Pop, */
194 0x09, 0x30, /* Usage (Tip Pressure), */
195 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
196 0x81, 0x02, /* Input (Variable), */
197 0xC0, /* End Collection, */
198 0xC0 /* End Collection */
199};
200
201/*
202 * Original Media Tablet 10.6 inch report descriptor.
203 *
204 * There are at least two versions of this model in the wild. They are
205 * represented by Genius G-Pen M609 (older version) and Genius G-Pen M609X
206 * (newer version).
207 *
208 * Both versions have the usual pen with two barrel buttons and two
209 * identical wheels with center buttons in the top corners of the tablet
210 * base. They also have buttons on the top, between the wheels, for
211 * selecting the wheels' functions and wide/standard mode. In the wide mode
212 * the whole working surface is sensed, in the standard mode a narrower area
213 * is sensed, but the logical report extents remain the same. These modes
214 * correspond roughly to 16:9 and 4:3 aspect ratios respectively.
215 *
216 * The older version has three wheel function buttons ("scroll", "zoom" and
217 * "volume") and two separate buttons for wide and standard mode. The newer
218 * version has four wheel function buttons (plus "brush") and only one
219 * button is used for selecting wide/standard mode. So, the total number of
220 * buttons remains the same, but one of the mode buttons is repurposed as a
221 * wheels' function button in the newer version.
222 *
223 * The wheel functions are:
224 * scroll - the wheels act as scroll wheels, the center buttons do nothing.
225 * zoom - the wheels zoom in/out, the buttons supposedly reset to 100%.
226 * volume - the wheels control the sound volume, the buttons mute.
227 * brush - the wheels are supposed to control brush width in a graphics
228 * editor, the buttons do nothing.
229 *
230 * Below is the newer version's report descriptor. It may very well be that
231 * the older version's descriptor is different and thus it won't be
232 * supported.
233 *
234 * The mouse report (ID 1) only uses the wheel field for reporting the tablet
235 * wheels' scroll mode. The keyboard report (ID 13) is used to report the
236 * wheels' zoom and brush control functions as key presses. The report ID 12
237 * is used to report the wheels' volume control functions. The stylus report
238 * (ID 16) has the same problems as the Slim Tablet 5.8 inch report has.
239 *
240 * The rest of the reports are unused, at least in the default configuration.
241 * The purpose of the features is unknown.
242 *
243 * Usage Page (Desktop),
244 * Usage (Mouse),
245 * Collection (Application),
246 * Report ID (1),
247 * Usage (Pointer),
248 * Collection (Physical),
249 * Usage Page (Button),
250 * Usage Minimum (01h),
251 * Usage Maximum (05h),
252 * Logical Minimum (0),
253 * Logical Maximum (1),
254 * Report Size (1),
255 * Report Count (5),
256 * Input (Variable),
257 * Report Size (3),
258 * Report Count (1),
259 * Input (Constant, Variable),
260 * Usage Page (Desktop),
261 * Usage (X),
262 * Usage (Y),
263 * Usage (Wheel),
264 * Logical Minimum (-127),
265 * Logical Maximum (127),
266 * Report Size (8),
267 * Report Count (3),
268 * Input (Variable, Relative),
269 * End Collection,
270 * End Collection,
271 * Usage Page (Digitizer),
272 * Usage (Pen),
273 * Collection (Application),
274 * Report ID (2),
275 * Usage (Stylus),
276 * Collection (Physical),
277 * Usage (00h),
278 * Logical Minimum (0),
279 * Logical Maximum (255),
280 * Report Size (8),
281 * Report Count (7),
282 * Input (Variable),
283 * Usage (Azimuth),
284 * Usage (Altitude),
285 * Logical Minimum (0),
286 * Logical Maximum (255),
287 * Report Size (8),
288 * Report Count (2),
289 * Feature (Variable),
290 * End Collection,
291 * Report ID (5),
292 * Usage Page (Digitizer),
293 * Usage (Stylus),
294 * Collection (Physical),
295 * Usage (00h),
296 * Logical Minimum (0),
297 * Logical Maximum (255),
298 * Report Size (8),
299 * Report Count (7),
300 * Input (Variable),
301 * End Collection,
302 * Report ID (10),
303 * Usage Page (Digitizer),
304 * Usage (Stylus),
305 * Collection (Physical),
306 * Usage (00h),
307 * Logical Minimum (0),
308 * Logical Maximum (255),
309 * Report Size (8),
310 * Report Count (7),
311 * Input (Variable),
312 * End Collection,
313 * Report ID (16),
314 * Usage (Stylus),
315 * Collection (Physical),
316 * Usage (Tip Switch),
317 * Usage (Barrel Switch),
318 * Usage (Invert),
319 * Usage (Eraser),
320 * Usage (In Range),
321 * Logical Minimum (0),
322 * Logical Maximum (1),
323 * Report Size (1),
324 * Report Count (5),
325 * Input (Variable),
326 * Report Count (3),
327 * Input (Constant, Variable),
328 * Usage Page (Desktop),
329 * Usage (X),
330 * Report Size (16),
331 * Report Count (1),
332 * Push,
333 * Unit Exponent (13),
334 * Unit (Inch^3),
335 * Logical Minimum (0),
336 * Logical Maximum (18000),
337 * Physical Minimum (0),
338 * Physical Maximum (18000),
339 * Input (Variable),
340 * Usage (Y),
341 * Logical Maximum (11000),
342 * Physical Maximum (11000),
343 * Input (Variable),
344 * Usage Page (Digitizer),
345 * Usage (Tip Pressure),
346 * Logical Minimum (0),
347 * Logical Maximum (1023),
348 * Physical Minimum (0),
349 * Physical Maximum (1023),
350 * Input (Variable),
351 * End Collection,
352 * End Collection,
353 * Usage Page (Desktop),
354 * Usage (Keyboard),
355 * Collection (Application),
356 * Report ID (13),
357 * Usage Page (Keyboard),
358 * Usage Minimum (KB Leftcontrol),
359 * Usage Maximum (KB Right GUI),
360 * Logical Minimum (0),
361 * Logical Maximum (1),
362 * Report Size (1),
363 * Report Count (8),
364 * Input (Variable),
365 * Report Size (8),
366 * Report Count (1),
367 * Input (Constant),
368 * Usage Page (Keyboard),
369 * Usage Minimum (None),
370 * Usage Maximum (KB Application),
371 * Logical Minimum (0),
372 * Logical Maximum (101),
373 * Report Size (8),
374 * Report Count (5),
375 * Input,
376 * End Collection,
377 * Usage Page (Consumer),
378 * Usage (Consumer Control),
379 * Collection (Application),
380 * Report ID (12),
381 * Usage (Volume Inc),
382 * Usage (Volume Dec),
383 * Usage (Mute),
384 * Logical Minimum (0),
385 * Logical Maximum (1),
386 * Report Size (1),
387 * Report Count (3),
388 * Input (Variable, Relative),
389 * Report Size (5),
390 * Report Count (1),
391 * Input (Constant, Variable, Relative),
392 * End Collection
393 */
394
395/* Size of the original report descriptor of Media Tablet 10.6 inch */
396#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300
397
398/*
399 * Fixed Media Tablet 10.6 inch descriptor.
400 *
401 * The descriptions of reports unused in the default configuration are
402 * removed. The stylus report (ID 16) is fixed similarly to Slim Tablet 5.8
403 * inch. The unused mouse report (ID 1) fields are replaced with constant
404 * padding.
405 *
406 * The keyboard report (ID 13) is hacked to instead have an "array" field
407 * reporting consumer page controls, and all the unused bits are masked out
408 * with constant padding. The "brush" wheels' function is represented as "Scan
409 * Previous/Next Track" controls due to the lack of brush controls in the
410 * usage tables specification.
411 */
412static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
413 0x05, 0x0D, /* Usage Page (Digitizer), */
414 0x09, 0x02, /* Usage (Pen), */
415 0xA1, 0x01, /* Collection (Application), */
416 0x85, 0x10, /* Report ID (16), */
417 0x09, 0x20, /* Usage (Stylus), */
418 0xA0, /* Collection (Physical), */
419 0x09, 0x42, /* Usage (Tip Switch), */
420 0x09, 0x44, /* Usage (Barrel Switch), */
421 0x09, 0x46, /* Usage (Tablet Pick), */
422 0x15, 0x01, /* Logical Minimum (1), */
423 0x25, 0x03, /* Logical Maximum (3), */
424 0x75, 0x04, /* Report Size (4), */
425 0x95, 0x01, /* Report Count (1), */
426 0x80, /* Input, */
427 0x75, 0x01, /* Report Size (1), */
428 0x09, 0x32, /* Usage (In Range), */
429 0x14, /* Logical Minimum (0), */
430 0x25, 0x01, /* Logical Maximum (1), */
431 0x95, 0x01, /* Report Count (1), */
432 0x81, 0x02, /* Input (Variable), */
433 0x95, 0x03, /* Report Count (3), */
434 0x81, 0x03, /* Input (Constant, Variable), */
435 0x75, 0x10, /* Report Size (16), */
436 0x95, 0x01, /* Report Count (1), */
437 0x14, /* Logical Minimum (0), */
438 0xA4, /* Push, */
439 0x05, 0x01, /* Usage Page (Desktop), */
440 0x65, 0x13, /* Unit (Inch), */
441 0x55, 0xFD, /* Unit Exponent (-3), */
442 0x34, /* Physical Minimum (0), */
443 0x09, 0x30, /* Usage (X), */
444 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
445 0x26, 0x50, 0x46, /* Logical Maximum (18000), */
446 0x81, 0x02, /* Input (Variable), */
447 0x09, 0x31, /* Usage (Y), */
448 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
449 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */
450 0x81, 0x02, /* Input (Variable), */
451 0xB4, /* Pop, */
452 0x09, 0x30, /* Usage (Tip Pressure), */
453 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
454 0x81, 0x02, /* Input (Variable), */
455 0xC0, /* End Collection, */
456 0xC0, /* End Collection, */
457 0x05, 0x01, /* Usage Page (Desktop), */
458 0x09, 0x02, /* Usage (Mouse), */
459 0xA1, 0x01, /* Collection (Application), */
460 0x85, 0x01, /* Report ID (1), */
461 0x09, 0x01, /* Usage (Pointer), */
462 0xA0, /* Collection (Physical), */
463 0x95, 0x01, /* Report Count (1), */
464 0x75, 0x18, /* Report Size (24), */
465 0x81, 0x03, /* Input (Constant, Variable), */
466 0x05, 0x01, /* Usage Page (Desktop), */
467 0x09, 0x38, /* Usage (Wheel), */
468 0x15, 0xFF, /* Logical Minimum (-1), */
469 0x25, 0x01, /* Logical Maximum (1), */
470 0x75, 0x08, /* Report Size (8), */
471 0x81, 0x06, /* Input (Variable, Relative), */
472 0x75, 0x18, /* Report Size (24), */
473 0x81, 0x03, /* Input (Constant, Variable), */
474 0xC0, /* End Collection, */
475 0xC0, /* End Collection, */
476 0x05, 0x0C, /* Usage Page (Consumer), */
477 0x09, 0x01, /* Usage (Consumer Control), */
478 0xA1, 0x01, /* Collection (Application), */
479 0x85, 0x0D, /* Report ID (13), */
480 0x95, 0x01, /* Report Count (1), */
481 0x75, 0x10, /* Report Size (16), */
482 0x81, 0x03, /* Input (Constant, Variable), */
483 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
484 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
485 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
486 0x09, 0xB6, /* Usage (Scan Previous Track), */
487 0x09, 0xB5, /* Usage (Scan Next Track), */
488 0x15, 0x2C, /* Logical Minimum (44), */
489 0x25, 0x30, /* Logical Maximum (48), */
490 0x75, 0x08, /* Report Size (8), */
491 0x80, /* Input, */
492 0x75, 0x20, /* Report Size (32), */
493 0x81, 0x03, /* Input (Constant, Variable), */
494 0xC0, /* End Collection, */
495 0x09, 0x01, /* Usage (Consumer Control), */
496 0xA1, 0x01, /* Collection (Application), */
497 0x85, 0x0C, /* Report ID (12), */
498 0x75, 0x01, /* Report Size (1), */
499 0x09, 0xE9, /* Usage (Volume Inc), */
500 0x09, 0xEA, /* Usage (Volume Dec), */
501 0x09, 0xE2, /* Usage (Mute), */
502 0x14, /* Logical Minimum (0), */
503 0x25, 0x01, /* Logical Maximum (1), */
504 0x95, 0x03, /* Report Count (3), */
505 0x81, 0x06, /* Input (Variable, Relative), */
506 0x95, 0x35, /* Report Count (53), */
507 0x81, 0x03, /* Input (Constant, Variable), */
508 0xC0 /* End Collection */
509};
510
511static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
512 unsigned int *rsize)
513{
514 switch (hdev->product) {
515 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
516 if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
517 rdesc = slim_tablet_5_8_inch_rdesc_fixed;
518 *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
519 }
520 break;
521 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
522 if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
523 rdesc = media_tablet_10_6_inch_rdesc_fixed;
524 *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
525 }
526 break;
527 }
528 return rdesc;
529}
530
531static const struct hid_device_id waltop_devices[] = {
532 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
533 USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
534 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
535 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
536 { }
537};
538MODULE_DEVICE_TABLE(hid, waltop_devices);
539
540static struct hid_driver waltop_driver = {
541 .name = "waltop",
542 .id_table = waltop_devices,
543 .report_fixup = waltop_report_fixup,
544};
545
546static int __init waltop_init(void)
547{
548 return hid_register_driver(&waltop_driver);
549}
550
551static void __exit waltop_exit(void)
552{
553 hid_unregister_driver(&waltop_driver);
554}
555
556module_init(waltop_init);
557module_exit(waltop_exit);
558MODULE_LICENSE("GPL");