Skip to content

Commit eb9a30b

Browse files
committed
Force HID descriptor when not referrencing 0x80 output channel
1 parent 0a315b4 commit eb9a30b

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

drivers/hid/hid-nintendo.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,100 @@ static const u16 JC_IMU_GYRO_RES_PER_DPS = 14247; /* (14.247*1000) */
176176
static const u16 JC_IMU_GYRO_FUZZ = 10;
177177
static const u16 JC_IMU_GYRO_FLAT /*= 0*/;
178178

179+
static u8 jc_desc[] = {
180+
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
181+
0x15, 0x00, // Logical Minimum (0)
182+
0x09, 0x04, // Usage (Joystick)
183+
0xA1, 0x01, // Collection (Application)
184+
0x85, 0x30, // Report ID (48)
185+
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
186+
0x05, 0x09, // Usage Page (Button)
187+
0x19, 0x01, // Usage Minimum (0x01)
188+
0x29, 0x0A, // Usage Maximum (0x0A)
189+
0x15, 0x00, // Logical Minimum (0)
190+
0x25, 0x01, // Logical Maximum (1)
191+
0x75, 0x01, // Report Size (1)
192+
0x95, 0x0A, // Report Count (10)
193+
0x55, 0x00, // Unit Exponent (0)
194+
0x65, 0x00, // Unit (None)
195+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
196+
0x05, 0x09, // Usage Page (Button)
197+
0x19, 0x0B, // Usage Minimum (0x0B)
198+
0x29, 0x0E, // Usage Maximum (0x0E)
199+
0x15, 0x00, // Logical Minimum (0)
200+
0x25, 0x01, // Logical Maximum (1)
201+
0x75, 0x01, // Report Size (1)
202+
0x95, 0x04, // Report Count (4)
203+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
204+
0x75, 0x01, // Report Size (1)
205+
0x95, 0x02, // Report Count (2)
206+
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
207+
0x0B, 0x01, 0x00, 0x01, 0x00, // Usage (0x010001)
208+
0xA1, 0x00, // Collection (Physical)
209+
0x0B, 0x30, 0x00, 0x01, 0x00, // Usage (0x010030)
210+
0x0B, 0x31, 0x00, 0x01, 0x00, // Usage (0x010031)
211+
0x0B, 0x32, 0x00, 0x01, 0x00, // Usage (0x010032)
212+
0x0B, 0x35, 0x00, 0x01, 0x00, // Usage (0x010035)
213+
0x15, 0x00, // Logical Minimum (0)
214+
0x27, 0xFF, 0xFF, 0x00, 0x00, // Logical Maximum (65534)
215+
0x75, 0x10, // Report Size (16)
216+
0x95, 0x04, // Report Count (4)
217+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
218+
0xC0, // End Collection
219+
0x0B, 0x39, 0x00, 0x01, 0x00, // Usage (0x010039)
220+
0x15, 0x00, // Logical Minimum (0)
221+
0x25, 0x07, // Logical Maximum (7)
222+
0x35, 0x00, // Physical Minimum (0)
223+
0x46, 0x3B, 0x01, // Physical Maximum (315)
224+
0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter)
225+
0x75, 0x04, // Report Size (4)
226+
0x95, 0x01, // Report Count (1) Data,Var,Abs,No Wrap,Linear,Preferred State,Null State
227+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
228+
0x05, 0x09, // Usage Page (Button)
229+
0x19, 0x0F, // Usage Minimum (0x0F)
230+
0x29, 0x12, // Usage Maximum (0x12)
231+
0x15, 0x00, // Logical Minimum (0)
232+
0x25, 0x01, // Logical Maximum (1)
233+
0x75, 0x01, // Report Size (1)
234+
0x95, 0x04, // Report Count (4)
235+
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
236+
0x75, 0x08, // Report Size (8)
237+
0x95, 0x34, // Report Count (52)
238+
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
239+
0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
240+
0x85, 0x21, // Report ID (33)
241+
0x09, 0x01, // Usage (0x01)
242+
0x75, 0x08, // Report Size (8)
243+
0x95, 0x3F, // Report Count (63)
244+
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
245+
0x85, 0x81, // Report ID (-127)
246+
0x09, 0x02, // Usage (0x02)
247+
0x75, 0x08, // Report Size (8)
248+
0x95, 0x3F, // Report Count (63)
249+
0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
250+
0x85, 0x01, // Report ID (1)
251+
0x09, 0x03, // Usage (0x03)
252+
0x75, 0x08, // Report Size (8)
253+
0x95, 0x3F, // Report Count (63)
254+
0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
255+
0x85, 0x10, // Report ID (16)
256+
0x09, 0x04, // Usage (0x04)
257+
0x75, 0x08, // Report Size (8)
258+
0x95, 0x3F, // Report Count (63)
259+
0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
260+
0x85, 0x80, // Report ID (-128)
261+
0x09, 0x05, // Usage (0x05)
262+
0x75, 0x08, // Report Size (8)
263+
0x95, 0x3F, // Report Count (63)
264+
0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
265+
0x85, 0x82, // Report ID (-126)
266+
0x09, 0x06, // Usage (0x06)
267+
0x75, 0x08, // Report Size (8)
268+
0x95, 0x3F, // Report Count (63)
269+
0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
270+
0xC0, // End Collection
271+
};
272+
179273
/* frequency/amplitude tables for rumble */
180274
struct joycon_rumble_freq_data {
181275
u16 high;
@@ -2246,6 +2340,31 @@ static void nintendo_hid_remove(struct hid_device *hdev)
22462340
hid_hw_stop(hdev);
22472341
}
22482342

2343+
static inline u8* nintendo_hid_report_fixup(struct hid_device *hdev, u8 *buf,
2344+
unsigned int *size)
2345+
{
2346+
static const char subcmd_report_descr[] = {
2347+
0x85, 0x80, // Report ID (-128)
2348+
0x09, 0x05, // Usage (0x05)
2349+
0x75, 0x08, // Report Size (8)
2350+
0x95, 0x3F, // Report Count (63)
2351+
0x91, 0x83, // Output (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Volatile)
2352+
0x00, // To use with strpos
2353+
};
2354+
2355+
char* subcmd_report_pos = strnstr(buf, subcmd_report_descr, *size);
2356+
2357+
if (subcmd_report_pos != NULL) {
2358+
/* we found our subcmd report */
2359+
return buf;
2360+
}
2361+
2362+
/* Force standard report */
2363+
hid_warn(hdev, "Invalid report, forcing standard one");
2364+
*size = sizeof(jc_desc);
2365+
return jc_desc;
2366+
}
2367+
22492368
static const struct hid_device_id nintendo_hid_devices[] = {
22502369
{ HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO,
22512370
USB_DEVICE_ID_NINTENDO_PROCON) },
@@ -2267,6 +2386,7 @@ static struct hid_driver nintendo_hid_driver = {
22672386
.probe = nintendo_hid_probe,
22682387
.remove = nintendo_hid_remove,
22692388
.raw_event = nintendo_hid_event,
2389+
.report_fixup = nintendo_hid_report_fixup,
22702390
};
22712391
module_hid_driver(nintendo_hid_driver);
22722392

0 commit comments

Comments
 (0)