aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Praznik <frank.praznik@oh.rr.com>2014-02-05 20:03:45 -0500
committerJiri Kosina <jkosina@suse.cz>2014-02-17 08:11:06 -0500
commitd829674d29d7eb99aeb3ad11eba61d06cda7aff4 (patch)
treebf08005448d0c22121bd6912bd1860185fbeacf7
parent48220237bac3555f2dbba37ccd6f0c1644490269 (diff)
HID: sony: Add modified Dualshock 4 Bluetooth HID descriptor
By default, the Dualshock 4 sends controller data via report 1. Once a valid output report 0x11 is received or a feature report of type 0x02 is requested the controller changes from sending data in report 1 to sending data in report 17, which is unmapped in the default descriptor. The mappings have to be moved to report 17 to let the HID driver properly process the incoming reports. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> Reviewed-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-sony.c214
1 files changed, 214 insertions, 0 deletions
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f93f3ca2c231..362fb45954ea 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -336,6 +336,216 @@ static u8 dualshock4_usb_rdesc[] = {
336 0xC0 /* End Collection */ 336 0xC0 /* End Collection */
337}; 337};
338 338
339/* The default behavior of the Dualshock 4 is to send reports using report
340 * type 1 when running over Bluetooth. However, as soon as it receives a
341 * report of type 17 to set the LEDs or rumble it starts returning it's state
342 * in report 17 instead of 1. Since report 17 is undefined in the default HID
343 * descriptor the button and axis definitions must be moved to report 17 or
344 * the HID layer won't process the received input once a report is sent.
345 */
346static u8 dualshock4_bt_rdesc[] = {
347 0x05, 0x01, /* Usage Page (Desktop), */
348 0x09, 0x05, /* Usage (Gamepad), */
349 0xA1, 0x01, /* Collection (Application), */
350 0x85, 0x01, /* Report ID (1), */
351 0x75, 0x08, /* Report Size (8), */
352 0x95, 0x0A, /* Report Count (9), */
353 0x81, 0x02, /* Input (Variable), */
354 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */
355 0x85, 0x02, /* Report ID (2), */
356 0x09, 0x24, /* Usage (24h), */
357 0x95, 0x24, /* Report Count (36), */
358 0xB1, 0x02, /* Feature (Variable), */
359 0x85, 0xA3, /* Report ID (163), */
360 0x09, 0x25, /* Usage (25h), */
361 0x95, 0x30, /* Report Count (48), */
362 0xB1, 0x02, /* Feature (Variable), */
363 0x85, 0x05, /* Report ID (5), */
364 0x09, 0x26, /* Usage (26h), */
365 0x95, 0x28, /* Report Count (40), */
366 0xB1, 0x02, /* Feature (Variable), */
367 0x85, 0x06, /* Report ID (6), */
368 0x09, 0x27, /* Usage (27h), */
369 0x95, 0x34, /* Report Count (52), */
370 0xB1, 0x02, /* Feature (Variable), */
371 0x85, 0x07, /* Report ID (7), */
372 0x09, 0x28, /* Usage (28h), */
373 0x95, 0x30, /* Report Count (48), */
374 0xB1, 0x02, /* Feature (Variable), */
375 0x85, 0x08, /* Report ID (8), */
376 0x09, 0x29, /* Usage (29h), */
377 0x95, 0x2F, /* Report Count (47), */
378 0xB1, 0x02, /* Feature (Variable), */
379 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */
380 0x85, 0x03, /* Report ID (3), */
381 0x09, 0x21, /* Usage (21h), */
382 0x95, 0x26, /* Report Count (38), */
383 0xB1, 0x02, /* Feature (Variable), */
384 0x85, 0x04, /* Report ID (4), */
385 0x09, 0x22, /* Usage (22h), */
386 0x95, 0x2E, /* Report Count (46), */
387 0xB1, 0x02, /* Feature (Variable), */
388 0x85, 0xF0, /* Report ID (240), */
389 0x09, 0x47, /* Usage (47h), */
390 0x95, 0x3F, /* Report Count (63), */
391 0xB1, 0x02, /* Feature (Variable), */
392 0x85, 0xF1, /* Report ID (241), */
393 0x09, 0x48, /* Usage (48h), */
394 0x95, 0x3F, /* Report Count (63), */
395 0xB1, 0x02, /* Feature (Variable), */
396 0x85, 0xF2, /* Report ID (242), */
397 0x09, 0x49, /* Usage (49h), */
398 0x95, 0x0F, /* Report Count (15), */
399 0xB1, 0x02, /* Feature (Variable), */
400 0x85, 0x11, /* Report ID (17), */
401 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
402 0x09, 0x20, /* Usage (20h), */
403 0x95, 0x02, /* Report Count (2), */
404 0x81, 0x02, /* Input (Variable), */
405 0x05, 0x01, /* Usage Page (Desktop), */
406 0x09, 0x30, /* Usage (X), */
407 0x09, 0x31, /* Usage (Y), */
408 0x09, 0x32, /* Usage (Z), */
409 0x09, 0x35, /* Usage (Rz), */
410 0x15, 0x00, /* Logical Minimum (0), */
411 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
412 0x75, 0x08, /* Report Size (8), */
413 0x95, 0x04, /* Report Count (4), */
414 0x81, 0x02, /* Input (Variable), */
415 0x09, 0x39, /* Usage (Hat Switch), */
416 0x15, 0x00, /* Logical Minimum (0), */
417 0x25, 0x07, /* Logical Maximum (7), */
418 0x75, 0x04, /* Report Size (4), */
419 0x95, 0x01, /* Report Count (1), */
420 0x81, 0x42, /* Input (Variable, Null State), */
421 0x05, 0x09, /* Usage Page (Button), */
422 0x19, 0x01, /* Usage Minimum (01h), */
423 0x29, 0x0E, /* Usage Maximum (0Eh), */
424 0x15, 0x00, /* Logical Minimum (0), */
425 0x25, 0x01, /* Logical Maximum (1), */
426 0x75, 0x01, /* Report Size (1), */
427 0x95, 0x0E, /* Report Count (14), */
428 0x81, 0x02, /* Input (Variable), */
429 0x75, 0x06, /* Report Size (6), */
430 0x95, 0x01, /* Report Count (1), */
431 0x81, 0x01, /* Input (Constant), */
432 0x05, 0x01, /* Usage Page (Desktop), */
433 0x09, 0x33, /* Usage (Rx), */
434 0x09, 0x34, /* Usage (Ry), */
435 0x15, 0x00, /* Logical Minimum (0), */
436 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
437 0x75, 0x08, /* Report Size (8), */
438 0x95, 0x02, /* Report Count (2), */
439 0x81, 0x02, /* Input (Variable), */
440 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
441 0x09, 0x20, /* Usage (20h), */
442 0x95, 0x03, /* Report Count (3), */
443 0x81, 0x02, /* Input (Variable), */
444 0x05, 0x01, /* Usage Page (Desktop), */
445 0x19, 0x40, /* Usage Minimum (40h), */
446 0x29, 0x42, /* Usage Maximum (42h), */
447 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
448 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */
449 0x75, 0x10, /* Report Size (16), */
450 0x95, 0x03, /* Report Count (3), */
451 0x81, 0x02, /* Input (Variable), */
452 0x19, 0x43, /* Usage Minimum (43h), */
453 0x29, 0x45, /* Usage Maximum (45h), */
454 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */
455 0x26, 0x00, 0x40, /* Logical Maximum (16384), */
456 0x95, 0x03, /* Report Count (3), */
457 0x81, 0x02, /* Input (Variable), */
458 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */
459 0x09, 0x20, /* Usage (20h), */
460 0x15, 0x00, /* Logical Minimum (0), */
461 0x26, 0xFF, 0x00, /* Logical Maximum (255), */
462 0x75, 0x08, /* Report Size (8), */
463 0x95, 0x31, /* Report Count (51), */
464 0x81, 0x02, /* Input (Variable), */
465 0x09, 0x21, /* Usage (21h), */
466 0x75, 0x08, /* Report Size (8), */
467 0x95, 0x4D, /* Report Count (77), */
468 0x91, 0x02, /* Output (Variable), */
469 0x85, 0x12, /* Report ID (18), */
470 0x09, 0x22, /* Usage (22h), */
471 0x95, 0x8D, /* Report Count (141), */
472 0x81, 0x02, /* Input (Variable), */
473 0x09, 0x23, /* Usage (23h), */
474 0x91, 0x02, /* Output (Variable), */
475 0x85, 0x13, /* Report ID (19), */
476 0x09, 0x24, /* Usage (24h), */
477 0x95, 0xCD, /* Report Count (205), */
478 0x81, 0x02, /* Input (Variable), */
479 0x09, 0x25, /* Usage (25h), */
480 0x91, 0x02, /* Output (Variable), */
481 0x85, 0x14, /* Report ID (20), */
482 0x09, 0x26, /* Usage (26h), */
483 0x96, 0x0D, 0x01, /* Report Count (269), */
484 0x81, 0x02, /* Input (Variable), */
485 0x09, 0x27, /* Usage (27h), */
486 0x91, 0x02, /* Output (Variable), */
487 0x85, 0x15, /* Report ID (21), */
488 0x09, 0x28, /* Usage (28h), */
489 0x96, 0x4D, 0x01, /* Report Count (333), */
490 0x81, 0x02, /* Input (Variable), */
491 0x09, 0x29, /* Usage (29h), */
492 0x91, 0x02, /* Output (Variable), */
493 0x85, 0x16, /* Report ID (22), */
494 0x09, 0x2A, /* Usage (2Ah), */
495 0x96, 0x8D, 0x01, /* Report Count (397), */
496 0x81, 0x02, /* Input (Variable), */
497 0x09, 0x2B, /* Usage (2Bh), */
498 0x91, 0x02, /* Output (Variable), */
499 0x85, 0x17, /* Report ID (23), */
500 0x09, 0x2C, /* Usage (2Ch), */
501 0x96, 0xCD, 0x01, /* Report Count (461), */
502 0x81, 0x02, /* Input (Variable), */
503 0x09, 0x2D, /* Usage (2Dh), */
504 0x91, 0x02, /* Output (Variable), */
505 0x85, 0x18, /* Report ID (24), */
506 0x09, 0x2E, /* Usage (2Eh), */
507 0x96, 0x0D, 0x02, /* Report Count (525), */
508 0x81, 0x02, /* Input (Variable), */
509 0x09, 0x2F, /* Usage (2Fh), */
510 0x91, 0x02, /* Output (Variable), */
511 0x85, 0x19, /* Report ID (25), */
512 0x09, 0x30, /* Usage (30h), */
513 0x96, 0x22, 0x02, /* Report Count (546), */
514 0x81, 0x02, /* Input (Variable), */
515 0x09, 0x31, /* Usage (31h), */
516 0x91, 0x02, /* Output (Variable), */
517 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */
518 0x85, 0x82, /* Report ID (130), */
519 0x09, 0x22, /* Usage (22h), */
520 0x95, 0x3F, /* Report Count (63), */
521 0xB1, 0x02, /* Feature (Variable), */
522 0x85, 0x83, /* Report ID (131), */
523 0x09, 0x23, /* Usage (23h), */
524 0xB1, 0x02, /* Feature (Variable), */
525 0x85, 0x84, /* Report ID (132), */
526 0x09, 0x24, /* Usage (24h), */
527 0xB1, 0x02, /* Feature (Variable), */
528 0x85, 0x90, /* Report ID (144), */
529 0x09, 0x30, /* Usage (30h), */
530 0xB1, 0x02, /* Feature (Variable), */
531 0x85, 0x91, /* Report ID (145), */
532 0x09, 0x31, /* Usage (31h), */
533 0xB1, 0x02, /* Feature (Variable), */
534 0x85, 0x92, /* Report ID (146), */
535 0x09, 0x32, /* Usage (32h), */
536 0xB1, 0x02, /* Feature (Variable), */
537 0x85, 0x93, /* Report ID (147), */
538 0x09, 0x33, /* Usage (33h), */
539 0xB1, 0x02, /* Feature (Variable), */
540 0x85, 0xA0, /* Report ID (160), */
541 0x09, 0x40, /* Usage (40h), */
542 0xB1, 0x02, /* Feature (Variable), */
543 0x85, 0xA4, /* Report ID (164), */
544 0x09, 0x44, /* Usage (44h), */
545 0xB1, 0x02, /* Feature (Variable), */
546 0xC0 /* End Collection */
547};
548
339static __u8 ps3remote_rdesc[] = { 549static __u8 ps3remote_rdesc[] = {
340 0x05, 0x01, /* GUsagePage Generic Desktop */ 550 0x05, 0x01, /* GUsagePage Generic Desktop */
341 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ 551 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
@@ -591,6 +801,10 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
591 hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); 801 hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
592 rdesc = dualshock4_usb_rdesc; 802 rdesc = dualshock4_usb_rdesc;
593 *rsize = sizeof(dualshock4_usb_rdesc); 803 *rsize = sizeof(dualshock4_usb_rdesc);
804 } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
805 hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
806 rdesc = dualshock4_bt_rdesc;
807 *rsize = sizeof(dualshock4_bt_rdesc);
594 } 808 }
595 809
596 /* The HID descriptor exposed over BT has a trailing zero byte */ 810 /* The HID descriptor exposed over BT has a trailing zero byte */