]> rtime.felk.cvut.cz Git - linux-imx.git/blob - drivers/hid/hid-lg.c
Merge branch 'upstream' into for-linus
[linux-imx.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/wait.h>
25
26 #include "hid-ids.h"
27 #include "hid-lg.h"
28
29 #define LG_RDESC                0x001
30 #define LG_BAD_RELATIVE_KEYS    0x002
31 #define LG_DUPLICATE_USAGES     0x004
32 #define LG_EXPANDED_KEYMAP      0x010
33 #define LG_IGNORE_DOUBLED_WHEEL 0x020
34 #define LG_WIRELESS             0x040
35 #define LG_INVERT_HWHEEL        0x080
36 #define LG_NOGET                0x100
37 #define LG_FF                   0x200
38 #define LG_FF2                  0x400
39 #define LG_RDESC_REL_ABS        0x800
40 #define LG_FF3                  0x1000
41 #define LG_FF4                  0x2000
42
43 /* Size of the original descriptor of the Driving Force Pro wheel */
44 #define DFP_RDESC_ORIG_SIZE     97
45
46 /* Fixed report descriptor for Logitech Driving Force Pro wheel controller
47  *
48  * The original descriptor hides the separate throttle and brake axes in
49  * a custom vendor usage page, providing only a combined value as
50  * GenericDesktop.Y.
51  * This descriptor removes the combined Y axis and instead reports
52  * separate throttle (Y) and brake (RZ).
53  */
54 static __u8 dfp_rdesc_fixed[] = {
55 0x05, 0x01,         /*  Usage Page (Desktop),                   */
56 0x09, 0x04,         /*  Usage (Joystik),                        */
57 0xA1, 0x01,         /*  Collection (Application),               */
58 0xA1, 0x02,         /*      Collection (Logical),               */
59 0x95, 0x01,         /*          Report Count (1),               */
60 0x75, 0x0E,         /*          Report Size (14),               */
61 0x14,               /*          Logical Minimum (0),            */
62 0x26, 0xFF, 0x3F,   /*          Logical Maximum (16383),        */
63 0x34,               /*          Physical Minimum (0),           */
64 0x46, 0xFF, 0x3F,   /*          Physical Maximum (16383),       */
65 0x09, 0x30,         /*          Usage (X),                      */
66 0x81, 0x02,         /*          Input (Variable),               */
67 0x95, 0x0E,         /*          Report Count (14),              */
68 0x75, 0x01,         /*          Report Size (1),                */
69 0x25, 0x01,         /*          Logical Maximum (1),            */
70 0x45, 0x01,         /*          Physical Maximum (1),           */
71 0x05, 0x09,         /*          Usage Page (Button),            */
72 0x19, 0x01,         /*          Usage Minimum (01h),            */
73 0x29, 0x0E,         /*          Usage Maximum (0Eh),            */
74 0x81, 0x02,         /*          Input (Variable),               */
75 0x05, 0x01,         /*          Usage Page (Desktop),           */
76 0x95, 0x01,         /*          Report Count (1),               */
77 0x75, 0x04,         /*          Report Size (4),                */
78 0x25, 0x07,         /*          Logical Maximum (7),            */
79 0x46, 0x3B, 0x01,   /*          Physical Maximum (315),         */
80 0x65, 0x14,         /*          Unit (Degrees),                 */
81 0x09, 0x39,         /*          Usage (Hat Switch),             */
82 0x81, 0x42,         /*          Input (Variable, Nullstate),    */
83 0x65, 0x00,         /*          Unit,                           */
84 0x26, 0xFF, 0x00,   /*          Logical Maximum (255),          */
85 0x46, 0xFF, 0x00,   /*          Physical Maximum (255),         */
86 0x75, 0x08,         /*          Report Size (8),                */
87 0x81, 0x01,         /*          Input (Constant),               */
88 0x09, 0x31,         /*          Usage (Y),                      */
89 0x81, 0x02,         /*          Input (Variable),               */
90 0x09, 0x35,         /*          Usage (Rz),                     */
91 0x81, 0x02,         /*          Input (Variable),               */
92 0x81, 0x01,         /*          Input (Constant),               */
93 0xC0,               /*      End Collection,                     */
94 0xA1, 0x02,         /*      Collection (Logical),               */
95 0x09, 0x02,         /*          Usage (02h),                    */
96 0x95, 0x07,         /*          Report Count (7),               */
97 0x91, 0x02,         /*          Output (Variable),              */
98 0xC0,               /*      End Collection,                     */
99 0xC0                /*  End Collection                          */
100 };
101
102
103 /*
104  * Certain Logitech keyboards send in report #3 keys which are far
105  * above the logical maximum described in descriptor. This extends
106  * the original value of 0x28c of logical maximum to 0x104d
107  */
108 static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
109                 unsigned int *rsize)
110 {
111         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
112
113         if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
114                         rdesc[84] == 0x8c && rdesc[85] == 0x02) {
115                 hid_info(hdev,
116                          "fixing up Logitech keyboard report descriptor\n");
117                 rdesc[84] = rdesc[89] = 0x4d;
118                 rdesc[85] = rdesc[90] = 0x10;
119         }
120         if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
121                         rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
122                         rdesc[49] == 0x81 && rdesc[50] == 0x06) {
123                 hid_info(hdev,
124                          "fixing up rel/abs in Logitech report descriptor\n");
125                 rdesc[33] = rdesc[50] = 0x02;
126         }
127         if ((drv_data->quirks & LG_FF4) && *rsize >= 101 &&
128                         rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
129                         rdesc[47] == 0x05 && rdesc[48] == 0x09) {
130                 hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n");
131                 rdesc[41] = 0x05;
132                 rdesc[42] = 0x09;
133                 rdesc[47] = 0x95;
134                 rdesc[48] = 0x0B;
135         }
136
137         switch (hdev->product) {
138         case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
139                 if (*rsize == DFP_RDESC_ORIG_SIZE) {
140                         hid_info(hdev,
141                                 "fixing up Logitech Driving Force Pro report descriptor\n");
142                         rdesc = dfp_rdesc_fixed;
143                         *rsize = sizeof(dfp_rdesc_fixed);
144                 }
145                 break;
146         }
147
148         return rdesc;
149 }
150
151 #define lg_map_key_clear(c)     hid_map_usage_clear(hi, usage, bit, max, \
152                 EV_KEY, (c))
153
154 static int lg_ultrax_remote_mapping(struct hid_input *hi,
155                 struct hid_usage *usage, unsigned long **bit, int *max)
156 {
157         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
158                 return 0;
159
160         set_bit(EV_REP, hi->input->evbit);
161         switch (usage->hid & HID_USAGE) {
162         /* Reported on Logitech Ultra X Media Remote */
163         case 0x004: lg_map_key_clear(KEY_AGAIN);        break;
164         case 0x00d: lg_map_key_clear(KEY_HOME);         break;
165         case 0x024: lg_map_key_clear(KEY_SHUFFLE);      break;
166         case 0x025: lg_map_key_clear(KEY_TV);           break;
167         case 0x026: lg_map_key_clear(KEY_MENU);         break;
168         case 0x031: lg_map_key_clear(KEY_AUDIO);        break;
169         case 0x032: lg_map_key_clear(KEY_TEXT);         break;
170         case 0x033: lg_map_key_clear(KEY_LAST);         break;
171         case 0x047: lg_map_key_clear(KEY_MP3);          break;
172         case 0x048: lg_map_key_clear(KEY_DVD);          break;
173         case 0x049: lg_map_key_clear(KEY_MEDIA);        break;
174         case 0x04a: lg_map_key_clear(KEY_VIDEO);        break;
175         case 0x04b: lg_map_key_clear(KEY_ANGLE);        break;
176         case 0x04c: lg_map_key_clear(KEY_LANGUAGE);     break;
177         case 0x04d: lg_map_key_clear(KEY_SUBTITLE);     break;
178         case 0x051: lg_map_key_clear(KEY_RED);          break;
179         case 0x052: lg_map_key_clear(KEY_CLOSE);        break;
180
181         default:
182                 return 0;
183         }
184         return 1;
185 }
186
187 static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
188                 unsigned long **bit, int *max)
189 {
190         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
191                 return 0;
192
193         switch (usage->hid & HID_USAGE) {
194
195         case 0x00d: lg_map_key_clear(KEY_MEDIA);        break;
196         default:
197                 return 0;
198
199         }
200         return 1;
201 }
202
203 static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
204                 unsigned long **bit, int *max)
205 {
206         if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
207                 return 0;
208
209         switch (usage->hid & HID_USAGE) {
210         case 0x1001: lg_map_key_clear(KEY_MESSENGER);           break;
211         case 0x1003: lg_map_key_clear(KEY_SOUND);               break;
212         case 0x1004: lg_map_key_clear(KEY_VIDEO);               break;
213         case 0x1005: lg_map_key_clear(KEY_AUDIO);               break;
214         case 0x100a: lg_map_key_clear(KEY_DOCUMENTS);           break;
215         /* The following two entries are Playlist 1 and 2 on the MX3200 */
216         case 0x100f: lg_map_key_clear(KEY_FN_1);                break;
217         case 0x1010: lg_map_key_clear(KEY_FN_2);                break;
218         case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG);        break;
219         case 0x1012: lg_map_key_clear(KEY_NEXTSONG);            break;
220         case 0x1013: lg_map_key_clear(KEY_CAMERA);              break;
221         case 0x1014: lg_map_key_clear(KEY_MESSENGER);           break;
222         case 0x1015: lg_map_key_clear(KEY_RECORD);              break;
223         case 0x1016: lg_map_key_clear(KEY_PLAYER);              break;
224         case 0x1017: lg_map_key_clear(KEY_EJECTCD);             break;
225         case 0x1018: lg_map_key_clear(KEY_MEDIA);               break;
226         case 0x1019: lg_map_key_clear(KEY_PROG1);               break;
227         case 0x101a: lg_map_key_clear(KEY_PROG2);               break;
228         case 0x101b: lg_map_key_clear(KEY_PROG3);               break;
229         case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS);        break;
230         case 0x101f: lg_map_key_clear(KEY_ZOOMIN);              break;
231         case 0x1020: lg_map_key_clear(KEY_ZOOMOUT);             break;
232         case 0x1021: lg_map_key_clear(KEY_ZOOMRESET);           break;
233         case 0x1023: lg_map_key_clear(KEY_CLOSE);               break;
234         case 0x1027: lg_map_key_clear(KEY_MENU);                break;
235         /* this one is marked as 'Rotate' */
236         case 0x1028: lg_map_key_clear(KEY_ANGLE);               break;
237         case 0x1029: lg_map_key_clear(KEY_SHUFFLE);             break;
238         case 0x102a: lg_map_key_clear(KEY_BACK);                break;
239         case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS);        break;
240         case 0x102d: lg_map_key_clear(KEY_WWW);                 break;
241         /* The following two are 'Start/answer call' and 'End/reject call'
242            on the MX3200 */
243         case 0x1031: lg_map_key_clear(KEY_OK);                  break;
244         case 0x1032: lg_map_key_clear(KEY_CANCEL);              break;
245         case 0x1041: lg_map_key_clear(KEY_BATTERY);             break;
246         case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR);       break;
247         case 0x1043: lg_map_key_clear(KEY_SPREADSHEET);         break;
248         case 0x1044: lg_map_key_clear(KEY_PRESENTATION);        break;
249         case 0x1045: lg_map_key_clear(KEY_UNDO);                break;
250         case 0x1046: lg_map_key_clear(KEY_REDO);                break;
251         case 0x1047: lg_map_key_clear(KEY_PRINT);               break;
252         case 0x1048: lg_map_key_clear(KEY_SAVE);                break;
253         case 0x1049: lg_map_key_clear(KEY_PROG1);               break;
254         case 0x104a: lg_map_key_clear(KEY_PROG2);               break;
255         case 0x104b: lg_map_key_clear(KEY_PROG3);               break;
256         case 0x104c: lg_map_key_clear(KEY_PROG4);               break;
257
258         default:
259                 return 0;
260         }
261         return 1;
262 }
263
264 static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
265                 struct hid_field *field, struct hid_usage *usage,
266                 unsigned long **bit, int *max)
267 {
268         /* extended mapping for certain Logitech hardware (Logitech cordless
269            desktop LX500) */
270         static const u8 e_keymap[] = {
271                   0,216,  0,213,175,156,  0,  0,  0,  0,
272                 144,  0,  0,  0,  0,  0,  0,  0,  0,212,
273                 174,167,152,161,112,  0,  0,  0,154,  0,
274                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
275                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
276                   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
277                   0,  0,  0,  0,  0,183,184,185,186,187,
278                 188,189,190,191,192,193,194,  0,  0,  0
279         };
280         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
281         unsigned int hid = usage->hid;
282
283         if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
284                         lg_ultrax_remote_mapping(hi, usage, bit, max))
285                 return 1;
286
287         if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
288                         lg_dinovo_mapping(hi, usage, bit, max))
289                 return 1;
290
291         if ((drv_data->quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
292                 return 1;
293
294         if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
295                 return 0;
296
297         hid &= HID_USAGE;
298
299         /* Special handling for Logitech Cordless Desktop */
300         if (field->application == HID_GD_MOUSE) {
301                 if ((drv_data->quirks & LG_IGNORE_DOUBLED_WHEEL) &&
302                                 (hid == 7 || hid == 8))
303                         return -1;
304         } else {
305                 if ((drv_data->quirks & LG_EXPANDED_KEYMAP) &&
306                                 hid < ARRAY_SIZE(e_keymap) &&
307                                 e_keymap[hid] != 0) {
308                         hid_map_usage(hi, usage, bit, max, EV_KEY,
309                                         e_keymap[hid]);
310                         return 1;
311                 }
312         }
313
314         return 0;
315 }
316
317 static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
318                 struct hid_field *field, struct hid_usage *usage,
319                 unsigned long **bit, int *max)
320 {
321         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
322
323         if ((drv_data->quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
324                         (field->flags & HID_MAIN_ITEM_RELATIVE))
325                 field->flags &= ~HID_MAIN_ITEM_RELATIVE;
326
327         if ((drv_data->quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
328                          usage->type == EV_REL || usage->type == EV_ABS))
329                 clear_bit(usage->code, *bit);
330
331         return 0;
332 }
333
334 static int lg_event(struct hid_device *hdev, struct hid_field *field,
335                 struct hid_usage *usage, __s32 value)
336 {
337         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
338
339         if ((drv_data->quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
340                 input_event(field->hidinput->input, usage->type, usage->code,
341                                 -value);
342                 return 1;
343         }
344         if (drv_data->quirks & LG_FF4) {
345                 return lg4ff_adjust_input_event(hdev, field, usage, value, drv_data);
346         }
347
348         return 0;
349 }
350
351 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
352 {
353         unsigned int connect_mask = HID_CONNECT_DEFAULT;
354         struct lg_drv_data *drv_data;
355         int ret;
356
357         drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL);
358         if (!drv_data) {
359                 hid_err(hdev, "Insufficient memory, cannot allocate driver data\n");
360                 return -ENOMEM;
361         }
362         drv_data->quirks = id->driver_data;
363
364         hid_set_drvdata(hdev, (void *)drv_data);
365
366         if (drv_data->quirks & LG_NOGET)
367                 hdev->quirks |= HID_QUIRK_NOGET;
368
369         ret = hid_parse(hdev);
370         if (ret) {
371                 hid_err(hdev, "parse failed\n");
372                 goto err_free;
373         }
374
375         if (drv_data->quirks & (LG_FF | LG_FF2 | LG_FF3 | LG_FF4))
376                 connect_mask &= ~HID_CONNECT_FF;
377
378         ret = hid_hw_start(hdev, connect_mask);
379         if (ret) {
380                 hid_err(hdev, "hw start failed\n");
381                 goto err_free;
382         }
383
384         /* Setup wireless link with Logitech Wii wheel */
385         if (hdev->product == USB_DEVICE_ID_LOGITECH_WII_WHEEL) {
386                 unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
387
388                 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
389
390                 if (ret >= 0) {
391                         /* insert a little delay of 10 jiffies ~ 40ms */
392                         wait_queue_head_t wait;
393                         init_waitqueue_head (&wait);
394                         wait_event_interruptible_timeout(wait, 0, 10);
395
396                         /* Select random Address */
397                         buf[1] = 0xB2;
398                         get_random_bytes(&buf[2], 2);
399
400                         ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
401                 }
402         }
403
404         if (drv_data->quirks & LG_FF)
405                 lgff_init(hdev);
406         if (drv_data->quirks & LG_FF2)
407                 lg2ff_init(hdev);
408         if (drv_data->quirks & LG_FF3)
409                 lg3ff_init(hdev);
410         if (drv_data->quirks & LG_FF4)
411                 lg4ff_init(hdev);
412
413         return 0;
414 err_free:
415         kfree(drv_data);
416         return ret;
417 }
418
419 static void lg_remove(struct hid_device *hdev)
420 {
421         struct lg_drv_data *drv_data = hid_get_drvdata(hdev);
422         if (drv_data->quirks & LG_FF4)
423                 lg4ff_deinit(hdev);
424
425         hid_hw_stop(hdev);
426         kfree(drv_data);
427 }
428
429 static const struct hid_device_id lg_devices[] = {
430         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
431                 .driver_data = LG_RDESC | LG_WIRELESS },
432         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER),
433                 .driver_data = LG_RDESC | LG_WIRELESS },
434         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2),
435                 .driver_data = LG_RDESC | LG_WIRELESS },
436
437         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER),
438                 .driver_data = LG_BAD_RELATIVE_KEYS },
439
440         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
441                 .driver_data = LG_DUPLICATE_USAGES },
442         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
443                 .driver_data = LG_DUPLICATE_USAGES },
444         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
445                 .driver_data = LG_DUPLICATE_USAGES },
446
447         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
448                 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
449         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
450                 .driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
451
452         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
453                 .driver_data = LG_NOGET },
454         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
455                 .driver_data = LG_NOGET | LG_FF4 },
456
457         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
458                 .driver_data = LG_FF2 },
459         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
460                 .driver_data = LG_FF },
461         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
462                 .driver_data = LG_FF },
463         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D),
464                 .driver_data = LG_FF },
465         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
466                 .driver_data = LG_FF },
467         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
468                 .driver_data = LG_FF4 },
469         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
470                 .driver_data = LG_FF4 },
471         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
472                 .driver_data = LG_FF4 },
473         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
474                 .driver_data = LG_FF4 },
475         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
476                 .driver_data = LG_FF4 },
477         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
478                 .driver_data = LG_NOGET | LG_FF4 },
479         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
480                 .driver_data = LG_FF4 },
481         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG),
482                 .driver_data = LG_FF },
483         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
484                 .driver_data = LG_FF2 },
485         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
486                 .driver_data = LG_FF3 },
487         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
488                 .driver_data = LG_RDESC_REL_ABS },
489         { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
490                 .driver_data = LG_RDESC_REL_ABS },
491         { }
492 };
493
494 MODULE_DEVICE_TABLE(hid, lg_devices);
495
496 static struct hid_driver lg_driver = {
497         .name = "logitech",
498         .id_table = lg_devices,
499         .report_fixup = lg_report_fixup,
500         .input_mapping = lg_input_mapping,
501         .input_mapped = lg_input_mapped,
502         .event = lg_event,
503         .probe = lg_probe,
504         .remove = lg_remove,
505 };
506
507 static int __init lg_init(void)
508 {
509         return hid_register_driver(&lg_driver);
510 }
511
512 static void __exit lg_exit(void)
513 {
514         hid_unregister_driver(&lg_driver);
515 }
516
517 module_init(lg_init);
518 module_exit(lg_exit);
519 MODULE_LICENSE("GPL");