@@ -176,6 +176,100 @@ static const u16 JC_IMU_GYRO_RES_PER_DPS = 14247; /* (14.247*1000) */
176176static const u16 JC_IMU_GYRO_FUZZ = 10 ;
177177static 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 */
180274struct 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+
22492368static 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};
22712391module_hid_driver (nintendo_hid_driver );
22722392
0 commit comments