summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
Diffstat (limited to 'usr')
-rw-r--r--usr/src/dkms_main_tree/dkms_dbversion1
-rw-r--r--usr/src/dkms_source_tree/KERNEL_SOURCE_VERSION1
-rw-r--r--usr/src/dkms_source_tree/Makefile38
-rw-r--r--usr/src/dkms_source_tree/dkms.conf9
-rw-r--r--usr/src/dkms_source_tree/hid-core.c1145
-rw-r--r--usr/src/dkms_source_tree/hid-ff.c95
-rw-r--r--usr/src/dkms_source_tree/hid-lg2ff.c114
-rw-r--r--usr/src/dkms_source_tree/hid-lgff.c151
-rw-r--r--usr/src/dkms_source_tree/hid-pidff.c1332
-rw-r--r--usr/src/dkms_source_tree/hid-plff.c139
-rw-r--r--usr/src/dkms_source_tree/hid-quirks.c1224
-rw-r--r--usr/src/dkms_source_tree/hid-tmff.c225
-rw-r--r--usr/src/dkms_source_tree/hid-zpff.c107
-rw-r--r--usr/src/dkms_source_tree/hiddev.c893
-rw-r--r--usr/src/dkms_source_tree/patches/10-ignore-trackpad-on-unibody-macbooks.patch24
-rw-r--r--usr/src/dkms_source_tree/usbhid.h88
-rw-r--r--usr/src/dkms_source_tree/usbkbd.c365
-rw-r--r--usr/src/dkms_source_tree/usbmouse.c253
18 files changed, 6204 insertions, 0 deletions
diff --git a/usr/src/dkms_main_tree/dkms_dbversion b/usr/src/dkms_main_tree/dkms_dbversion
new file mode 100644
index 0000000..227cea2
--- /dev/null
+++ b/usr/src/dkms_main_tree/dkms_dbversion
@@ -0,0 +1 @@
2.0.0
diff --git a/usr/src/dkms_source_tree/KERNEL_SOURCE_VERSION b/usr/src/dkms_source_tree/KERNEL_SOURCE_VERSION
new file mode 100644
index 0000000..9cd2822
--- /dev/null
+++ b/usr/src/dkms_source_tree/KERNEL_SOURCE_VERSION
@@ -0,0 +1 @@
2.6.27-7-generic
diff --git a/usr/src/dkms_source_tree/Makefile b/usr/src/dkms_source_tree/Makefile
new file mode 100644
index 0000000..00a7b70
--- /dev/null
+++ b/usr/src/dkms_source_tree/Makefile
@@ -0,0 +1,38 @@
1#
2# Makefile for the USB input drivers
3#
4
5# Multipart objects.
6usbhid-objs := hid-core.o hid-quirks.o
7
8# Optional parts of multipart objects.
9
10ifeq ($(CONFIG_USB_HIDDEV),y)
11 usbhid-objs += hiddev.o
12endif
13ifeq ($(CONFIG_HID_PID),y)
14 usbhid-objs += hid-pidff.o
15endif
16ifeq ($(CONFIG_LOGITECH_FF),y)
17 usbhid-objs += hid-lgff.o
18endif
19ifeq ($(CONFIG_LOGIRUMBLEPAD2_FF),y)
20 usbhid-objs += hid-lg2ff.o
21endif
22ifeq ($(CONFIG_PANTHERLORD_FF),y)
23 usbhid-objs += hid-plff.o
24endif
25ifeq ($(CONFIG_THRUSTMASTER_FF),y)
26 usbhid-objs += hid-tmff.o
27endif
28ifeq ($(CONFIG_ZEROPLUS_FF),y)
29 usbhid-objs += hid-zpff.o
30endif
31ifeq ($(CONFIG_HID_FF),y)
32 usbhid-objs += hid-ff.o
33endif
34
35obj-$(CONFIG_USB_HID) += usbhid.o
36obj-$(CONFIG_USB_KBD) += usbkbd.o
37obj-$(CONFIG_USB_MOUSE) += usbmouse.o
38
diff --git a/usr/src/dkms_source_tree/dkms.conf b/usr/src/dkms_source_tree/dkms.conf
new file mode 100644
index 0000000..34d0f25
--- /dev/null
+++ b/usr/src/dkms_source_tree/dkms.conf
@@ -0,0 +1,9 @@
1NAME=usbhid
2VERSION=0.10.2
3PACKAGE_NAME="$NAME"
4PACKAGE_VERSION="$VERSION"
5MAKE[0]="make -C ${kernel_source_dir}
6 SUBDIRS=${dkms_tree}/${NAME}/${VERSION}/build modules"
7BUILT_MODULE_NAME[0]="usbhid"
8DEST_MODULE_LOCATION[0]="/kernel/drivers/hid/usbhid"
9REMAKE_INITRD=y
diff --git a/usr/src/dkms_source_tree/hid-core.c b/usr/src/dkms_source_tree/hid-core.c
new file mode 100644
index 0000000..27fe4d8
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-core.c
@@ -0,0 +1,1145 @@
1/*
2 * USB HID support for Linux
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your option)
14 * any later version.
15 */
16
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/list.h>
22#include <linux/mm.h>
23#include <linux/smp_lock.h>
24#include <linux/spinlock.h>
25#include <asm/unaligned.h>
26#include <asm/byteorder.h>
27#include <linux/input.h>
28#include <linux/wait.h>
29
30#include <linux/usb.h>
31
32#include <linux/hid.h>
33#include <linux/hiddev.h>
34#include <linux/hid-debug.h>
35#include <linux/hidraw.h>
36#include "usbhid.h"
37
38/*
39 * Version Information
40 */
41
42#define DRIVER_VERSION "v2.6"
43#define DRIVER_AUTHOR "Andreas Gal, Vojtech Pavlik, Jiri Kosina"
44#define DRIVER_DESC "USB HID core driver"
45#define DRIVER_LICENSE "GPL"
46
47static char *hid_types[] = {"Device", "Pointer", "Mouse", "Device", "Joystick",
48 "Gamepad", "Keyboard", "Keypad", "Multi-Axis Controller"};
49/*
50 * Module parameters.
51 */
52
53static unsigned int hid_mousepoll_interval;
54module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
55MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
56
57/* Quirks specified at module load time */
58static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
59module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
60MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
61 " quirks=vendorID:productID:quirks"
62 " where vendorID, productID, and quirks are all in"
63 " 0x-prefixed hex");
64static char *rdesc_quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
65module_param_array_named(rdesc_quirks, rdesc_quirks_param, charp, NULL, 0444);
66MODULE_PARM_DESC(rdesc_quirks, "Add/modify report descriptor quirks by specifying "
67 " rdesc_quirks=vendorID:productID:rdesc_quirks"
68 " where vendorID, productID, and rdesc_quirks are all in"
69 " 0x-prefixed hex");
70/*
71 * Input submission and I/O error handler.
72 */
73
74static void hid_io_error(struct hid_device *hid);
75
76/* Start up the input URB */
77static int hid_start_in(struct hid_device *hid)
78{
79 unsigned long flags;
80 int rc = 0;
81 struct usbhid_device *usbhid = hid->driver_data;
82
83 spin_lock_irqsave(&usbhid->inlock, flags);
84 if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
85 !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
86 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
87 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
88 if (rc != 0)
89 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
90 }
91 spin_unlock_irqrestore(&usbhid->inlock, flags);
92 return rc;
93}
94
95/* I/O retry timer routine */
96static void hid_retry_timeout(unsigned long _hid)
97{
98 struct hid_device *hid = (struct hid_device *) _hid;
99 struct usbhid_device *usbhid = hid->driver_data;
100
101 dev_dbg(&usbhid->intf->dev, "retrying intr urb\n");
102 if (hid_start_in(hid))
103 hid_io_error(hid);
104}
105
106/* Workqueue routine to reset the device or clear a halt */
107static void hid_reset(struct work_struct *work)
108{
109 struct usbhid_device *usbhid =
110 container_of(work, struct usbhid_device, reset_work);
111 struct hid_device *hid = usbhid->hid;
112 int rc_lock, rc = 0;
113
114 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
115 dev_dbg(&usbhid->intf->dev, "clear halt\n");
116 rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
117 clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
118 hid_start_in(hid);
119 }
120
121 else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
122 dev_dbg(&usbhid->intf->dev, "resetting device\n");
123 rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
124 if (rc_lock >= 0) {
125 rc = usb_reset_device(hid_to_usb_dev(hid));
126 if (rc_lock)
127 usb_unlock_device(hid_to_usb_dev(hid));
128 }
129 clear_bit(HID_RESET_PENDING, &usbhid->iofl);
130 }
131
132 switch (rc) {
133 case 0:
134 if (!test_bit(HID_IN_RUNNING, &usbhid->iofl))
135 hid_io_error(hid);
136 break;
137 default:
138 err_hid("can't reset device, %s-%s/input%d, status %d",
139 hid_to_usb_dev(hid)->bus->bus_name,
140 hid_to_usb_dev(hid)->devpath,
141 usbhid->ifnum, rc);
142 /* FALLTHROUGH */
143 case -EHOSTUNREACH:
144 case -ENODEV:
145 case -EINTR:
146 break;
147 }
148}
149
150/* Main I/O error handler */
151static void hid_io_error(struct hid_device *hid)
152{
153 unsigned long flags;
154 struct usbhid_device *usbhid = hid->driver_data;
155
156 spin_lock_irqsave(&usbhid->inlock, flags);
157
158 /* Stop when disconnected */
159 if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
160 goto done;
161
162 /* If it has been a while since the last error, we'll assume
163 * this a brand new error and reset the retry timeout. */
164 if (time_after(jiffies, usbhid->stop_retry + HZ/2))
165 usbhid->retry_delay = 0;
166
167 /* When an error occurs, retry at increasing intervals */
168 if (usbhid->retry_delay == 0) {
169 usbhid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */
170 usbhid->stop_retry = jiffies + msecs_to_jiffies(1000);
171 } else if (usbhid->retry_delay < 100)
172 usbhid->retry_delay *= 2;
173
174 if (time_after(jiffies, usbhid->stop_retry)) {
175
176 /* Retries failed, so do a port reset */
177 if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) {
178 schedule_work(&usbhid->reset_work);
179 goto done;
180 }
181 }
182
183 mod_timer(&usbhid->io_retry,
184 jiffies + msecs_to_jiffies(usbhid->retry_delay));
185done:
186 spin_unlock_irqrestore(&usbhid->inlock, flags);
187}
188
189/*
190 * Input interrupt completion handler.
191 */
192
193static void hid_irq_in(struct urb *urb)
194{
195 struct hid_device *hid = urb->context;
196 struct usbhid_device *usbhid = hid->driver_data;
197 int status;
198
199 switch (urb->status) {
200 case 0: /* success */
201 usbhid->retry_delay = 0;
202 hid_input_report(urb->context, HID_INPUT_REPORT,
203 urb->transfer_buffer,
204 urb->actual_length, 1);
205 break;
206 case -EPIPE: /* stall */
207 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
208 set_bit(HID_CLEAR_HALT, &usbhid->iofl);
209 schedule_work(&usbhid->reset_work);
210 return;
211 case -ECONNRESET: /* unlink */
212 case -ENOENT:
213 case -ESHUTDOWN: /* unplug */
214 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
215 return;
216 case -EILSEQ: /* protocol error or unplug */
217 case -EPROTO: /* protocol error or unplug */
218 case -ETIME: /* protocol error or unplug */
219 case -ETIMEDOUT: /* Should never happen, but... */
220 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
221 hid_io_error(hid);
222 return;
223 default: /* error */
224 warn("input irq status %d received", urb->status);
225 }
226
227 status = usb_submit_urb(urb, GFP_ATOMIC);
228 if (status) {
229 clear_bit(HID_IN_RUNNING, &usbhid->iofl);
230 if (status != -EPERM) {
231 err_hid("can't resubmit intr, %s-%s/input%d, status %d",
232 hid_to_usb_dev(hid)->bus->bus_name,
233 hid_to_usb_dev(hid)->devpath,
234 usbhid->ifnum, status);
235 hid_io_error(hid);
236 }
237 }
238}
239
240static int hid_submit_out(struct hid_device *hid)
241{
242 struct hid_report *report;
243 struct usbhid_device *usbhid = hid->driver_data;
244
245 report = usbhid->out[usbhid->outtail];
246
247 hid_output_report(report, usbhid->outbuf);
248 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
249 usbhid->urbout->dev = hid_to_usb_dev(hid);
250
251 dbg_hid("submitting out urb\n");
252
253 if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
254 err_hid("usb_submit_urb(out) failed");
255 return -1;
256 }
257
258 return 0;
259}
260
261static int hid_submit_ctrl(struct hid_device *hid)
262{
263 struct hid_report *report;
264 unsigned char dir;
265 int len;
266 struct usbhid_device *usbhid = hid->driver_data;
267
268 report = usbhid->ctrl[usbhid->ctrltail].report;
269 dir = usbhid->ctrl[usbhid->ctrltail].dir;
270
271 len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
272 if (dir == USB_DIR_OUT) {
273 hid_output_report(report, usbhid->ctrlbuf);
274 usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
275 usbhid->urbctrl->transfer_buffer_length = len;
276 } else {
277 int maxpacket, padlen;
278
279 usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
280 maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
281 if (maxpacket > 0) {
282 padlen = DIV_ROUND_UP(len, maxpacket);
283 padlen *= maxpacket;
284 if (padlen > usbhid->bufsize)
285 padlen = usbhid->bufsize;
286 } else
287 padlen = 0;
288 usbhid->urbctrl->transfer_buffer_length = padlen;
289 }
290 usbhid->urbctrl->dev = hid_to_usb_dev(hid);
291
292 usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
293 usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
294 usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
295 usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
296 usbhid->cr->wLength = cpu_to_le16(len);
297
298 dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
299 usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
300 usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
301
302 if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
303 err_hid("usb_submit_urb(ctrl) failed");
304 return -1;
305 }
306
307 return 0;
308}
309
310/*
311 * Output interrupt completion handler.
312 */
313
314static void hid_irq_out(struct urb *urb)
315{
316 struct hid_device *hid = urb->context;
317 struct usbhid_device *usbhid = hid->driver_data;
318 unsigned long flags;
319 int unplug = 0;
320
321 switch (urb->status) {
322 case 0: /* success */
323 break;
324 case -ESHUTDOWN: /* unplug */
325 unplug = 1;
326 case -EILSEQ: /* protocol error or unplug */
327 case -EPROTO: /* protocol error or unplug */
328 case -ECONNRESET: /* unlink */
329 case -ENOENT:
330 break;
331 default: /* error */
332 warn("output irq status %d received", urb->status);
333 }
334
335 spin_lock_irqsave(&usbhid->outlock, flags);
336
337 if (unplug)
338 usbhid->outtail = usbhid->outhead;
339 else
340 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
341
342 if (usbhid->outhead != usbhid->outtail) {
343 if (hid_submit_out(hid)) {
344 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
345 wake_up(&usbhid->wait);
346 }
347 spin_unlock_irqrestore(&usbhid->outlock, flags);
348 return;
349 }
350
351 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
352 spin_unlock_irqrestore(&usbhid->outlock, flags);
353 wake_up(&usbhid->wait);
354}
355
356/*
357 * Control pipe completion handler.
358 */
359
360static void hid_ctrl(struct urb *urb)
361{
362 struct hid_device *hid = urb->context;
363 struct usbhid_device *usbhid = hid->driver_data;
364 unsigned long flags;
365 int unplug = 0;
366
367 spin_lock_irqsave(&usbhid->ctrllock, flags);
368
369 switch (urb->status) {
370 case 0: /* success */
371 if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
372 hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type,
373 urb->transfer_buffer, urb->actual_length, 0);
374 break;
375 case -ESHUTDOWN: /* unplug */
376 unplug = 1;
377 case -EILSEQ: /* protocol error or unplug */
378 case -EPROTO: /* protocol error or unplug */
379 case -ECONNRESET: /* unlink */
380 case -ENOENT:
381 case -EPIPE: /* report not available */
382 break;
383 default: /* error */
384 warn("ctrl urb status %d received", urb->status);
385 }
386
387 if (unplug)
388 usbhid->ctrltail = usbhid->ctrlhead;
389 else
390 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
391
392 if (usbhid->ctrlhead != usbhid->ctrltail) {
393 if (hid_submit_ctrl(hid)) {
394 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
395 wake_up(&usbhid->wait);
396 }
397 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
398 return;
399 }
400
401 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
402 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
403 wake_up(&usbhid->wait);
404}
405
406void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
407{
408 int head;
409 unsigned long flags;
410 struct usbhid_device *usbhid = hid->driver_data;
411
412 if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN)
413 return;
414
415 if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
416
417 spin_lock_irqsave(&usbhid->outlock, flags);
418
419 if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
420 spin_unlock_irqrestore(&usbhid->outlock, flags);
421 warn("output queue full");
422 return;
423 }
424
425 usbhid->out[usbhid->outhead] = report;
426 usbhid->outhead = head;
427
428 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
429 if (hid_submit_out(hid))
430 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
431
432 spin_unlock_irqrestore(&usbhid->outlock, flags);
433 return;
434 }
435
436 spin_lock_irqsave(&usbhid->ctrllock, flags);
437
438 if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
439 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
440 warn("control queue full");
441 return;
442 }
443
444 usbhid->ctrl[usbhid->ctrlhead].report = report;
445 usbhid->ctrl[usbhid->ctrlhead].dir = dir;
446 usbhid->ctrlhead = head;
447
448 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
449 if (hid_submit_ctrl(hid))
450 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
451
452 spin_unlock_irqrestore(&usbhid->ctrllock, flags);
453}
454
455static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
456{
457 struct hid_device *hid = input_get_drvdata(dev);
458 struct hid_field *field;
459 int offset;
460
461 if (type == EV_FF)
462 return input_ff_event(dev, type, code, value);
463
464 if (type != EV_LED)
465 return -1;
466
467 if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
468 warn("event field not found");
469 return -1;
470 }
471
472 hid_set_field(field, offset, value);
473 usbhid_submit_report(hid, field->report, USB_DIR_OUT);
474
475 return 0;
476}
477
478int usbhid_wait_io(struct hid_device *hid)
479{
480 struct usbhid_device *usbhid = hid->driver_data;
481
482 if (!wait_event_timeout(usbhid->wait,
483 (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
484 !test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
485 10*HZ)) {
486 dbg_hid("timeout waiting for ctrl or out queue to clear\n");
487 return -1;
488 }
489
490 return 0;
491}
492
493static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
494{
495 return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
496 HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
497 ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
498}
499
500static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
501 unsigned char type, void *buf, int size)
502{
503 int result, retries = 4;
504
505 memset(buf, 0, size);
506
507 do {
508 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
509 USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
510 (type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT);
511 retries--;
512 } while (result < size && retries);
513 return result;
514}
515
516int usbhid_open(struct hid_device *hid)
517{
518 struct usbhid_device *usbhid = hid->driver_data;
519 int res;
520
521 if (!hid->open++) {
522 res = usb_autopm_get_interface(usbhid->intf);
523 if (res < 0) {
524 hid->open--;
525 return -EIO;
526 }
527 }
528 if (hid_start_in(hid))
529 hid_io_error(hid);
530 return 0;
531}
532
533void usbhid_close(struct hid_device *hid)
534{
535 struct usbhid_device *usbhid = hid->driver_data;
536
537 if (!--hid->open) {
538 usb_kill_urb(usbhid->urbin);
539 usb_autopm_put_interface(usbhid->intf);
540 }
541}
542
543/*
544 * Initialize all reports
545 */
546
547void usbhid_init_reports(struct hid_device *hid)
548{
549 struct hid_report *report;
550 struct usbhid_device *usbhid = hid->driver_data;
551 int err, ret;
552
553 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list)
554 usbhid_submit_report(hid, report, USB_DIR_IN);
555
556 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
557 usbhid_submit_report(hid, report, USB_DIR_IN);
558
559 err = 0;
560 ret = usbhid_wait_io(hid);
561 while (ret) {
562 err |= ret;
563 if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
564 usb_kill_urb(usbhid->urbctrl);
565 if (test_bit(HID_OUT_RUNNING, &usbhid->iofl))
566 usb_kill_urb(usbhid->urbout);
567 ret = usbhid_wait_io(hid);
568 }
569
570 if (err)
571 warn("timeout initializing reports");
572}
573
574/*
575 * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01).
576 */
577static int hid_find_field_early(struct hid_device *hid, unsigned int page,
578 unsigned int hid_code, struct hid_field **pfield)
579{
580 struct hid_report *report;
581 struct hid_field *field;
582 struct hid_usage *usage;
583 int i, j;
584
585 list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
586 for (i = 0; i < report->maxfield; i++) {
587 field = report->field[i];
588 for (j = 0; j < field->maxusage; j++) {
589 usage = &field->usage[j];
590 if ((usage->hid & HID_USAGE_PAGE) == page &&
591 (usage->hid & 0xFFFF) == hid_code) {
592 *pfield = field;
593 return j;
594 }
595 }
596 }
597 }
598 return -1;
599}
600
601static void usbhid_set_leds(struct hid_device *hid)
602{
603 struct hid_field *field;
604 int offset;
605
606 if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) {
607 hid_set_field(field, offset, 0);
608 usbhid_submit_report(hid, field->report, USB_DIR_OUT);
609 }
610}
611
612/*
613 * Traverse the supplied list of reports and find the longest
614 */
615static void hid_find_max_report(struct hid_device *hid, unsigned int type,
616 unsigned int *max)
617{
618 struct hid_report *report;
619 unsigned int size;
620
621 list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
622 size = ((report->size - 1) >> 3) + 1;
623 if (type == HID_INPUT_REPORT && hid->report_enum[type].numbered)
624 size++;
625 if (*max < size)
626 *max = size;
627 }
628}
629
630static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
631{
632 struct usbhid_device *usbhid = hid->driver_data;
633
634 if (!(usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->inbuf_dma)))
635 return -1;
636 if (!(usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->outbuf_dma)))
637 return -1;
638 if (!(usbhid->cr = usb_buffer_alloc(dev, sizeof(*(usbhid->cr)), GFP_ATOMIC, &usbhid->cr_dma)))
639 return -1;
640 if (!(usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->ctrlbuf_dma)))
641 return -1;
642
643 return 0;
644}
645
646static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count)
647{
648 struct usbhid_device *usbhid = hid->driver_data;
649 struct usb_device *dev = hid_to_usb_dev(hid);
650 struct usb_interface *intf = usbhid->intf;
651 struct usb_host_interface *interface = intf->cur_altsetting;
652 int ret;
653
654 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
655 HID_REQ_SET_REPORT,
656 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
657 ((HID_OUTPUT_REPORT + 1) << 8) | *buf,
658 interface->desc.bInterfaceNumber, buf + 1, count - 1,
659 USB_CTRL_SET_TIMEOUT);
660
661 /* count also the report id */
662 if (ret > 0)
663 ret++;
664
665 return ret;
666}
667
668static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
669{
670 struct usbhid_device *usbhid = hid->driver_data;
671
672 usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
673 usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
674 usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma);
675 usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
676}
677
678/*
679 * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller
680 * to "operational". Without this, the ps3 controller will not report any
681 * events.
682 */
683static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum)
684{
685 int result;
686 char *buf = kmalloc(18, GFP_KERNEL);
687
688 if (!buf)
689 return;
690
691 result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
692 HID_REQ_GET_REPORT,
693 USB_DIR_IN | USB_TYPE_CLASS |
694 USB_RECIP_INTERFACE,
695 (3 << 8) | 0xf2, ifnum, buf, 17,
696 USB_CTRL_GET_TIMEOUT);
697
698 if (result < 0)
699 err_hid("%s failed: %d\n", __func__, result);
700
701 kfree(buf);
702}
703
704static struct hid_device *usb_hid_configure(struct usb_interface *intf)
705{
706 struct usb_host_interface *interface = intf->cur_altsetting;
707 struct usb_device *dev = interface_to_usbdev (intf);
708 struct hid_descriptor *hdesc;
709 struct hid_device *hid;
710 u32 quirks = 0;
711 unsigned int insize = 0, rsize = 0;
712 char *rdesc;
713 int n, len;
714 struct usbhid_device *usbhid;
715
716 quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
717 le16_to_cpu(dev->descriptor.idProduct));
718
719 /* Many keyboards and mice don't like to be polled for reports,
720 * so we will always set the HID_QUIRK_NOGET flag for them. */
721 if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
722 if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD ||
723 interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
724 quirks |= HID_QUIRK_NOGET;
725 }
726
727 if (quirks & HID_QUIRK_IGNORE)
728 return NULL;
729
730 if ((quirks & HID_QUIRK_IGNORE_MOUSE) &&
731 (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE))
732 return NULL;
733
734
735 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
736 (!interface->desc.bNumEndpoints ||
737 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
738 dbg_hid("class descriptor not present\n");
739 return NULL;
740 }
741
742 for (n = 0; n < hdesc->bNumDescriptors; n++)
743 if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
744 rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
745
746 if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
747 dbg_hid("weird size of report descriptor (%u)\n", rsize);
748 return NULL;
749 }
750
751 if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
752 dbg_hid("couldn't allocate rdesc memory\n");
753 return NULL;
754 }
755
756 hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
757
758 if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {
759 dbg_hid("reading report descriptor failed\n");
760 kfree(rdesc);
761 return NULL;
762 }
763
764 usbhid_fixup_report_descriptor(le16_to_cpu(dev->descriptor.idVendor),
765 le16_to_cpu(dev->descriptor.idProduct), rdesc,
766 rsize, rdesc_quirks_param);
767
768 dbg_hid("report descriptor (size %u, read %d) = ", rsize, n);
769 for (n = 0; n < rsize; n++)
770 dbg_hid_line(" %02x", (unsigned char) rdesc[n]);
771 dbg_hid_line("\n");
772
773 if (!(hid = hid_parse_report(rdesc, n))) {
774 dbg_hid("parsing report descriptor failed\n");
775 kfree(rdesc);
776 return NULL;
777 }
778
779 kfree(rdesc);
780 hid->quirks = quirks;
781
782 if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL)))
783 goto fail_no_usbhid;
784
785 hid->driver_data = usbhid;
786 usbhid->hid = hid;
787
788 usbhid->bufsize = HID_MIN_BUFFER_SIZE;
789 hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
790 hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
791 hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize);
792
793 if (usbhid->bufsize > HID_MAX_BUFFER_SIZE)
794 usbhid->bufsize = HID_MAX_BUFFER_SIZE;
795
796 hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
797
798 if (insize > HID_MAX_BUFFER_SIZE)
799 insize = HID_MAX_BUFFER_SIZE;
800
801 if (hid_alloc_buffers(dev, hid)) {
802 hid_free_buffers(dev, hid);
803 goto fail;
804 }
805
806 hid->name[0] = 0;
807
808 if (dev->manufacturer)
809 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
810
811 if (dev->product) {
812 if (dev->manufacturer)
813 strlcat(hid->name, " ", sizeof(hid->name));
814 strlcat(hid->name, dev->product, sizeof(hid->name));
815 }
816
817 if (!strlen(hid->name))
818 snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
819 le16_to_cpu(dev->descriptor.idVendor),
820 le16_to_cpu(dev->descriptor.idProduct));
821
822 for (n = 0; n < interface->desc.bNumEndpoints; n++) {
823
824 struct usb_endpoint_descriptor *endpoint;
825 int pipe;
826 int interval;
827
828 endpoint = &interface->endpoint[n].desc;
829 if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */
830 continue;
831
832 interval = endpoint->bInterval;
833
834 /* Some vendors give fullspeed interval on highspeed devides */
835 if (quirks & HID_QUIRK_FULLSPEED_INTERVAL &&
836 dev->speed == USB_SPEED_HIGH) {
837 interval = fls(endpoint->bInterval*8);
838 printk(KERN_INFO "%s: Fixing fullspeed to highspeed interval: %d -> %d\n",
839 hid->name, endpoint->bInterval, interval);
840 }
841
842 /* Change the polling interval of mice. */
843 if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
844 interval = hid_mousepoll_interval;
845
846 if (usb_endpoint_dir_in(endpoint)) {
847 if (usbhid->urbin)
848 continue;
849 if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
850 goto fail;
851 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
852 usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize,
853 hid_irq_in, hid, interval);
854 usbhid->urbin->transfer_dma = usbhid->inbuf_dma;
855 usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
856 } else {
857 if (usbhid->urbout)
858 continue;
859 if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
860 goto fail;
861 pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);
862 usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0,
863 hid_irq_out, hid, interval);
864 usbhid->urbout->transfer_dma = usbhid->outbuf_dma;
865 usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
866 }
867 }
868
869 if (!usbhid->urbin) {
870 err_hid("couldn't find an input interrupt endpoint");
871 goto fail;
872 }
873
874 init_waitqueue_head(&usbhid->wait);
875 INIT_WORK(&usbhid->reset_work, hid_reset);
876 setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
877
878 spin_lock_init(&usbhid->inlock);
879 spin_lock_init(&usbhid->outlock);
880 spin_lock_init(&usbhid->ctrllock);
881
882 hid->version = le16_to_cpu(hdesc->bcdHID);
883 hid->country = hdesc->bCountryCode;
884 hid->dev = &intf->dev;
885 usbhid->intf = intf;
886 usbhid->ifnum = interface->desc.bInterfaceNumber;
887
888 hid->bus = BUS_USB;
889 hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
890 hid->product = le16_to_cpu(dev->descriptor.idProduct);
891
892 usb_make_path(dev, hid->phys, sizeof(hid->phys));
893 strlcat(hid->phys, "/input", sizeof(hid->phys));
894 len = strlen(hid->phys);
895 if (len < sizeof(hid->phys) - 1)
896 snprintf(hid->phys + len, sizeof(hid->phys) - len,
897 "%d", intf->altsetting[0].desc.bInterfaceNumber);
898
899 if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
900 hid->uniq[0] = 0;
901
902 usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
903 if (!usbhid->urbctrl)
904 goto fail;
905
906 usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr,
907 usbhid->ctrlbuf, 1, hid_ctrl, hid);
908 usbhid->urbctrl->setup_dma = usbhid->cr_dma;
909 usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
910 usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
911 hid->hidinput_input_event = usb_hidinput_input_event;
912 hid->hid_open = usbhid_open;
913 hid->hid_close = usbhid_close;
914#ifdef CONFIG_USB_HIDDEV
915 hid->hiddev_hid_event = hiddev_hid_event;
916 hid->hiddev_report_event = hiddev_report_event;
917#endif
918 hid->hid_output_raw_report = usbhid_output_raw_report;
919 return hid;
920
921fail:
922 usb_free_urb(usbhid->urbin);
923 usb_free_urb(usbhid->urbout);
924 usb_free_urb(usbhid->urbctrl);
925 hid_free_buffers(dev, hid);
926 kfree(usbhid);
927fail_no_usbhid:
928 hid_free_device(hid);
929
930 return NULL;
931}
932
933static void hid_disconnect(struct usb_interface *intf)
934{
935 struct hid_device *hid = usb_get_intfdata (intf);
936 struct usbhid_device *usbhid;
937
938 if (!hid)
939 return;
940
941 usbhid = hid->driver_data;
942
943 spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
944 usb_set_intfdata(intf, NULL);
945 set_bit(HID_DISCONNECTED, &usbhid->iofl);
946 spin_unlock_irq(&usbhid->inlock);
947 usb_kill_urb(usbhid->urbin);
948 usb_kill_urb(usbhid->urbout);
949 usb_kill_urb(usbhid->urbctrl);
950
951 del_timer_sync(&usbhid->io_retry);
952 cancel_work_sync(&usbhid->reset_work);
953
954 if (hid->claimed & HID_CLAIMED_INPUT)
955 hidinput_disconnect(hid);
956 if (hid->claimed & HID_CLAIMED_HIDDEV)
957 hiddev_disconnect(hid);
958 if (hid->claimed & HID_CLAIMED_HIDRAW)
959 hidraw_disconnect(hid);
960
961 usb_free_urb(usbhid->urbin);
962 usb_free_urb(usbhid->urbctrl);
963 usb_free_urb(usbhid->urbout);
964
965 hid_free_buffers(hid_to_usb_dev(hid), hid);
966 kfree(usbhid);
967 hid_free_device(hid);
968}
969
970static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
971{
972 struct hid_device *hid;
973 char path[64];
974 int i;
975 char *c;
976
977 dbg_hid("HID probe called for ifnum %d\n",
978 intf->altsetting->desc.bInterfaceNumber);
979
980 if (!(hid = usb_hid_configure(intf)))
981 return -ENODEV;
982
983 usbhid_init_reports(hid);
984 hid_dump_device(hid);
985 if (hid->quirks & HID_QUIRK_RESET_LEDS)
986 usbhid_set_leds(hid);
987
988 if (!hidinput_connect(hid))
989 hid->claimed |= HID_CLAIMED_INPUT;
990 if (!hiddev_connect(hid))
991 hid->claimed |= HID_CLAIMED_HIDDEV;
992 if (!hidraw_connect(hid))
993 hid->claimed |= HID_CLAIMED_HIDRAW;
994
995 usb_set_intfdata(intf, hid);
996
997 if (!hid->claimed) {
998 printk ("HID device claimed by neither input, hiddev nor hidraw\n");
999 hid_disconnect(intf);
1000 return -ENODEV;
1001 }
1002
1003 if ((hid->claimed & HID_CLAIMED_INPUT))
1004 hid_ff_init(hid);
1005
1006 if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER)
1007 hid_fixup_sony_ps3_controller(interface_to_usbdev(intf),
1008 intf->cur_altsetting->desc.bInterfaceNumber);
1009
1010 printk(KERN_INFO);
1011
1012 if (hid->claimed & HID_CLAIMED_INPUT)
1013 printk("input");
1014 if ((hid->claimed & HID_CLAIMED_INPUT) && ((hid->claimed & HID_CLAIMED_HIDDEV) ||
1015 hid->claimed & HID_CLAIMED_HIDRAW))
1016 printk(",");
1017 if (hid->claimed & HID_CLAIMED_HIDDEV)
1018 printk("hiddev%d", hid->minor);
1019 if ((hid->claimed & HID_CLAIMED_INPUT) && (hid->claimed & HID_CLAIMED_HIDDEV) &&
1020 (hid->claimed & HID_CLAIMED_HIDRAW))
1021 printk(",");
1022 if (hid->claimed & HID_CLAIMED_HIDRAW)
1023 printk("hidraw%d", ((struct hidraw*)hid->hidraw)->minor);
1024
1025 c = "Device";
1026 for (i = 0; i < hid->maxcollection; i++) {
1027 if (hid->collection[i].type == HID_COLLECTION_APPLICATION &&
1028 (hid->collection[i].usage & HID_USAGE_PAGE) == HID_UP_GENDESK &&
1029 (hid->collection[i].usage & 0xffff) < ARRAY_SIZE(hid_types)) {
1030 c = hid_types[hid->collection[i].usage & 0xffff];
1031 break;
1032 }
1033 }
1034
1035 usb_make_path(interface_to_usbdev(intf), path, 63);
1036
1037 printk(": USB HID v%x.%02x %s [%s] on %s\n",
1038 hid->version >> 8, hid->version & 0xff, c, hid->name, path);
1039
1040 return 0;
1041}
1042
1043static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1044{
1045 struct hid_device *hid = usb_get_intfdata (intf);
1046 struct usbhid_device *usbhid = hid->driver_data;
1047
1048 spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
1049 set_bit(HID_SUSPENDED, &usbhid->iofl);
1050 spin_unlock_irq(&usbhid->inlock);
1051 del_timer(&usbhid->io_retry);
1052 usb_kill_urb(usbhid->urbin);
1053 dev_dbg(&intf->dev, "suspend\n");
1054 return 0;
1055}
1056
1057static int hid_resume(struct usb_interface *intf)
1058{
1059 struct hid_device *hid = usb_get_intfdata (intf);
1060 struct usbhid_device *usbhid = hid->driver_data;
1061 int status;
1062
1063 clear_bit(HID_SUSPENDED, &usbhid->iofl);
1064 usbhid->retry_delay = 0;
1065 status = hid_start_in(hid);
1066 dev_dbg(&intf->dev, "resume status %d\n", status);
1067 return status;
1068}
1069
1070/* Treat USB reset pretty much the same as suspend/resume */
1071static int hid_pre_reset(struct usb_interface *intf)
1072{
1073 /* FIXME: What if the interface is already suspended? */
1074 hid_suspend(intf, PMSG_ON);
1075 return 0;
1076}
1077
1078/* Same routine used for post_reset and reset_resume */
1079static int hid_post_reset(struct usb_interface *intf)
1080{
1081 struct usb_device *dev = interface_to_usbdev (intf);
1082
1083 hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
1084 /* FIXME: Any more reinitialization needed? */
1085
1086 return hid_resume(intf);
1087}
1088
1089static struct usb_device_id hid_usb_ids [] = {
1090 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
1091 .bInterfaceClass = USB_INTERFACE_CLASS_HID },
1092 { } /* Terminating entry */
1093};
1094
1095MODULE_DEVICE_TABLE (usb, hid_usb_ids);
1096
1097static struct usb_driver hid_driver = {
1098 .name = "usbhid",
1099 .probe = hid_probe,
1100 .disconnect = hid_disconnect,
1101 .suspend = hid_suspend,
1102 .resume = hid_resume,
1103 .reset_resume = hid_post_reset,
1104 .pre_reset = hid_pre_reset,
1105 .post_reset = hid_post_reset,
1106 .id_table = hid_usb_ids,
1107 .supports_autosuspend = 1,
1108};
1109
1110static int __init hid_init(void)
1111{
1112 int retval;
1113 retval = usbhid_quirks_init(quirks_param);
1114 if (retval)
1115 goto usbhid_quirks_init_fail;
1116 retval = hiddev_init();
1117 if (retval)
1118 goto hiddev_init_fail;
1119 retval = usb_register(&hid_driver);
1120 if (retval)
1121 goto usb_register_fail;
1122 info(DRIVER_VERSION ":" DRIVER_DESC);
1123
1124 return 0;
1125usb_register_fail:
1126 hiddev_exit();
1127hiddev_init_fail:
1128 usbhid_quirks_exit();
1129usbhid_quirks_init_fail:
1130 return retval;
1131}
1132
1133static void __exit hid_exit(void)
1134{
1135 usb_deregister(&hid_driver);
1136 hiddev_exit();
1137 usbhid_quirks_exit();
1138}
1139
1140module_init(hid_init);
1141module_exit(hid_exit);
1142
1143MODULE_AUTHOR(DRIVER_AUTHOR);
1144MODULE_DESCRIPTION(DRIVER_DESC);
1145MODULE_LICENSE(DRIVER_LICENSE);
diff --git a/usr/src/dkms_source_tree/hid-ff.c b/usr/src/dkms_source_tree/hid-ff.c
new file mode 100644
index 0000000..1d0dac5
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-ff.c
@@ -0,0 +1,95 @@
1/*
2 * Force feedback support for hid devices.
3 * Not all hid devices use the same protocol. For example, some use PID,
4 * other use their own proprietary procotol.
5 *
6 * Copyright (c) 2002-2004 Johann Deneux
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Should you need to contact me, the author, you can do so by
25 * e-mail - mail your message to <johann.deneux@it.uu.se>
26 */
27
28#include <linux/input.h>
29
30#undef DEBUG
31#include <linux/usb.h>
32
33#include <linux/hid.h>
34#include "usbhid.h"
35
36/*
37 * This table contains pointers to initializers. To add support for new
38 * devices, you need to add the USB vendor and product ids here.
39 */
40struct hid_ff_initializer {
41 u16 idVendor;
42 u16 idProduct;
43 int (*init)(struct hid_device*);
44};
45
46/*
47 * We try pidff when no other driver is found because PID is the
48 * standards compliant way of implementing force feedback in HID.
49 * pidff_init() will quickly abort if the device doesn't appear to
50 * be a PID device
51 */
52static struct hid_ff_initializer inits[] = {
53#ifdef CONFIG_LOGITECH_FF
54 { 0x46d, 0xc211, hid_lgff_init }, /* Logitech Cordless rumble pad */
55 { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */
56 { 0x46d, 0xc283, hid_lgff_init }, /* Logitech Wingman Force 3d */
57 { 0x46d, 0xc286, hid_lgff_init }, /* Logitech Force 3D Pro Joystick */
58 { 0x46d, 0xc294, hid_lgff_init }, /* Logitech Formula Force EX */
59 { 0x46d, 0xc295, hid_lgff_init }, /* Logitech MOMO force wheel */
60 { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */
61#endif
62#ifdef CONFIG_LOGIRUMBLEPAD2_FF
63 { 0x46d, 0xc218, hid_lg2ff_init }, /* Logitech Rumblepad 2 */
64#endif
65#ifdef CONFIG_PANTHERLORD_FF
66 { 0x810, 0x0001, hid_plff_init }, /* "Twin USB Joystick" */
67 { 0xe8f, 0x0003, hid_plff_init }, /* "GreenAsia Inc. USB Joystick " */
68#endif
69#ifdef CONFIG_THRUSTMASTER_FF
70 { 0x44f, 0xb300, hid_tmff_init },
71 { 0x44f, 0xb304, hid_tmff_init },
72 { 0x44f, 0xb651, hid_tmff_init }, /* FGT Rumble Force Wheel */
73 { 0x44f, 0xb654, hid_tmff_init }, /* FGT Force Feedback Wheel */
74#endif
75#ifdef CONFIG_ZEROPLUS_FF
76 { 0xc12, 0x0005, hid_zpff_init },
77 { 0xc12, 0x0030, hid_zpff_init },
78#endif
79 { 0, 0, hid_pidff_init} /* Matches anything */
80};
81
82int hid_ff_init(struct hid_device* hid)
83{
84 struct hid_ff_initializer *init;
85 int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor);
86 int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct);
87
88 for (init = inits; init->idVendor; init++)
89 if (init->idVendor == vendor && init->idProduct == product)
90 break;
91
92 return init->init(hid);
93}
94EXPORT_SYMBOL_GPL(hid_ff_init);
95
diff --git a/usr/src/dkms_source_tree/hid-lg2ff.c b/usr/src/dkms_source_tree/hid-lg2ff.c
new file mode 100644
index 0000000..d469bd0
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-lg2ff.c
@@ -0,0 +1,114 @@
1/*
2 * Force feedback support for Logitech Rumblepad 2
3 *
4 * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24#include <linux/input.h>
25#include <linux/usb.h>
26#include <linux/hid.h>
27#include "usbhid.h"
28
29struct lg2ff_device {
30 struct hid_report *report;
31};
32
33static int play_effect(struct input_dev *dev, void *data,
34 struct ff_effect *effect)
35{
36 struct hid_device *hid = input_get_drvdata(dev);
37 struct lg2ff_device *lg2ff = data;
38 int weak, strong;
39
40 strong = effect->u.rumble.strong_magnitude;
41 weak = effect->u.rumble.weak_magnitude;
42
43 if (weak || strong) {
44 weak = weak * 0xff / 0xffff;
45 strong = strong * 0xff / 0xffff;
46
47 lg2ff->report->field[0]->value[0] = 0x51;
48 lg2ff->report->field[0]->value[2] = weak;
49 lg2ff->report->field[0]->value[4] = strong;
50 } else {
51 lg2ff->report->field[0]->value[0] = 0xf3;
52 lg2ff->report->field[0]->value[2] = 0x00;
53 lg2ff->report->field[0]->value[4] = 0x00;
54 }
55
56 usbhid_submit_report(hid, lg2ff->report, USB_DIR_OUT);
57 return 0;
58}
59
60int hid_lg2ff_init(struct hid_device *hid)
61{
62 struct lg2ff_device *lg2ff;
63 struct hid_report *report;
64 struct hid_input *hidinput = list_entry(hid->inputs.next,
65 struct hid_input, list);
66 struct list_head *report_list =
67 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
68 struct input_dev *dev = hidinput->input;
69 int error;
70
71 if (list_empty(report_list)) {
72 printk(KERN_ERR "hid-lg2ff: no output report found\n");
73 return -ENODEV;
74 }
75
76 report = list_entry(report_list->next, struct hid_report, list);
77
78 if (report->maxfield < 1) {
79 printk(KERN_ERR "hid-lg2ff: output report is empty\n");
80 return -ENODEV;
81 }
82 if (report->field[0]->report_count < 7) {
83 printk(KERN_ERR "hid-lg2ff: not enough values in the field\n");
84 return -ENODEV;
85 }
86
87 lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
88 if (!lg2ff)
89 return -ENOMEM;
90
91 set_bit(FF_RUMBLE, dev->ffbit);
92
93 error = input_ff_create_memless(dev, lg2ff, play_effect);
94 if (error) {
95 kfree(lg2ff);
96 return error;
97 }
98
99 lg2ff->report = report;
100 report->field[0]->value[0] = 0xf3;
101 report->field[0]->value[1] = 0x00;
102 report->field[0]->value[2] = 0x00;
103 report->field[0]->value[3] = 0x00;
104 report->field[0]->value[4] = 0x00;
105 report->field[0]->value[5] = 0x00;
106 report->field[0]->value[6] = 0x00;
107
108 usbhid_submit_report(hid, report, USB_DIR_OUT);
109
110 printk(KERN_INFO "Force feedback for Logitech Rumblepad 2 by "
111 "Anssi Hannula <anssi.hannula@gmail.com>\n");
112
113 return 0;
114}
diff --git a/usr/src/dkms_source_tree/hid-lgff.c b/usr/src/dkms_source_tree/hid-lgff.c
new file mode 100644
index 0000000..4b7ab6a
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-lgff.c
@@ -0,0 +1,151 @@
1/*
2 * Force feedback support for hid-compliant for some of the devices from
3 * Logitech, namely:
4 * - WingMan Cordless RumblePad
5 * - WingMan Force 3D
6 *
7 * Copyright (c) 2002-2004 Johann Deneux
8 * Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
9 */
10
11/*
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * Should you need to contact me, the author, you can do so by
27 * e-mail - mail your message to <johann.deneux@it.uu.se>
28 */
29
30#include <linux/input.h>
31#include <linux/usb.h>
32#include <linux/hid.h>
33#include "usbhid.h"
34
35struct dev_type {
36 u16 idVendor;
37 u16 idProduct;
38 const signed short *ff;
39};
40
41static const signed short ff_rumble[] = {
42 FF_RUMBLE,
43 -1
44};
45
46static const signed short ff_joystick[] = {
47 FF_CONSTANT,
48 -1
49};
50
51static const struct dev_type devices[] = {
52 { 0x046d, 0xc211, ff_rumble },
53 { 0x046d, 0xc219, ff_rumble },
54 { 0x046d, 0xc283, ff_joystick },
55 { 0x046d, 0xc286, ff_joystick },
56 { 0x046d, 0xc294, ff_joystick },
57 { 0x046d, 0xc295, ff_joystick },
58 { 0x046d, 0xca03, ff_joystick },
59};
60
61static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
62{
63 struct hid_device *hid = input_get_drvdata(dev);
64 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
65 struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
66 int x, y;
67 unsigned int left, right;
68
69#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff
70
71 switch (effect->type) {
72 case FF_CONSTANT:
73 x = effect->u.ramp.start_level + 0x7f; /* 0x7f is center */
74 y = effect->u.ramp.end_level + 0x7f;
75 CLAMP(x);
76 CLAMP(y);
77 report->field[0]->value[0] = 0x51;
78 report->field[0]->value[1] = 0x08;
79 report->field[0]->value[2] = x;
80 report->field[0]->value[3] = y;
81 dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
82 usbhid_submit_report(hid, report, USB_DIR_OUT);
83 break;
84
85 case FF_RUMBLE:
86 right = effect->u.rumble.strong_magnitude;
87 left = effect->u.rumble.weak_magnitude;
88 right = right * 0xff / 0xffff;
89 left = left * 0xff / 0xffff;
90 CLAMP(left);
91 CLAMP(right);
92 report->field[0]->value[0] = 0x42;
93 report->field[0]->value[1] = 0x00;
94 report->field[0]->value[2] = left;
95 report->field[0]->value[3] = right;
96 dbg_hid("(left, right)=(%04x, %04x)\n", left, right);
97 usbhid_submit_report(hid, report, USB_DIR_OUT);
98 break;
99 }
100 return 0;
101}
102
103int hid_lgff_init(struct hid_device* hid)
104{
105 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
106 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
107 struct input_dev *dev = hidinput->input;
108 struct hid_report *report;
109 struct hid_field *field;
110 const signed short *ff_bits = ff_joystick;
111 int error;
112 int i;
113
114 /* Find the report to use */
115 if (list_empty(report_list)) {
116 err_hid("No output report found");
117 return -1;
118 }
119
120 /* Check that the report looks ok */
121 report = list_entry(report_list->next, struct hid_report, list);
122 if (!report) {
123 err_hid("NULL output report");
124 return -1;
125 }
126
127 field = report->field[0];
128 if (!field) {
129 err_hid("NULL field");
130 return -1;
131 }
132
133 for (i = 0; i < ARRAY_SIZE(devices); i++) {
134 if (dev->id.vendor == devices[i].idVendor &&
135 dev->id.product == devices[i].idProduct) {
136 ff_bits = devices[i].ff;
137 break;
138 }
139 }
140
141 for (i = 0; ff_bits[i] >= 0; i++)
142 set_bit(ff_bits[i], dev->ffbit);
143
144 error = input_ff_create_memless(dev, NULL, hid_lgff_play);
145 if (error)
146 return error;
147
148 printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux <johann.deneux@it.uu.se>\n");
149
150 return 0;
151}
diff --git a/usr/src/dkms_source_tree/hid-pidff.c b/usr/src/dkms_source_tree/hid-pidff.c
new file mode 100644
index 0000000..0113261
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-pidff.c
@@ -0,0 +1,1332 @@
1/*
2 * Force feedback driver for USB HID PID compliant devices
3 *
4 * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23/* #define DEBUG */
24
25#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg)
26
27#include <linux/input.h>
28#include <linux/usb.h>
29
30#include <linux/hid.h>
31
32#include "usbhid.h"
33
34#define PID_EFFECTS_MAX 64
35
36/* Report usage table used to put reports into an array */
37
38#define PID_SET_EFFECT 0
39#define PID_EFFECT_OPERATION 1
40#define PID_DEVICE_GAIN 2
41#define PID_POOL 3
42#define PID_BLOCK_LOAD 4
43#define PID_BLOCK_FREE 5
44#define PID_DEVICE_CONTROL 6
45#define PID_CREATE_NEW_EFFECT 7
46
47#define PID_REQUIRED_REPORTS 7
48
49#define PID_SET_ENVELOPE 8
50#define PID_SET_CONDITION 9
51#define PID_SET_PERIODIC 10
52#define PID_SET_CONSTANT 11
53#define PID_SET_RAMP 12
54static const u8 pidff_reports[] = {
55 0x21, 0x77, 0x7d, 0x7f, 0x89, 0x90, 0x96, 0xab,
56 0x5a, 0x5f, 0x6e, 0x73, 0x74
57};
58
59/* device_control is really 0x95, but 0x96 specified as it is the usage of
60the only field in that report */
61
62/* Value usage tables used to put fields and values into arrays */
63
64#define PID_EFFECT_BLOCK_INDEX 0
65
66#define PID_DURATION 1
67#define PID_GAIN 2
68#define PID_TRIGGER_BUTTON 3
69#define PID_TRIGGER_REPEAT_INT 4
70#define PID_DIRECTION_ENABLE 5
71#define PID_START_DELAY 6
72static const u8 pidff_set_effect[] = {
73 0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7
74};
75
76#define PID_ATTACK_LEVEL 1
77#define PID_ATTACK_TIME 2
78#define PID_FADE_LEVEL 3
79#define PID_FADE_TIME 4
80static const u8 pidff_set_envelope[] = { 0x22, 0x5b, 0x5c, 0x5d, 0x5e };
81
82#define PID_PARAM_BLOCK_OFFSET 1
83#define PID_CP_OFFSET 2
84#define PID_POS_COEFFICIENT 3
85#define PID_NEG_COEFFICIENT 4
86#define PID_POS_SATURATION 5
87#define PID_NEG_SATURATION 6
88#define PID_DEAD_BAND 7
89static const u8 pidff_set_condition[] = {
90 0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65
91};
92
93#define PID_MAGNITUDE 1
94#define PID_OFFSET 2
95#define PID_PHASE 3
96#define PID_PERIOD 4
97static const u8 pidff_set_periodic[] = { 0x22, 0x70, 0x6f, 0x71, 0x72 };
98static const u8 pidff_set_constant[] = { 0x22, 0x70 };
99
100#define PID_RAMP_START 1
101#define PID_RAMP_END 2
102static const u8 pidff_set_ramp[] = { 0x22, 0x75, 0x76 };
103
104#define PID_RAM_POOL_AVAILABLE 1
105static const u8 pidff_block_load[] = { 0x22, 0xac };
106
107#define PID_LOOP_COUNT 1
108static const u8 pidff_effect_operation[] = { 0x22, 0x7c };
109
110static const u8 pidff_block_free[] = { 0x22 };
111
112#define PID_DEVICE_GAIN_FIELD 0
113static const u8 pidff_device_gain[] = { 0x7e };
114
115#define PID_RAM_POOL_SIZE 0
116#define PID_SIMULTANEOUS_MAX 1
117#define PID_DEVICE_MANAGED_POOL 2
118static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
119
120/* Special field key tables used to put special field keys into arrays */
121
122#define PID_ENABLE_ACTUATORS 0
123#define PID_RESET 1
124static const u8 pidff_device_control[] = { 0x97, 0x9a };
125
126#define PID_CONSTANT 0
127#define PID_RAMP 1
128#define PID_SQUARE 2
129#define PID_SINE 3
130#define PID_TRIANGLE 4
131#define PID_SAW_UP 5
132#define PID_SAW_DOWN 6
133#define PID_SPRING 7
134#define PID_DAMPER 8
135#define PID_INERTIA 9
136#define PID_FRICTION 10
137static const u8 pidff_effect_types[] = {
138 0x26, 0x27, 0x30, 0x31, 0x32, 0x33, 0x34,
139 0x40, 0x41, 0x42, 0x43
140};
141
142#define PID_BLOCK_LOAD_SUCCESS 0
143#define PID_BLOCK_LOAD_FULL 1
144static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
145
146#define PID_EFFECT_START 0
147#define PID_EFFECT_STOP 1
148static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
149
150struct pidff_usage {
151 struct hid_field *field;
152 s32 *value;
153};
154
155struct pidff_device {
156 struct hid_device *hid;
157
158 struct hid_report *reports[sizeof(pidff_reports)];
159
160 struct pidff_usage set_effect[sizeof(pidff_set_effect)];
161 struct pidff_usage set_envelope[sizeof(pidff_set_envelope)];
162 struct pidff_usage set_condition[sizeof(pidff_set_condition)];
163 struct pidff_usage set_periodic[sizeof(pidff_set_periodic)];
164 struct pidff_usage set_constant[sizeof(pidff_set_constant)];
165 struct pidff_usage set_ramp[sizeof(pidff_set_ramp)];
166
167 struct pidff_usage device_gain[sizeof(pidff_device_gain)];
168 struct pidff_usage block_load[sizeof(pidff_block_load)];
169 struct pidff_usage pool[sizeof(pidff_pool)];
170 struct pidff_usage effect_operation[sizeof(pidff_effect_operation)];
171 struct pidff_usage block_free[sizeof(pidff_block_free)];
172
173 /* Special field is a field that is not composed of
174 usage<->value pairs that pidff_usage values are */
175
176 /* Special field in create_new_effect */
177 struct hid_field *create_new_effect_type;
178
179 /* Special fields in set_effect */
180 struct hid_field *set_effect_type;
181 struct hid_field *effect_direction;
182
183 /* Special field in device_control */
184 struct hid_field *device_control;
185
186 /* Special field in block_load */
187 struct hid_field *block_load_status;
188
189 /* Special field in effect_operation */
190 struct hid_field *effect_operation_status;
191
192 int control_id[sizeof(pidff_device_control)];
193 int type_id[sizeof(pidff_effect_types)];
194 int status_id[sizeof(pidff_block_load_status)];
195 int operation_id[sizeof(pidff_effect_operation_status)];
196
197 int pid_id[PID_EFFECTS_MAX];
198};
199
200/*
201 * Scale an unsigned value with range 0..max for the given field
202 */
203static int pidff_rescale(int i, int max, struct hid_field *field)
204{
205 return i * (field->logical_maximum - field->logical_minimum) / max +
206 field->logical_minimum;
207}
208
209/*
210 * Scale a signed value in range -0x8000..0x7fff for the given field
211 */
212static int pidff_rescale_signed(int i, struct hid_field *field)
213{
214 return i == 0 ? 0 : i >
215 0 ? i * field->logical_maximum / 0x7fff : i *
216 field->logical_minimum / -0x8000;
217}
218
219static void pidff_set(struct pidff_usage *usage, u16 value)
220{
221 usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
222 debug("calculated from %d to %d", value, usage->value[0]);
223}
224
225static void pidff_set_signed(struct pidff_usage *usage, s16 value)
226{
227 if (usage->field->logical_minimum < 0)
228 usage->value[0] = pidff_rescale_signed(value, usage->field);
229 else {
230 if (value < 0)
231 usage->value[0] =
232 pidff_rescale(-value, 0x8000, usage->field);
233 else
234 usage->value[0] =
235 pidff_rescale(value, 0x7fff, usage->field);
236 }
237 debug("calculated from %d to %d", value, usage->value[0]);
238}
239
240/*
241 * Send envelope report to the device
242 */
243static void pidff_set_envelope_report(struct pidff_device *pidff,
244 struct ff_envelope *envelope)
245{
246 pidff->set_envelope[PID_EFFECT_BLOCK_INDEX].value[0] =
247 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
248
249 pidff->set_envelope[PID_ATTACK_LEVEL].value[0] =
250 pidff_rescale(envelope->attack_level >
251 0x7fff ? 0x7fff : envelope->attack_level, 0x7fff,
252 pidff->set_envelope[PID_ATTACK_LEVEL].field);
253 pidff->set_envelope[PID_FADE_LEVEL].value[0] =
254 pidff_rescale(envelope->fade_level >
255 0x7fff ? 0x7fff : envelope->fade_level, 0x7fff,
256 pidff->set_envelope[PID_FADE_LEVEL].field);
257
258 pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length;
259 pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length;
260
261 debug("attack %u => %d", envelope->attack_level,
262 pidff->set_envelope[PID_ATTACK_LEVEL].value[0]);
263
264 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE],
265 USB_DIR_OUT);
266}
267
268/*
269 * Test if the new envelope differs from old one
270 */
271static int pidff_needs_set_envelope(struct ff_envelope *envelope,
272 struct ff_envelope *old)
273{
274 return envelope->attack_level != old->attack_level ||
275 envelope->fade_level != old->fade_level ||
276 envelope->attack_length != old->attack_length ||
277 envelope->fade_length != old->fade_length;
278}
279
280/*
281 * Send constant force report to the device
282 */
283static void pidff_set_constant_force_report(struct pidff_device *pidff,
284 struct ff_effect *effect)
285{
286 pidff->set_constant[PID_EFFECT_BLOCK_INDEX].value[0] =
287 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
288 pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE],
289 effect->u.constant.level);
290
291 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT],
292 USB_DIR_OUT);
293}
294
295/*
296 * Test if the constant parameters have changed between effects
297 */
298static int pidff_needs_set_constant(struct ff_effect *effect,
299 struct ff_effect *old)
300{
301 return effect->u.constant.level != old->u.constant.level;
302}
303
304/*
305 * Send set effect report to the device
306 */
307static void pidff_set_effect_report(struct pidff_device *pidff,
308 struct ff_effect *effect)
309{
310 pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
311 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
312 pidff->set_effect_type->value[0] =
313 pidff->create_new_effect_type->value[0];
314 pidff->set_effect[PID_DURATION].value[0] = effect->replay.length;
315 pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button;
316 pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] =
317 effect->trigger.interval;
318 pidff->set_effect[PID_GAIN].value[0] =
319 pidff->set_effect[PID_GAIN].field->logical_maximum;
320 pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
321 pidff->effect_direction->value[0] =
322 pidff_rescale(effect->direction, 0xffff,
323 pidff->effect_direction);
324 pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay;
325
326 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
327 USB_DIR_OUT);
328}
329
330/*
331 * Test if the values used in set_effect have changed
332 */
333static int pidff_needs_set_effect(struct ff_effect *effect,
334 struct ff_effect *old)
335{
336 return effect->replay.length != old->replay.length ||
337 effect->trigger.interval != old->trigger.interval ||
338 effect->trigger.button != old->trigger.button ||
339 effect->direction != old->direction ||
340 effect->replay.delay != old->replay.delay;
341}
342
343/*
344 * Send periodic effect report to the device
345 */
346static void pidff_set_periodic_report(struct pidff_device *pidff,
347 struct ff_effect *effect)
348{
349 pidff->set_periodic[PID_EFFECT_BLOCK_INDEX].value[0] =
350 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
351 pidff_set_signed(&pidff->set_periodic[PID_MAGNITUDE],
352 effect->u.periodic.magnitude);
353 pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
354 effect->u.periodic.offset);
355 pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
356 pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
357
358 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC],
359 USB_DIR_OUT);
360
361}
362
363/*
364 * Test if periodic effect parameters have changed
365 */
366static int pidff_needs_set_periodic(struct ff_effect *effect,
367 struct ff_effect *old)
368{
369 return effect->u.periodic.magnitude != old->u.periodic.magnitude ||
370 effect->u.periodic.offset != old->u.periodic.offset ||
371 effect->u.periodic.phase != old->u.periodic.phase ||
372 effect->u.periodic.period != old->u.periodic.period;
373}
374
375/*
376 * Send condition effect reports to the device
377 */
378static void pidff_set_condition_report(struct pidff_device *pidff,
379 struct ff_effect *effect)
380{
381 int i;
382
383 pidff->set_condition[PID_EFFECT_BLOCK_INDEX].value[0] =
384 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
385
386 for (i = 0; i < 2; i++) {
387 pidff->set_condition[PID_PARAM_BLOCK_OFFSET].value[0] = i;
388 pidff_set_signed(&pidff->set_condition[PID_CP_OFFSET],
389 effect->u.condition[i].center);
390 pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT],
391 effect->u.condition[i].right_coeff);
392 pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT],
393 effect->u.condition[i].left_coeff);
394 pidff_set(&pidff->set_condition[PID_POS_SATURATION],
395 effect->u.condition[i].right_saturation);
396 pidff_set(&pidff->set_condition[PID_NEG_SATURATION],
397 effect->u.condition[i].left_saturation);
398 pidff_set(&pidff->set_condition[PID_DEAD_BAND],
399 effect->u.condition[i].deadband);
400 usbhid_wait_io(pidff->hid);
401 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION],
402 USB_DIR_OUT);
403 }
404}
405
406/*
407 * Test if condition effect parameters have changed
408 */
409static int pidff_needs_set_condition(struct ff_effect *effect,
410 struct ff_effect *old)
411{
412 int i;
413 int ret = 0;
414
415 for (i = 0; i < 2; i++) {
416 struct ff_condition_effect *cond = &effect->u.condition[i];
417 struct ff_condition_effect *old_cond = &old->u.condition[i];
418
419 ret |= cond->center != old_cond->center ||
420 cond->right_coeff != old_cond->right_coeff ||
421 cond->left_coeff != old_cond->left_coeff ||
422 cond->right_saturation != old_cond->right_saturation ||
423 cond->left_saturation != old_cond->left_saturation ||
424 cond->deadband != old_cond->deadband;
425 }
426
427 return ret;
428}
429
430/*
431 * Send ramp force report to the device
432 */
433static void pidff_set_ramp_force_report(struct pidff_device *pidff,
434 struct ff_effect *effect)
435{
436 pidff->set_ramp[PID_EFFECT_BLOCK_INDEX].value[0] =
437 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
438 pidff_set_signed(&pidff->set_ramp[PID_RAMP_START],
439 effect->u.ramp.start_level);
440 pidff_set_signed(&pidff->set_ramp[PID_RAMP_END],
441 effect->u.ramp.end_level);
442 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP],
443 USB_DIR_OUT);
444}
445
446/*
447 * Test if ramp force parameters have changed
448 */
449static int pidff_needs_set_ramp(struct ff_effect *effect, struct ff_effect *old)
450{
451 return effect->u.ramp.start_level != old->u.ramp.start_level ||
452 effect->u.ramp.end_level != old->u.ramp.end_level;
453}
454
455/*
456 * Send a request for effect upload to the device
457 *
458 * Returns 0 if device reported success, -ENOSPC if the device reported memory
459 * is full. Upon unknown response the function will retry for 60 times, if
460 * still unsuccessful -EIO is returned.
461 */
462static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum)
463{
464 int j;
465
466 pidff->create_new_effect_type->value[0] = efnum;
467 usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT],
468 USB_DIR_OUT);
469 debug("create_new_effect sent, type: %d", efnum);
470
471 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0;
472 pidff->block_load_status->value[0] = 0;
473 usbhid_wait_io(pidff->hid);
474
475 for (j = 0; j < 60; j++) {
476 debug("pid_block_load requested");
477 usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD],
478 USB_DIR_IN);
479 usbhid_wait_io(pidff->hid);
480 if (pidff->block_load_status->value[0] ==
481 pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) {
482 debug("device reported free memory: %d bytes",
483 pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
484 pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
485 return 0;
486 }
487 if (pidff->block_load_status->value[0] ==
488 pidff->status_id[PID_BLOCK_LOAD_FULL]) {
489 debug("not enough memory free: %d bytes",
490 pidff->block_load[PID_RAM_POOL_AVAILABLE].value ?
491 pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1);
492 return -ENOSPC;
493 }
494 }
495 printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n");
496 return -EIO;
497}
498
499/*
500 * Play the effect with PID id n times
501 */
502static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n)
503{
504 pidff->effect_operation[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
505
506 if (n == 0) {
507 pidff->effect_operation_status->value[0] =
508 pidff->operation_id[PID_EFFECT_STOP];
509 } else {
510 pidff->effect_operation_status->value[0] =
511 pidff->operation_id[PID_EFFECT_START];
512 pidff->effect_operation[PID_LOOP_COUNT].value[0] = n;
513 }
514
515 usbhid_wait_io(pidff->hid);
516 usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION],
517 USB_DIR_OUT);
518}
519
520/**
521 * Play the effect with effect id @effect_id for @value times
522 */
523static int pidff_playback(struct input_dev *dev, int effect_id, int value)
524{
525 struct pidff_device *pidff = dev->ff->private;
526
527 pidff_playback_pid(pidff, pidff->pid_id[effect_id], value);
528
529 return 0;
530}
531
532/*
533 * Erase effect with PID id
534 */
535static void pidff_erase_pid(struct pidff_device *pidff, int pid_id)
536{
537 pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id;
538 usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE],
539 USB_DIR_OUT);
540}
541
542/*
543 * Stop and erase effect with effect_id
544 */
545static int pidff_erase_effect(struct input_dev *dev, int effect_id)
546{
547 struct pidff_device *pidff = dev->ff->private;
548 int pid_id = pidff->pid_id[effect_id];
549
550 debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]);
551 pidff_playback_pid(pidff, pid_id, 0);
552 pidff_erase_pid(pidff, pid_id);
553
554 return 0;
555}
556
557/*
558 * Effect upload handler
559 */
560static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect,
561 struct ff_effect *old)
562{
563 struct pidff_device *pidff = dev->ff->private;
564 int type_id;
565 int error;
566
567 switch (effect->type) {
568 case FF_CONSTANT:
569 if (!old) {
570 error = pidff_request_effect_upload(pidff,
571 pidff->type_id[PID_CONSTANT]);
572 if (error)
573 return error;
574 }
575 if (!old || pidff_needs_set_effect(effect, old))
576 pidff_set_effect_report(pidff, effect);
577 if (!old || pidff_needs_set_constant(effect, old))
578 pidff_set_constant_force_report(pidff, effect);
579 if (!old ||
580 pidff_needs_set_envelope(&effect->u.constant.envelope,
581 &old->u.constant.envelope))
582 pidff_set_envelope_report(pidff,
583 &effect->u.constant.envelope);
584 break;
585
586 case FF_PERIODIC:
587 if (!old) {
588 switch (effect->u.periodic.waveform) {
589 case FF_SQUARE:
590 type_id = PID_SQUARE;
591 break;
592 case FF_TRIANGLE:
593 type_id = PID_TRIANGLE;
594 break;
595 case FF_SINE:
596 type_id = PID_SINE;
597 break;
598 case FF_SAW_UP:
599 type_id = PID_SAW_UP;
600 break;
601 case FF_SAW_DOWN:
602 type_id = PID_SAW_DOWN;
603 break;
604 default:
605 printk(KERN_ERR
606 "hid-pidff: invalid waveform\n");
607 return -EINVAL;
608 }
609
610 error = pidff_request_effect_upload(pidff,
611 pidff->type_id[type_id]);
612 if (error)
613 return error;
614 }
615 if (!old || pidff_needs_set_effect(effect, old))
616 pidff_set_effect_report(pidff, effect);
617 if (!old || pidff_needs_set_periodic(effect, old))
618 pidff_set_periodic_report(pidff, effect);
619 if (!old ||
620 pidff_needs_set_envelope(&effect->u.periodic.envelope,
621 &old->u.periodic.envelope))
622 pidff_set_envelope_report(pidff,
623 &effect->u.periodic.envelope);
624 break;
625
626 case FF_RAMP:
627 if (!old) {
628 error = pidff_request_effect_upload(pidff,
629 pidff->type_id[PID_RAMP]);
630 if (error)
631 return error;
632 }
633 if (!old || pidff_needs_set_effect(effect, old))
634 pidff_set_effect_report(pidff, effect);
635 if (!old || pidff_needs_set_ramp(effect, old))
636 pidff_set_ramp_force_report(pidff, effect);
637 if (!old ||
638 pidff_needs_set_envelope(&effect->u.ramp.envelope,
639 &old->u.ramp.envelope))
640 pidff_set_envelope_report(pidff,
641 &effect->u.ramp.envelope);
642 break;
643
644 case FF_SPRING:
645 if (!old) {
646 error = pidff_request_effect_upload(pidff,
647 pidff->type_id[PID_SPRING]);
648 if (error)
649 return error;
650 }
651 if (!old || pidff_needs_set_effect(effect, old))
652 pidff_set_effect_report(pidff, effect);
653 if (!old || pidff_needs_set_condition(effect, old))
654 pidff_set_condition_report(pidff, effect);
655 break;
656
657 case FF_FRICTION:
658 if (!old) {
659 error = pidff_request_effect_upload(pidff,
660 pidff->type_id[PID_FRICTION]);
661 if (error)
662 return error;
663 }
664 if (!old || pidff_needs_set_effect(effect, old))
665 pidff_set_effect_report(pidff, effect);
666 if (!old || pidff_needs_set_condition(effect, old))
667 pidff_set_condition_report(pidff, effect);
668 break;
669
670 case FF_DAMPER:
671 if (!old) {
672 error = pidff_request_effect_upload(pidff,
673 pidff->type_id[PID_DAMPER]);
674 if (error)
675 return error;
676 }
677 if (!old || pidff_needs_set_effect(effect, old))
678 pidff_set_effect_report(pidff, effect);
679 if (!old || pidff_needs_set_condition(effect, old))
680 pidff_set_condition_report(pidff, effect);
681 break;
682
683 case FF_INERTIA:
684 if (!old) {
685 error = pidff_request_effect_upload(pidff,
686 pidff->type_id[PID_INERTIA]);
687 if (error)
688 return error;
689 }
690 if (!old || pidff_needs_set_effect(effect, old))
691 pidff_set_effect_report(pidff, effect);
692 if (!old || pidff_needs_set_condition(effect, old))
693 pidff_set_condition_report(pidff, effect);
694 break;
695
696 default:
697 printk(KERN_ERR "hid-pidff: invalid type\n");
698 return -EINVAL;
699 }
700
701 if (!old)
702 pidff->pid_id[effect->id] =
703 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0];
704
705 debug("uploaded");
706
707 return 0;
708}
709
710/*
711 * set_gain() handler
712 */
713static void pidff_set_gain(struct input_dev *dev, u16 gain)
714{
715 struct pidff_device *pidff = dev->ff->private;
716
717 pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain);
718 usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
719 USB_DIR_OUT);
720}
721
722static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude)
723{
724 struct hid_field *field =
725 pidff->block_load[PID_EFFECT_BLOCK_INDEX].field;
726
727 if (!magnitude) {
728 pidff_playback_pid(pidff, field->logical_minimum, 0);
729 return;
730 }
731
732 pidff_playback_pid(pidff, field->logical_minimum, 1);
733
734 pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] =
735 pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum;
736 pidff->set_effect_type->value[0] = pidff->type_id[PID_SPRING];
737 pidff->set_effect[PID_DURATION].value[0] = 0;
738 pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = 0;
739 pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = 0;
740 pidff_set(&pidff->set_effect[PID_GAIN], magnitude);
741 pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
742 pidff->set_effect[PID_START_DELAY].value[0] = 0;
743
744 usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT],
745 USB_DIR_OUT);
746}
747
748/*
749 * pidff_set_autocenter() handler
750 */
751static void pidff_set_autocenter(struct input_dev *dev, u16 magnitude)
752{
753 struct pidff_device *pidff = dev->ff->private;
754
755 pidff_autocenter(pidff, magnitude);
756}
757
758/*
759 * Find fields from a report and fill a pidff_usage
760 */
761static int pidff_find_fields(struct pidff_usage *usage, const u8 *table,
762 struct hid_report *report, int count, int strict)
763{
764 int i, j, k, found;
765
766 for (k = 0; k < count; k++) {
767 found = 0;
768 for (i = 0; i < report->maxfield; i++) {
769 if (report->field[i]->maxusage !=
770 report->field[i]->report_count) {
771 debug("maxusage and report_count do not match, "
772 "skipping");
773 continue;
774 }
775 for (j = 0; j < report->field[i]->maxusage; j++) {
776 if (report->field[i]->usage[j].hid ==
777 (HID_UP_PID | table[k])) {
778 debug("found %d at %d->%d", k, i, j);
779 usage[k].field = report->field[i];
780 usage[k].value =
781 &report->field[i]->value[j];
782 found = 1;
783 break;
784 }
785 }
786 if (found)
787 break;
788 }
789 if (!found && strict) {
790 debug("failed to locate %d", k);
791 return -1;
792 }
793 }
794 return 0;
795}
796
797/*
798 * Return index into pidff_reports for the given usage
799 */
800static int pidff_check_usage(int usage)
801{
802 int i;
803
804 for (i = 0; i < sizeof(pidff_reports); i++)
805 if (usage == (HID_UP_PID | pidff_reports[i]))
806 return i;
807
808 return -1;
809}
810
811/*
812 * Find the reports and fill pidff->reports[]
813 * report_type specifies either OUTPUT or FEATURE reports
814 */
815static void pidff_find_reports(struct hid_device *hid, int report_type,
816 struct pidff_device *pidff)
817{
818 struct hid_report *report;
819 int i, ret;
820
821 list_for_each_entry(report,
822 &hid->report_enum[report_type].report_list, list) {
823 if (report->maxfield < 1)
824 continue;
825 ret = pidff_check_usage(report->field[0]->logical);
826 if (ret != -1) {
827 debug("found usage 0x%02x from field->logical",
828 pidff_reports[ret]);
829 pidff->reports[ret] = report;
830 continue;
831 }
832
833 /*
834 * Sometimes logical collections are stacked to indicate
835 * different usages for the report and the field, in which
836 * case we want the usage of the parent. However, Linux HID
837 * implementation hides this fact, so we have to dig it up
838 * ourselves
839 */
840 i = report->field[0]->usage[0].collection_index;
841 if (i <= 0 ||
842 hid->collection[i - 1].type != HID_COLLECTION_LOGICAL)
843 continue;
844 ret = pidff_check_usage(hid->collection[i - 1].usage);
845 if (ret != -1 && !pidff->reports[ret]) {
846 debug("found usage 0x%02x from collection array",
847 pidff_reports[ret]);
848 pidff->reports[ret] = report;
849 }
850 }
851}
852
853/*
854 * Test if the required reports have been found
855 */
856static int pidff_reports_ok(struct pidff_device *pidff)
857{
858 int i;
859
860 for (i = 0; i <= PID_REQUIRED_REPORTS; i++) {
861 if (!pidff->reports[i]) {
862 debug("%d missing", i);
863 return 0;
864 }
865 }
866
867 return 1;
868}
869
870/*
871 * Find a field with a specific usage within a report
872 */
873static struct hid_field *pidff_find_special_field(struct hid_report *report,
874 int usage, int enforce_min)
875{
876 int i;
877
878 for (i = 0; i < report->maxfield; i++) {
879 if (report->field[i]->logical == (HID_UP_PID | usage) &&
880 report->field[i]->report_count > 0) {
881 if (!enforce_min ||
882 report->field[i]->logical_minimum == 1)
883 return report->field[i];
884 else {
885 printk(KERN_ERR "hid-pidff: logical_minimum "
886 "is not 1 as it should be\n");
887 return NULL;
888 }
889 }
890 }
891 return NULL;
892}
893
894/*
895 * Fill a pidff->*_id struct table
896 */
897static int pidff_find_special_keys(int *keys, struct hid_field *fld,
898 const u8 *usagetable, int count)
899{
900
901 int i, j;
902 int found = 0;
903
904 for (i = 0; i < count; i++) {
905 for (j = 0; j < fld->maxusage; j++) {
906 if (fld->usage[j].hid == (HID_UP_PID | usagetable[i])) {
907 keys[i] = j + 1;
908 found++;
909 break;
910 }
911 }
912 }
913 return found;
914}
915
916#define PIDFF_FIND_SPECIAL_KEYS(keys, field, name) \
917 pidff_find_special_keys(pidff->keys, pidff->field, pidff_ ## name, \
918 sizeof(pidff_ ## name))
919
920/*
921 * Find and check the special fields
922 */
923static int pidff_find_special_fields(struct pidff_device *pidff)
924{
925 debug("finding special fields");
926
927 pidff->create_new_effect_type =
928 pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT],
929 0x25, 1);
930 pidff->set_effect_type =
931 pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
932 0x25, 1);
933 pidff->effect_direction =
934 pidff_find_special_field(pidff->reports[PID_SET_EFFECT],
935 0x57, 0);
936 pidff->device_control =
937 pidff_find_special_field(pidff->reports[PID_DEVICE_CONTROL],
938 0x96, 1);
939 pidff->block_load_status =
940 pidff_find_special_field(pidff->reports[PID_BLOCK_LOAD],
941 0x8b, 1);
942 pidff->effect_operation_status =
943 pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION],
944 0x78, 1);
945
946 debug("search done");
947
948 if (!pidff->create_new_effect_type || !pidff->set_effect_type) {
949 printk(KERN_ERR "hid-pidff: effect lists not found\n");
950 return -1;
951 }
952
953 if (!pidff->effect_direction) {
954 printk(KERN_ERR "hid-pidff: direction field not found\n");
955 return -1;
956 }
957
958 if (!pidff->device_control) {
959 printk(KERN_ERR "hid-pidff: device control field not found\n");
960 return -1;
961 }
962
963 if (!pidff->block_load_status) {
964 printk(KERN_ERR
965 "hid-pidff: block load status field not found\n");
966 return -1;
967 }
968
969 if (!pidff->effect_operation_status) {
970 printk(KERN_ERR
971 "hid-pidff: effect operation field not found\n");
972 return -1;
973 }
974
975 pidff_find_special_keys(pidff->control_id, pidff->device_control,
976 pidff_device_control,
977 sizeof(pidff_device_control));
978
979 PIDFF_FIND_SPECIAL_KEYS(control_id, device_control, device_control);
980
981 if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type,
982 effect_types)) {
983 printk(KERN_ERR "hid-pidff: no effect types found\n");
984 return -1;
985 }
986
987 if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status,
988 block_load_status) !=
989 sizeof(pidff_block_load_status)) {
990 printk(KERN_ERR
991 "hidpidff: block load status identifiers not found\n");
992 return -1;
993 }
994
995 if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status,
996 effect_operation_status) !=
997 sizeof(pidff_effect_operation_status)) {
998 printk(KERN_ERR
999 "hidpidff: effect operation identifiers not found\n");
1000 return -1;
1001 }
1002
1003 return 0;
1004}
1005
1006/**
1007 * Find the implemented effect types
1008 */
1009static int pidff_find_effects(struct pidff_device *pidff,
1010 struct input_dev *dev)
1011{
1012 int i;
1013
1014 for (i = 0; i < sizeof(pidff_effect_types); i++) {
1015 int pidff_type = pidff->type_id[i];
1016 if (pidff->set_effect_type->usage[pidff_type].hid !=
1017 pidff->create_new_effect_type->usage[pidff_type].hid) {
1018 printk(KERN_ERR "hid-pidff: "
1019 "effect type number %d is invalid\n", i);
1020 return -1;
1021 }
1022 }
1023
1024 if (pidff->type_id[PID_CONSTANT])
1025 set_bit(FF_CONSTANT, dev->ffbit);
1026 if (pidff->type_id[PID_RAMP])
1027 set_bit(FF_RAMP, dev->ffbit);
1028 if (pidff->type_id[PID_SQUARE]) {
1029 set_bit(FF_SQUARE, dev->ffbit);
1030 set_bit(FF_PERIODIC, dev->ffbit);
1031 }
1032 if (pidff->type_id[PID_SINE]) {
1033 set_bit(FF_SINE, dev->ffbit);
1034 set_bit(FF_PERIODIC, dev->ffbit);
1035 }
1036 if (pidff->type_id[PID_TRIANGLE]) {
1037 set_bit(FF_TRIANGLE, dev->ffbit);
1038 set_bit(FF_PERIODIC, dev->ffbit);
1039 }
1040 if (pidff->type_id[PID_SAW_UP]) {
1041 set_bit(FF_SAW_UP, dev->ffbit);
1042 set_bit(FF_PERIODIC, dev->ffbit);
1043 }
1044 if (pidff->type_id[PID_SAW_DOWN]) {
1045 set_bit(FF_SAW_DOWN, dev->ffbit);
1046 set_bit(FF_PERIODIC, dev->ffbit);
1047 }
1048 if (pidff->type_id[PID_SPRING])
1049 set_bit(FF_SPRING, dev->ffbit);
1050 if (pidff->type_id[PID_DAMPER])
1051 set_bit(FF_DAMPER, dev->ffbit);
1052 if (pidff->type_id[PID_INERTIA])
1053 set_bit(FF_INERTIA, dev->ffbit);
1054 if (pidff->type_id[PID_FRICTION])
1055 set_bit(FF_FRICTION, dev->ffbit);
1056
1057 return 0;
1058
1059}
1060
1061#define PIDFF_FIND_FIELDS(name, report, strict) \
1062 pidff_find_fields(pidff->name, pidff_ ## name, \
1063 pidff->reports[report], \
1064 sizeof(pidff_ ## name), strict)
1065
1066/*
1067 * Fill and check the pidff_usages
1068 */
1069static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev)
1070{
1071 int envelope_ok = 0;
1072
1073 if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) {
1074 printk(KERN_ERR
1075 "hid-pidff: unknown set_effect report layout\n");
1076 return -ENODEV;
1077 }
1078
1079 PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0);
1080 if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) {
1081 printk(KERN_ERR
1082 "hid-pidff: unknown pid_block_load report layout\n");
1083 return -ENODEV;
1084 }
1085
1086 if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) {
1087 printk(KERN_ERR
1088 "hid-pidff: unknown effect_operation report layout\n");
1089 return -ENODEV;
1090 }
1091
1092 if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) {
1093 printk(KERN_ERR
1094 "hid-pidff: unknown pid_block_free report layout\n");
1095 return -ENODEV;
1096 }
1097
1098 if (!PIDFF_FIND_FIELDS(set_envelope, PID_SET_ENVELOPE, 1))
1099 envelope_ok = 1;
1100
1101 if (pidff_find_special_fields(pidff) || pidff_find_effects(pidff, dev))
1102 return -ENODEV;
1103
1104 if (!envelope_ok) {
1105 if (test_and_clear_bit(FF_CONSTANT, dev->ffbit))
1106 printk(KERN_WARNING "hid-pidff: "
1107 "has constant effect but no envelope\n");
1108 if (test_and_clear_bit(FF_RAMP, dev->ffbit))
1109 printk(KERN_WARNING "hid-pidff: "
1110 "has ramp effect but no envelope\n");
1111
1112 if (test_and_clear_bit(FF_PERIODIC, dev->ffbit))
1113 printk(KERN_WARNING "hid-pidff: "
1114 "has periodic effect but no envelope\n");
1115 }
1116
1117 if (test_bit(FF_CONSTANT, dev->ffbit) &&
1118 PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) {
1119 printk(KERN_WARNING
1120 "hid-pidff: unknown constant effect layout\n");
1121 clear_bit(FF_CONSTANT, dev->ffbit);
1122 }
1123
1124 if (test_bit(FF_RAMP, dev->ffbit) &&
1125 PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) {
1126 printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n");
1127 clear_bit(FF_RAMP, dev->ffbit);
1128 }
1129
1130 if ((test_bit(FF_SPRING, dev->ffbit) ||
1131 test_bit(FF_DAMPER, dev->ffbit) ||
1132 test_bit(FF_FRICTION, dev->ffbit) ||
1133 test_bit(FF_INERTIA, dev->ffbit)) &&
1134 PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) {
1135 printk(KERN_WARNING
1136 "hid-pidff: unknown condition effect layout\n");
1137 clear_bit(FF_SPRING, dev->ffbit);
1138 clear_bit(FF_DAMPER, dev->ffbit);
1139 clear_bit(FF_FRICTION, dev->ffbit);
1140 clear_bit(FF_INERTIA, dev->ffbit);
1141 }
1142
1143 if (test_bit(FF_PERIODIC, dev->ffbit) &&
1144 PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) {
1145 printk(KERN_WARNING
1146 "hid-pidff: unknown periodic effect layout\n");
1147 clear_bit(FF_PERIODIC, dev->ffbit);
1148 }
1149
1150 PIDFF_FIND_FIELDS(pool, PID_POOL, 0);
1151
1152 if (!PIDFF_FIND_FIELDS(device_gain, PID_DEVICE_GAIN, 1))
1153 set_bit(FF_GAIN, dev->ffbit);
1154
1155 return 0;
1156}
1157
1158/*
1159 * Reset the device
1160 */
1161static void pidff_reset(struct pidff_device *pidff)
1162{
1163 struct hid_device *hid = pidff->hid;
1164 int i = 0;
1165
1166 pidff->device_control->value[0] = pidff->control_id[PID_RESET];
1167 /* We reset twice as sometimes hid_wait_io isn't waiting long enough */
1168 usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
1169 usbhid_wait_io(hid);
1170 usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
1171 usbhid_wait_io(hid);
1172
1173 pidff->device_control->value[0] =
1174 pidff->control_id[PID_ENABLE_ACTUATORS];
1175 usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT);
1176 usbhid_wait_io(hid);
1177
1178 /* pool report is sometimes messed up, refetch it */
1179 usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN);
1180 usbhid_wait_io(hid);
1181
1182 if (pidff->pool[PID_SIMULTANEOUS_MAX].value) {
1183 int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0];
1184 while (sim_effects < 2) {
1185 if (i++ > 20) {
1186 printk(KERN_WARNING "hid-pidff: device reports "
1187 "%d simultaneous effects\n",
1188 sim_effects);
1189 break;
1190 }
1191 debug("pid_pool requested again");
1192 usbhid_submit_report(hid, pidff->reports[PID_POOL],
1193 USB_DIR_IN);
1194 usbhid_wait_io(hid);
1195 }
1196 }
1197}
1198
1199/*
1200 * Test if autocenter modification is using the supported method
1201 */
1202static int pidff_check_autocenter(struct pidff_device *pidff,
1203 struct input_dev *dev)
1204{
1205 int error;
1206
1207 /*
1208 * Let's find out if autocenter modification is supported
1209 * Specification doesn't specify anything, so we request an
1210 * effect upload and cancel it immediately. If the approved
1211 * effect id was one above the minimum, then we assume the first
1212 * effect id is a built-in spring type effect used for autocenter
1213 */
1214
1215 error = pidff_request_effect_upload(pidff, 1);
1216 if (error) {
1217 printk(KERN_ERR "hid-pidff: upload request failed\n");
1218 return error;
1219 }
1220
1221 if (pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] ==
1222 pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1) {
1223 pidff_autocenter(pidff, 0xffff);
1224 set_bit(FF_AUTOCENTER, dev->ffbit);
1225 } else {
1226 printk(KERN_NOTICE "hid-pidff: "
1227 "device has unknown autocenter control method\n");
1228 }
1229
1230 pidff_erase_pid(pidff,
1231 pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]);
1232
1233 return 0;
1234
1235}
1236
1237/*
1238 * Check if the device is PID and initialize it
1239 */
1240int hid_pidff_init(struct hid_device *hid)
1241{
1242 struct pidff_device *pidff;
1243 struct hid_input *hidinput = list_entry(hid->inputs.next,
1244 struct hid_input, list);
1245 struct input_dev *dev = hidinput->input;
1246 struct ff_device *ff;
1247 int max_effects;
1248 int error;
1249
1250 debug("starting pid init");
1251
1252 if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) {
1253 debug("not a PID device, no output report");
1254 return -ENODEV;
1255 }
1256
1257 pidff = kzalloc(sizeof(*pidff), GFP_KERNEL);
1258 if (!pidff)
1259 return -ENOMEM;
1260
1261 pidff->hid = hid;
1262
1263 pidff_find_reports(hid, HID_OUTPUT_REPORT, pidff);
1264 pidff_find_reports(hid, HID_FEATURE_REPORT, pidff);
1265
1266 if (!pidff_reports_ok(pidff)) {
1267 debug("reports not ok, aborting");
1268 error = -ENODEV;
1269 goto fail;
1270 }
1271
1272 error = pidff_init_fields(pidff, dev);
1273 if (error)
1274 goto fail;
1275
1276 pidff_reset(pidff);
1277
1278 if (test_bit(FF_GAIN, dev->ffbit)) {
1279 pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff);
1280 usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN],
1281 USB_DIR_OUT);
1282 }
1283
1284 error = pidff_check_autocenter(pidff, dev);
1285 if (error)
1286 goto fail;
1287
1288 max_effects =
1289 pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum -
1290 pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum +
1291 1;
1292 debug("max effects is %d", max_effects);
1293
1294 if (max_effects > PID_EFFECTS_MAX)
1295 max_effects = PID_EFFECTS_MAX;
1296
1297 if (pidff->pool[PID_SIMULTANEOUS_MAX].value)
1298 debug("max simultaneous effects is %d",
1299 pidff->pool[PID_SIMULTANEOUS_MAX].value[0]);
1300
1301 if (pidff->pool[PID_RAM_POOL_SIZE].value)
1302 debug("device memory size is %d bytes",
1303 pidff->pool[PID_RAM_POOL_SIZE].value[0]);
1304
1305 if (pidff->pool[PID_DEVICE_MANAGED_POOL].value &&
1306 pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) {
1307 printk(KERN_NOTICE "hid-pidff: "
1308 "device does not support device managed pool\n");
1309 goto fail;
1310 }
1311
1312 error = input_ff_create(dev, max_effects);
1313 if (error)
1314 goto fail;
1315
1316 ff = dev->ff;
1317 ff->private = pidff;
1318 ff->upload = pidff_upload_effect;
1319 ff->erase = pidff_erase_effect;
1320 ff->set_gain = pidff_set_gain;
1321 ff->set_autocenter = pidff_set_autocenter;
1322 ff->playback = pidff_playback;
1323
1324 printk(KERN_INFO "Force feedback for USB HID PID devices by "
1325 "Anssi Hannula <anssi.hannula@gmail.com>\n");
1326
1327 return 0;
1328
1329 fail:
1330 kfree(pidff);
1331 return error;
1332}
diff --git a/usr/src/dkms_source_tree/hid-plff.c b/usr/src/dkms_source_tree/hid-plff.c
new file mode 100644
index 0000000..9eb83cf
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-plff.c
@@ -0,0 +1,139 @@
1/*
2 * Force feedback support for PantherLord/GreenAsia based devices
3 *
4 * The devices are distributed under various names and the same USB device ID
5 * can be used in both adapters and actual game controllers.
6 *
7 * 0810:0001 "Twin USB Joystick"
8 * - tested with PantherLord USB/PS2 2in1 Adapter
9 * - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
10 *
11 * 0e8f:0003 "GreenAsia Inc. USB Joystick "
12 * - tested with Köng Gaming gamepad
13 *
14 * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
15 */
16
17/*
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33
34/* #define DEBUG */
35
36#define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg)
37
38#include <linux/input.h>
39#include <linux/usb.h>
40#include <linux/hid.h>
41#include "usbhid.h"
42
43struct plff_device {
44 struct hid_report *report;
45};
46
47static int hid_plff_play(struct input_dev *dev, void *data,
48 struct ff_effect *effect)
49{
50 struct hid_device *hid = input_get_drvdata(dev);
51 struct plff_device *plff = data;
52 int left, right;
53
54 left = effect->u.rumble.strong_magnitude;
55 right = effect->u.rumble.weak_magnitude;
56 debug("called with 0x%04x 0x%04x", left, right);
57
58 left = left * 0x7f / 0xffff;
59 right = right * 0x7f / 0xffff;
60
61 plff->report->field[0]->value[2] = left;
62 plff->report->field[0]->value[3] = right;
63 debug("running with 0x%02x 0x%02x", left, right);
64 usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
65
66 return 0;
67}
68
69int hid_plff_init(struct hid_device *hid)
70{
71 struct plff_device *plff;
72 struct hid_report *report;
73 struct hid_input *hidinput;
74 struct list_head *report_list =
75 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
76 struct list_head *report_ptr = report_list;
77 struct input_dev *dev;
78 int error;
79
80 /* The device contains one output report per physical device, all
81 containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
82 absolute values.
83
84 The input reports also contain a field which contains
85 8 ff00.0001 usages and 8 boolean values. Their meaning is
86 currently unknown. */
87
88 if (list_empty(report_list)) {
89 printk(KERN_ERR "hid-plff: no output reports found\n");
90 return -ENODEV;
91 }
92
93 list_for_each_entry(hidinput, &hid->inputs, list) {
94
95 report_ptr = report_ptr->next;
96
97 if (report_ptr == report_list) {
98 printk(KERN_ERR "hid-plff: required output report is missing\n");
99 return -ENODEV;
100 }
101
102 report = list_entry(report_ptr, struct hid_report, list);
103 if (report->maxfield < 1) {
104 printk(KERN_ERR "hid-plff: no fields in the report\n");
105 return -ENODEV;
106 }
107
108 if (report->field[0]->report_count < 4) {
109 printk(KERN_ERR "hid-plff: not enough values in the field\n");
110 return -ENODEV;
111 }
112
113 plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL);
114 if (!plff)
115 return -ENOMEM;
116
117 dev = hidinput->input;
118
119 set_bit(FF_RUMBLE, dev->ffbit);
120
121 error = input_ff_create_memless(dev, plff, hid_plff_play);
122 if (error) {
123 kfree(plff);
124 return error;
125 }
126
127 plff->report = report;
128 plff->report->field[0]->value[0] = 0x00;
129 plff->report->field[0]->value[1] = 0x00;
130 plff->report->field[0]->value[2] = 0x00;
131 plff->report->field[0]->value[3] = 0x00;
132 usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
133 }
134
135 printk(KERN_INFO "hid-plff: Force feedback for PantherLord/GreenAsia "
136 "devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
137
138 return 0;
139}
diff --git a/usr/src/dkms_source_tree/hid-quirks.c b/usr/src/dkms_source_tree/hid-quirks.c
new file mode 100644
index 0000000..870247d
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-quirks.c
@@ -0,0 +1,1224 @@
1/*
2 * USB HID quirks support for Linux
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 */
10
11/*
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 */
17
18#include <linux/hid.h>
19
20#define USB_VENDOR_ID_A4TECH 0x09da
21#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
22#define USB_DEVICE_ID_A4TECH_X5_005D 0x000a
23
24#define USB_VENDOR_ID_AASHIMA 0x06d6
25#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
26#define USB_DEVICE_ID_AASHIMA_PREDATOR 0x0026
27
28#define USB_VENDOR_ID_ACECAD 0x0460
29#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
30#define USB_DEVICE_ID_ACECAD_302 0x0008
31
32#define USB_VENDOR_ID_ADS_TECH 0x06e1
33#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
34
35#define USB_VENDOR_ID_AFATECH 0x15a4
36#define USB_DEVICE_ID_AFATECH_AF9016 0x9016
37
38#define USB_VENDOR_ID_AIPTEK 0x08ca
39#define USB_DEVICE_ID_AIPTEK_01 0x0001
40#define USB_DEVICE_ID_AIPTEK_10 0x0010
41#define USB_DEVICE_ID_AIPTEK_20 0x0020
42#define USB_DEVICE_ID_AIPTEK_21 0x0021
43#define USB_DEVICE_ID_AIPTEK_22 0x0022
44#define USB_DEVICE_ID_AIPTEK_23 0x0023
45#define USB_DEVICE_ID_AIPTEK_24 0x0024
46
47#define USB_VENDOR_ID_AIRCABLE 0x16CA
48#define USB_DEVICE_ID_AIRCABLE1 0x1502
49
50#define USB_VENDOR_ID_ALCOR 0x058f
51#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
52
53#define USB_VENDOR_ID_ALPS 0x0433
54#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
55
56#define USB_VENDOR_ID_APPLE 0x05ac
57#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
58#define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
59#define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
60#define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
61#define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
62#define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
63#define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
64#define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
65#define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
66#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
67#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
68#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
69#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
70#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
71#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
72#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
73#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
74#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
75#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
76#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
77#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
78#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
79#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
80#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
81#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
82#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
83#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
84#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
85#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
86#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
87#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
88#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
89#define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
90
91#define USB_VENDOR_ID_ASUS 0x0b05
92#define USB_DEVICE_ID_ASUS_LCM 0x1726
93
94#define USB_VENDOR_ID_ATEN 0x0557
95#define USB_DEVICE_ID_ATEN_UC100KM 0x2004
96#define USB_DEVICE_ID_ATEN_CS124U 0x2202
97#define USB_DEVICE_ID_ATEN_2PORTKVM 0x2204
98#define USB_DEVICE_ID_ATEN_4PORTKVM 0x2205
99#define USB_DEVICE_ID_ATEN_4PORTKVMC 0x2208
100
101#define USB_VENDOR_ID_BELKIN 0x050d
102#define USB_DEVICE_ID_FLIP_KVM 0x3201
103
104#define USB_VENDOR_ID_BERKSHIRE 0x0c98
105#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
106
107#define USB_VENDOR_ID_CHERRY 0x046a
108#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
109
110#define USB_VENDOR_ID_CHIC 0x05fe
111#define USB_DEVICE_ID_CHIC_GAMEPAD 0x0014
112
113#define USB_VENDOR_ID_CIDC 0x1677
114
115#define USB_VENDOR_ID_CMEDIA 0x0d8c
116#define USB_DEVICE_ID_CM109 0x000e
117
118#define USB_VENDOR_ID_CODEMERCS 0x07c0
119#define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500
120#define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff
121
122#define USB_VENDOR_ID_CYGNAL 0x10c4
123#define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a
124
125#define USB_VENDOR_ID_CYPRESS 0x04b4
126#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
127#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
128#define USB_DEVICE_ID_CYPRESS_ULTRAMOUSE 0x7417
129#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
130#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
131
132#define USB_VENDOR_ID_DELL 0x413c
133#define USB_DEVICE_ID_DELL_W7658 0x2005
134
135#define USB_VENDOR_ID_DELORME 0x1163
136#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
137#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
138
139#define USB_VENDOR_ID_DMI 0x0c0b
140#define USB_DEVICE_ID_DMI_ENC 0x5fab
141
142#define USB_VENDOR_ID_ELO 0x04E7
143#define USB_DEVICE_ID_ELO_TS2700 0x0020
144
145#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
146#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
147
148#define USB_VENDOR_ID_EZKEY 0x0518
149#define USB_DEVICE_ID_BTC_8193 0x0002
150
151#define USB_VENDOR_ID_GAMERON 0x0810
152#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
153
154#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
155
156#define USB_VENDOR_ID_GLAB 0x06c2
157#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
158#define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039
159#define USB_DEVICE_ID_0_0_4_IF_KIT 0x0040
160#define USB_DEVICE_ID_0_16_16_IF_KIT 0x0044
161#define USB_DEVICE_ID_8_8_8_IF_KIT 0x0045
162#define USB_DEVICE_ID_0_8_7_IF_KIT 0x0051
163#define USB_DEVICE_ID_0_8_8_IF_KIT 0x0053
164#define USB_DEVICE_ID_PHIDGET_MOTORCONTROL 0x0058
165
166#define USB_VENDOR_ID_GOTOP 0x08f2
167#define USB_DEVICE_ID_SUPER_Q2 0x007f
168#define USB_DEVICE_ID_GOGOPEN 0x00ce
169#define USB_DEVICE_ID_PENPOWER 0x00f4
170
171#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
172#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
173
174#define USB_VENDOR_ID_GRIFFIN 0x077d
175#define USB_DEVICE_ID_POWERMATE 0x0410
176#define USB_DEVICE_ID_SOUNDKNOB 0x04AA
177
178#define USB_VENDOR_ID_GTCO 0x078c
179#define USB_DEVICE_ID_GTCO_90 0x0090
180#define USB_DEVICE_ID_GTCO_100 0x0100
181#define USB_DEVICE_ID_GTCO_101 0x0101
182#define USB_DEVICE_ID_GTCO_103 0x0103
183#define USB_DEVICE_ID_GTCO_104 0x0104
184#define USB_DEVICE_ID_GTCO_105 0x0105
185#define USB_DEVICE_ID_GTCO_106 0x0106
186#define USB_DEVICE_ID_GTCO_107 0x0107
187#define USB_DEVICE_ID_GTCO_108 0x0108
188#define USB_DEVICE_ID_GTCO_200 0x0200
189#define USB_DEVICE_ID_GTCO_201 0x0201
190#define USB_DEVICE_ID_GTCO_202 0x0202
191#define USB_DEVICE_ID_GTCO_203 0x0203
192#define USB_DEVICE_ID_GTCO_204 0x0204
193#define USB_DEVICE_ID_GTCO_205 0x0205
194#define USB_DEVICE_ID_GTCO_206 0x0206
195#define USB_DEVICE_ID_GTCO_207 0x0207
196#define USB_DEVICE_ID_GTCO_300 0x0300
197#define USB_DEVICE_ID_GTCO_301 0x0301
198#define USB_DEVICE_ID_GTCO_302 0x0302
199#define USB_DEVICE_ID_GTCO_303 0x0303
200#define USB_DEVICE_ID_GTCO_304 0x0304
201#define USB_DEVICE_ID_GTCO_305 0x0305
202#define USB_DEVICE_ID_GTCO_306 0x0306
203#define USB_DEVICE_ID_GTCO_307 0x0307
204#define USB_DEVICE_ID_GTCO_308 0x0308
205#define USB_DEVICE_ID_GTCO_309 0x0309
206#define USB_DEVICE_ID_GTCO_400 0x0400
207#define USB_DEVICE_ID_GTCO_401 0x0401
208#define USB_DEVICE_ID_GTCO_402 0x0402
209#define USB_DEVICE_ID_GTCO_403 0x0403
210#define USB_DEVICE_ID_GTCO_404 0x0404
211#define USB_DEVICE_ID_GTCO_405 0x0405
212#define USB_DEVICE_ID_GTCO_500 0x0500
213#define USB_DEVICE_ID_GTCO_501 0x0501
214#define USB_DEVICE_ID_GTCO_502 0x0502
215#define USB_DEVICE_ID_GTCO_503 0x0503
216#define USB_DEVICE_ID_GTCO_504 0x0504
217#define USB_DEVICE_ID_GTCO_1000 0x1000
218#define USB_DEVICE_ID_GTCO_1001 0x1001
219#define USB_DEVICE_ID_GTCO_1002 0x1002
220#define USB_DEVICE_ID_GTCO_1003 0x1003
221#define USB_DEVICE_ID_GTCO_1004 0x1004
222#define USB_DEVICE_ID_GTCO_1005 0x1005
223#define USB_DEVICE_ID_GTCO_1006 0x1006
224#define USB_DEVICE_ID_GTCO_1007 0x1007
225#define USB_VENDOR_ID_HAPP 0x078b
226#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
227#define USB_DEVICE_ID_UGCI_FLYING 0x0020
228#define USB_DEVICE_ID_UGCI_FIGHTING 0x0030
229
230#define USB_VENDOR_ID_IMATION 0x0718
231#define USB_DEVICE_ID_DISC_STAKKA 0xd000
232
233#define USB_VENDOR_ID_KBGEAR 0x084e
234#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
235
236#define USB_VENDOR_ID_LD 0x0f11
237#define USB_DEVICE_ID_LD_CASSY 0x1000
238#define USB_DEVICE_ID_LD_POCKETCASSY 0x1010
239#define USB_DEVICE_ID_LD_MOBILECASSY 0x1020
240#define USB_DEVICE_ID_LD_JWM 0x1080
241#define USB_DEVICE_ID_LD_DMMP 0x1081
242#define USB_DEVICE_ID_LD_UMIP 0x1090
243#define USB_DEVICE_ID_LD_XRAY1 0x1100
244#define USB_DEVICE_ID_LD_XRAY2 0x1101
245#define USB_DEVICE_ID_LD_VIDEOCOM 0x1200
246#define USB_DEVICE_ID_LD_COM3LAB 0x2000
247#define USB_DEVICE_ID_LD_TELEPORT 0x2010
248#define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020
249#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
250#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
251
252#define USB_VENDOR_ID_LOGITECH 0x046d
253#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
254#define USB_DEVICE_ID_LOGITECH_HARMONY 0xc110
255#define USB_DEVICE_ID_LOGITECH_HARMONY_2 0xc111
256#define USB_DEVICE_ID_LOGITECH_HARMONY_3 0xc112
257#define USB_DEVICE_ID_LOGITECH_HARMONY_4 0xc113
258#define USB_DEVICE_ID_LOGITECH_HARMONY_5 0xc114
259#define USB_DEVICE_ID_LOGITECH_HARMONY_6 0xc115
260#define USB_DEVICE_ID_LOGITECH_HARMONY_7 0xc116
261#define USB_DEVICE_ID_LOGITECH_HARMONY_8 0xc117
262#define USB_DEVICE_ID_LOGITECH_HARMONY_9 0xc118
263#define USB_DEVICE_ID_LOGITECH_HARMONY_10 0xc119
264#define USB_DEVICE_ID_LOGITECH_HARMONY_11 0xc11a
265#define USB_DEVICE_ID_LOGITECH_HARMONY_12 0xc11b
266#define USB_DEVICE_ID_LOGITECH_HARMONY_13 0xc11c
267#define USB_DEVICE_ID_LOGITECH_HARMONY_14 0xc11d
268#define USB_DEVICE_ID_LOGITECH_HARMONY_15 0xc11e
269#define USB_DEVICE_ID_LOGITECH_HARMONY_16 0xc11f
270#define USB_DEVICE_ID_LOGITECH_HARMONY_17 0xc120
271#define USB_DEVICE_ID_LOGITECH_HARMONY_18 0xc121
272#define USB_DEVICE_ID_LOGITECH_HARMONY_19 0xc122
273#define USB_DEVICE_ID_LOGITECH_HARMONY_20 0xc123
274#define USB_DEVICE_ID_LOGITECH_HARMONY_21 0xc124
275#define USB_DEVICE_ID_LOGITECH_HARMONY_22 0xc125
276#define USB_DEVICE_ID_LOGITECH_HARMONY_23 0xc126
277#define USB_DEVICE_ID_LOGITECH_HARMONY_24 0xc127
278#define USB_DEVICE_ID_LOGITECH_HARMONY_25 0xc128
279#define USB_DEVICE_ID_LOGITECH_HARMONY_26 0xc129
280#define USB_DEVICE_ID_LOGITECH_HARMONY_27 0xc12a
281#define USB_DEVICE_ID_LOGITECH_HARMONY_28 0xc12b
282#define USB_DEVICE_ID_LOGITECH_HARMONY_29 0xc12c
283#define USB_DEVICE_ID_LOGITECH_HARMONY_30 0xc12d
284#define USB_DEVICE_ID_LOGITECH_HARMONY_31 0xc12e
285#define USB_DEVICE_ID_LOGITECH_HARMONY_32 0xc12f
286#define USB_DEVICE_ID_LOGITECH_HARMONY_33 0xc130
287#define USB_DEVICE_ID_LOGITECH_HARMONY_34 0xc131
288#define USB_DEVICE_ID_LOGITECH_HARMONY_35 0xc132
289#define USB_DEVICE_ID_LOGITECH_HARMONY_36 0xc133
290#define USB_DEVICE_ID_LOGITECH_HARMONY_37 0xc134
291#define USB_DEVICE_ID_LOGITECH_HARMONY_38 0xc135
292#define USB_DEVICE_ID_LOGITECH_HARMONY_39 0xc136
293#define USB_DEVICE_ID_LOGITECH_HARMONY_40 0xc137
294#define USB_DEVICE_ID_LOGITECH_HARMONY_41 0xc138
295#define USB_DEVICE_ID_LOGITECH_HARMONY_42 0xc139
296#define USB_DEVICE_ID_LOGITECH_HARMONY_43 0xc13a
297#define USB_DEVICE_ID_LOGITECH_HARMONY_44 0xc13b
298#define USB_DEVICE_ID_LOGITECH_HARMONY_45 0xc13c
299#define USB_DEVICE_ID_LOGITECH_HARMONY_46 0xc13d
300#define USB_DEVICE_ID_LOGITECH_HARMONY_47 0xc13e
301#define USB_DEVICE_ID_LOGITECH_HARMONY_48 0xc13f
302#define USB_DEVICE_ID_LOGITECH_HARMONY_49 0xc140
303#define USB_DEVICE_ID_LOGITECH_HARMONY_50 0xc141
304#define USB_DEVICE_ID_LOGITECH_HARMONY_51 0xc142
305#define USB_DEVICE_ID_LOGITECH_HARMONY_52 0xc143
306#define USB_DEVICE_ID_LOGITECH_HARMONY_53 0xc144
307#define USB_DEVICE_ID_LOGITECH_HARMONY_54 0xc145
308#define USB_DEVICE_ID_LOGITECH_HARMONY_55 0xc146
309#define USB_DEVICE_ID_LOGITECH_HARMONY_56 0xc147
310#define USB_DEVICE_ID_LOGITECH_HARMONY_57 0xc148
311#define USB_DEVICE_ID_LOGITECH_HARMONY_58 0xc149
312#define USB_DEVICE_ID_LOGITECH_HARMONY_59 0xc14a
313#define USB_DEVICE_ID_LOGITECH_HARMONY_60 0xc14b
314#define USB_DEVICE_ID_LOGITECH_HARMONY_61 0xc14c
315#define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d
316#define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e
317#define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f
318#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
319#define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294
320#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
321#define USB_DEVICE_ID_LOGITECH_KBD 0xc311
322#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
323#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
324#define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
325#define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
326#define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704
327#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
328#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
329
330#define USB_VENDOR_ID_MCC 0x09db
331#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
332#define USB_DEVICE_ID_MCC_PMD1208LS 0x007a
333
334#define USB_VENDOR_ID_MGE 0x0463
335#define USB_DEVICE_ID_MGE_UPS 0xffff
336#define USB_DEVICE_ID_MGE_UPS1 0x0001
337
338#define USB_VENDOR_ID_MICROCHIP 0x04d8
339#define USB_DEVICE_ID_PICKIT1 0x0032
340#define USB_DEVICE_ID_PICKIT2 0x0033
341
342#define USB_VENDOR_ID_MICROSOFT 0x045e
343#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
344#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
345#define USB_DEVICE_ID_DESKTOP_RECV_1028 0x00f9
346#define USB_DEVICE_ID_MS_NE4K 0x00db
347#define USB_DEVICE_ID_MS_LK6K 0x00f9
348
349#define USB_VENDOR_ID_MONTEREY 0x0566
350#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
351
352#define USB_VENDOR_ID_NCR 0x0404
353#define USB_DEVICE_ID_NCR_FIRST 0x0300
354#define USB_DEVICE_ID_NCR_LAST 0x03ff
355
356#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
357#define USB_DEVICE_ID_N_S_HARMONY 0xc359
358
359#define USB_VENDOR_ID_NATSU 0x08b7
360#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
361
362#define USB_VENDOR_ID_NEC 0x073e
363#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
364
365#define USB_VENDOR_ID_ONTRAK 0x0a07
366#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
367
368#define USB_VENDOR_ID_PANJIT 0x134c
369
370#define USB_VENDOR_ID_PANTHERLORD 0x0810
371#define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001
372
373#define USB_VENDOR_ID_PETALYNX 0x18b1
374#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
375
376#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
377#define USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII 0x0003
378
379#define USB_VENDOR_ID_SAITEK 0x06a3
380#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
381
382#define USB_VENDOR_ID_SAMSUNG 0x0419
383#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
384
385#define USB_VENDOR_ID_SONY 0x054c
386#define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
387
388#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
389#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
390
391#define USB_VENDOR_ID_SUN 0x0430
392#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
393
394#define USB_VENDOR_ID_SUNPLUS 0x04fc
395#define USB_DEVICE_ID_SUNPLUS_WDESKTOP 0x05d8
396
397#define USB_VENDOR_ID_TOPMAX 0x0663
398#define USB_DEVICE_ID_TOPMAX_COBRAPAD 0x0103
399
400#define USB_VENDOR_ID_TURBOX 0x062a
401#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
402
403#define USB_VENDOR_ID_VERNIER 0x08f7
404#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
405#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002
406#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
407#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
408#define USB_DEVICE_ID_VERNIER_LCSPEC 0x0006
409
410#define USB_VENDOR_ID_WACOM 0x056a
411
412#define USB_VENDOR_ID_WISEGROUP 0x0925
413#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
414#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
415#define USB_DEVICE_ID_8_8_4_IF_KIT 0x8201
416#define USB_DEVICE_ID_QUAD_USB_JOYPAD 0x8800
417#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
418
419#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677
420#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
421
422#define USB_VENDOR_ID_YEALINK 0x6993
423#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
424
425#define USB_VENDOR_ID_KYE 0x0458
426#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
427
428/*
429 * Alphabetically sorted blacklist by quirk type.
430 */
431
432static const struct hid_blacklist {
433 __u16 idVendor;
434 __u16 idProduct;
435 __u32 quirks;
436} hid_blacklist[] = {
437
438 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
439 { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 },
440 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
441
442 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
443
444 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
445 { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
446 { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
447 { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
448 { USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR, HID_QUIRK_MULTI_INPUT },
449 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
450 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
451 { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
452 { USB_VENDOR_ID_NATSU, USB_DEVICE_ID_NATSU_GAMEPAD, HID_QUIRK_BADPAD },
453 { USB_VENDOR_ID_NEC, USB_DEVICE_ID_NEC_USB_GAME_PAD, HID_QUIRK_BADPAD },
454 { USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RUMBLEPAD, HID_QUIRK_BADPAD },
455 { USB_VENDOR_ID_TOPMAX, USB_DEVICE_ID_TOPMAX_COBRAPAD, HID_QUIRK_BADPAD },
456
457 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP, HID_QUIRK_DUPLICATE_USAGES },
458 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE, HID_QUIRK_DUPLICATE_USAGES },
459 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI, HID_QUIRK_DUPLICATE_USAGES },
460
461 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
462
463 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
464 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
465 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
466 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
467
468 { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT },
469
470 { USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X, HID_QUIRK_IGNORE },
471 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE },
472 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE },
473 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE },
474 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_21, HID_QUIRK_IGNORE },
475 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_22, HID_QUIRK_IGNORE },
476 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_23, HID_QUIRK_IGNORE },
477 { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24, HID_QUIRK_IGNORE },
478 { USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1, HID_QUIRK_IGNORE },
479 { USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232, HID_QUIRK_IGNORE },
480 { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE},
481 { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE },
482 { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
483 { USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X, HID_QUIRK_IGNORE },
484 { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE },
485 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE },
486 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE },
487 { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE },
488 { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE },
489 { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE },
490 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0001, HID_QUIRK_IGNORE },
491 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0002, HID_QUIRK_IGNORE },
492 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0003, HID_QUIRK_IGNORE },
493 { USB_VENDOR_ID_GENERAL_TOUCH, 0x0004, HID_QUIRK_IGNORE },
494 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
495 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE },
496 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_0_4_IF_KIT, HID_QUIRK_IGNORE },
497 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_16_16_IF_KIT, HID_QUIRK_IGNORE },
498 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_8_8_8_IF_KIT, HID_QUIRK_IGNORE },
499 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_7_IF_KIT, HID_QUIRK_IGNORE },
500 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_0_8_8_IF_KIT, HID_QUIRK_IGNORE },
501 { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_PHIDGET_MOTORCONTROL, HID_QUIRK_IGNORE },
502 { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE },
503 { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE },
504 { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE },
505 { USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY, HID_QUIRK_IGNORE },
506 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE },
507 { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE },
508 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE },
509 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_100, HID_QUIRK_IGNORE },
510 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_101, HID_QUIRK_IGNORE },
511 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_103, HID_QUIRK_IGNORE },
512 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_104, HID_QUIRK_IGNORE },
513 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_105, HID_QUIRK_IGNORE },
514 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_106, HID_QUIRK_IGNORE },
515 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_107, HID_QUIRK_IGNORE },
516 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_108, HID_QUIRK_IGNORE },
517 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_200, HID_QUIRK_IGNORE },
518 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_201, HID_QUIRK_IGNORE },
519 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_202, HID_QUIRK_IGNORE },
520 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_203, HID_QUIRK_IGNORE },
521 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_204, HID_QUIRK_IGNORE },
522 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_205, HID_QUIRK_IGNORE },
523 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_206, HID_QUIRK_IGNORE },
524 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_207, HID_QUIRK_IGNORE },
525 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_300, HID_QUIRK_IGNORE },
526 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_301, HID_QUIRK_IGNORE },
527 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_302, HID_QUIRK_IGNORE },
528 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_303, HID_QUIRK_IGNORE },
529 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_304, HID_QUIRK_IGNORE },
530 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_305, HID_QUIRK_IGNORE },
531 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_306, HID_QUIRK_IGNORE },
532 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_307, HID_QUIRK_IGNORE },
533 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_308, HID_QUIRK_IGNORE },
534 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_309, HID_QUIRK_IGNORE },
535 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_400, HID_QUIRK_IGNORE },
536 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_401, HID_QUIRK_IGNORE },
537 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_402, HID_QUIRK_IGNORE },
538 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_403, HID_QUIRK_IGNORE },
539 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_404, HID_QUIRK_IGNORE },
540 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_405, HID_QUIRK_IGNORE },
541 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_500, HID_QUIRK_IGNORE },
542 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_501, HID_QUIRK_IGNORE },
543 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_502, HID_QUIRK_IGNORE },
544 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_503, HID_QUIRK_IGNORE },
545 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_504, HID_QUIRK_IGNORE },
546 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1000, HID_QUIRK_IGNORE },
547 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1001, HID_QUIRK_IGNORE },
548 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1002, HID_QUIRK_IGNORE },
549 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1003, HID_QUIRK_IGNORE },
550 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
551 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
552 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
553 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007, HID_QUIRK_IGNORE },
554 { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE },
555 { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
556 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
557 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE },
558 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY, HID_QUIRK_IGNORE },
559 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM, HID_QUIRK_IGNORE },
560 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP, HID_QUIRK_IGNORE },
561 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP, HID_QUIRK_IGNORE },
562 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1, HID_QUIRK_IGNORE },
563 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2, HID_QUIRK_IGNORE },
564 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM, HID_QUIRK_IGNORE },
565 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB, HID_QUIRK_IGNORE },
566 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT, HID_QUIRK_IGNORE },
567 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER, HID_QUIRK_IGNORE },
568 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL, HID_QUIRK_IGNORE },
569 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST, HID_QUIRK_IGNORE },
570 { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE },
571 { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE },
572 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE },
573 { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS1, HID_QUIRK_IGNORE },
574 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100, HID_QUIRK_IGNORE },
575 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20, HID_QUIRK_IGNORE },
576 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 30, HID_QUIRK_IGNORE },
577 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 100, HID_QUIRK_IGNORE },
578 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 108, HID_QUIRK_IGNORE },
579 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 118, HID_QUIRK_IGNORE },
580 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 200, HID_QUIRK_IGNORE },
581 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE },
582 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE },
583 { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE },
584 { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
585 { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
586 { USB_VENDOR_ID_PANJIT, 0x0003, HID_QUIRK_IGNORE },
587 { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
588 { USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD, HID_QUIRK_IGNORE },
589 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE },
590 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE },
591 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE },
592 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE },
593 { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LCSPEC, HID_QUIRK_IGNORE },
594 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
595 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE },
596 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT, HID_QUIRK_IGNORE },
597 { USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K, HID_QUIRK_IGNORE },
598
599 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE },
600 { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE },
601
602 { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1, HID_QUIRK_IGNORE },
603 { USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2, HID_QUIRK_IGNORE },
604
605 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
606 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP },
607
608 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
609 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
610
611 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
612
613 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
614 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
615
616 { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV },
617
618 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
619 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
620 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
621 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
622 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
623 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
624 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
625 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET },
626 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET },
627 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET },
628 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
629 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
630 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
631 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
632 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
633
634 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
635
636 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
637 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
638 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
639 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
640 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
641 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
642 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
643 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
644 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
645 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
646 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
647 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN },
648 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
649 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN },
650 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
651 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
652 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
653 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
654 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
655 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
656 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
657 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE},
658 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
659 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
660 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
661 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
662 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
663 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
664 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
665 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
666 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
667
668 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
669 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS },
670 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY, HID_QUIRK_IGNORE },
671 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_2, HID_QUIRK_IGNORE },
672 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_3, HID_QUIRK_IGNORE },
673 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_4, HID_QUIRK_IGNORE },
674 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_5, HID_QUIRK_IGNORE },
675 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_6, HID_QUIRK_IGNORE },
676 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_7, HID_QUIRK_IGNORE },
677 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_8, HID_QUIRK_IGNORE },
678 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_9, HID_QUIRK_IGNORE },
679 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_10, HID_QUIRK_IGNORE },
680 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_11, HID_QUIRK_IGNORE },
681 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_12, HID_QUIRK_IGNORE },
682 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_13, HID_QUIRK_IGNORE },
683 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_14, HID_QUIRK_IGNORE },
684 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_15, HID_QUIRK_IGNORE },
685 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_16, HID_QUIRK_IGNORE },
686 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_17, HID_QUIRK_IGNORE },
687 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_18, HID_QUIRK_IGNORE },
688 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_19, HID_QUIRK_IGNORE },
689 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_20, HID_QUIRK_IGNORE },
690 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_21, HID_QUIRK_IGNORE },
691 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_22, HID_QUIRK_IGNORE },
692 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_23, HID_QUIRK_IGNORE },
693 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_24, HID_QUIRK_IGNORE },
694 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_25, HID_QUIRK_IGNORE },
695 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_26, HID_QUIRK_IGNORE },
696 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_27, HID_QUIRK_IGNORE },
697 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_28, HID_QUIRK_IGNORE },
698 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_29, HID_QUIRK_IGNORE },
699 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_30, HID_QUIRK_IGNORE },
700 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_31, HID_QUIRK_IGNORE },
701 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_32, HID_QUIRK_IGNORE },
702 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_33, HID_QUIRK_IGNORE },
703 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_34, HID_QUIRK_IGNORE },
704 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_35, HID_QUIRK_IGNORE },
705 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_36, HID_QUIRK_IGNORE },
706 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_37, HID_QUIRK_IGNORE },
707 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_38, HID_QUIRK_IGNORE },
708 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_39, HID_QUIRK_IGNORE },
709 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_40, HID_QUIRK_IGNORE },
710 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_41, HID_QUIRK_IGNORE },
711 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_42, HID_QUIRK_IGNORE },
712 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_43, HID_QUIRK_IGNORE },
713 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_44, HID_QUIRK_IGNORE },
714 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_45, HID_QUIRK_IGNORE },
715 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_46, HID_QUIRK_IGNORE },
716 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_47, HID_QUIRK_IGNORE },
717 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_48, HID_QUIRK_IGNORE },
718 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_49, HID_QUIRK_IGNORE },
719 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_50, HID_QUIRK_IGNORE },
720 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_51, HID_QUIRK_IGNORE },
721 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_52, HID_QUIRK_IGNORE },
722 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_53, HID_QUIRK_IGNORE },
723 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_54, HID_QUIRK_IGNORE },
724 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_55, HID_QUIRK_IGNORE },
725 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_56, HID_QUIRK_IGNORE },
726 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_57, HID_QUIRK_IGNORE },
727 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_58, HID_QUIRK_IGNORE },
728 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_59, HID_QUIRK_IGNORE },
729 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_60, HID_QUIRK_IGNORE },
730 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_61, HID_QUIRK_IGNORE },
731 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_62, HID_QUIRK_IGNORE },
732 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_63, HID_QUIRK_IGNORE },
733 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_64, HID_QUIRK_IGNORE },
734 { USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY, HID_QUIRK_IGNORE },
735 { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560, HID_QUIRK_IGNORE },
736
737 { 0, 0 }
738};
739
740/* Quirks for devices which require report descriptor fixup go here */
741static const struct hid_rdesc_blacklist {
742 __u16 idVendor;
743 __u16 idProduct;
744 __u32 quirks;
745} hid_rdesc_blacklist[] = {
746
747 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION },
748
749 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
750 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH },
751 { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH },
752 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_DESKTOP_RECV_1028, HID_QUIRK_RDESC_MICROSOFT_RECV_1028 },
753
754 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER },
755
756 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS },
757
758 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
759
760 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE },
761
762 { USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP, HID_QUIRK_RDESC_SUNPLUS_WDESKTOP },
763
764 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
765 { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX },
766
767 { 0, 0 }
768};
769
770/* Dynamic HID quirks list - specified at runtime */
771struct quirks_list_struct {
772 struct hid_blacklist hid_bl_item;
773 struct list_head node;
774};
775
776static LIST_HEAD(dquirks_list);
777static DECLARE_RWSEM(dquirks_rwsem);
778
779/* Runtime ("dynamic") quirks manipulation functions */
780
781/**
782 * usbhid_exists_dquirk: find any dynamic quirks for a USB HID device
783 * @idVendor: the 16-bit USB vendor ID, in native byteorder
784 * @idProduct: the 16-bit USB product ID, in native byteorder
785 *
786 * Description:
787 * Scans dquirks_list for a matching dynamic quirk and returns
788 * the pointer to the relevant struct hid_blacklist if found.
789 * Must be called with a read lock held on dquirks_rwsem.
790 *
791 * Returns: NULL if no quirk found, struct hid_blacklist * if found.
792 */
793static struct hid_blacklist *usbhid_exists_dquirk(const u16 idVendor,
794 const u16 idProduct)
795{
796 struct quirks_list_struct *q;
797 struct hid_blacklist *bl_entry = NULL;
798
799 list_for_each_entry(q, &dquirks_list, node) {
800 if (q->hid_bl_item.idVendor == idVendor &&
801 q->hid_bl_item.idProduct == idProduct) {
802 bl_entry = &q->hid_bl_item;
803 break;
804 }
805 }
806
807 if (bl_entry != NULL)
808 dbg_hid("Found dynamic quirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
809 bl_entry->quirks, bl_entry->idVendor,
810 bl_entry->idProduct);
811
812 return bl_entry;
813}
814
815
816/**
817 * usbhid_modify_dquirk: add/replace a HID quirk
818 * @idVendor: the 16-bit USB vendor ID, in native byteorder
819 * @idProduct: the 16-bit USB product ID, in native byteorder
820 * @quirks: the u32 quirks value to add/replace
821 *
822 * Description:
823 * If an dynamic quirk exists in memory for this (idVendor,
824 * idProduct) pair, replace its quirks value with what was
825 * provided. Otherwise, add the quirk to the dynamic quirks list.
826 *
827 * Returns: 0 OK, -error on failure.
828 */
829static int usbhid_modify_dquirk(const u16 idVendor, const u16 idProduct,
830 const u32 quirks)
831{
832 struct quirks_list_struct *q_new, *q;
833 int list_edited = 0;
834
835 if (!idVendor) {
836 dbg_hid("Cannot add a quirk with idVendor = 0\n");
837 return -EINVAL;
838 }
839
840 q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL);
841 if (!q_new) {
842 dbg_hid("Could not allocate quirks_list_struct\n");
843 return -ENOMEM;
844 }
845
846 q_new->hid_bl_item.idVendor = idVendor;
847 q_new->hid_bl_item.idProduct = idProduct;
848 q_new->hid_bl_item.quirks = quirks;
849
850 down_write(&dquirks_rwsem);
851
852 list_for_each_entry(q, &dquirks_list, node) {
853
854 if (q->hid_bl_item.idVendor == idVendor &&
855 q->hid_bl_item.idProduct == idProduct) {
856
857 list_replace(&q->node, &q_new->node);
858 kfree(q);
859 list_edited = 1;
860 break;
861
862 }
863
864 }
865
866 if (!list_edited)
867 list_add_tail(&q_new->node, &dquirks_list);
868
869 up_write(&dquirks_rwsem);
870
871 return 0;
872}
873
874/**
875 * usbhid_remove_all_dquirks: remove all runtime HID quirks from memory
876 *
877 * Description:
878 * Free all memory associated with dynamic quirks - called before
879 * module unload.
880 *
881 */
882static void usbhid_remove_all_dquirks(void)
883{
884 struct quirks_list_struct *q, *temp;
885
886 down_write(&dquirks_rwsem);
887 list_for_each_entry_safe(q, temp, &dquirks_list, node) {
888 list_del(&q->node);
889 kfree(q);
890 }
891 up_write(&dquirks_rwsem);
892
893}
894
895/**
896 * usbhid_quirks_init: apply USB HID quirks specified at module load time
897 */
898int usbhid_quirks_init(char **quirks_param)
899{
900 u16 idVendor, idProduct;
901 u32 quirks;
902 int n = 0, m;
903
904 for (; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
905
906 m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
907 &idVendor, &idProduct, &quirks);
908
909 if (m != 3 ||
910 usbhid_modify_dquirk(idVendor, idProduct, quirks) != 0) {
911 printk(KERN_WARNING
912 "Could not parse HID quirk module param %s\n",
913 quirks_param[n]);
914 }
915 }
916
917 return 0;
918}
919
920/**
921 * usbhid_quirks_exit: release memory associated with dynamic_quirks
922 *
923 * Description:
924 * Release all memory associated with dynamic quirks. Called upon
925 * module unload.
926 *
927 * Returns: nothing
928 */
929void usbhid_quirks_exit(void)
930{
931 usbhid_remove_all_dquirks();
932}
933
934/**
935 * usbhid_exists_squirk: return any static quirks for a USB HID device
936 * @idVendor: the 16-bit USB vendor ID, in native byteorder
937 * @idProduct: the 16-bit USB product ID, in native byteorder
938 *
939 * Description:
940 * Given a USB vendor ID and product ID, return a pointer to
941 * the hid_blacklist entry associated with that device.
942 *
943 * Returns: pointer if quirk found, or NULL if no quirks found.
944 */
945static const struct hid_blacklist *usbhid_exists_squirk(const u16 idVendor,
946 const u16 idProduct)
947{
948 const struct hid_blacklist *bl_entry = NULL;
949 int n = 0;
950
951 for (; hid_blacklist[n].idVendor; n++)
952 if (hid_blacklist[n].idVendor == idVendor &&
953 hid_blacklist[n].idProduct == idProduct)
954 bl_entry = &hid_blacklist[n];
955
956 if (bl_entry != NULL)
957 dbg_hid("Found squirk 0x%x for USB HID vendor 0x%hx prod 0x%hx\n",
958 bl_entry->quirks, bl_entry->idVendor,
959 bl_entry->idProduct);
960 return bl_entry;
961}
962
963/**
964 * usbhid_lookup_quirk: return any quirks associated with a USB HID device
965 * @idVendor: the 16-bit USB vendor ID, in native byteorder
966 * @idProduct: the 16-bit USB product ID, in native byteorder
967 *
968 * Description:
969 * Given a USB vendor ID and product ID, return any quirks associated
970 * with that device.
971 *
972 * Returns: a u32 quirks value.
973 */
974u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct)
975{
976 u32 quirks = 0;
977 const struct hid_blacklist *bl_entry = NULL;
978
979 /* Ignore all Wacom devices */
980 if (idVendor == USB_VENDOR_ID_WACOM)
981 return HID_QUIRK_IGNORE;
982
983 /* ignore all Code Mercenaries IOWarrior devices */
984 if (idVendor == USB_VENDOR_ID_CODEMERCS)
985 if (idProduct >= USB_DEVICE_ID_CODEMERCS_IOW_FIRST &&
986 idProduct <= USB_DEVICE_ID_CODEMERCS_IOW_LAST)
987 return HID_QUIRK_IGNORE;
988
989 /* NCR devices must not be queried for reports */
990 if (idVendor == USB_VENDOR_ID_NCR &&
991 idProduct >= USB_DEVICE_ID_NCR_FIRST &&
992 idProduct <= USB_DEVICE_ID_NCR_LAST)
993 return HID_QUIRK_NOGET;
994
995 down_read(&dquirks_rwsem);
996 bl_entry = usbhid_exists_dquirk(idVendor, idProduct);
997 if (!bl_entry)
998 bl_entry = usbhid_exists_squirk(idVendor, idProduct);
999 if (bl_entry)
1000 quirks = bl_entry->quirks;
1001 up_read(&dquirks_rwsem);
1002
1003 return quirks;
1004}
1005
1006EXPORT_SYMBOL_GPL(usbhid_lookup_quirk);
1007
1008/*
1009 * Cherry Cymotion keyboard have an invalid HID report descriptor,
1010 * that needs fixing before we can parse it.
1011 */
1012static void usbhid_fixup_cymotion_descriptor(char *rdesc, int rsize)
1013{
1014 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
1015 printk(KERN_INFO "Fixing up Cherry Cymotion report descriptor\n");
1016 rdesc[11] = rdesc[16] = 0xff;
1017 rdesc[12] = rdesc[17] = 0x03;
1018 }
1019}
1020
1021
1022/*
1023 * Certain Logitech keyboards send in report #3 keys which are far
1024 * above the logical maximum described in descriptor. This extends
1025 * the original value of 0x28c of logical maximum to 0x104d
1026 */
1027static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize)
1028{
1029 if (rsize >= 90 && rdesc[83] == 0x26
1030 && rdesc[84] == 0x8c
1031 && rdesc[85] == 0x02) {
1032 printk(KERN_INFO "Fixing up Logitech keyboard report descriptor\n");
1033 rdesc[84] = rdesc[89] = 0x4d;
1034 rdesc[85] = rdesc[90] = 0x10;
1035 }
1036}
1037
1038static void usbhid_fixup_sunplus_wdesktop(unsigned char *rdesc, int rsize)
1039{
1040 if (rsize >= 107 && rdesc[104] == 0x26
1041 && rdesc[105] == 0x80
1042 && rdesc[106] == 0x03) {
1043 printk(KERN_INFO "Fixing up Sunplus Wireless Desktop report descriptor\n");
1044 rdesc[105] = rdesc[110] = 0x03;
1045 rdesc[106] = rdesc[111] = 0x21;
1046 }
1047}
1048
1049/*
1050 * Samsung IrDA remote controller (reports as Cypress USB Mouse).
1051 *
1052 * Vendor specific report #4 has a size of 48 bit,
1053 * and therefore is not accepted when inspecting the descriptors.
1054 * As a workaround we reinterpret the report as:
1055 * Variable type, count 6, size 8 bit, log. maximum 255
1056 * The burden to reconstruct the data is moved into user space.
1057 */
1058static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc,
1059 int rsize)
1060{
1061 if (rsize >= 182 && rdesc[175] == 0x25
1062 && rdesc[176] == 0x40
1063 && rdesc[177] == 0x75
1064 && rdesc[178] == 0x30
1065 && rdesc[179] == 0x95
1066 && rdesc[180] == 0x01
1067 && rdesc[182] == 0x40) {
1068 printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n");
1069 rdesc[176] = 0xff;
1070 rdesc[178] = 0x08;
1071 rdesc[180] = 0x06;
1072 rdesc[182] = 0x42;
1073 }
1074}
1075
1076/* Petalynx Maxter Remote has maximum for consumer page set too low */
1077static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize)
1078{
1079 if (rsize >= 60 && rdesc[39] == 0x2a
1080 && rdesc[40] == 0xf5
1081 && rdesc[41] == 0x00
1082 && rdesc[59] == 0x26
1083 && rdesc[60] == 0xf9
1084 && rdesc[61] == 0x00) {
1085 printk(KERN_INFO "Fixing up Petalynx Maxter Remote report descriptor\n");
1086 rdesc[60] = 0xfa;
1087 rdesc[40] = 0xfa;
1088 }
1089}
1090
1091/*
1092 * Some USB barcode readers from cypress have usage min and usage max in
1093 * the wrong order
1094 */
1095static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
1096{
1097 short fixed = 0;
1098 int i;
1099
1100 for (i = 0; i < rsize - 4; i++) {
1101 if (rdesc[i] == 0x29 && rdesc [i+2] == 0x19) {
1102 unsigned char tmp;
1103
1104 rdesc[i] = 0x19; rdesc[i+2] = 0x29;
1105 tmp = rdesc[i+3];
1106 rdesc[i+3] = rdesc[i+1];
1107 rdesc[i+1] = tmp;
1108 }
1109 }
1110
1111 if (fixed)
1112 printk(KERN_INFO "Fixing up Cypress report descriptor\n");
1113}
1114
1115/*
1116 * MacBook JIS keyboard has wrong logical maximum
1117 */
1118static void usbhid_fixup_macbook_descriptor(unsigned char *rdesc, int rsize)
1119{
1120 if (rsize >= 60 && rdesc[53] == 0x65
1121 && rdesc[59] == 0x65) {
1122 printk(KERN_INFO "Fixing up MacBook JIS keyboard report descriptor\n");
1123 rdesc[53] = rdesc[59] = 0xe7;
1124 }
1125}
1126
1127static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize)
1128{
1129 if (rsize >= 30 && rdesc[29] == 0x05
1130 && rdesc[30] == 0x09) {
1131 printk(KERN_INFO "Fixing up button/consumer in HID report descriptor\n");
1132 rdesc[30] = 0x0c;
1133 }
1134}
1135
1136/*
1137 * Microsoft Wireless Desktop Receiver (Model 1028) has several
1138 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
1139 */
1140static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize)
1141{
1142 if (rsize == 571 && rdesc[284] == 0x19
1143 && rdesc[286] == 0x2a
1144 && rdesc[304] == 0x19
1145 && rdesc[306] == 0x29
1146 && rdesc[352] == 0x1a
1147 && rdesc[355] == 0x2a
1148 && rdesc[557] == 0x19
1149 && rdesc[559] == 0x29) {
1150 printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
1151 rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
1152 rdesc[352] = 0x36;
1153 rdesc[286] = rdesc[355] = 0x46;
1154 rdesc[306] = rdesc[559] = 0x45;
1155 }
1156}
1157
1158static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
1159{
1160 if ((quirks & HID_QUIRK_RDESC_CYMOTION))
1161 usbhid_fixup_cymotion_descriptor(rdesc, rsize);
1162
1163 if (quirks & HID_QUIRK_RDESC_LOGITECH)
1164 usbhid_fixup_logitech_descriptor(rdesc, rsize);
1165
1166 if (quirks & HID_QUIRK_RDESC_SWAPPED_MIN_MAX)
1167 usbhid_fixup_cypress_descriptor(rdesc, rsize);
1168
1169 if (quirks & HID_QUIRK_RDESC_PETALYNX)
1170 usbhid_fixup_petalynx_descriptor(rdesc, rsize);
1171
1172 if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS)
1173 usbhid_fixup_macbook_descriptor(rdesc, rsize);
1174
1175 if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER)
1176 usbhid_fixup_button_consumer_descriptor(rdesc, rsize);
1177
1178 if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE)
1179 usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);
1180
1181 if (quirks & HID_QUIRK_RDESC_MICROSOFT_RECV_1028)
1182 usbhid_fixup_microsoft_descriptor(rdesc, rsize);
1183
1184 if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP)
1185 usbhid_fixup_sunplus_wdesktop(rdesc, rsize);
1186}
1187
1188/**
1189 * usbhid_fixup_report_descriptor: check if report descriptor needs fixup
1190 *
1191 * Description:
1192 * Walks the hid_rdesc_blacklist[] array and checks whether the device
1193 * is known to have broken report descriptor that needs to be fixed up
1194 * prior to entering the HID parser
1195 *
1196 * Returns: nothing
1197 */
1198void usbhid_fixup_report_descriptor(const u16 idVendor, const u16 idProduct,
1199 char *rdesc, unsigned rsize, char **quirks_param)
1200{
1201 int n, m;
1202 u16 paramVendor, paramProduct;
1203 u32 quirks;
1204
1205 /* static rdesc quirk entries */
1206 for (n = 0; hid_rdesc_blacklist[n].idVendor; n++)
1207 if (hid_rdesc_blacklist[n].idVendor == idVendor &&
1208 hid_rdesc_blacklist[n].idProduct == idProduct)
1209 __usbhid_fixup_report_descriptor(hid_rdesc_blacklist[n].quirks,
1210 rdesc, rsize);
1211
1212 /* runtime rdesc quirk entries handling */
1213 for (n = 0; quirks_param[n] && n < MAX_USBHID_BOOT_QUIRKS; n++) {
1214 m = sscanf(quirks_param[n], "0x%hx:0x%hx:0x%x",
1215 &paramVendor, &paramProduct, &quirks);
1216
1217 if (m != 3)
1218 printk(KERN_WARNING
1219 "Could not parse HID quirk module param %s\n",
1220 quirks_param[n]);
1221 else if (paramVendor == idVendor && paramProduct == idProduct)
1222 __usbhid_fixup_report_descriptor(quirks, rdesc, rsize);
1223 }
1224}
diff --git a/usr/src/dkms_source_tree/hid-tmff.c b/usr/src/dkms_source_tree/hid-tmff.c
new file mode 100644
index 0000000..144578b
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-tmff.c
@@ -0,0 +1,225 @@
1/*
2 * Force feedback support for various HID compliant devices by ThrustMaster:
3 * ThrustMaster FireStorm Dual Power 2
4 * and possibly others whose device ids haven't been added.
5 *
6 * Modified to support ThrustMaster devices by Zinx Verituse
7 * on 2003-01-25 from the Logitech force feedback driver,
8 * which is by Johann Deneux.
9 *
10 * Copyright (c) 2003 Zinx Verituse <zinx@epicsol.org>
11 * Copyright (c) 2002 Johann Deneux
12 */
13
14/*
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/input.h>
31
32#undef DEBUG
33#include <linux/usb.h>
34
35#include <linux/hid.h>
36#include "usbhid.h"
37
38/* Usages for thrustmaster devices I know about */
39#define THRUSTMASTER_USAGE_FF (HID_UP_GENDESK | 0xbb)
40
41struct dev_type {
42 u16 idVendor;
43 u16 idProduct;
44 const signed short *ff;
45};
46
47static const signed short ff_rumble[] = {
48 FF_RUMBLE,
49 -1
50};
51
52static const signed short ff_joystick[] = {
53 FF_CONSTANT,
54 -1
55};
56
57static const struct dev_type devices[] = {
58 { 0x44f, 0xb300, ff_rumble },
59 { 0x44f, 0xb304, ff_rumble },
60 { 0x44f, 0xb651, ff_rumble }, /* FGT Rumble Force Wheel */
61 { 0x44f, 0xb654, ff_joystick }, /* FGT Force Feedback Wheel */
62};
63
64struct tmff_device {
65 struct hid_report *report;
66 struct hid_field *ff_field;
67};
68
69/* Changes values from 0 to 0xffff into values from minimum to maximum */
70static inline int hid_tmff_scale_u16(unsigned int in,
71 int minimum, int maximum)
72{
73 int ret;
74
75 ret = (in * (maximum - minimum) / 0xffff) + minimum;
76 if (ret < minimum)
77 return minimum;
78 if (ret > maximum)
79 return maximum;
80 return ret;
81}
82
83/* Changes values from -0x80 to 0x7f into values from minimum to maximum */
84static inline int hid_tmff_scale_s8(int in,
85 int minimum, int maximum)
86{
87 int ret;
88
89 ret = (((in + 0x80) * (maximum - minimum)) / 0xff) + minimum;
90 if (ret < minimum)
91 return minimum;
92 if (ret > maximum)
93 return maximum;
94 return ret;
95}
96
97static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *effect)
98{
99 struct hid_device *hid = input_get_drvdata(dev);
100 struct tmff_device *tmff = data;
101 struct hid_field *ff_field = tmff->ff_field;
102 int x, y;
103 int left, right; /* Rumbling */
104
105 switch (effect->type) {
106 case FF_CONSTANT:
107 x = hid_tmff_scale_s8(effect->u.ramp.start_level,
108 ff_field->logical_minimum,
109 ff_field->logical_maximum);
110 y = hid_tmff_scale_s8(effect->u.ramp.end_level,
111 ff_field->logical_minimum,
112 ff_field->logical_maximum);
113
114 dbg_hid("(x, y)=(%04x, %04x)\n", x, y);
115 ff_field->value[0] = x;
116 ff_field->value[1] = y;
117 usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
118 break;
119
120 case FF_RUMBLE:
121 left = hid_tmff_scale_u16(effect->u.rumble.weak_magnitude,
122 ff_field->logical_minimum,
123 ff_field->logical_maximum);
124 right = hid_tmff_scale_u16(effect->u.rumble.strong_magnitude,
125 ff_field->logical_minimum,
126 ff_field->logical_maximum);
127
128 dbg_hid("(left,right)=(%08x, %08x)\n", left, right);
129 ff_field->value[0] = left;
130 ff_field->value[1] = right;
131 usbhid_submit_report(hid, tmff->report, USB_DIR_OUT);
132 break;
133 }
134 return 0;
135}
136
137int hid_tmff_init(struct hid_device *hid)
138{
139 struct tmff_device *tmff;
140 struct hid_report *report;
141 struct list_head *report_list;
142 struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
143 struct input_dev *input_dev = hidinput->input;
144 const signed short *ff_bits = ff_joystick;
145 int error;
146 int i;
147
148 tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL);
149 if (!tmff)
150 return -ENOMEM;
151
152 /* Find the report to use */
153 report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
154 list_for_each_entry(report, report_list, list) {
155 int fieldnum;
156
157 for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) {
158 struct hid_field *field = report->field[fieldnum];
159
160 if (field->maxusage <= 0)
161 continue;
162
163 switch (field->usage[0].hid) {
164 case THRUSTMASTER_USAGE_FF:
165 if (field->report_count < 2) {
166 warn("ignoring FF field with report_count < 2");
167 continue;
168 }
169
170 if (field->logical_maximum == field->logical_minimum) {
171 warn("ignoring FF field with logical_maximum == logical_minimum");
172 continue;
173 }
174
175 if (tmff->report && tmff->report != report) {
176 warn("ignoring FF field in other report");
177 continue;
178 }
179
180 if (tmff->ff_field && tmff->ff_field != field) {
181 warn("ignoring duplicate FF field");
182 continue;
183 }
184
185 tmff->report = report;
186 tmff->ff_field = field;
187
188 for (i = 0; i < ARRAY_SIZE(devices); i++) {
189 if (input_dev->id.vendor == devices[i].idVendor &&
190 input_dev->id.product == devices[i].idProduct) {
191 ff_bits = devices[i].ff;
192 break;
193 }
194 }
195
196 for (i = 0; ff_bits[i] >= 0; i++)
197 set_bit(ff_bits[i], input_dev->ffbit);
198
199 break;
200
201 default:
202 warn("ignoring unknown output usage %08x", field->usage[0].hid);
203 continue;
204 }
205 }
206 }
207
208 if (!tmff->report) {
209 err("cant find FF field in output reports\n");
210 error = -ENODEV;
211 goto fail;
212 }
213
214 error = input_ff_create_memless(input_dev, tmff, hid_tmff_play);
215 if (error)
216 goto fail;
217
218 info("Force feedback for ThrustMaster devices by Zinx Verituse <zinx@epicsol.org>");
219 return 0;
220
221 fail:
222 kfree(tmff);
223 return error;
224}
225
diff --git a/usr/src/dkms_source_tree/hid-zpff.c b/usr/src/dkms_source_tree/hid-zpff.c
new file mode 100644
index 0000000..5a68827
--- /dev/null
+++ b/usr/src/dkms_source_tree/hid-zpff.c
@@ -0,0 +1,107 @@
1/*
2 * Force feedback support for Zeroplus based devices
3 *
4 * Copyright (c) 2005, 2006 Anssi Hannula <anssi.hannula@gmail.com>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23
24#include <linux/input.h>
25#include <linux/usb.h>
26#include <linux/hid.h>
27#include "usbhid.h"
28
29struct zpff_device {
30 struct hid_report *report;
31};
32
33static int hid_zpff_play(struct input_dev *dev, void *data,
34 struct ff_effect *effect)
35{
36 struct hid_device *hid = input_get_drvdata(dev);
37 struct zpff_device *zpff = data;
38 int left, right;
39
40 /*
41 * The following is specified the other way around in the Zeroplus
42 * datasheet but the order below is correct for the XFX Executioner;
43 * however it is possible that the XFX Executioner is an exception
44 */
45
46 left = effect->u.rumble.strong_magnitude;
47 right = effect->u.rumble.weak_magnitude;
48 dbg_hid("called with 0x%04x 0x%04x\n", left, right);
49
50 left = left * 0x7f / 0xffff;
51 right = right * 0x7f / 0xffff;
52
53 zpff->report->field[2]->value[0] = left;
54 zpff->report->field[3]->value[0] = right;
55 dbg_hid("running with 0x%02x 0x%02x\n", left, right);
56 usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
57
58 return 0;
59}
60
61int hid_zpff_init(struct hid_device *hid)
62{
63 struct zpff_device *zpff;
64 struct hid_report *report;
65 struct hid_input *hidinput = list_entry(hid->inputs.next,
66 struct hid_input, list);
67 struct list_head *report_list =
68 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
69 struct input_dev *dev = hidinput->input;
70 int error;
71
72 if (list_empty(report_list)) {
73 printk(KERN_ERR "hid-zpff: no output report found\n");
74 return -ENODEV;
75 }
76
77 report = list_entry(report_list->next, struct hid_report, list);
78
79 if (report->maxfield < 4) {
80 printk(KERN_ERR "hid-zpff: not enough fields in report\n");
81 return -ENODEV;
82 }
83
84 zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
85 if (!zpff)
86 return -ENOMEM;
87
88 set_bit(FF_RUMBLE, dev->ffbit);
89
90 error = input_ff_create_memless(dev, zpff, hid_zpff_play);
91 if (error) {
92 kfree(zpff);
93 return error;
94 }
95
96 zpff->report = report;
97 zpff->report->field[0]->value[0] = 0x00;
98 zpff->report->field[1]->value[0] = 0x02;
99 zpff->report->field[2]->value[0] = 0x00;
100 zpff->report->field[3]->value[0] = 0x00;
101 usbhid_submit_report(hid, zpff->report, USB_DIR_OUT);
102
103 printk(KERN_INFO "Force feedback for Zeroplus based devices by "
104 "Anssi Hannula <anssi.hannula@gmail.com>\n");
105
106 return 0;
107}
diff --git a/usr/src/dkms_source_tree/hiddev.c b/usr/src/dkms_source_tree/hiddev.c
new file mode 100644
index 0000000..842e9ed
--- /dev/null
+++ b/usr/src/dkms_source_tree/hiddev.c
@@ -0,0 +1,893 @@
1/*
2 * Copyright (c) 2001 Paul Stewart
3 * Copyright (c) 2001 Vojtech Pavlik
4 *
5 * HID char devices, giving access to raw HID device events.
6 *
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Should you need to contact me, the author, you can do so either by
25 * e-mail - mail your message to Paul Stewart <stewart@wetlogic.net>
26 */
27
28#include <linux/poll.h>
29#include <linux/slab.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/smp_lock.h>
33#include <linux/input.h>
34#include <linux/usb.h>
35#include <linux/hid.h>
36#include <linux/hiddev.h>
37#include <linux/compat.h>
38#include "usbhid.h"
39
40#ifdef CONFIG_USB_DYNAMIC_MINORS
41#define HIDDEV_MINOR_BASE 0
42#define HIDDEV_MINORS 256
43#else
44#define HIDDEV_MINOR_BASE 96
45#define HIDDEV_MINORS 16
46#endif
47#define HIDDEV_BUFFER_SIZE 64
48
49struct hiddev {
50 int exist;
51 int open;
52 wait_queue_head_t wait;
53 struct hid_device *hid;
54 struct list_head list;
55 spinlock_t list_lock;
56};
57
58struct hiddev_list {
59 struct hiddev_usage_ref buffer[HIDDEV_BUFFER_SIZE];
60 int head;
61 int tail;
62 unsigned flags;
63 struct fasync_struct *fasync;
64 struct hiddev *hiddev;
65 struct list_head node;
66};
67
68static struct hiddev *hiddev_table[HIDDEV_MINORS];
69
70/*
71 * Find a report, given the report's type and ID. The ID can be specified
72 * indirectly by REPORT_ID_FIRST (which returns the first report of the given
73 * type) or by (REPORT_ID_NEXT | old_id), which returns the next report of the
74 * given type which follows old_id.
75 */
76static struct hid_report *
77hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo)
78{
79 unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK;
80 unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK;
81 struct hid_report_enum *report_enum;
82 struct hid_report *report;
83 struct list_head *list;
84
85 if (rinfo->report_type < HID_REPORT_TYPE_MIN ||
86 rinfo->report_type > HID_REPORT_TYPE_MAX)
87 return NULL;
88
89 report_enum = hid->report_enum +
90 (rinfo->report_type - HID_REPORT_TYPE_MIN);
91
92 switch (flags) {
93 case 0: /* Nothing to do -- report_id is already set correctly */
94 break;
95
96 case HID_REPORT_ID_FIRST:
97 if (list_empty(&report_enum->report_list))
98 return NULL;
99
100 list = report_enum->report_list.next;
101 report = list_entry(list, struct hid_report, list);
102 rinfo->report_id = report->id;
103 break;
104
105 case HID_REPORT_ID_NEXT:
106 report = report_enum->report_id_hash[rid];
107 if (!report)
108 return NULL;
109
110 list = report->list.next;
111 if (list == &report_enum->report_list)
112 return NULL;
113
114 report = list_entry(list, struct hid_report, list);
115 rinfo->report_id = report->id;
116 break;
117
118 default:
119 return NULL;
120 }
121
122 return report_enum->report_id_hash[rinfo->report_id];
123}
124
125/*
126 * Perform an exhaustive search of the report table for a usage, given its
127 * type and usage id.
128 */
129static struct hid_field *
130hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref)
131{
132 int i, j;
133 struct hid_report *report;
134 struct hid_report_enum *report_enum;
135 struct hid_field *field;
136
137 if (uref->report_type < HID_REPORT_TYPE_MIN ||
138 uref->report_type > HID_REPORT_TYPE_MAX)
139 return NULL;
140
141 report_enum = hid->report_enum +
142 (uref->report_type - HID_REPORT_TYPE_MIN);
143
144 list_for_each_entry(report, &report_enum->report_list, list) {
145 for (i = 0; i < report->maxfield; i++) {
146 field = report->field[i];
147 for (j = 0; j < field->maxusage; j++) {
148 if (field->usage[j].hid == uref->usage_code) {
149 uref->report_id = report->id;
150 uref->field_index = i;
151 uref->usage_index = j;
152 return field;
153 }
154 }
155 }
156 }
157
158 return NULL;
159}
160
161static void hiddev_send_event(struct hid_device *hid,
162 struct hiddev_usage_ref *uref)
163{
164 struct hiddev *hiddev = hid->hiddev;
165 struct hiddev_list *list;
166 unsigned long flags;
167
168 spin_lock_irqsave(&hiddev->list_lock, flags);
169 list_for_each_entry(list, &hiddev->list, node) {
170 if (uref->field_index != HID_FIELD_INDEX_NONE ||
171 (list->flags & HIDDEV_FLAG_REPORT) != 0) {
172 list->buffer[list->head] = *uref;
173 list->head = (list->head + 1) &
174 (HIDDEV_BUFFER_SIZE - 1);
175 kill_fasync(&list->fasync, SIGIO, POLL_IN);
176 }
177 }
178 spin_unlock_irqrestore(&hiddev->list_lock, flags);
179
180 wake_up_interruptible(&hiddev->wait);
181}
182
183/*
184 * This is where hid.c calls into hiddev to pass an event that occurred over
185 * the interrupt pipe
186 */
187void hiddev_hid_event(struct hid_device *hid, struct hid_field *field,
188 struct hid_usage *usage, __s32 value)
189{
190 unsigned type = field->report_type;
191 struct hiddev_usage_ref uref;
192
193 uref.report_type =
194 (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
195 ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
196 ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
197 uref.report_id = field->report->id;
198 uref.field_index = field->index;
199 uref.usage_index = (usage - field->usage);
200 uref.usage_code = usage->hid;
201 uref.value = value;
202
203 hiddev_send_event(hid, &uref);
204}
205EXPORT_SYMBOL_GPL(hiddev_hid_event);
206
207void hiddev_report_event(struct hid_device *hid, struct hid_report *report)
208{
209 unsigned type = report->type;
210 struct hiddev_usage_ref uref;
211
212 memset(&uref, 0, sizeof(uref));
213 uref.report_type =
214 (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT :
215 ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT :
216 ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0));
217 uref.report_id = report->id;
218 uref.field_index = HID_FIELD_INDEX_NONE;
219
220 hiddev_send_event(hid, &uref);
221}
222
223/*
224 * fasync file op
225 */
226static int hiddev_fasync(int fd, struct file *file, int on)
227{
228 int retval;
229 struct hiddev_list *list = file->private_data;
230
231 retval = fasync_helper(fd, file, on, &list->fasync);
232
233 return retval < 0 ? retval : 0;
234}
235
236
237/*
238 * release file op
239 */
240static int hiddev_release(struct inode * inode, struct file * file)
241{
242 struct hiddev_list *list = file->private_data;
243 unsigned long flags;
244
245 hiddev_fasync(-1, file, 0);
246
247 spin_lock_irqsave(&list->hiddev->list_lock, flags);
248 list_del(&list->node);
249 spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
250
251 if (!--list->hiddev->open) {
252 if (list->hiddev->exist)
253 usbhid_close(list->hiddev->hid);
254 else
255 kfree(list->hiddev);
256 }
257
258 kfree(list);
259
260 return 0;
261}
262
263/*
264 * open file op
265 */
266static int hiddev_open(struct inode *inode, struct file *file)
267{
268 struct hiddev_list *list;
269 unsigned long flags;
270
271 int i = iminor(inode) - HIDDEV_MINOR_BASE;
272
273 if (i >= HIDDEV_MINORS || !hiddev_table[i])
274 return -ENODEV;
275
276 if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
277 return -ENOMEM;
278
279 list->hiddev = hiddev_table[i];
280
281 spin_lock_irqsave(&list->hiddev->list_lock, flags);
282 list_add_tail(&list->node, &hiddev_table[i]->list);
283 spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
284
285 file->private_data = list;
286
287 if (!list->hiddev->open++)
288 if (list->hiddev->exist)
289 usbhid_open(hiddev_table[i]->hid);
290
291 return 0;
292}
293
294/*
295 * "write" file op
296 */
297static ssize_t hiddev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
298{
299 return -EINVAL;
300}
301
302/*
303 * "read" file op
304 */
305static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
306{
307 DECLARE_WAITQUEUE(wait, current);
308 struct hiddev_list *list = file->private_data;
309 int event_size;
310 int retval = 0;
311
312 event_size = ((list->flags & HIDDEV_FLAG_UREF) != 0) ?
313 sizeof(struct hiddev_usage_ref) : sizeof(struct hiddev_event);
314
315 if (count < event_size)
316 return 0;
317
318 while (retval == 0) {
319 if (list->head == list->tail) {
320 add_wait_queue(&list->hiddev->wait, &wait);
321 set_current_state(TASK_INTERRUPTIBLE);
322
323 while (list->head == list->tail) {
324 if (file->f_flags & O_NONBLOCK) {
325 retval = -EAGAIN;
326 break;
327 }
328 if (signal_pending(current)) {
329 retval = -ERESTARTSYS;
330 break;
331 }
332 if (!list->hiddev->exist) {
333 retval = -EIO;
334 break;
335 }
336
337 schedule();
338 set_current_state(TASK_INTERRUPTIBLE);
339 }
340
341 set_current_state(TASK_RUNNING);
342 remove_wait_queue(&list->hiddev->wait, &wait);
343 }
344
345 if (retval)
346 return retval;
347
348
349 while (list->head != list->tail &&
350 retval + event_size <= count) {
351 if ((list->flags & HIDDEV_FLAG_UREF) == 0) {
352 if (list->buffer[list->tail].field_index !=
353 HID_FIELD_INDEX_NONE) {
354 struct hiddev_event event;
355 event.hid = list->buffer[list->tail].usage_code;
356 event.value = list->buffer[list->tail].value;
357 if (copy_to_user(buffer + retval, &event, sizeof(struct hiddev_event)))
358 return -EFAULT;
359 retval += sizeof(struct hiddev_event);
360 }
361 } else {
362 if (list->buffer[list->tail].field_index != HID_FIELD_INDEX_NONE ||
363 (list->flags & HIDDEV_FLAG_REPORT) != 0) {
364 if (copy_to_user(buffer + retval, list->buffer + list->tail, sizeof(struct hiddev_usage_ref)))
365 return -EFAULT;
366 retval += sizeof(struct hiddev_usage_ref);
367 }
368 }
369 list->tail = (list->tail + 1) & (HIDDEV_BUFFER_SIZE - 1);
370 }
371
372 }
373
374 return retval;
375}
376
377/*
378 * "poll" file op
379 * No kernel lock - fine
380 */
381static unsigned int hiddev_poll(struct file *file, poll_table *wait)
382{
383 struct hiddev_list *list = file->private_data;
384
385 poll_wait(file, &list->hiddev->wait, wait);
386 if (list->head != list->tail)
387 return POLLIN | POLLRDNORM;
388 if (!list->hiddev->exist)
389 return POLLERR | POLLHUP;
390 return 0;
391}
392
393/*
394 * "ioctl" file op
395 */
396static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
397{
398 struct hid_device *hid = hiddev->hid;
399 struct hiddev_report_info rinfo;
400 struct hiddev_usage_ref_multi *uref_multi = NULL;
401 struct hiddev_usage_ref *uref;
402 struct hid_report *report;
403 struct hid_field *field;
404 int i;
405
406 uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
407 if (!uref_multi)
408 return -ENOMEM;
409 lock_kernel();
410 uref = &uref_multi->uref;
411 if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
412 if (copy_from_user(uref_multi, user_arg,
413 sizeof(*uref_multi)))
414 goto fault;
415 } else {
416 if (copy_from_user(uref, user_arg, sizeof(*uref)))
417 goto fault;
418 }
419
420 switch (cmd) {
421 case HIDIOCGUCODE:
422 rinfo.report_type = uref->report_type;
423 rinfo.report_id = uref->report_id;
424 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
425 goto inval;
426
427 if (uref->field_index >= report->maxfield)
428 goto inval;
429
430 field = report->field[uref->field_index];
431 if (uref->usage_index >= field->maxusage)
432 goto inval;
433
434 uref->usage_code = field->usage[uref->usage_index].hid;
435
436 if (copy_to_user(user_arg, uref, sizeof(*uref)))
437 goto fault;
438
439 kfree(uref_multi);
440 return 0;
441
442 default:
443 if (cmd != HIDIOCGUSAGE &&
444 cmd != HIDIOCGUSAGES &&
445 uref->report_type == HID_REPORT_TYPE_INPUT)
446 goto inval;
447
448 if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
449 field = hiddev_lookup_usage(hid, uref);
450 if (field == NULL)
451 goto inval;
452 } else {
453 rinfo.report_type = uref->report_type;
454 rinfo.report_id = uref->report_id;
455 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
456 goto inval;
457
458 if (uref->field_index >= report->maxfield)
459 goto inval;
460
461 field = report->field[uref->field_index];
462
463 if (cmd == HIDIOCGCOLLECTIONINDEX) {
464 if (uref->usage_index >= field->maxusage)
465 goto inval;
466 } else if (uref->usage_index >= field->report_count)
467 goto inval;
468
469 else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
470 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
471 uref->usage_index + uref_multi->num_values > field->report_count))
472 goto inval;
473 }
474
475 switch (cmd) {
476 case HIDIOCGUSAGE:
477 uref->value = field->value[uref->usage_index];
478 if (copy_to_user(user_arg, uref, sizeof(*uref)))
479 goto fault;
480 goto goodreturn;
481
482 case HIDIOCSUSAGE:
483 field->value[uref->usage_index] = uref->value;
484 goto goodreturn;
485
486 case HIDIOCGCOLLECTIONINDEX:
487 kfree(uref_multi);
488 return field->usage[uref->usage_index].collection_index;
489 case HIDIOCGUSAGES:
490 for (i = 0; i < uref_multi->num_values; i++)
491 uref_multi->values[i] =
492 field->value[uref->usage_index + i];
493 if (copy_to_user(user_arg, uref_multi,
494 sizeof(*uref_multi)))
495 goto fault;
496 goto goodreturn;
497 case HIDIOCSUSAGES:
498 for (i = 0; i < uref_multi->num_values; i++)
499 field->value[uref->usage_index + i] =
500 uref_multi->values[i];
501 goto goodreturn;
502 }
503
504goodreturn:
505 unlock_kernel();
506 kfree(uref_multi);
507 return 0;
508fault:
509 unlock_kernel();
510 kfree(uref_multi);
511 return -EFAULT;
512inval:
513 unlock_kernel();
514 kfree(uref_multi);
515 return -EINVAL;
516 }
517}
518
519static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd, void __user *user_arg)
520{
521 struct hid_device *hid = hiddev->hid;
522 struct usb_device *dev = hid_to_usb_dev(hid);
523 int idx, len;
524 char *buf;
525
526 if (get_user(idx, (int __user *)user_arg))
527 return -EFAULT;
528
529 if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
530 return -ENOMEM;
531
532 if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
533 kfree(buf);
534 return -EINVAL;
535 }
536
537 if (copy_to_user(user_arg+sizeof(int), buf, len+1)) {
538 kfree(buf);
539 return -EFAULT;
540 }
541
542 kfree(buf);
543
544 return len;
545}
546
547static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
548{
549 struct hiddev_list *list = file->private_data;
550 struct hiddev *hiddev = list->hiddev;
551 struct hid_device *hid = hiddev->hid;
552 struct usb_device *dev = hid_to_usb_dev(hid);
553 struct hiddev_collection_info cinfo;
554 struct hiddev_report_info rinfo;
555 struct hiddev_field_info finfo;
556 struct hiddev_devinfo dinfo;
557 struct hid_report *report;
558 struct hid_field *field;
559 struct usbhid_device *usbhid = hid->driver_data;
560 void __user *user_arg = (void __user *)arg;
561 int i;
562
563 /* Called without BKL by compat methods so no BKL taken */
564
565 /* FIXME: Who or what stop this racing with a disconnect ?? */
566 if (!hiddev->exist)
567 return -EIO;
568
569 switch (cmd) {
570
571 case HIDIOCGVERSION:
572 return put_user(HID_VERSION, (int __user *)arg);
573
574 case HIDIOCAPPLICATION:
575 if (arg < 0 || arg >= hid->maxapplication)
576 return -EINVAL;
577
578 for (i = 0; i < hid->maxcollection; i++)
579 if (hid->collection[i].type ==
580 HID_COLLECTION_APPLICATION && arg-- == 0)
581 break;
582
583 if (i == hid->maxcollection)
584 return -EINVAL;
585
586 return hid->collection[i].usage;
587
588 case HIDIOCGDEVINFO:
589 dinfo.bustype = BUS_USB;
590 dinfo.busnum = dev->bus->busnum;
591 dinfo.devnum = dev->devnum;
592 dinfo.ifnum = usbhid->ifnum;
593 dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
594 dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
595 dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
596 dinfo.num_applications = hid->maxapplication;
597 if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
598 return -EFAULT;
599
600 return 0;
601
602 case HIDIOCGFLAG:
603 if (put_user(list->flags, (int __user *)arg))
604 return -EFAULT;
605
606 return 0;
607
608 case HIDIOCSFLAG:
609 {
610 int newflags;
611 if (get_user(newflags, (int __user *)arg))
612 return -EFAULT;
613
614 if ((newflags & ~HIDDEV_FLAGS) != 0 ||
615 ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
616 (newflags & HIDDEV_FLAG_UREF) == 0))
617 return -EINVAL;
618
619 list->flags = newflags;
620
621 return 0;
622 }
623
624 case HIDIOCGSTRING:
625 return hiddev_ioctl_string(hiddev, cmd, user_arg);
626
627 case HIDIOCINITREPORT:
628 usbhid_init_reports(hid);
629
630 return 0;
631
632 case HIDIOCGREPORT:
633 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
634 return -EFAULT;
635
636 if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
637 return -EINVAL;
638
639 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
640 return -EINVAL;
641
642 usbhid_submit_report(hid, report, USB_DIR_IN);
643 usbhid_wait_io(hid);
644
645 return 0;
646
647 case HIDIOCSREPORT:
648 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
649 return -EFAULT;
650
651 if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
652 return -EINVAL;
653
654 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
655 return -EINVAL;
656
657 usbhid_submit_report(hid, report, USB_DIR_OUT);
658 usbhid_wait_io(hid);
659
660 return 0;
661
662 case HIDIOCGREPORTINFO:
663 if (copy_from_user(&rinfo, user_arg, sizeof(rinfo)))
664 return -EFAULT;
665
666 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
667 return -EINVAL;
668
669 rinfo.num_fields = report->maxfield;
670
671 if (copy_to_user(user_arg, &rinfo, sizeof(rinfo)))
672 return -EFAULT;
673
674 return 0;
675
676 case HIDIOCGFIELDINFO:
677 if (copy_from_user(&finfo, user_arg, sizeof(finfo)))
678 return -EFAULT;
679 rinfo.report_type = finfo.report_type;
680 rinfo.report_id = finfo.report_id;
681 if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
682 return -EINVAL;
683
684 if (finfo.field_index >= report->maxfield)
685 return -EINVAL;
686
687 field = report->field[finfo.field_index];
688 memset(&finfo, 0, sizeof(finfo));
689 finfo.report_type = rinfo.report_type;
690 finfo.report_id = rinfo.report_id;
691 finfo.field_index = field->report_count - 1;
692 finfo.maxusage = field->maxusage;
693 finfo.flags = field->flags;
694 finfo.physical = field->physical;
695 finfo.logical = field->logical;
696 finfo.application = field->application;
697 finfo.logical_minimum = field->logical_minimum;
698 finfo.logical_maximum = field->logical_maximum;
699 finfo.physical_minimum = field->physical_minimum;
700 finfo.physical_maximum = field->physical_maximum;
701 finfo.unit_exponent = field->unit_exponent;
702 finfo.unit = field->unit;
703
704 if (copy_to_user(user_arg, &finfo, sizeof(finfo)))
705 return -EFAULT;
706
707 return 0;
708
709 case HIDIOCGUCODE:
710 /* fall through */
711 case HIDIOCGUSAGE:
712 case HIDIOCSUSAGE:
713 case HIDIOCGUSAGES:
714 case HIDIOCSUSAGES:
715 case HIDIOCGCOLLECTIONINDEX:
716 return hiddev_ioctl_usage(hiddev, cmd, user_arg);
717
718 case HIDIOCGCOLLECTIONINFO:
719 if (copy_from_user(&cinfo, user_arg, sizeof(cinfo)))
720 return -EFAULT;
721
722 if (cinfo.index >= hid->maxcollection)
723 return -EINVAL;
724
725 cinfo.type = hid->collection[cinfo.index].type;
726 cinfo.usage = hid->collection[cinfo.index].usage;
727 cinfo.level = hid->collection[cinfo.index].level;
728
729 if (copy_to_user(user_arg, &cinfo, sizeof(cinfo)))
730 return -EFAULT;
731 return 0;
732
733 default:
734
735 if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
736 return -EINVAL;
737
738 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
739 int len;
740 if (!hid->name)
741 return 0;
742 len = strlen(hid->name) + 1;
743 if (len > _IOC_SIZE(cmd))
744 len = _IOC_SIZE(cmd);
745 return copy_to_user(user_arg, hid->name, len) ?
746 -EFAULT : len;
747 }
748
749 if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
750 int len;
751 if (!hid->phys)
752 return 0;
753 len = strlen(hid->phys) + 1;
754 if (len > _IOC_SIZE(cmd))
755 len = _IOC_SIZE(cmd);
756 return copy_to_user(user_arg, hid->phys, len) ?
757 -EFAULT : len;
758 }
759 }
760 return -EINVAL;
761}
762
763#ifdef CONFIG_COMPAT
764static long hiddev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
765{
766 return hiddev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
767}
768#endif
769
770static const struct file_operations hiddev_fops = {
771 .owner = THIS_MODULE,
772 .read = hiddev_read,
773 .write = hiddev_write,
774 .poll = hiddev_poll,
775 .open = hiddev_open,
776 .release = hiddev_release,
777 .unlocked_ioctl = hiddev_ioctl,
778 .fasync = hiddev_fasync,
779#ifdef CONFIG_COMPAT
780 .compat_ioctl = hiddev_compat_ioctl,
781#endif
782};
783
784static struct usb_class_driver hiddev_class = {
785 .name = "hiddev%d",
786 .fops = &hiddev_fops,
787 .minor_base = HIDDEV_MINOR_BASE,
788};
789
790/*
791 * This is where hid.c calls us to connect a hid device to the hiddev driver
792 */
793int hiddev_connect(struct hid_device *hid)
794{
795 struct hiddev *hiddev;
796 struct usbhid_device *usbhid = hid->driver_data;
797 int i;
798 int retval;
799
800 for (i = 0; i < hid->maxcollection; i++)
801 if (hid->collection[i].type ==
802 HID_COLLECTION_APPLICATION &&
803 !IS_INPUT_APPLICATION(hid->collection[i].usage))
804 break;
805
806 if (i == hid->maxcollection && (hid->quirks & HID_QUIRK_HIDDEV) == 0)
807 return -1;
808
809 if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL)))
810 return -1;
811
812 retval = usb_register_dev(usbhid->intf, &hiddev_class);
813 if (retval) {
814 err_hid("Not able to get a minor for this device.");
815 kfree(hiddev);
816 return -1;
817 }
818
819 init_waitqueue_head(&hiddev->wait);
820 INIT_LIST_HEAD(&hiddev->list);
821 spin_lock_init(&hiddev->list_lock);
822 hiddev->hid = hid;
823 hiddev->exist = 1;
824
825 hid->minor = usbhid->intf->minor;
826 hid->hiddev = hiddev;
827
828 hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
829
830 return 0;
831}
832
833/*
834 * This is where hid.c calls us to disconnect a hiddev device from the
835 * corresponding hid device (usually because the usb device has disconnected)
836 */
837static struct usb_class_driver hiddev_class;
838void hiddev_disconnect(struct hid_device *hid)
839{
840 struct hiddev *hiddev = hid->hiddev;
841 struct usbhid_device *usbhid = hid->driver_data;
842
843 hiddev->exist = 0;
844
845 hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
846 usb_deregister_dev(usbhid->intf, &hiddev_class);
847
848 if (hiddev->open) {
849 usbhid_close(hiddev->hid);
850 wake_up_interruptible(&hiddev->wait);
851 } else {
852 kfree(hiddev);
853 }
854}
855
856/* Currently this driver is a USB driver. It's not a conventional one in
857 * the sense that it doesn't probe at the USB level. Instead it waits to
858 * be connected by HID through the hiddev_connect / hiddev_disconnect
859 * routines. The reason to register as a USB device is to gain part of the
860 * minor number space from the USB major.
861 *
862 * In theory, should the HID code be generalized to more than one physical
863 * medium (say, IEEE 1384), this driver will probably need to register its
864 * own major number, and in doing so, no longer need to register with USB.
865 * At that point the probe routine and hiddev_driver struct below will no
866 * longer be useful.
867 */
868
869
870/* We never attach in this manner, and rely on HID to connect us. This
871 * is why there is no disconnect routine defined in the usb_driver either.
872 */
873static int hiddev_usbd_probe(struct usb_interface *intf,
874 const struct usb_device_id *hiddev_info)
875{
876 return -ENODEV;
877}
878
879
880static /* const */ struct usb_driver hiddev_driver = {
881 .name = "hiddev",
882 .probe = hiddev_usbd_probe,
883};
884
885int __init hiddev_init(void)
886{
887 return usb_register(&hiddev_driver);
888}
889
890void hiddev_exit(void)
891{
892 usb_deregister(&hiddev_driver);
893}
diff --git a/usr/src/dkms_source_tree/patches/10-ignore-trackpad-on-unibody-macbooks.patch b/usr/src/dkms_source_tree/patches/10-ignore-trackpad-on-unibody-macbooks.patch
new file mode 100644
index 0000000..a527d1b
--- /dev/null
+++ b/usr/src/dkms_source_tree/patches/10-ignore-trackpad-on-unibody-macbooks.patch
@@ -0,0 +1,24 @@
1diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
2index b15f882..1c07576 100644
3--- a/drivers/hid/usbhid/hid-quirks.c
4+++ b/drivers/hid/usbhid/hid-quirks.c
5@@ -81,6 +81,9 @@
6 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
7 #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
8 #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
9+#define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
10+#define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
11+#define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
12 #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
13 #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
14 #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242
15@@ -660,6 +663,9 @@ static const struct hid_blacklist {
16 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
17 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
18 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
19+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
20+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
21+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
22 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
23 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
24
diff --git a/usr/src/dkms_source_tree/usbhid.h b/usr/src/dkms_source_tree/usbhid.h
new file mode 100644
index 0000000..62d2d7c
--- /dev/null
+++ b/usr/src/dkms_source_tree/usbhid.h
@@ -0,0 +1,88 @@
1#ifndef __USBHID_H
2#define __USBHID_H
3
4/*
5 * Copyright (c) 1999 Andreas Gal
6 * Copyright (c) 2000-2001 Vojtech Pavlik
7 * Copyright (c) 2006 Jiri Kosina
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#include <linux/types.h>
28#include <linux/slab.h>
29#include <linux/list.h>
30#include <linux/timer.h>
31#include <linux/wait.h>
32#include <linux/workqueue.h>
33#include <linux/input.h>
34
35/* API provided by hid-core.c for USB HID drivers */
36int usbhid_wait_io(struct hid_device* hid);
37void usbhid_close(struct hid_device *hid);
38int usbhid_open(struct hid_device *hid);
39void usbhid_init_reports(struct hid_device *hid);
40void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
41
42/*
43 * USB-specific HID struct, to be pointed to
44 * from struct hid_device->driver_data
45 */
46
47struct usbhid_device {
48 struct hid_device *hid; /* pointer to corresponding HID dev */
49
50 struct usb_interface *intf; /* USB interface */
51 int ifnum; /* USB interface number */
52
53 unsigned int bufsize; /* URB buffer size */
54
55 struct urb *urbin; /* Input URB */
56 char *inbuf; /* Input buffer */
57 dma_addr_t inbuf_dma; /* Input buffer dma */
58 spinlock_t inlock; /* Input fifo spinlock */
59
60 struct urb *urbctrl; /* Control URB */
61 struct usb_ctrlrequest *cr; /* Control request struct */
62 dma_addr_t cr_dma; /* Control request struct dma */
63 struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */
64 unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
65 char *ctrlbuf; /* Control buffer */
66 dma_addr_t ctrlbuf_dma; /* Control buffer dma */
67 spinlock_t ctrllock; /* Control fifo spinlock */
68
69 struct urb *urbout; /* Output URB */
70 struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
71 unsigned char outhead, outtail; /* Output pipe fifo head & tail */
72 char *outbuf; /* Output buffer */
73 dma_addr_t outbuf_dma; /* Output buffer dma */
74 spinlock_t outlock; /* Output fifo spinlock */
75
76 unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
77 struct timer_list io_retry; /* Retry timer */
78 unsigned long stop_retry; /* Time to give up, in jiffies */
79 unsigned int retry_delay; /* Delay length in ms */
80 struct work_struct reset_work; /* Task context for resets */
81 wait_queue_head_t wait; /* For sleeping */
82};
83
84#define hid_to_usb_dev(hid_dev) \
85 container_of(hid_dev->dev->parent, struct usb_device, dev)
86
87#endif
88
diff --git a/usr/src/dkms_source_tree/usbkbd.c b/usr/src/dkms_source_tree/usbkbd.c
new file mode 100644
index 0000000..0caaafe
--- /dev/null
+++ b/usr/src/dkms_source_tree/usbkbd.c
@@ -0,0 +1,365 @@
1/*
2 * Copyright (c) 1999-2001 Vojtech Pavlik
3 *
4 * USB HIDBP Keyboard support
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Should you need to contact me, the author, you can do so either by
23 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
24 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
25 */
26
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/usb/input.h>
32#include <linux/hid.h>
33
34/*
35 * Version Information
36 */
37#define DRIVER_VERSION ""
38#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
39#define DRIVER_DESC "USB HID Boot Protocol keyboard driver"
40#define DRIVER_LICENSE "GPL"
41
42MODULE_AUTHOR(DRIVER_AUTHOR);
43MODULE_DESCRIPTION(DRIVER_DESC);
44MODULE_LICENSE(DRIVER_LICENSE);
45
46static const unsigned char usb_kbd_keycode[256] = {
47 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
48 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
49 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
50 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
51 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
52 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
53 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
54 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
55 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
56 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
62 150,158,159,128,136,177,178,176,142,152,173,140
63};
64
65struct usb_kbd {
66 struct input_dev *dev;
67 struct usb_device *usbdev;
68 unsigned char old[8];
69 struct urb *irq, *led;
70 unsigned char newleds;
71 char name[128];
72 char phys[64];
73
74 unsigned char *new;
75 struct usb_ctrlrequest *cr;
76 unsigned char *leds;
77 dma_addr_t cr_dma;
78 dma_addr_t new_dma;
79 dma_addr_t leds_dma;
80};
81
82static void usb_kbd_irq(struct urb *urb)
83{
84 struct usb_kbd *kbd = urb->context;
85 int i;
86
87 switch (urb->status) {
88 case 0: /* success */
89 break;
90 case -ECONNRESET: /* unlink */
91 case -ENOENT:
92 case -ESHUTDOWN:
93 return;
94 /* -EPIPE: should clear the halt */
95 default: /* error */
96 goto resubmit;
97 }
98
99 for (i = 0; i < 8; i++)
100 input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
101
102 for (i = 2; i < 8; i++) {
103
104 if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
105 if (usb_kbd_keycode[kbd->old[i]])
106 input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
107 else
108 info("Unknown key (scancode %#x) released.", kbd->old[i]);
109 }
110
111 if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
112 if (usb_kbd_keycode[kbd->new[i]])
113 input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
114 else
115 info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
116 }
117 }
118
119 input_sync(kbd->dev);
120
121 memcpy(kbd->old, kbd->new, 8);
122
123resubmit:
124 i = usb_submit_urb (urb, GFP_ATOMIC);
125 if (i)
126 err_hid ("can't resubmit intr, %s-%s/input0, status %d",
127 kbd->usbdev->bus->bus_name,
128 kbd->usbdev->devpath, i);
129}
130
131static int usb_kbd_event(struct input_dev *dev, unsigned int type,
132 unsigned int code, int value)
133{
134 struct usb_kbd *kbd = input_get_drvdata(dev);
135
136 if (type != EV_LED)
137 return -1;
138
139 kbd->newleds = (!!test_bit(LED_KANA, dev->led) << 3) | (!!test_bit(LED_COMPOSE, dev->led) << 3) |
140 (!!test_bit(LED_SCROLLL, dev->led) << 2) | (!!test_bit(LED_CAPSL, dev->led) << 1) |
141 (!!test_bit(LED_NUML, dev->led));
142
143 if (kbd->led->status == -EINPROGRESS)
144 return 0;
145
146 if (*(kbd->leds) == kbd->newleds)
147 return 0;
148
149 *(kbd->leds) = kbd->newleds;
150 kbd->led->dev = kbd->usbdev;
151 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
152 err_hid("usb_submit_urb(leds) failed");
153
154 return 0;
155}
156
157static void usb_kbd_led(struct urb *urb)
158{
159 struct usb_kbd *kbd = urb->context;
160
161 if (urb->status)
162 warn("led urb status %d received", urb->status);
163
164 if (*(kbd->leds) == kbd->newleds)
165 return;
166
167 *(kbd->leds) = kbd->newleds;
168 kbd->led->dev = kbd->usbdev;
169 if (usb_submit_urb(kbd->led, GFP_ATOMIC))
170 err_hid("usb_submit_urb(leds) failed");
171}
172
173static int usb_kbd_open(struct input_dev *dev)
174{
175 struct usb_kbd *kbd = input_get_drvdata(dev);
176
177 kbd->irq->dev = kbd->usbdev;
178 if (usb_submit_urb(kbd->irq, GFP_KERNEL))
179 return -EIO;
180
181 return 0;
182}
183
184static void usb_kbd_close(struct input_dev *dev)
185{
186 struct usb_kbd *kbd = input_get_drvdata(dev);
187
188 usb_kill_urb(kbd->irq);
189}
190
191static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd)
192{
193 if (!(kbd->irq = usb_alloc_urb(0, GFP_KERNEL)))
194 return -1;
195 if (!(kbd->led = usb_alloc_urb(0, GFP_KERNEL)))
196 return -1;
197 if (!(kbd->new = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &kbd->new_dma)))
198 return -1;
199 if (!(kbd->cr = usb_buffer_alloc(dev, sizeof(struct usb_ctrlrequest), GFP_ATOMIC, &kbd->cr_dma)))
200 return -1;
201 if (!(kbd->leds = usb_buffer_alloc(dev, 1, GFP_ATOMIC, &kbd->leds_dma)))
202 return -1;
203
204 return 0;
205}
206
207static void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
208{
209 usb_free_urb(kbd->irq);
210 usb_free_urb(kbd->led);
211 usb_buffer_free(dev, 8, kbd->new, kbd->new_dma);
212 usb_buffer_free(dev, sizeof(struct usb_ctrlrequest), kbd->cr, kbd->cr_dma);
213 usb_buffer_free(dev, 1, kbd->leds, kbd->leds_dma);
214}
215
216static int usb_kbd_probe(struct usb_interface *iface,
217 const struct usb_device_id *id)
218{
219 struct usb_device *dev = interface_to_usbdev(iface);
220 struct usb_host_interface *interface;
221 struct usb_endpoint_descriptor *endpoint;
222 struct usb_kbd *kbd;
223 struct input_dev *input_dev;
224 int i, pipe, maxp;
225 int error = -ENOMEM;
226
227 interface = iface->cur_altsetting;
228
229 if (interface->desc.bNumEndpoints != 1)
230 return -ENODEV;
231
232 endpoint = &interface->endpoint[0].desc;
233 if (!usb_endpoint_is_int_in(endpoint))
234 return -ENODEV;
235
236 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
237 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
238
239 kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
240 input_dev = input_allocate_device();
241 if (!kbd || !input_dev)
242 goto fail1;
243
244 if (usb_kbd_alloc_mem(dev, kbd))
245 goto fail2;
246
247 kbd->usbdev = dev;
248 kbd->dev = input_dev;
249
250 if (dev->manufacturer)
251 strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
252
253 if (dev->product) {
254 if (dev->manufacturer)
255 strlcat(kbd->name, " ", sizeof(kbd->name));
256 strlcat(kbd->name, dev->product, sizeof(kbd->name));
257 }
258
259 if (!strlen(kbd->name))
260 snprintf(kbd->name, sizeof(kbd->name),
261 "USB HIDBP Keyboard %04x:%04x",
262 le16_to_cpu(dev->descriptor.idVendor),
263 le16_to_cpu(dev->descriptor.idProduct));
264
265 usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
266 strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
267
268 input_dev->name = kbd->name;
269 input_dev->phys = kbd->phys;
270 usb_to_input_id(dev, &input_dev->id);
271 input_dev->dev.parent = &iface->dev;
272
273 input_set_drvdata(input_dev, kbd);
274
275 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
276 BIT_MASK(EV_REP);
277 input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
278 BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
279 BIT_MASK(LED_KANA);
280
281 for (i = 0; i < 255; i++)
282 set_bit(usb_kbd_keycode[i], input_dev->keybit);
283 clear_bit(0, input_dev->keybit);
284
285 input_dev->event = usb_kbd_event;
286 input_dev->open = usb_kbd_open;
287 input_dev->close = usb_kbd_close;
288
289 usb_fill_int_urb(kbd->irq, dev, pipe,
290 kbd->new, (maxp > 8 ? 8 : maxp),
291 usb_kbd_irq, kbd, endpoint->bInterval);
292 kbd->irq->transfer_dma = kbd->new_dma;
293 kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
294
295 kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
296 kbd->cr->bRequest = 0x09;
297 kbd->cr->wValue = cpu_to_le16(0x200);
298 kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
299 kbd->cr->wLength = cpu_to_le16(1);
300
301 usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
302 (void *) kbd->cr, kbd->leds, 1,
303 usb_kbd_led, kbd);
304 kbd->led->setup_dma = kbd->cr_dma;
305 kbd->led->transfer_dma = kbd->leds_dma;
306 kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
307
308 error = input_register_device(kbd->dev);
309 if (error)
310 goto fail2;
311
312 usb_set_intfdata(iface, kbd);
313 return 0;
314
315fail2:
316 usb_kbd_free_mem(dev, kbd);
317fail1:
318 input_free_device(input_dev);
319 kfree(kbd);
320 return error;
321}
322
323static void usb_kbd_disconnect(struct usb_interface *intf)
324{
325 struct usb_kbd *kbd = usb_get_intfdata (intf);
326
327 usb_set_intfdata(intf, NULL);
328 if (kbd) {
329 usb_kill_urb(kbd->irq);
330 input_unregister_device(kbd->dev);
331 usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
332 kfree(kbd);
333 }
334}
335
336static struct usb_device_id usb_kbd_id_table [] = {
337 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
338 USB_INTERFACE_PROTOCOL_KEYBOARD) },
339 { } /* Terminating entry */
340};
341
342MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
343
344static struct usb_driver usb_kbd_driver = {
345 .name = "usbkbd",
346 .probe = usb_kbd_probe,
347 .disconnect = usb_kbd_disconnect,
348 .id_table = usb_kbd_id_table,
349};
350
351static int __init usb_kbd_init(void)
352{
353 int result = usb_register(&usb_kbd_driver);
354 if (result == 0)
355 info(DRIVER_VERSION ":" DRIVER_DESC);
356 return result;
357}
358
359static void __exit usb_kbd_exit(void)
360{
361 usb_deregister(&usb_kbd_driver);
362}
363
364module_init(usb_kbd_init);
365module_exit(usb_kbd_exit);
diff --git a/usr/src/dkms_source_tree/usbmouse.c b/usr/src/dkms_source_tree/usbmouse.c
new file mode 100644
index 0000000..35689ef
--- /dev/null
+++ b/usr/src/dkms_source_tree/usbmouse.c
@@ -0,0 +1,253 @@
1/*
2 * Copyright (c) 1999-2001 Vojtech Pavlik
3 *
4 * USB HIDBP Mouse support
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Should you need to contact me, the author, you can do so either by
23 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
24 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
25 */
26
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/usb/input.h>
32#include <linux/hid.h>
33
34/*
35 * Version Information
36 */
37#define DRIVER_VERSION "v1.6"
38#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
39#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
40#define DRIVER_LICENSE "GPL"
41
42MODULE_AUTHOR(DRIVER_AUTHOR);
43MODULE_DESCRIPTION(DRIVER_DESC);
44MODULE_LICENSE(DRIVER_LICENSE);
45
46struct usb_mouse {
47 char name[128];
48 char phys[64];
49 struct usb_device *usbdev;
50 struct input_dev *dev;
51 struct urb *irq;
52
53 signed char *data;
54 dma_addr_t data_dma;
55};
56
57static void usb_mouse_irq(struct urb *urb)
58{
59 struct usb_mouse *mouse = urb->context;
60 signed char *data = mouse->data;
61 struct input_dev *dev = mouse->dev;
62 int status;
63
64 switch (urb->status) {
65 case 0: /* success */
66 break;
67 case -ECONNRESET: /* unlink */
68 case -ENOENT:
69 case -ESHUTDOWN:
70 return;
71 /* -EPIPE: should clear the halt */
72 default: /* error */
73 goto resubmit;
74 }
75
76 input_report_key(dev, BTN_LEFT, data[0] & 0x01);
77 input_report_key(dev, BTN_RIGHT, data[0] & 0x02);
78 input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
79 input_report_key(dev, BTN_SIDE, data[0] & 0x08);
80 input_report_key(dev, BTN_EXTRA, data[0] & 0x10);
81
82 input_report_rel(dev, REL_X, data[1]);
83 input_report_rel(dev, REL_Y, data[2]);
84 input_report_rel(dev, REL_WHEEL, data[3]);
85
86 input_sync(dev);
87resubmit:
88 status = usb_submit_urb (urb, GFP_ATOMIC);
89 if (status)
90 err ("can't resubmit intr, %s-%s/input0, status %d",
91 mouse->usbdev->bus->bus_name,
92 mouse->usbdev->devpath, status);
93}
94
95static int usb_mouse_open(struct input_dev *dev)
96{
97 struct usb_mouse *mouse = input_get_drvdata(dev);
98
99 mouse->irq->dev = mouse->usbdev;
100 if (usb_submit_urb(mouse->irq, GFP_KERNEL))
101 return -EIO;
102
103 return 0;
104}
105
106static void usb_mouse_close(struct input_dev *dev)
107{
108 struct usb_mouse *mouse = input_get_drvdata(dev);
109
110 usb_kill_urb(mouse->irq);
111}
112
113static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
114{
115 struct usb_device *dev = interface_to_usbdev(intf);
116 struct usb_host_interface *interface;
117 struct usb_endpoint_descriptor *endpoint;
118 struct usb_mouse *mouse;
119 struct input_dev *input_dev;
120 int pipe, maxp;
121 int error = -ENOMEM;
122
123 interface = intf->cur_altsetting;
124
125 if (interface->desc.bNumEndpoints != 1)
126 return -ENODEV;
127
128 endpoint = &interface->endpoint[0].desc;
129 if (!usb_endpoint_is_int_in(endpoint))
130 return -ENODEV;
131
132 pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
133 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
134
135 mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
136 input_dev = input_allocate_device();
137 if (!mouse || !input_dev)
138 goto fail1;
139
140 mouse->data = usb_buffer_alloc(dev, 8, GFP_ATOMIC, &mouse->data_dma);
141 if (!mouse->data)
142 goto fail1;
143
144 mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
145 if (!mouse->irq)
146 goto fail2;
147
148 mouse->usbdev = dev;
149 mouse->dev = input_dev;
150
151 if (dev->manufacturer)
152 strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
153
154 if (dev->product) {
155 if (dev->manufacturer)
156 strlcat(mouse->name, " ", sizeof(mouse->name));
157 strlcat(mouse->name, dev->product, sizeof(mouse->name));
158 }
159
160 if (!strlen(mouse->name))
161 snprintf(mouse->name, sizeof(mouse->name),
162 "USB HIDBP Mouse %04x:%04x",
163 le16_to_cpu(dev->descriptor.idVendor),
164 le16_to_cpu(dev->descriptor.idProduct));
165
166 usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
167 strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
168
169 input_dev->name = mouse->name;
170 input_dev->phys = mouse->phys;
171 usb_to_input_id(dev, &input_dev->id);
172 input_dev->dev.parent = &intf->dev;
173
174 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
175 input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
176 BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
177 input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
178 input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
179 BIT_MASK(BTN_EXTRA);
180 input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
181
182 input_set_drvdata(input_dev, mouse);
183
184 input_dev->open = usb_mouse_open;
185 input_dev->close = usb_mouse_close;
186
187 usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
188 (maxp > 8 ? 8 : maxp),
189 usb_mouse_irq, mouse, endpoint->bInterval);
190 mouse->irq->transfer_dma = mouse->data_dma;
191 mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
192
193 error = input_register_device(mouse->dev);
194 if (error)
195 goto fail3;
196
197 usb_set_intfdata(intf, mouse);
198 return 0;
199
200fail3:
201 usb_free_urb(mouse->irq);
202fail2:
203 usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
204fail1:
205 input_free_device(input_dev);
206 kfree(mouse);
207 return error;
208}
209
210static void usb_mouse_disconnect(struct usb_interface *intf)
211{
212 struct usb_mouse *mouse = usb_get_intfdata (intf);
213
214 usb_set_intfdata(intf, NULL);
215 if (mouse) {
216 usb_kill_urb(mouse->irq);
217 input_unregister_device(mouse->dev);
218 usb_free_urb(mouse->irq);
219 usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
220 kfree(mouse);
221 }
222}
223
224static struct usb_device_id usb_mouse_id_table [] = {
225 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
226 USB_INTERFACE_PROTOCOL_MOUSE) },
227 { } /* Terminating entry */
228};
229
230MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
231
232static struct usb_driver usb_mouse_driver = {
233 .name = "usbmouse",
234 .probe = usb_mouse_probe,
235 .disconnect = usb_mouse_disconnect,
236 .id_table = usb_mouse_id_table,
237};
238
239static int __init usb_mouse_init(void)
240{
241 int retval = usb_register(&usb_mouse_driver);
242 if (retval == 0)
243 info(DRIVER_VERSION ":" DRIVER_DESC);
244 return retval;
245}
246
247static void __exit usb_mouse_exit(void)
248{
249 usb_deregister(&usb_mouse_driver);
250}
251
252module_init(usb_mouse_init);
253module_exit(usb_mouse_exit);