diff options
author | Michael Bauer <michael@m-bauer.org> | 2011-06-02 18:40:14 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2011-06-07 09:48:05 -0400 |
commit | dc0a4f0ce2b1a9ef5947cdb6d62f60008a7e42bf (patch) | |
tree | 425ac5646c161cb59d6594f9c2e0572cbcc39ff7 /drivers/hid | |
parent | 6dc1418e13144162e8bc4858789010d8f0e1e65c (diff) |
HID: Fix Logitech Driving Force Pro wheel
- Add the quirk "NOGET" to make the wheel work at all in native mode.
- Replace the somehow broken report descriptor with a custom one to have
separate throttle and brake axes.
As there are significant differences in the descriptor (original descriptor
"hides" the separate axes in a 24 bit FF00 usagepage, new descripter replaces
that with two individual 8 bit desktop.y and desktop.rz usages) I provided a
complete replacement descriptor instead trying to patch the original one.
Patching the descriptor seems not feasible as the new one is much larger.
Note: To actually test this you have to use the tool "ltwheelconf" to put the
DFP into it's native mode - See below for more info.
Background:
Most Logitech wheels are initially reporting themselves with a "fallback"
deviceID (USB_DEVICE_ID_LOGITECH_WHEEL - 0xc294), in order to make sure they
are working even without having the proper driver installed.
If the Logitech driver is installed it sends a special command to the wheel
which sets the wheel to "native mode", enabling enhance features like:
- Clutch pedal
- extended wheel rotation range (up to 900 degrees)
- H-gate shifter
- separate axis for throttle / brake
- all buttons
When the wheel is set to native mode it basically disconnects and reconnects
with a different deviceID (USB_DEVICE_ID_LOGITECH_DFP_WHEEL - 0xc298 in this
case).
I am working on a userspace tool [1] which does the switching from fallback to
native mode. During development I found out that the Driving Force Pro wheel
is not supported in native mode - quierk NOGET is missing and the throttle and
brake axes are reported in a combined way only.
Signed-off-by: Michael Bauer <michael@m-bauer.org>
Signed-off-by: Simon Wood <simon@mungewell.org>
[1] https://github.com/TripleSpeeder/LTWheelConf
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-lg.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 21f205f09250..a7f916e8fc32 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -41,6 +41,66 @@ | |||
41 | #define LG_FF3 0x1000 | 41 | #define LG_FF3 0x1000 |
42 | #define LG_FF4 0x2000 | 42 | #define LG_FF4 0x2000 |
43 | 43 | ||
44 | /* Size of the original descriptor of the Driving Force Pro wheel */ | ||
45 | #define DFP_RDESC_ORIG_SIZE 97 | ||
46 | |||
47 | /* Fixed report descriptor for Logitech Driving Force Pro wheel controller | ||
48 | * | ||
49 | * The original descriptor hides the separate throttle and brake axes in | ||
50 | * a custom vendor usage page, providing only a combined value as | ||
51 | * GenericDesktop.Y. | ||
52 | * This descriptor removes the combined Y axis and instead reports | ||
53 | * separate throttle (Y) and brake (RZ). | ||
54 | */ | ||
55 | static __u8 dfp_rdesc_fixed[] = { | ||
56 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
57 | 0x09, 0x04, /* Usage (Joystik), */ | ||
58 | 0xA1, 0x01, /* Collection (Application), */ | ||
59 | 0xA1, 0x02, /* Collection (Logical), */ | ||
60 | 0x95, 0x01, /* Report Count (1), */ | ||
61 | 0x75, 0x0E, /* Report Size (14), */ | ||
62 | 0x14, /* Logical Minimum (0), */ | ||
63 | 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */ | ||
64 | 0x34, /* Physical Minimum (0), */ | ||
65 | 0x46, 0xFF, 0x3F, /* Physical Maximum (16383), */ | ||
66 | 0x09, 0x30, /* Usage (X), */ | ||
67 | 0x81, 0x02, /* Input (Variable), */ | ||
68 | 0x95, 0x0E, /* Report Count (14), */ | ||
69 | 0x75, 0x01, /* Report Size (1), */ | ||
70 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
71 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
72 | 0x05, 0x09, /* Usage Page (Button), */ | ||
73 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
74 | 0x29, 0x0E, /* Usage Maximum (0Eh), */ | ||
75 | 0x81, 0x02, /* Input (Variable), */ | ||
76 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
77 | 0x95, 0x01, /* Report Count (1), */ | ||
78 | 0x75, 0x04, /* Report Size (4), */ | ||
79 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
80 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
81 | 0x65, 0x14, /* Unit (Degrees), */ | ||
82 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
83 | 0x81, 0x42, /* Input (Variable, Nullstate), */ | ||
84 | 0x65, 0x00, /* Unit, */ | ||
85 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
86 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
87 | 0x75, 0x08, /* Report Size (8), */ | ||
88 | 0x81, 0x01, /* Input (Constant), */ | ||
89 | 0x09, 0x31, /* Usage (Y), */ | ||
90 | 0x81, 0x02, /* Input (Variable), */ | ||
91 | 0x09, 0x35, /* Usage (Rz), */ | ||
92 | 0x81, 0x02, /* Input (Variable), */ | ||
93 | 0x81, 0x01, /* Input (Constant), */ | ||
94 | 0xC0, /* End Collection, */ | ||
95 | 0xA1, 0x02, /* Collection (Logical), */ | ||
96 | 0x09, 0x02, /* Usage (02h), */ | ||
97 | 0x95, 0x07, /* Report Count (7), */ | ||
98 | 0x91, 0x02, /* Output (Variable), */ | ||
99 | 0xC0, /* End Collection, */ | ||
100 | 0xC0 /* End Collection */ | ||
101 | }; | ||
102 | |||
103 | |||
44 | /* | 104 | /* |
45 | * Certain Logitech keyboards send in report #3 keys which are far | 105 | * Certain Logitech keyboards send in report #3 keys which are far |
46 | * above the logical maximum described in descriptor. This extends | 106 | * above the logical maximum described in descriptor. This extends |
@@ -74,6 +134,18 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
74 | rdesc[47] = 0x95; | 134 | rdesc[47] = 0x95; |
75 | rdesc[48] = 0x0B; | 135 | rdesc[48] = 0x0B; |
76 | } | 136 | } |
137 | |||
138 | switch (hdev->product) { | ||
139 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | ||
140 | if (*rsize == DFP_RDESC_ORIG_SIZE) { | ||
141 | hid_info(hdev, | ||
142 | "fixing up Logitech Driving Force Pro report descriptor\n"); | ||
143 | rdesc = dfp_rdesc_fixed; | ||
144 | *rsize = sizeof(dfp_rdesc_fixed); | ||
145 | } | ||
146 | break; | ||
147 | } | ||
148 | |||
77 | return rdesc; | 149 | return rdesc; |
78 | } | 150 | } |
79 | 151 | ||
@@ -380,7 +452,7 @@ static const struct hid_device_id lg_devices[] = { | |||
380 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), | 452 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), |
381 | .driver_data = LG_FF }, | 453 | .driver_data = LG_FF }, |
382 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), | 454 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), |
383 | .driver_data = LG_FF }, | 455 | .driver_data = LG_NOGET | LG_FF }, |
384 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), | 456 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), |
385 | .driver_data = LG_FF4 }, | 457 | .driver_data = LG_FF4 }, |
386 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), | 458 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), |