Merge branch 'gma500-next' of git://github.com/patjak/drm-gma500 into drm-next
[pandora-kernel.git] / drivers / hid / hid-lg.c
1 /*
2  *  HID driver for some logitech "special" devices
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) 2008 Jiri Slaby
9  *  Copyright (c) 2010 Hendrik Iben
10  */
11
12 /*
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the Free
15  * Software Foundation; either version 2 of the License, or (at your option)
16  * any later version.
17  */
18
19 #include <linux/device.h>
20 #include <linux/hid.h>
21 #include <linux/module.h>
22 #include <linux/random.h>
23 #include <linux/sched.h>
24 #include <linux/usb.h>
25 #include <linux/wait.h>
26
27 #include "usbhid/usbhid.h"
28 #include "hid-ids.h"
29 #include "hid-lg.h"
30
31 #define LG_RDESC                0x001
32 #define LG_BAD_RELATIVE_KEYS    0x002
33 #define LG_DUPLICATE_USAGES     0x004
34 #define LG_EXPANDED_KEYMAP      0x010
35 #define LG_IGNORE_DOUBLED_WHEEL 0x020
36 #define LG_WIRELESS             0x040
37 #define LG_INVERT_HWHEEL        0x080
38 #define LG_NOGET                0x100
39 #define LG_FF                   0x200
40 #define LG_FF2                  0x400
41 #define LG_RDESC_REL_ABS        0x800
42 #define LG_FF3                  0x1000
43 #define LG_FF4                  0x2000
44
45 /* Size of the original descriptors of the Driving Force (and Pro) wheels */
46 #define DF_RDESC_ORIG_SIZE      130
47 #define DFP_RDESC_ORIG_SIZE     97
48 #define MOMO_RDESC_ORIG_SIZE    87
49
50 /* Fixed report descriptors for Logitech Driving Force (and Pro)
51  * wheel controllers
52  *
53  * The original descriptors hide the separate throttle and brake axes in
54  * a custom vendor usage page, providing only a combined value as
55  * GenericDesktop.Y.
56  * These descriptors remove the combined Y axis and instead report
57  * separate throttle (Y) and brake (RZ).
58  */
59 static __u8 df_rdesc_fixed[] = {
60 0x05, 0x01,         /*  Usage Page (Desktop),                   */
61 0x09, 0x04,         /*  Usage (Joystik),                        */
62 0xA1, 0x01,         /*  Collection (Application),               */
63 0xA1, 0x02,         /*      Collection (Logical),               */
64 0x95, 0x01,         /*          Report Count (1),               */
65 0x75, 0x0A,         /*          Report Size (10),               */
66 0x14,               /*          Logical Minimum (0),            */
67 0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),         */
68 0x34,               /*          Physical Minimum (0),           */
69 0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),        */
70 0x09, 0x30,         /*          Usage (X),                      */
71 0x81, 0x02,         /*          Input (Variable),               */
72 0x95, 0x0C,         /*          Report Count (12),              */
73 0x75, 0x01,         /*          Report Size (1),                */
74 0x25, 0x01,         /*          Logical Maximum (1),            */
75 0x45, 0x01,         /*          Physical Maximum (1),           */
76 0x05, 0x09,         /*          Usage (Buttons),                */
77 0x19, 0x01,         /*          Usage Minimum (1),              */
78 0x29, 0x0c,         /*          Usage Maximum (12),             */
79 0x81, 0x02,         /*          Input (Variable),               */
80 0x95, 0x02,         /*          Report Count (2),               */
81 0x06, 0x00, 0xFF,   /*          Usage Page (Vendor: 65280),     */
82 0x09, 0x01,         /*          Usage (?: 1),                   */
83 0x81, 0x02,         /*          Input (Variable),               */
84 0x05, 0x01,         /*          Usage Page (Desktop),           */
85 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
86 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
87 0x95, 0x01,         /*          Report Count (1),               */
88 0x75, 0x08,         /*          Report Size (8),                */
89 0x81, 0x02,         /*          Input (Variable),               */
90 0x25, 0x07,         /*          Logical Maximum (7),            */
91 0x46, 0x3B, 0x01,   /*          Physical Maximum (315),         */
92 0x75, 0x04,         /*          Report Size (4),                */
93 0x65, 0x14,         /*          Unit (Degrees),                 */
94 0x09, 0x39,         /*          Usage (Hat Switch),             */
95 0x81, 0x42,         /*          Input (Variable, Null State),   */
96 0x75, 0x01,         /*          Report Size (1),                */
97 0x95, 0x04,         /*          Report Count (4),               */
98 0x65, 0x00,         /*          Unit (none),                    */
99 0x06, 0x00, 0xFF,   /*          Usage Page (Vendor: 65280),     */
100 0x09, 0x01,         /*          Usage (?: 1),                   */
101 0x25, 0x01,         /*          Logical Maximum (1),            */
102 0x45, 0x01,         /*          Physical Maximum (1),           */
103 0x81, 0x02,         /*          Input (Variable),               */
104 0x05, 0x01,         /*          Usage Page (Desktop),           */
105 0x95, 0x01,         /*          Report Count (1),               */
106 0x75, 0x08,         /*          Report Size (8),                */
107 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
108 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
109 0x09, 0x31,         /*          Usage (Y),                      */
110 0x81, 0x02,         /*          Input (Variable),               */
111 0x09, 0x35,         /*          Usage (Rz),                     */
112 0x81, 0x02,         /*          Input (Variable),               */
113 0xC0,               /*      End Collection,                     */
114 0xA1, 0x02,         /*      Collection (Logical),               */
115 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
116 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
117 0x95, 0x07,         /*          Report Count (7),               */
118 0x75, 0x08,         /*          Report Size (8),                */
119 0x09, 0x03,         /*          Usage (?: 3),                   */
120 0x91, 0x02,         /*          Output (Variable),              */
121 0xC0,               /*      End Collection,                     */
122 0xC0                /*  End Collection                          */
123 };
124
125 static __u8 dfp_rdesc_fixed[] = {
126 0x05, 0x01,         /*  Usage Page (Desktop),                   */
127 0x09, 0x04,         /*  Usage (Joystik),                        */
128 0xA1, 0x01,         /*  Collection (Application),               */
129 0xA1, 0x02,         /*      Collection (Logical),               */
130 0x95, 0x01,         /*          Report Count (1),               */
131 0x75, 0x0E,         /*          Report Size (14),               */
132 0x14,               /*          Logical Minimum (0),            */
133 0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),        */
134 0x34,               /*          Physical Minimum (0),           */
135 0x46, 0xFF, 0x3F,   /*          Physical Maximum (16383),       */
136 0x09, 0x30,         /*          Usage (X),                      */
137 0x81, 0x02,         /*          Input (Variable),               */
138 0x95, 0x0E,         /*          Report Count (14),              */
139 0x75, 0x01,         /*          Report Size (1),                */
140 0x25, 0x01,         /*          Logical Maximum (1),            */
141 0x45, 0x01,         /*          Physical Maximum (1),           */
142 0x05, 0x09,         /*          Usage Page (Button),            */
143 0x19, 0x01,         /*          Usage Minimum (01h),            */
144 0x29, 0x0E,         /*          Usage Maximum (0Eh),            */
145 0x81, 0x02,         /*          Input (Variable),               */
146 0x05, 0x01,         /*          Usage Page (Desktop),           */
147 0x95, 0x01,         /*          Report Count (1),               */
148 0x75, 0x04,         /*          Report Size (4),                */
149 0x25, 0x07,         /*          Logical Maximum (7),            */
150 0x46, 0x3B, 0x01,   /*          Physical Maximum (315),         */
151 0x65, 0x14,         /*          Unit (Degrees),                 */
152 0x09, 0x39,         /*          Usage (Hat Switch),             */
153 0x81, 0x42,         /*          Input (Variable, Nullstate),    */
154 0x65, 0x00,         /*          Unit,                           */
155 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
156 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
157 0x75, 0x08,         /*          Report Size (8),                */
158 0x81, 0x01,         /*          Input (Constant),               */
159 0x09, 0x31,         /*          Usage (Y),                      */
160 0x81, 0x02,         /*          Input (Variable),               */
161 0x09, 0x35,         /*          Usage (Rz),                     */
162 0x81, 0x02,         /*          Input (Variable),               */
163 0x81, 0x01,         /*          Input (Constant),               */
164 0xC0,               /*      End Collection,                     */
165 0xA1, 0x02,         /*      Collection (Logical),               */
166 0x09, 0x02,         /*          Usage (02h),                    */
167 0x95, 0x07,         /*          Report Count (7),               */
168 0x91, 0x02,         /*          Output (Variable),              */
169 0xC0,               /*      End Collection,                     */
170 0xC0                /*  End Collection                          */
171 };
172
173 static __u8 momo_rdesc_fixed[] = {
174 0x05, 0x01,         /*  Usage Page (Desktop),               */
175 0x09, 0x04,         /*  Usage (Joystik),                    */
176 0xA1, 0x01,         /*  Collection (Application),           */
177 0xA1, 0x02,         /*      Collection (Logical),           */
178 0x95, 0x01,         /*          Report Count (1),           */
179 0x75, 0x0A,         /*          Report Size (10),           */
180 0x15, 0x00,         /*          Logical Minimum (0),        */
181 0x26, 0xFF, 0x03,   /*          Logical Maximum (1023),     */
182 0x35, 0x00,         /*          Physical Minimum (0),       */
183 0x46, 0xFF, 0x03,   /*          Physical Maximum (1023),    */
184 0x09, 0x30,         /*          Usage (X),                  */
185 0x81, 0x02,         /*          Input (Variable),           */
186 0x95, 0x08,         /*          Report Count (8),           */
187 0x75, 0x01,         /*          Report Size (1),            */
188 0x25, 0x01,         /*          Logical Maximum (1),        */
189 0x45, 0x01,         /*          Physical Maximum (1),       */
190 0x05, 0x09,         /*          Usage Page (Button),        */
191 0x19, 0x01,         /*          Usage Minimum (01h),        */
192 0x29, 0x08,         /*          Usage Maximum (08h),        */
193 0x81, 0x02,         /*          Input (Variable),           */
194 0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
195 0x75, 0x0E,         /*          Report Size (14),           */
196 0x95, 0x01,         /*          Report Count (1),           */
197 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),      */
198 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),     */
199 0x09, 0x00,         /*          Usage (00h),                */
200 0x81, 0x02,         /*          Input (Variable),           */
201 0x05, 0x01,         /*          Usage Page (Desktop),       */
202 0x75, 0x08,         /*          Report Size (8),            */
203 0x09, 0x31,         /*          Usage (Y),                  */
204 0x81, 0x02,         /*          Input (Variable),           */
205 0x09, 0x32,         /*          Usage (Z),                  */
206 0x81, 0x02,         /*          Input (Variable),           */
207 0x06, 0x00, 0xFF,   /*          Usage Page (FF00h),         */
208 0x09, 0x01,         /*          Usage (01h),                */
209 0x81, 0x02,         /*          Input (Variable),           */
210 0xC0,               /*      End Collection,                 */
211 0xA1, 0x02,         /*      Collection (Logical),           */
212 0x09, 0x02,         /*          Usage (02h),                */
213 0x95, 0x07,         /*          Report Count (7),           */
214 0x91, 0x02,         /*          Output (Variable),          */
215 0xC0,               /*      End Collection,                 */
216 0xC0                /*  End Collection                      */
217 };
218
219 /*
220  * Certain Logitech keyboards send in report #3 keys which are far
221  * above the logical maximum described in descriptor. This extends
222  * the original value of 0x28c of logical maximum to 0x104d
223  */
224 static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
225                 unsigned int *rsize)
226 {
227         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
228         struct usb_device_descriptor *udesc;
229         __u16 bcdDevice, rev_maj, rev_min;
230
231         if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
232                         rdesc[84] == 0x8c && rdesc[85] == 0x02) {
233                 hid_info(hdev,
234                          "fixing up Logitech keyboard report descriptor\n");
235                 rdesc[84] = rdesc[89] = 0x4d;
236                 rdesc[85] = rdesc[90] = 0x10;
237         }
238         if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
239                         rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
240                         rdesc[49] == 0x81 && rdesc[50] == 0x06) {
241                 hid_info(hdev,
242                          "fixing up rel/abs in Logitech report descriptor\n");
243                 rdesc[33] = rdesc[50] = 0x02;
244         }
245
246         switch (hdev->product) {
247
248         /* Several wheels report as this id when operating in emulation mode. */
249         case USB_DEVICE_ID_LOGITECH_WHEEL:
250                 udesc = &(hid_to_usb_dev(hdev)->descriptor);
251                 if (!udesc) {
252                         hid_err(hdev, "NULL USB device descriptor\n");
253                         break;
254                 }
255                 bcdDevice = le16_to_cpu(udesc->bcdDevice);
256                 rev_maj = bcdDevice >> 8;
257                 rev_min = bcdDevice & 0xff;
258
259                 /* Update the report descriptor for only the Driving Force wheel */
260                 if (rev_maj == 1 && rev_min == 2 &&
261                                 *rsize == DF_RDESC_ORIG_SIZE) {
262                         hid_info(hdev,
263                                 "fixing up Logitech Driving Force report descriptor\n");
264                         rdesc = df_rdesc_fixed;
265                         *rsize = sizeof(df_rdesc_fixed);
266                 }
267                 break;
268
269         case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
270                 if (*rsize == MOMO_RDESC_ORIG_SIZE) {
271                         hid_info(hdev,
272                                 "fixing up Logitech Momo Force (Red) report descriptor\n");
273                         rdesc = momo_rdesc_fixed;
274                         *rsize = sizeof(momo_rdesc_fixed);
275                 }
276                 break;
277
278         case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
279                 if (*rsize == DFP_RDESC_ORIG_SIZE) {
280                         hid_info(hdev,
281                                 "fixing up Logitech Driving Force Pro report descriptor\n");
282                         rdesc = dfp_rdesc_fixed;
283                         *rsize = sizeof(dfp_rdesc_fixed);
284                 }
285                 break;
286
287         case USB_DEVICE_ID_LOGITECH_WII_WHEEL:
288                 if (*rsize >= 101 && rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
289                                 rdesc[47] == 0x05 && rdesc[48] == 0x09) {
290                         hid_info(hdev, "fixing up Logitech Speed Force Wireless report descriptor\n");
291                         rdesc[41] = 0x05;
292                         rdesc[42] = 0x09;
293                         rdesc[47] = 0x95;
294                         rdesc[48] = 0x0B;
295                 }
296                 break;
297         }
298
299         return rdesc;
300 }
301
302 #define lg_map_key_clear(c)     hid_map_usage_clear(hi, usage, bit, max, \
303                 EV_KEY, (c))
304
305 static int lg_ultrax_remote_mapping(struct hid_input *hi,
306                 struct hid_usage *usage, unsigned long **bit, int *max)
307 {
308         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
309                 return 0;
310
311         set_bit(EV_REP, hi->input->evbit);
312         switch (usage->hid & HID_USAGE) {
313         /* Reported on Logitech Ultra X Media Remote */
314         case 0x004: lg_map_key_clear(KEY_AGAIN);        break;
315         case 0x00d: lg_map_key_clear(KEY_HOME);         break;
316         case 0x024: lg_map_key_clear(KEY_SHUFFLE);      break;
317         case 0x025: lg_map_key_clear(KEY_TV);           break;
318         case 0x026: lg_map_key_clear(KEY_MENU);         break;
319         case 0x031: lg_map_key_clear(KEY_AUDIO);        break;
320         case 0x032: lg_map_key_clear(KEY_TEXT);         break;
321         case 0x033: lg_map_key_clear(KEY_LAST);         break;
322         case 0x047: lg_map_key_clear(KEY_MP3);          break;
323         case 0x048: lg_map_key_clear(KEY_DVD);          break;
324         case 0x049: lg_map_key_clear(KEY_MEDIA);        break;
325         case 0x04a: lg_map_key_clear(KEY_VIDEO);        break;
326         case 0x04b: lg_map_key_clear(KEY_ANGLE);        break;
327         case 0x04c: lg_map_key_clear(KEY_LANGUAGE);     break;
328         case 0x04d: lg_map_key_clear(KEY_SUBTITLE);     break;
329         case 0x051: lg_map_key_clear(KEY_RED);          break;
330         case 0x052: lg_map_key_clear(KEY_CLOSE);        break;
331
332         default:
333                 return 0;
334         }
335         return 1;
336 }
337
338 static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
339                 unsigned long **bit, int *max)
340 {
341         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
342                 return 0;
343
344         switch (usage->hid & HID_USAGE) {
345
346         case 0x00d: lg_map_key_clear(KEY_MEDIA);        break;
347         default:
348                 return 0;
349
350         }
351         return 1;
352 }
353
354 static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
355                 unsigned long **bit, int *max)
356 {
357         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
358                 return 0;
359
360         switch (usage->hid & HID_USAGE) {
361         case 0x1001: lg_map_key_clear(KEY_MESSENGER);           break;
362         case 0x1003: lg_map_key_clear(KEY_SOUND);               break;
363         case 0x1004: lg_map_key_clear(KEY_VIDEO);               break;
364         case 0x1005: lg_map_key_clear(KEY_AUDIO);               break;
365         case 0x100a: lg_map_key_clear(KEY_DOCUMENTS);           break;
366         /* The following two entries are Playlist 1 and 2 on the MX3200 */
367         case 0x100f: lg_map_key_clear(KEY_FN_1);                break;
368         case 0x1010: lg_map_key_clear(KEY_FN_2);                break;
369         case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG);        break;
370         case 0x1012: lg_map_key_clear(KEY_NEXTSONG);            break;
371         case 0x1013: lg_map_key_clear(KEY_CAMERA);              break;
372         case 0x1014: lg_map_key_clear(KEY_MESSENGER);           break;
373         case 0x1015: lg_map_key_clear(KEY_RECORD);              break;
374         case 0x1016: lg_map_key_clear(KEY_PLAYER);              break;
375         case 0x1017: lg_map_key_clear(KEY_EJECTCD);             break;
376         case 0x1018: lg_map_key_clear(KEY_MEDIA);               break;
377         case 0x1019: lg_map_key_clear(KEY_PROG1);               break;
378         case 0x101a: lg_map_key_clear(KEY_PROG2);               break;
379         case 0x101b: lg_map_key_clear(KEY_PROG3);               break;
380         case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS);        break;
381         case 0x101f: lg_map_key_clear(KEY_ZOOMIN);              break;
382         case 0x1020: lg_map_key_clear(KEY_ZOOMOUT);             break;
383         case 0x1021: lg_map_key_clear(KEY_ZOOMRESET);           break;
384         case 0x1023: lg_map_key_clear(KEY_CLOSE);               break;
385         case 0x1027: lg_map_key_clear(KEY_MENU);                break;
386         /* this one is marked as 'Rotate' */
387         case 0x1028: lg_map_key_clear(KEY_ANGLE);               break;
388         case 0x1029: lg_map_key_clear(KEY_SHUFFLE);             break;
389         case 0x102a: lg_map_key_clear(KEY_BACK);                break;
390         case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS);        break;
391         case 0x102d: lg_map_key_clear(KEY_WWW);                 break;
392         /* The following two are 'Start/answer call' and 'End/reject call'
393            on the MX3200 */
394         case 0x1031: lg_map_key_clear(KEY_OK);                  break;
395         case 0x1032: lg_map_key_clear(KEY_CANCEL);              break;
396         case 0x1041: lg_map_key_clear(KEY_BATTERY);             break;
397         case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR);       break;
398         case 0x1043: lg_map_key_clear(KEY_SPREADSHEET);         break;
399         case 0x1044: lg_map_key_clear(KEY_PRESENTATION);        break;
400         case 0x1045: lg_map_key_clear(KEY_UNDO);                break;
401         case 0x1046: lg_map_key_clear(KEY_REDO);                break;
402         case 0x1047: lg_map_key_clear(KEY_PRINT);               break;
403         case 0x1048: lg_map_key_clear(KEY_SAVE);                break;
404         case 0x1049: lg_map_key_clear(KEY_PROG1);               break;
405         case 0x104a: lg_map_key_clear(KEY_PROG2);               break;
406         case 0x104b: lg_map_key_clear(KEY_PROG3);               break;
407         case 0x104c: lg_map_key_clear(KEY_PROG4);               break;
408
409         default:
410                 return 0;
411         }
412         return 1;
413 }
414
415 static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
416                 struct hid_field *field, struct hid_usage *usage,
417                 unsigned long **bit, int *max)
418 {
419         /* extended mapping for certain Logitech hardware (Logitech cordless
420            desktop LX500) */
421         static const u8 e_keymap[] = {
422                   0,216,  0,213,175,156,  0,  0,  0,  0,
423                 144,  0,  0,  0,  0,  0,  0,  0,  0,212,
424                 174,167,152,161,112,  0,  0,  0,154,  0,
425                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
426                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
427                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
428                   0,  0,  0,  0,  0,183,184,185,186,187,
429                 188,189,190,191,192,193,194,  0,  0,  0
430         };
431         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
432         unsigned int hid = usage->hid;
433
434         if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
435                         lg_ultrax_remote_mapping(hi, usage, bit, max))
436                 return 1;
437
438         if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
439                         lg_dinovo_mapping(hi, usage, bit, max))
440                 return 1;
441
442         if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
443                 return 1;
444
445         if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
446                 return 0;
447
448         hid &= HID_USAGE;
449
450         /* Special handling for Logitech Cordless Desktop */
451         if (field->application == HID_GD_MOUSE) {
452                 if ((drv_data->quirks & LG_IGNORE_DOUBLED_WHEEL) &&
453                                 (hid == 7 || hid == 8))
454                         return -1;
455         } else {
456                 if ((drv_data->quirks & LG_EXPANDED_KEYMAP) &&
457                                 hid < ARRAY_SIZE(e_keymap) &&
458                                 e_keymap[hid] != 0) {
459                         hid_map_usage(hi, usage, bit, max, EV_KEY,
460                                         e_keymap[hid]);
461                         return 1;
462                 }
463         }
464
465         return 0;
466 }
467
468 static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
469                 struct hid_field *field, struct hid_usage *usage,
470                 unsigned long **bit, int *max)
471 {
472         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
473
474         if ((drv_data->quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
475                         (field->flags & HID_MAIN_ITEM_RELATIVE))
476                 field->flags &= ~HID_MAIN_ITEM_RELATIVE;
477
478         if ((drv_data->quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
479                          usage->type == EV_REL || usage->type == EV_ABS))
480                 clear_bit(usage->code, *bit);
481
482         /* Ensure that Logitech wheels are not given a default fuzz/flat value */
483         if (usage->type == EV_ABS && (usage->code == ABS_X ||
484                         usage->code == ABS_Y || usage->code == ABS_Z ||
485                         usage->code == ABS_RZ)) {
486                 switch (hdev->product) {
487                 case USB_DEVICE_ID_LOGITECH_WHEEL:
488                 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
489                 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
490                 case USB_DEVICE_ID_LOGITECH_G25_WHEEL:
491                 case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL:
492                 case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
493                 case USB_DEVICE_ID_LOGITECH_WII_WHEEL:
494                 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
495                         field->application = HID_GD_MULTIAXIS;
496                         break;
497                 default:
498                         break;
499                 }
500         }
501
502         return 0;
503 }
504
505 static int lg_event(struct hid_device *hdev, struct hid_field *field,
506                 struct hid_usage *usage, __s32 value)
507 {
508         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
509
510         if ((drv_data->quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
511                 input_event(field->hidinput->input, usage->type, usage->code,
512                                 -value);
513                 return 1;
514         }
515         if (drv_data->quirks & LG_FF4) {
516                 return lg4ff_adjust_input_event(hdev, field, usage, value, drv_data);
517         }
518
519         return 0;
520 }
521
522 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
523 {
524         unsigned int connect_mask = HID_CONNECT_DEFAULT;
525         struct lg_drv_data *drv_data;
526         int ret;
527
528         drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
529         if (!drv_data) {
530                 hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
531                 return -ENOMEM;
532         }
533         drv_data->quirks = id->driver_data;
534
535         hid_set_drvdata(hdev, (void *)drv_data);
536
537         if (drv_data->quirks & LG_NOGET)
538                 hdev->quirks |= HID_QUIRK_NOGET;
539
540         ret = hid_parse(hdev);
541         if (ret) {
542                 hid_err(hdev, "parse failed\n");
543                 goto err_free;
544         }
545
546         if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
547                 connect_mask &= ~HID_CONNECT_FF;
548
549         ret = hid_hw_start(hdev, connect_mask);
550         if (ret) {
551                 hid_err(hdev, "hw start failed\n");
552                 goto err_free;
553         }
554
555         /* Setup wireless link with Logitech Wii wheel */
556         if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
557                 unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
558
559                 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
560
561                 if (ret >= 0) {
562                         /* insert a little delay of 10 jiffies ~ 40ms */
563                         wait_queue_head_t wait;
564                         init_waitqueue_head (&wait);
565                         wait_event_interruptible_timeout(wait, 0, 10);
566
567                         /* Select random Address */
568                         buf[1] = 0xB2;
569                         get_random_bytes(&buf[2], 2);
570
571                         ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
572                 }
573         }
574
575         if (drv_data->quirks & LG_FF)
576                 lgff_init(hdev);
577         if (drv_data->quirks & LG_FF2)
578                 lg2ff_init(hdev);
579         if (drv_data->quirks & LG_FF3)
580                 lg3ff_init(hdev);
581         if (drv_data->quirks & LG_FF4)
582                 lg4ff_init(hdev);
583
584         return 0;
585 err_free:
586         kfree(drv_data);
587         return ret;
588 }
589
590 static void lg_remove(struct hid_device *hdev)
591 {
592         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
593         if (drv_data->quirks & LG_FF4)
594                 lg4ff_deinit(hdev);
595
596         hid_hw_stop(hdev);
597         kfree(drv_data);
598 }
599
600 static const struct hid_device_id lg_devices[] = {
601         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
602                 .driver_data = LG_RDESC | LG_WIRELESS },
603         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER),
604                 .driver_data = LG_RDESC | LG_WIRELESS },
605         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2),
606                 .driver_data = LG_RDESC | LG_WIRELESS },
607
608         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER),
609                 .driver_data = LG_BAD_RELATIVE_KEYS },
610
611         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
612                 .driver_data = LG_DUPLICATE_USAGES },
613         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
614                 .driver_data = LG_DUPLICATE_USAGES },
615         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
616                 .driver_data = LG_DUPLICATE_USAGES },
617
618         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
619                 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
620         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
621                 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
622
623         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
624                 .driver_data = LG_NOGET },
625         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
626                 .driver_data = LG_NOGET | LG_FF4 },
627
628         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
629                 .driver_data = LG_FF2 },
630         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
631                 .driver_data = LG_FF },
632         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
633                 .driver_data = LG_FF },
634         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D),
635                 .driver_data = LG_FF },
636         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
637                 .driver_data = LG_FF },
638         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
639                 .driver_data = LG_NOGET | LG_FF4 },
640         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
641                 .driver_data = LG_FF4 },
642         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
643                 .driver_data = LG_FF4 },
644         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
645                 .driver_data = LG_FF4 },
646         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
647                 .driver_data = LG_FF4 },
648         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
649                 .driver_data = LG_NOGET | LG_FF4 },
650         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
651                 .driver_data = LG_FF4 },
652         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG),
653                 .driver_data = LG_FF },
654         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
655                 .driver_data = LG_FF2 },
656         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
657                 .driver_data = LG_FF3 },
658         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
659                 .driver_data = LG_RDESC_REL_ABS },
660         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
661                 .driver_data = LG_RDESC_REL_ABS },
662         { }
663 };
664
665 MODULE_DEVICE_TABLE(hid, lg_devices);
666
667 static struct hid_driver lg_driver = {
668         .name = "logitech",
669         .id_table = lg_devices,
670         .report_fixup = lg_report_fixup,
671         .input_mapping = lg_input_mapping,
672         .input_mapped = lg_input_mapped,
673         .event = lg_event,
674         .probe = lg_probe,
675         .remove = lg_remove,
676 };
677 module_hid_driver(lg_driver);
678
679 MODULE_LICENSE("GPL");