diff options
author | Paul Sbarra <sbarra.paul@gmail.com> | 2013-02-17 12:53:13 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-02-19 07:50:10 -0500 |
commit | 54bfe3f0dab2b2f0ac629690f187537d95adeb4f (patch) | |
tree | d6d03915a5763f7061e9882e0941eca49612692d /drivers/hid | |
parent | cf5425bfcd6909f9831a00bc06ccb9a5b163766a (diff) |
HID: logitech: add report descriptor for Driving Force wheel
This is the original report descriptor as reported by lsusb -vd 046d:c294.
Signed-off-by: Paul Sbarra <sbarra.paul@gmail.com>
Signed-off-by: Simon Wood <simon@mungewell.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-lg.c | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a2f8e88b9fa2..6daa1927bf69 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -21,8 +21,10 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/usb.h> | ||
24 | #include <linux/wait.h> | 25 | #include <linux/wait.h> |
25 | 26 | ||
27 | #include "usbhid/usbhid.h" | ||
26 | #include "hid-ids.h" | 28 | #include "hid-ids.h" |
27 | #include "hid-lg.h" | 29 | #include "hid-lg.h" |
28 | 30 | ||
@@ -40,17 +42,83 @@ | |||
40 | #define LG_FF3 0x1000 | 42 | #define LG_FF3 0x1000 |
41 | #define LG_FF4 0x2000 | 43 | #define LG_FF4 0x2000 |
42 | 44 | ||
43 | /* Size of the original descriptor of the Driving Force Pro wheel */ | 45 | /* Size of the original descriptors of the Driving Force (and Pro) wheels */ |
46 | #define DF_RDESC_ORIG_SIZE 130 | ||
44 | #define DFP_RDESC_ORIG_SIZE 97 | 47 | #define DFP_RDESC_ORIG_SIZE 97 |
45 | 48 | ||
46 | /* Fixed report descriptor for Logitech Driving Force Pro wheel controller | 49 | /* Fixed report descriptors for Logitech Driving Force (and Pro) |
50 | * wheel controllers | ||
47 | * | 51 | * |
48 | * The original descriptor hides the separate throttle and brake axes in | 52 | * The original descriptors hide the separate throttle and brake axes in |
49 | * a custom vendor usage page, providing only a combined value as | 53 | * a custom vendor usage page, providing only a combined value as |
50 | * GenericDesktop.Y. | 54 | * GenericDesktop.Y. |
51 | * This descriptor removes the combined Y axis and instead reports | 55 | * These descriptors remove the combined Y axis and instead report |
52 | * separate throttle (Y) and brake (RZ). | 56 | * separate throttle (Y) and brake (RZ). |
53 | */ | 57 | */ |
58 | static __u8 df_rdesc_fixed[] = { | ||
59 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
60 | 0x09, 0x04, /* Usage (Joystik), */ | ||
61 | 0xA1, 0x01, /* Collection (Application), */ | ||
62 | 0xA1, 0x02, /* Collection (Logical), */ | ||
63 | 0x95, 0x01, /* Report Count (1), */ | ||
64 | 0x75, 0x0A, /* Report Size (10), */ | ||
65 | 0x14, /* Logical Minimum (0), */ | ||
66 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
67 | 0x34, /* Physical Minimum (0), */ | ||
68 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
69 | 0x09, 0x30, /* Usage (X), */ | ||
70 | 0x81, 0x02, /* Input (Variable), */ | ||
71 | 0x95, 0x0C, /* Report Count (12), */ | ||
72 | 0x75, 0x01, /* Report Size (1), */ | ||
73 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
74 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
75 | 0x05, 0x09, /* Usage (Buttons), */ | ||
76 | 0x19, 0x01, /* Usage Minimum (1), */ | ||
77 | 0x29, 0x0c, /* Usage Maximum (12), */ | ||
78 | 0x81, 0x02, /* Input (Variable), */ | ||
79 | 0x95, 0x02, /* Report Count (2), */ | ||
80 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ | ||
81 | 0x09, 0x01, /* Usage (?: 1), */ | ||
82 | 0x81, 0x02, /* Input (Variable), */ | ||
83 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
84 | 0x09, 0x31, /* Usage (Y), */ | ||
85 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
86 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
87 | 0x95, 0x01, /* Report Count (1), */ | ||
88 | 0x75, 0x08, /* Report Size (8), */ | ||
89 | 0x81, 0x02, /* Input (Variable), */ | ||
90 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
91 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
92 | 0x75, 0x04, /* Report Size (4), */ | ||
93 | 0x65, 0x14, /* Unit (Degrees), */ | ||
94 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
95 | 0x81, 0x42, /* Input (Variable, Null State), */ | ||
96 | 0x75, 0x01, /* Report Size (1), */ | ||
97 | 0x95, 0x04, /* Report Count (4), */ | ||
98 | 0x65, 0x00, /* Unit (none), */ | ||
99 | 0x06, 0x00, 0xFF, /* Usage Page (Vendor: 65280), */ | ||
100 | 0x09, 0x01, /* Usage (?: 1), */ | ||
101 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
102 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
103 | 0x81, 0x02, /* Input (Variable), */ | ||
104 | 0x95, 0x02, /* Report Count (2), */ | ||
105 | 0x75, 0x08, /* Report Size (8), */ | ||
106 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
107 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
108 | 0x09, 0x02, /* Usage (?: 2), */ | ||
109 | 0x81, 0x02, /* Input (Variable), */ | ||
110 | 0xC0, /* End Collection, */ | ||
111 | 0xA1, 0x02, /* Collection (Logical), */ | ||
112 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
113 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
114 | 0x95, 0x07, /* Report Count (7), */ | ||
115 | 0x75, 0x08, /* Report Size (8), */ | ||
116 | 0x09, 0x03, /* Usage (?: 3), */ | ||
117 | 0x91, 0x02, /* Output (Variable), */ | ||
118 | 0xC0, /* End Collection, */ | ||
119 | 0xC0 /* End Collection */ | ||
120 | }; | ||
121 | |||
54 | static __u8 dfp_rdesc_fixed[] = { | 122 | static __u8 dfp_rdesc_fixed[] = { |
55 | 0x05, 0x01, /* Usage Page (Desktop), */ | 123 | 0x05, 0x01, /* Usage Page (Desktop), */ |
56 | 0x09, 0x04, /* Usage (Joystik), */ | 124 | 0x09, 0x04, /* Usage (Joystik), */ |
@@ -99,7 +167,6 @@ static __u8 dfp_rdesc_fixed[] = { | |||
99 | 0xC0 /* End Collection */ | 167 | 0xC0 /* End Collection */ |
100 | }; | 168 | }; |
101 | 169 | ||
102 | |||
103 | /* | 170 | /* |
104 | * Certain Logitech keyboards send in report #3 keys which are far | 171 | * Certain Logitech keyboards send in report #3 keys which are far |
105 | * above the logical maximum described in descriptor. This extends | 172 | * above the logical maximum described in descriptor. This extends |
@@ -109,6 +176,8 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
109 | unsigned int *rsize) | 176 | unsigned int *rsize) |
110 | { | 177 | { |
111 | struct lg_drv_data *drv_data = hid_get_drvdata(hdev); | 178 | struct lg_drv_data *drv_data = hid_get_drvdata(hdev); |
179 | struct usb_device_descriptor *udesc; | ||
180 | __u16 bcdDevice, rev_maj, rev_min; | ||
112 | 181 | ||
113 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 182 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && |
114 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 183 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
@@ -135,6 +204,28 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
135 | } | 204 | } |
136 | 205 | ||
137 | switch (hdev->product) { | 206 | switch (hdev->product) { |
207 | |||
208 | /* Several wheels report as this id when operating in emulation mode. */ | ||
209 | case USB_DEVICE_ID_LOGITECH_WHEEL: | ||
210 | udesc = &(hid_to_usb_dev(hdev)->descriptor); | ||
211 | if (!udesc) { | ||
212 | hid_err(hdev, "NULL USB device descriptor\n"); | ||
213 | break; | ||
214 | } | ||
215 | bcdDevice = le16_to_cpu(udesc->bcdDevice); | ||
216 | rev_maj = bcdDevice >> 8; | ||
217 | rev_min = bcdDevice & 0xff; | ||
218 | |||
219 | /* Update the report descriptor for only the Driving Force wheel */ | ||
220 | if (rev_maj == 1 && rev_min == 2 && | ||
221 | *rsize == DF_RDESC_ORIG_SIZE) { | ||
222 | hid_info(hdev, | ||
223 | "fixing up Logitech Driving Force report descriptor\n"); | ||
224 | rdesc = df_rdesc_fixed; | ||
225 | *rsize = sizeof(df_rdesc_fixed); | ||
226 | } | ||
227 | break; | ||
228 | |||
138 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: | 229 | case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: |
139 | if (*rsize == DFP_RDESC_ORIG_SIZE) { | 230 | if (*rsize == DFP_RDESC_ORIG_SIZE) { |
140 | hid_info(hdev, | 231 | hid_info(hdev, |