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 | |
| 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>
| -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 ), |
