@@ -287,11 +287,17 @@ struct dualsense_output_report {
287
287
288
288
#define DS4_INPUT_REPORT_USB 0x01
289
289
#define DS4_INPUT_REPORT_USB_SIZE 64
290
+ #define DS4_INPUT_REPORT_BT 0x11
291
+ #define DS4_INPUT_REPORT_BT_SIZE 78
290
292
#define DS4_OUTPUT_REPORT_USB 0x05
291
293
#define DS4_OUTPUT_REPORT_USB_SIZE 32
294
+ #define DS4_OUTPUT_REPORT_BT 0x11
295
+ #define DS4_OUTPUT_REPORT_BT_SIZE 78
292
296
293
297
#define DS4_FEATURE_REPORT_CALIBRATION 0x02
294
298
#define DS4_FEATURE_REPORT_CALIBRATION_SIZE 37
299
+ #define DS4_FEATURE_REPORT_CALIBRATION_BT 0x05
300
+ #define DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE 41
295
301
#define DS4_FEATURE_REPORT_FIRMWARE_INFO 0xa3
296
302
#define DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE 49
297
303
#define DS4_FEATURE_REPORT_PAIRING_INFO 0x12
@@ -310,6 +316,9 @@ struct dualsense_output_report {
310
316
/* Battery status within batery_status field. */
311
317
#define DS4_BATTERY_STATUS_FULL 11
312
318
319
+ #define DS4_OUTPUT_HWCTL_CRC32 0x40
320
+ #define DS4_OUTPUT_HWCTL_HID 0x80
321
+
313
322
/* Flags for DualShock4 output report. */
314
323
#define DS4_OUTPUT_VALID_FLAG0_MOTOR 0x01
315
324
#define DS4_OUTPUT_VALID_FLAG0_LED 0x02
@@ -401,6 +410,17 @@ struct dualshock4_input_report_usb {
401
410
} __packed ;
402
411
static_assert (sizeof (struct dualshock4_input_report_usb ) == DS4_INPUT_REPORT_USB_SIZE );
403
412
413
+ struct dualshock4_input_report_bt {
414
+ uint8_t report_id ; /* 0x11 */
415
+ uint8_t reserved [2 ];
416
+ struct dualshock4_input_report_common common ;
417
+ uint8_t num_touch_reports ;
418
+ struct dualshock4_touch_report touch_reports [4 ]; /* BT has 4 compared to 3 for USB */
419
+ uint8_t reserved2 [2 ];
420
+ __le32 crc32 ;
421
+ } __packed ;
422
+ static_assert (sizeof (struct dualshock4_input_report_bt ) == DS4_INPUT_REPORT_BT_SIZE );
423
+
404
424
/* Common data between Bluetooth and USB DualShock4 output reports. */
405
425
struct dualshock4_output_report_common {
406
426
uint8_t valid_flag0 ;
@@ -425,6 +445,16 @@ struct dualshock4_output_report_usb {
425
445
} __packed ;
426
446
static_assert (sizeof (struct dualshock4_output_report_usb ) == DS4_OUTPUT_REPORT_USB_SIZE );
427
447
448
+ struct dualshock4_output_report_bt {
449
+ uint8_t report_id ; /* 0x11 */
450
+ uint8_t hw_control ;
451
+ uint8_t audio_control ;
452
+ struct dualshock4_output_report_common common ;
453
+ uint8_t reserved [61 ];
454
+ __le32 crc32 ;
455
+ } __packed ;
456
+ static_assert (sizeof (struct dualshock4_output_report_bt ) == DS4_OUTPUT_REPORT_BT_SIZE );
457
+
428
458
/*
429
459
* The DualShock4 has a main output report used to control most features. It is
430
460
* largely the same between Bluetooth and USB except for different headers and CRC.
@@ -434,6 +464,8 @@ struct dualshock4_output_report {
434
464
uint8_t * data ; /* Start of data */
435
465
uint8_t len ; /* Size of output report */
436
466
467
+ /* Points to Bluetooth data payload in case for a Bluetooth report else NULL. */
468
+ struct dualshock4_output_report_bt * bt ;
437
469
/* Points to USB data payload in case for a USB report else NULL. */
438
470
struct dualshock4_output_report_usb * usb ;
439
471
/* Points to common section of report, so past any headers. */
@@ -1646,26 +1678,49 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
1646
1678
int ret = 0 ;
1647
1679
uint8_t * buf ;
1648
1680
1649
- buf = kzalloc (DS4_FEATURE_REPORT_CALIBRATION_SIZE , GFP_KERNEL );
1650
- if (!buf )
1651
- return - ENOMEM ;
1681
+ if (ds4 -> base .hdev -> bus == BUS_USB ) {
1682
+ buf = kzalloc (DS4_FEATURE_REPORT_CALIBRATION_SIZE , GFP_KERNEL );
1683
+ if (!buf )
1684
+ return - ENOMEM ;
1652
1685
1653
- ret = ps_get_report (hdev , DS4_FEATURE_REPORT_CALIBRATION , buf ,
1654
- DS4_FEATURE_REPORT_CALIBRATION_SIZE , true);
1655
- if (ret ) {
1656
- hid_err (hdev , "Failed to retrieve DualShock4 calibration info: %d\n" , ret );
1657
- goto err_free ;
1686
+ ret = ps_get_report (hdev , DS4_FEATURE_REPORT_CALIBRATION , buf ,
1687
+ DS4_FEATURE_REPORT_CALIBRATION_SIZE , true);
1688
+ if (ret ) {
1689
+ hid_err (hdev , "Failed to retrieve DualShock4 calibration info: %d\n" , ret );
1690
+ goto err_free ;
1691
+ }
1692
+ } else { /* Bluetooth */
1693
+ buf = kzalloc (DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE , GFP_KERNEL );
1694
+ if (!buf )
1695
+ return - ENOMEM ;
1696
+
1697
+ ret = ps_get_report (hdev , DS4_FEATURE_REPORT_CALIBRATION_BT , buf ,
1698
+ DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE , true);
1699
+ if (ret ) {
1700
+ hid_err (hdev , "Failed to retrieve DualShock4 calibration info: %d\n" , ret );
1701
+ goto err_free ;
1702
+ }
1658
1703
}
1659
1704
1660
1705
gyro_pitch_bias = get_unaligned_le16 (& buf [1 ]);
1661
1706
gyro_yaw_bias = get_unaligned_le16 (& buf [3 ]);
1662
1707
gyro_roll_bias = get_unaligned_le16 (& buf [5 ]);
1663
- gyro_pitch_plus = get_unaligned_le16 (& buf [7 ]);
1664
- gyro_pitch_minus = get_unaligned_le16 (& buf [9 ]);
1665
- gyro_yaw_plus = get_unaligned_le16 (& buf [11 ]);
1666
- gyro_yaw_minus = get_unaligned_le16 (& buf [13 ]);
1667
- gyro_roll_plus = get_unaligned_le16 (& buf [15 ]);
1668
- gyro_roll_minus = get_unaligned_le16 (& buf [17 ]);
1708
+ if (ds4 -> base .hdev -> bus == BUS_USB ) {
1709
+ gyro_pitch_plus = get_unaligned_le16 (& buf [7 ]);
1710
+ gyro_pitch_minus = get_unaligned_le16 (& buf [9 ]);
1711
+ gyro_yaw_plus = get_unaligned_le16 (& buf [11 ]);
1712
+ gyro_yaw_minus = get_unaligned_le16 (& buf [13 ]);
1713
+ gyro_roll_plus = get_unaligned_le16 (& buf [15 ]);
1714
+ gyro_roll_minus = get_unaligned_le16 (& buf [17 ]);
1715
+ } else {
1716
+ /* BT + Dongle */
1717
+ gyro_pitch_plus = get_unaligned_le16 (& buf [7 ]);
1718
+ gyro_yaw_plus = get_unaligned_le16 (& buf [9 ]);
1719
+ gyro_roll_plus = get_unaligned_le16 (& buf [11 ]);
1720
+ gyro_pitch_minus = get_unaligned_le16 (& buf [13 ]);
1721
+ gyro_yaw_minus = get_unaligned_le16 (& buf [15 ]);
1722
+ gyro_roll_minus = get_unaligned_le16 (& buf [17 ]);
1723
+ }
1669
1724
gyro_speed_plus = get_unaligned_le16 (& buf [19 ]);
1670
1725
gyro_speed_minus = get_unaligned_le16 (& buf [21 ]);
1671
1726
acc_x_plus = get_unaligned_le16 (& buf [23 ]);
@@ -1731,8 +1786,11 @@ static int dualshock4_get_firmware_info(struct dualshock4 *ds4)
1731
1786
if (!buf )
1732
1787
return - ENOMEM ;
1733
1788
1789
+ /* Note USB and BT support the same feature report, but this report
1790
+ * lacks CRC support, so must be disabled in ps_get_report.
1791
+ */
1734
1792
ret = ps_get_report (ds4 -> base .hdev , DS4_FEATURE_REPORT_FIRMWARE_INFO , buf ,
1735
- DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE , true );
1793
+ DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE , false );
1736
1794
if (ret ) {
1737
1795
hid_err (ds4 -> base .hdev , "Failed to retrieve DualShock4 firmware info: %d\n" , ret );
1738
1796
goto err_free ;
@@ -1748,21 +1806,38 @@ static int dualshock4_get_firmware_info(struct dualshock4 *ds4)
1748
1806
1749
1807
static int dualshock4_get_mac_address (struct dualshock4 * ds4 )
1750
1808
{
1809
+ struct hid_device * hdev = ds4 -> base .hdev ;
1751
1810
uint8_t * buf ;
1752
1811
int ret = 0 ;
1753
1812
1754
- buf = kzalloc (DS4_FEATURE_REPORT_PAIRING_INFO_SIZE , GFP_KERNEL );
1755
- if (!buf )
1756
- return - ENOMEM ;
1813
+ if (hdev -> bus == BUS_USB ) {
1814
+ buf = kzalloc (DS4_FEATURE_REPORT_PAIRING_INFO_SIZE , GFP_KERNEL );
1815
+ if (!buf )
1816
+ return - ENOMEM ;
1817
+
1818
+ ret = ps_get_report (hdev , DS4_FEATURE_REPORT_PAIRING_INFO , buf ,
1819
+ DS4_FEATURE_REPORT_PAIRING_INFO_SIZE , false);
1820
+ if (ret ) {
1821
+ hid_err (hdev , "Failed to retrieve DualShock4 pairing info: %d\n" , ret );
1822
+ goto err_free ;
1823
+ }
1757
1824
1758
- ret = ps_get_report (ds4 -> base .hdev , DS4_FEATURE_REPORT_PAIRING_INFO , buf ,
1759
- DS4_FEATURE_REPORT_PAIRING_INFO_SIZE , true);
1760
- if (ret ) {
1761
- hid_err (ds4 -> base .hdev , "Failed to retrieve DualShock4 pairing info: %d\n" , ret );
1762
- goto err_free ;
1763
- }
1825
+ memcpy (ds4 -> base .mac_address , & buf [1 ], sizeof (ds4 -> base .mac_address ));
1826
+ } else {
1827
+ /* Rely on HIDP for Bluetooth */
1828
+ if (strlen (hdev -> uniq ) != 17 )
1829
+ return - EINVAL ;
1830
+
1831
+ ret = sscanf (hdev -> uniq , "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx" ,
1832
+ & ds4 -> base .mac_address [5 ], & ds4 -> base .mac_address [4 ],
1833
+ & ds4 -> base .mac_address [3 ], & ds4 -> base .mac_address [2 ],
1834
+ & ds4 -> base .mac_address [1 ], & ds4 -> base .mac_address [0 ]);
1764
1835
1765
- memcpy (ds4 -> base .mac_address , & buf [1 ], sizeof (ds4 -> base .mac_address ));
1836
+ if (ret != sizeof (ds4 -> base .mac_address ))
1837
+ return - EINVAL ;
1838
+
1839
+ ret = 0 ;
1840
+ }
1766
1841
1767
1842
err_free :
1768
1843
kfree (buf );
@@ -1859,14 +1934,26 @@ static void dualshock4_init_output_report(struct dualshock4 *ds4,
1859
1934
{
1860
1935
struct hid_device * hdev = ds4 -> base .hdev ;
1861
1936
1862
- if (hdev -> bus == BUS_USB ) {
1937
+ if (hdev -> bus == BUS_BLUETOOTH ) {
1938
+ struct dualshock4_output_report_bt * bt = buf ;
1939
+
1940
+ memset (bt , 0 , sizeof (* bt ));
1941
+ bt -> report_id = DS4_OUTPUT_REPORT_BT ;
1942
+
1943
+ rp -> data = buf ;
1944
+ rp -> len = sizeof (* bt );
1945
+ rp -> bt = bt ;
1946
+ rp -> usb = NULL ;
1947
+ rp -> common = & bt -> common ;
1948
+ } else { /* USB */
1863
1949
struct dualshock4_output_report_usb * usb = buf ;
1864
1950
1865
1951
memset (usb , 0 , sizeof (* usb ));
1866
1952
usb -> report_id = DS4_OUTPUT_REPORT_USB ;
1867
1953
1868
1954
rp -> data = buf ;
1869
1955
rp -> len = sizeof (* usb );
1956
+ rp -> bt = NULL ;
1870
1957
rp -> usb = usb ;
1871
1958
rp -> common = & usb -> common ;
1872
1959
}
@@ -1913,6 +2000,22 @@ static void dualshock4_output_worker(struct work_struct *work)
1913
2000
1914
2001
spin_unlock_irqrestore (& ds4 -> base .lock , flags );
1915
2002
2003
+ /* Bluetooth packets need additional flags as well as a CRC in the last 4 bytes. */
2004
+ if (report .bt ) {
2005
+ uint32_t crc ;
2006
+ uint8_t seed = PS_OUTPUT_CRC32_SEED ;
2007
+
2008
+ /* Hardware control flags need to set to let the device know
2009
+ * there is HID data as well as CRC.
2010
+ */
2011
+ report .bt -> hw_control = DS4_OUTPUT_HWCTL_HID | DS4_OUTPUT_HWCTL_CRC32 ;
2012
+
2013
+ crc = crc32_le (0xFFFFFFFF , & seed , 1 );
2014
+ crc = ~crc32_le (crc , report .data , report .len - 4 );
2015
+
2016
+ report .bt -> crc32 = cpu_to_le32 (crc );
2017
+ }
2018
+
1916
2019
hid_hw_output_report (ds4 -> base .hdev , report .data , report .len );
1917
2020
}
1918
2021
@@ -1940,6 +2043,19 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
1940
2043
ds4_report = & usb -> common ;
1941
2044
num_touch_reports = usb -> num_touch_reports ;
1942
2045
touch_reports = usb -> touch_reports ;
2046
+ } else if (hdev -> bus == BUS_BLUETOOTH && report -> id == DS4_INPUT_REPORT_BT &&
2047
+ size == DS4_INPUT_REPORT_BT_SIZE ) {
2048
+ struct dualshock4_input_report_bt * bt = (struct dualshock4_input_report_bt * )data ;
2049
+
2050
+ /* Last 4 bytes of input report contains CRC. */
2051
+ if (!ps_check_crc32 (PS_INPUT_CRC32_SEED , data , size - 4 , bt -> crc32 )) {
2052
+ hid_err (hdev , "DualShock4 input CRC's check failed\n" );
2053
+ return - EILSEQ ;
2054
+ }
2055
+
2056
+ ds4_report = & bt -> common ;
2057
+ num_touch_reports = bt -> num_touch_reports ;
2058
+ touch_reports = bt -> touch_reports ;
1943
2059
} else {
1944
2060
hid_err (hdev , "Unhandled reportID=%d\n" , report -> id );
1945
2061
return -1 ;
@@ -2354,7 +2470,9 @@ static void ps_remove(struct hid_device *hdev)
2354
2470
2355
2471
static const struct hid_device_id ps_devices [] = {
2356
2472
/* Sony DualShock 4 controllers for PS4 */
2473
+ { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER ) },
2357
2474
{ HID_USB_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER ) },
2475
+ { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 ) },
2358
2476
{ HID_USB_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 ) },
2359
2477
/* Sony DualSense controllers for PS5 */
2360
2478
{ HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER ) },
0 commit comments