xref: /openbmc/linux/drivers/hid/hid-lg.c (revision 8b66a16f)
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) 2007 Paul Walmsley
9  *  Copyright (c) 2008 Jiri Slaby
10  *  Copyright (c) 2010 Hendrik Iben
11  */
12 
13 /*
14  * This program is free software; you can redistribute it and/or modify it
15  * under the terms of the GNU General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at your option)
17  * any later version.
18  */
19 
20 #include <linux/device.h>
21 #include <linux/hid.h>
22 #include <linux/module.h>
23 #include <linux/random.h>
24 #include <linux/sched.h>
25 #include <linux/wait.h>
26 
27 #include "hid-ids.h"
28 #include "hid-lg.h"
29 
30 #define LG_RDESC		0x001
31 #define LG_BAD_RELATIVE_KEYS	0x002
32 #define LG_DUPLICATE_USAGES	0x004
33 #define LG_EXPANDED_KEYMAP	0x010
34 #define LG_IGNORE_DOUBLED_WHEEL	0x020
35 #define LG_WIRELESS		0x040
36 #define LG_INVERT_HWHEEL	0x080
37 #define LG_NOGET		0x100
38 #define LG_FF			0x200
39 #define LG_FF2			0x400
40 #define LG_RDESC_REL_ABS	0x800
41 #define LG_FF3			0x1000
42 #define LG_FF4			0x2000
43 
44 /*
45  * Certain Logitech keyboards send in report #3 keys which are far
46  * above the logical maximum described in descriptor. This extends
47  * the original value of 0x28c of logical maximum to 0x104d
48  */
49 static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
50 		unsigned int *rsize)
51 {
52 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
53 
54 	if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
55 			rdesc[84] == 0x8c && rdesc[85] == 0x02) {
56 		dev_info(&hdev->dev, "fixing up Logitech keyboard report "
57 				"descriptor\n");
58 		rdesc[84] = rdesc[89] = 0x4d;
59 		rdesc[85] = rdesc[90] = 0x10;
60 	}
61 	if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
62 			rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
63 			rdesc[49] == 0x81 && rdesc[50] == 0x06) {
64 		dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
65 				"report descriptor\n");
66 		rdesc[33] = rdesc[50] = 0x02;
67 	}
68 	if ((quirks & LG_FF4) && rsize >= 101 &&
69 			rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
70 			rdesc[47] == 0x05 && rdesc[48] == 0x09) {
71 		dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless "
72 			"button descriptor\n");
73 		rdesc[41] = 0x05;
74 		rdesc[42] = 0x09;
75 		rdesc[47] = 0x95;
76 		rdesc[48] = 0x0B;
77 	}
78 	return rdesc;
79 }
80 
81 #define lg_map_key_clear(c)	hid_map_usage_clear(hi, usage, bit, max, \
82 		EV_KEY, (c))
83 
84 static int lg_ultrax_remote_mapping(struct hid_input *hi,
85 		struct hid_usage *usage, unsigned long **bit, int *max)
86 {
87 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
88 		return 0;
89 
90 	set_bit(EV_REP, hi->input->evbit);
91 	switch (usage->hid & HID_USAGE) {
92 	/* Reported on Logitech Ultra X Media Remote */
93 	case 0x004: lg_map_key_clear(KEY_AGAIN);	break;
94 	case 0x00d: lg_map_key_clear(KEY_HOME);		break;
95 	case 0x024: lg_map_key_clear(KEY_SHUFFLE);	break;
96 	case 0x025: lg_map_key_clear(KEY_TV);		break;
97 	case 0x026: lg_map_key_clear(KEY_MENU);		break;
98 	case 0x031: lg_map_key_clear(KEY_AUDIO);	break;
99 	case 0x032: lg_map_key_clear(KEY_TEXT);		break;
100 	case 0x033: lg_map_key_clear(KEY_LAST);		break;
101 	case 0x047: lg_map_key_clear(KEY_MP3);		break;
102 	case 0x048: lg_map_key_clear(KEY_DVD);		break;
103 	case 0x049: lg_map_key_clear(KEY_MEDIA);	break;
104 	case 0x04a: lg_map_key_clear(KEY_VIDEO);	break;
105 	case 0x04b: lg_map_key_clear(KEY_ANGLE);	break;
106 	case 0x04c: lg_map_key_clear(KEY_LANGUAGE);	break;
107 	case 0x04d: lg_map_key_clear(KEY_SUBTITLE);	break;
108 	case 0x051: lg_map_key_clear(KEY_RED);		break;
109 	case 0x052: lg_map_key_clear(KEY_CLOSE);	break;
110 
111 	default:
112 		return 0;
113 	}
114 	return 1;
115 }
116 
117 static int lg_dinovo_mapping(struct hid_input *hi, struct hid_usage *usage,
118 		unsigned long **bit, int *max)
119 {
120 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
121 		return 0;
122 
123 	switch (usage->hid & HID_USAGE) {
124 
125 	case 0x00d: lg_map_key_clear(KEY_MEDIA);	break;
126 	default:
127 		return 0;
128 
129 	}
130 	return 1;
131 }
132 
133 static int lg_wireless_mapping(struct hid_input *hi, struct hid_usage *usage,
134 		unsigned long **bit, int *max)
135 {
136 	if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)
137 		return 0;
138 
139 	switch (usage->hid & HID_USAGE) {
140 	case 0x1001: lg_map_key_clear(KEY_MESSENGER);		break;
141 	case 0x1003: lg_map_key_clear(KEY_SOUND);		break;
142 	case 0x1004: lg_map_key_clear(KEY_VIDEO);		break;
143 	case 0x1005: lg_map_key_clear(KEY_AUDIO);		break;
144 	case 0x100a: lg_map_key_clear(KEY_DOCUMENTS);		break;
145 	/* The following two entries are Playlist 1 and 2 on the MX3200 */
146 	case 0x100f: lg_map_key_clear(KEY_FN_1);		break;
147 	case 0x1010: lg_map_key_clear(KEY_FN_2);		break;
148 	case 0x1011: lg_map_key_clear(KEY_PREVIOUSSONG);	break;
149 	case 0x1012: lg_map_key_clear(KEY_NEXTSONG);		break;
150 	case 0x1013: lg_map_key_clear(KEY_CAMERA);		break;
151 	case 0x1014: lg_map_key_clear(KEY_MESSENGER);		break;
152 	case 0x1015: lg_map_key_clear(KEY_RECORD);		break;
153 	case 0x1016: lg_map_key_clear(KEY_PLAYER);		break;
154 	case 0x1017: lg_map_key_clear(KEY_EJECTCD);		break;
155 	case 0x1018: lg_map_key_clear(KEY_MEDIA);		break;
156 	case 0x1019: lg_map_key_clear(KEY_PROG1);		break;
157 	case 0x101a: lg_map_key_clear(KEY_PROG2);		break;
158 	case 0x101b: lg_map_key_clear(KEY_PROG3);		break;
159 	case 0x101c: lg_map_key_clear(KEY_CYCLEWINDOWS);	break;
160 	case 0x101f: lg_map_key_clear(KEY_ZOOMIN);		break;
161 	case 0x1020: lg_map_key_clear(KEY_ZOOMOUT);		break;
162 	case 0x1021: lg_map_key_clear(KEY_ZOOMRESET);		break;
163 	case 0x1023: lg_map_key_clear(KEY_CLOSE);		break;
164 	case 0x1027: lg_map_key_clear(KEY_MENU);		break;
165 	/* this one is marked as 'Rotate' */
166 	case 0x1028: lg_map_key_clear(KEY_ANGLE);		break;
167 	case 0x1029: lg_map_key_clear(KEY_SHUFFLE);		break;
168 	case 0x102a: lg_map_key_clear(KEY_BACK);		break;
169 	case 0x102b: lg_map_key_clear(KEY_CYCLEWINDOWS);	break;
170 	case 0x102d: lg_map_key_clear(KEY_WWW);			break;
171 	/* The following two are 'Start/answer call' and 'End/reject call'
172 	   on the MX3200 */
173 	case 0x1031: lg_map_key_clear(KEY_OK);			break;
174 	case 0x1032: lg_map_key_clear(KEY_CANCEL);		break;
175 	case 0x1041: lg_map_key_clear(KEY_BATTERY);		break;
176 	case 0x1042: lg_map_key_clear(KEY_WORDPROCESSOR);	break;
177 	case 0x1043: lg_map_key_clear(KEY_SPREADSHEET);		break;
178 	case 0x1044: lg_map_key_clear(KEY_PRESENTATION);	break;
179 	case 0x1045: lg_map_key_clear(KEY_UNDO);		break;
180 	case 0x1046: lg_map_key_clear(KEY_REDO);		break;
181 	case 0x1047: lg_map_key_clear(KEY_PRINT);		break;
182 	case 0x1048: lg_map_key_clear(KEY_SAVE);		break;
183 	case 0x1049: lg_map_key_clear(KEY_PROG1);		break;
184 	case 0x104a: lg_map_key_clear(KEY_PROG2);		break;
185 	case 0x104b: lg_map_key_clear(KEY_PROG3);		break;
186 	case 0x104c: lg_map_key_clear(KEY_PROG4);		break;
187 
188 	default:
189 		return 0;
190 	}
191 	return 1;
192 }
193 
194 static int lg_input_mapping(struct hid_device *hdev, struct hid_input *hi,
195 		struct hid_field *field, struct hid_usage *usage,
196 		unsigned long **bit, int *max)
197 {
198 	/* extended mapping for certain Logitech hardware (Logitech cordless
199 	   desktop LX500) */
200 	static const u8 e_keymap[] = {
201 		  0,216,  0,213,175,156,  0,  0,  0,  0,
202 		144,  0,  0,  0,  0,  0,  0,  0,  0,212,
203 		174,167,152,161,112,  0,  0,  0,154,  0,
204 		  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
205 		  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
206 		  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
207 		  0,  0,  0,  0,  0,183,184,185,186,187,
208 		188,189,190,191,192,193,194,  0,  0,  0
209 	};
210 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
211 	unsigned int hid = usage->hid;
212 
213 	if (hdev->product == USB_DEVICE_ID_LOGITECH_RECEIVER &&
214 			lg_ultrax_remote_mapping(hi, usage, bit, max))
215 		return 1;
216 
217 	if (hdev->product == USB_DEVICE_ID_DINOVO_MINI &&
218 			lg_dinovo_mapping(hi, usage, bit, max))
219 		return 1;
220 
221 	if ((quirks & LG_WIRELESS) && lg_wireless_mapping(hi, usage, bit, max))
222 		return 1;
223 
224 	if ((hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
225 		return 0;
226 
227 	hid &= HID_USAGE;
228 
229 	/* Special handling for Logitech Cordless Desktop */
230 	if (field->application == HID_GD_MOUSE) {
231 		if ((quirks & LG_IGNORE_DOUBLED_WHEEL) &&
232 				(hid == 7 || hid == 8))
233 			return -1;
234 	} else {
235 		if ((quirks & LG_EXPANDED_KEYMAP) &&
236 				hid < ARRAY_SIZE(e_keymap) &&
237 				e_keymap[hid] != 0) {
238 			hid_map_usage(hi, usage, bit, max, EV_KEY,
239 					e_keymap[hid]);
240 			return 1;
241 		}
242 	}
243 
244 	return 0;
245 }
246 
247 static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
248 		struct hid_field *field, struct hid_usage *usage,
249 		unsigned long **bit, int *max)
250 {
251 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
252 
253 	if ((quirks & LG_BAD_RELATIVE_KEYS) && usage->type == EV_KEY &&
254 			(field->flags & HID_MAIN_ITEM_RELATIVE))
255 		field->flags &= ~HID_MAIN_ITEM_RELATIVE;
256 
257 	if ((quirks & LG_DUPLICATE_USAGES) && (usage->type == EV_KEY ||
258 			 usage->type == EV_REL || usage->type == EV_ABS))
259 		clear_bit(usage->code, *bit);
260 
261 	return 0;
262 }
263 
264 static int lg_event(struct hid_device *hdev, struct hid_field *field,
265 		struct hid_usage *usage, __s32 value)
266 {
267 	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
268 
269 	if ((quirks & LG_INVERT_HWHEEL) && usage->code == REL_HWHEEL) {
270 		input_event(field->hidinput->input, usage->type, usage->code,
271 				-value);
272 		return 1;
273 	}
274 
275 	return 0;
276 }
277 
278 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
279 {
280 	unsigned long quirks = id->driver_data;
281 	unsigned int connect_mask = HID_CONNECT_DEFAULT;
282 	int ret;
283 
284 	hid_set_drvdata(hdev, (void *)quirks);
285 
286 	if (quirks & LG_NOGET)
287 		hdev->quirks |= HID_QUIRK_NOGET;
288 
289 	ret = hid_parse(hdev);
290 	if (ret) {
291 		dev_err(&hdev->dev, "parse failed\n");
292 		goto err_free;
293 	}
294 
295 	if (quirks & (LG_FF | LG_FF2 | LG_FF3))
296 		connect_mask &= ~HID_CONNECT_FF;
297 
298 	ret = hid_hw_start(hdev, connect_mask);
299 	if (ret) {
300 		dev_err(&hdev->dev, "hw start failed\n");
301 		goto err_free;
302 	}
303 
304 	if (quirks & LG_FF4) {
305 		unsigned char buf[] = { 0x00, 0xAF,  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
306 
307 		ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
308 
309 		if (ret >= 0) {
310 			/* insert a little delay of 10 jiffies ~ 40ms */
311 			wait_queue_head_t wait;
312 			init_waitqueue_head (&wait);
313 			wait_event_interruptible_timeout(wait, 0, 10);
314 
315 			/* Select random Address */
316 			buf[1] = 0xB2;
317 			get_random_bytes(&buf[2], 2);
318 
319 			ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
320 		}
321 	}
322 
323 	if (quirks & LG_FF)
324 		lgff_init(hdev);
325 	if (quirks & LG_FF2)
326 		lg2ff_init(hdev);
327 	if (quirks & LG_FF3)
328 		lg3ff_init(hdev);
329 	if (quirks & LG_FF4)
330 		lg4ff_init(hdev);
331 
332 	return 0;
333 err_free:
334 	return ret;
335 }
336 
337 static const struct hid_device_id lg_devices[] = {
338 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
339 		.driver_data = LG_RDESC | LG_WIRELESS },
340 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER),
341 		.driver_data = LG_RDESC | LG_WIRELESS },
342 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2),
343 		.driver_data = LG_RDESC | LG_WIRELESS },
344 
345 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER),
346 		.driver_data = LG_BAD_RELATIVE_KEYS },
347 
348 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP),
349 		.driver_data = LG_DUPLICATE_USAGES },
350 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE),
351 		.driver_data = LG_DUPLICATE_USAGES },
352 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI),
353 		.driver_data = LG_DUPLICATE_USAGES },
354 
355 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD),
356 		.driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
357 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500),
358 		.driver_data = LG_IGNORE_DOUBLED_WHEEL | LG_EXPANDED_KEYMAP },
359 
360 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D),
361 		.driver_data = LG_NOGET },
362 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL),
363 		.driver_data = LG_NOGET | LG_FF },
364 
365 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD),
366 		.driver_data = LG_FF2 },
367 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD),
368 		.driver_data = LG_FF },
369 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2),
370 		.driver_data = LG_FF },
371 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D),
372 		.driver_data = LG_FF },
373 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO),
374 		.driver_data = LG_FF },
375 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL),
376 		.driver_data = LG_FF },
377 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
378 		.driver_data = LG_FF },
379 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
380 		.driver_data = LG_FF },
381 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
382 		.driver_data = LG_FF4 },
383 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
384 		.driver_data = LG_FF },
385 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),
386 		.driver_data = LG_FF2 },
387 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940),
388 		.driver_data = LG_FF3 },
389 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR),
390 		.driver_data = LG_RDESC_REL_ABS },
391 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER),
392 		.driver_data = LG_RDESC_REL_ABS },
393 	{ }
394 };
395 
396 MODULE_DEVICE_TABLE(hid, lg_devices);
397 
398 static struct hid_driver lg_driver = {
399 	.name = "logitech",
400 	.id_table = lg_devices,
401 	.report_fixup = lg_report_fixup,
402 	.input_mapping = lg_input_mapping,
403 	.input_mapped = lg_input_mapped,
404 	.event = lg_event,
405 	.probe = lg_probe,
406 };
407 
408 static int __init lg_init(void)
409 {
410 	return hid_register_driver(&lg_driver);
411 }
412 
413 static void __exit lg_exit(void)
414 {
415 	hid_unregister_driver(&lg_driver);
416 }
417 
418 module_init(lg_init);
419 module_exit(lg_exit);
420 MODULE_LICENSE("GPL");
421