aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-lg.c
diff options
context:
space:
mode:
authorSimon Wood <simon@mungewell.org>2010-09-22 07:19:42 -0400
committerJiri Kosina <jkosina@suse.cz>2010-09-22 07:25:39 -0400
commit32c88cbc3080f43c429f6456aa9cd845e37f3778 (patch)
tree18886cea811ef68ce20aea0fa975d8a3ca2b1589 /drivers/hid/hid-lg.c
parentfe2c91ee245bd81230f1d67645237a684b90be2b (diff)
HID: Add support for Logitech Speed Force Wireless gaming wheel
The following patch adds support for the Logitech Speed Force Wireless gaming wheel. Originally designed for the WII console. Details on the protocol: http://wiibrew.org/wiki/Logitech_USB_steering_wheel This patch relies on previous patch: "Don't Send Feature Reports on Interrupt Endpoint" Logitech as produce a very similar wheel for the PS2/PS3, it is expected that this patch could also support the PS2/PS3 wheel if the USB ID's are added and (if required) the HID descriptor is modified. Signed-off-by: Simon Wood <simon@mungewell.org> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-lg.c')
-rw-r--r--drivers/hid/hid-lg.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index f6433d8050a..8989f151e0d 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -19,6 +19,9 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/hid.h> 20#include <linux/hid.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/random.h>
23#include <linux/sched.h>
24#include <linux/wait.h>
22 25
23#include "hid-ids.h" 26#include "hid-ids.h"
24#include "hid-lg.h" 27#include "hid-lg.h"
@@ -35,6 +38,7 @@
35#define LG_FF2 0x400 38#define LG_FF2 0x400
36#define LG_RDESC_REL_ABS 0x800 39#define LG_RDESC_REL_ABS 0x800
37#define LG_FF3 0x1000 40#define LG_FF3 0x1000
41#define LG_FF4 0x2000
38 42
39/* 43/*
40 * Certain Logitech keyboards send in report #3 keys which are far 44 * Certain Logitech keyboards send in report #3 keys which are far
@@ -60,6 +64,17 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
60 "report descriptor\n"); 64 "report descriptor\n");
61 rdesc[33] = rdesc[50] = 0x02; 65 rdesc[33] = rdesc[50] = 0x02;
62 } 66 }
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 }
63} 78}
64 79
65#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 80#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
@@ -285,12 +300,33 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id)
285 goto err_free; 300 goto err_free;
286 } 301 }
287 302
303 if (quirks & LG_FF4) {
304 unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
305
306 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
307
308 if (ret >= 0) {
309 /* insert a little delay of 10 jiffies ~ 40ms */
310 wait_queue_head_t wait;
311 init_waitqueue_head (&wait);
312 wait_event_interruptible_timeout(wait, 0, 10);
313
314 /* Select random Address */
315 buf[1] = 0xB2;
316 get_random_bytes(&buf[2], 2);
317
318 ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
319 }
320 }
321
288 if (quirks & LG_FF) 322 if (quirks & LG_FF)
289 lgff_init(hdev); 323 lgff_init(hdev);
290 if (quirks & LG_FF2) 324 if (quirks & LG_FF2)
291 lg2ff_init(hdev); 325 lg2ff_init(hdev);
292 if (quirks & LG_FF3) 326 if (quirks & LG_FF3)
293 lg3ff_init(hdev); 327 lg3ff_init(hdev);
328 if (quirks & LG_FF4)
329 lg4ff_init(hdev);
294 330
295 return 0; 331 return 0;
296err_free: 332err_free:
@@ -339,6 +375,8 @@ static const struct hid_device_id lg_devices[] = {
339 .driver_data = LG_FF }, 375 .driver_data = LG_FF },
340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), 376 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
341 .driver_data = LG_FF }, 377 .driver_data = LG_FF },
378 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
379 .driver_data = LG_FF4 },
342 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), 380 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
343 .driver_data = LG_FF }, 381 .driver_data = LG_FF },
344 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), 382 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2),