From: Michael Bauer <michael@m-bauer.org>
To: linux-input@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Jiri Kosina <jkosina@suse.cz>
Subject: [PATCH] hid: Fix Logitech Driving Force Pro wheel
Date: Sat, 28 May 2011 20:37:22 +0200 [thread overview]
Message-ID: <201105282037.22888.michael@m-bauer.org> (raw)
Hi,
this is a patch for hid-lg.c which fixes the Logitech Driving Force Pro driver.
It was generated against vanilla 2.6.39.
This patch contains two parts:
- 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>
[1] https://github.com/TripleSpeeder/LTWheelConf
---
--- linux-2.6.39/drivers/hid/hid-lg.c.orig 2011-05-26 22:10:40.099883539
+0200
+++ linux-2.6.39/drivers/hid/hid-lg.c 2011-05-28 20:15:46.368912199 +0200
@@ -41,6 +41,137 @@
#define LG_FF3 0x1000
#define LG_FF4 0x2000
+/* Size of the original descriptor of the Driving Force Pro wheel */
+#define DFP_RDESC_ORIG_SIZE 97
+
+/* Fixed report descriptor for Logitech Driving Force Pro wheel controller
+ *
+ * The original descriptor hides the separate throttle and brake axes in
+ * a custom vendor usage page, providing only a combined value as
+ * GenericDesktop.Y.
+ * This descriptor removes the combined Y axis and instead reports
+ * separate throttle (Y) and brake (RZ).
+ *
+ * This is the original descriptor:
+ *
+ * 0x05, 0x01, // Usage Page (Desktop),
+ * 0x09, 0x04, // Usage (Joystik),
+ * 0xA1, 0x01, // Collection (Application),
+ * 0xA1, 0x02, // Collection (Logical),
+ * 0x95, 0x01, // Report Count (1),
+ * 0x75, 0x0E, // Report Size (14),
+ * 0x15, 0x00, // Logical Minimum (0),
+ * 0x26, 0xFF, 0x3F, // Logical Maximum (16383),
+ * 0x35, 0x00, // Physical Minimum (0),
+ * 0x46, 0xFF, 0x3F, // Physical Maximum (16383),
+ * 0x09, 0x30, // Usage (X),
+ * 0x81, 0x02, // Input (Variable),
+ * 0x95, 0x0E, // Report Count (14),
+ * 0x75, 0x01, // Report Size (1),
+ * 0x25, 0x01, // Logical Maximum (1),
+ * 0x45, 0x01, // Physical Maximum (1),
+ * 0x05, 0x09, // Usage Page (Button),
+ * 0x19, 0x01, // Usage Minimum (01h),
+ * 0x29, 0x0E, // Usage Maximum (0Eh),
+ * 0x81, 0x02, // Input (Variable),
+ * 0x05, 0x01, // Usage Page (Desktop),
+ * 0x95, 0x01, // Report Count (1),
+ * 0x75, 0x04, // Report Size (4),
+ * 0x25, 0x07, // Logical Maximum (7),
+ * 0x46, 0x3B, 0x01, // Physical Maximum (315),
+ * 0x65, 0x14, // Unit (Degrees),
+ * 0x09, 0x39, // Usage (Hat Switch),
+ * 0x81, 0x42, // Input (Variable, Null State),
+ * 0x65, 0x00, // Unit,
+ * 0x95, 0x01, // Report Count (1),
+ * 0x75, 0x08, // Report Size (8),
+ * 0x26, 0xFF, 0x00, // Logical Maximum (255),
+ * 0x46, 0xFF, 0x00, // Physical Maximum (255),
+ * 0x09, 0x31, // Usage (Y),
+ * 0x81, 0x02, // Input (Variable),
+ * 0x06, 0x00, 0xFF, // Usage Page (FF00h),
+ * 0x09, 0x00, // Usage (00h),
+ * 0x95, 0x03, // Report Count (3),
+ * 0x75, 0x08, // Report Size (8),
+ * 0x81, 0x02, // Input (Variable),
+ * 0xC0, // End Collection,
+ * 0xA1, 0x02, // Collection (Logical),
+ * 0x09, 0x02, // Usage (02h),
+ * 0x95, 0x07, // Report Count (7),
+ * 0x91, 0x02, // Output (Variable),
+ * 0xC0, // End Collection,
+ * 0xC0 // End Collection
+ *
+ */
+
+static __u8 dfp_rdesc_fixed[] = {
+0x05, 0x01, /* Usage Page (Desktop), */
+0x09, 0x04, /* Usage (Joystik), */
+0xA1, 0x01, /* Collection (Application), */
+0xA1, 0x02, /* Collection (Logical), */
+0x95, 0x01, /* Report Count (1), */
+0x75, 0x0E, /* Report Size (14), */
+0x14, /* Logical Minimum (0), */
+0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
+0x34, /* Physical Minimum (0), */
+0x46, 0xFF, 0x3F, /* Physical Maximum (16383), */
+0x09, 0x30, /* Usage (X), */
+0x81, 0x02, /* Input (Variable), */
+0x95, 0x0E, /* Report Count (14), */
+0x75, 0x01, /* Report Size (1), */
+0x25, 0x01, /* Logical Maximum (1), */
+0x45, 0x01, /* Physical Maximum (1), */
+0x05, 0x09, /* Usage Page (Button), */
+0x19, 0x01, /* Usage Minimum (01h), */
+0x29, 0x0E, /* Usage Maximum (0Eh), */
+0x81, 0x02, /* Input (Variable), */
+0x05, 0x01, /* Usage Page (Desktop), */
+0x95, 0x01, /* Report Count (1), */
+0x75, 0x04, /* Report Size (4), */
+0x25, 0x07, /* Logical Maximum (7), */
+0x46, 0x3B, 0x01, /* Physical Maximum (315), */
+0x65, 0x14, /* Unit (Degrees), */
+0x09, 0x39, /* Usage (Hat Switch), */
+0x81, 0x42, /* Input (Variable), */
+0x75, 0x01, /* Report Size (1), */
+0x95, 0x08, /* Report Count (8), */
+0x65, 0x00, /* Unit, */
+0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+0x25, 0x01, /* Logical Maximum (1), */
+0x45, 0x01, /* Physical Maximum (1), */
+0x09, 0x01, /* Usage (01h), */
+0x81, 0x02, /* Input (Variable), */
+0x05, 0x01, /* Usage Page (Desktop), */
+0x95, 0x01, /* Report Count (1), */
+0x75, 0x08, /* Report Size (8), */
+0x14, /* Logical Minimum (0), */
+0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+0x34, /* Physical Minimum (0), */
+0x46, 0xFF, 0x00, /* Physical Maximum (255), */
+0x09, 0x31, /* Usage (Y), */
+0x81, 0x02, /* Input (Variable), */
+0x95, 0x01, /* Report Count (1), */
+0x75, 0x08, /* Report Size (8), */
+0x14, /* Logical Minimum (0), */
+0x26, 0xFF, 0x00, /* Logical Maximum (255), */
+0x34, /* Physical Minimum (0), */
+0x46, 0xFF, 0x00, /* Physical Maximum (255), */
+0x09, 0x35, /* Usage (Rz), */
+0x81, 0x02, /* Input (Variable), */
+0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
+0x95, 0x01, /* Report Count (1), */
+0x75, 0x08, /* Report Size (8), */
+0x09, 0x00, /* Usage (00h), */
+0x81, 0x02, /* Input (Variable), */
+0xC0, /* End Collection, */
+0xA1, 0x02, /* Collection (Logical), */
+0x09, 0x02, /* Usage (02h), */
+0x95, 0x07, /* Report Count (7), */
+0x91, 0x02, /* Output (Variable), */
+0xC0, /* End Collection, */
+0xC0 /* End Collection */
+};
+
/*
* Certain Logitech keyboards send in report #3 keys which are far
* above the logical maximum described in descriptor. This extends
@@ -74,6 +205,18 @@ static __u8 *lg_report_fixup(struct hid_
rdesc[47] = 0x95;
rdesc[48] = 0x0B;
}
+
+ switch (hdev->product) {
+ case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
+ if (*rsize == DFP_RDESC_ORIG_SIZE) {
+ hid_info(hdev,
+ "fixing up Logitech Driving Force Pro report
descriptor\n");
+ rdesc = dfp_rdesc_fixed;
+ *rsize = sizeof(dfp_rdesc_fixed);
+ }
+ break;
+ }
+
return rdesc;
}
@@ -378,7 +521,7 @@ static const struct hid_device_id lg_dev
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_G25_WHEEL),
.driver_data = LG_FF },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
- .driver_data = LG_FF },
+ .driver_data = LG_NOGET | LG_FF },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_WII_WHEEL),
.driver_data = LG_FF4 },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
next reply other threads:[~2011-05-28 18:42 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-28 18:37 Michael Bauer [this message]
2011-05-28 21:31 ` [PATCH] hid: Fix Logitech Driving Force Pro wheel simon
2011-05-28 23:47 ` simon
2011-05-29 6:46 ` Michael Bauer
2011-05-29 14:50 ` simon
2011-05-30 6:17 ` Michael Bauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201105282037.22888.michael@m-bauer.org \
--to=michael@m-bauer.org \
--cc=jkosina@suse.cz \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.