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