diff options
Diffstat (limited to 'drivers/hid/hid-lg.c')
-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 ), |