@@ -287,11 +287,17 @@ struct dualsense_output_report {
287287
288288#define DS4_INPUT_REPORT_USB 0x01
289289#define DS4_INPUT_REPORT_USB_SIZE 64
290+ #define DS4_INPUT_REPORT_BT 0x11
291+ #define DS4_INPUT_REPORT_BT_SIZE 78
290292#define DS4_OUTPUT_REPORT_USB 0x05
291293#define DS4_OUTPUT_REPORT_USB_SIZE 32
294+ #define DS4_OUTPUT_REPORT_BT 0x11
295+ #define DS4_OUTPUT_REPORT_BT_SIZE 78
292296
293297#define DS4_FEATURE_REPORT_CALIBRATION 0x02
294298#define DS4_FEATURE_REPORT_CALIBRATION_SIZE 37
299+ #define DS4_FEATURE_REPORT_CALIBRATION_BT 0x05
300+ #define DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE 41
295301#define DS4_FEATURE_REPORT_FIRMWARE_INFO 0xa3
296302#define DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE 49
297303#define DS4_FEATURE_REPORT_PAIRING_INFO 0x12
@@ -310,6 +316,9 @@ struct dualsense_output_report {
310316/* Battery status within batery_status field. */
311317#define DS4_BATTERY_STATUS_FULL 11
312318
319+ #define DS4_OUTPUT_HWCTL_CRC32 0x40
320+ #define DS4_OUTPUT_HWCTL_HID 0x80
321+
313322/* Flags for DualShock4 output report. */
314323#define DS4_OUTPUT_VALID_FLAG0_MOTOR 0x01
315324#define DS4_OUTPUT_VALID_FLAG0_LED 0x02
@@ -401,6 +410,17 @@ struct dualshock4_input_report_usb {
401410} __packed ;
402411static_assert (sizeof (struct dualshock4_input_report_usb ) == DS4_INPUT_REPORT_USB_SIZE );
403412
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+
404424/* Common data between Bluetooth and USB DualShock4 output reports. */
405425struct dualshock4_output_report_common {
406426 uint8_t valid_flag0 ;
@@ -425,6 +445,16 @@ struct dualshock4_output_report_usb {
425445} __packed ;
426446static_assert (sizeof (struct dualshock4_output_report_usb ) == DS4_OUTPUT_REPORT_USB_SIZE );
427447
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+
428458/*
429459 * The DualShock4 has a main output report used to control most features. It is
430460 * largely the same between Bluetooth and USB except for different headers and CRC.
@@ -434,6 +464,8 @@ struct dualshock4_output_report {
434464 uint8_t * data ; /* Start of data */
435465 uint8_t len ; /* Size of output report */
436466
467+ /* Points to Bluetooth data payload in case for a Bluetooth report else NULL. */
468+ struct dualshock4_output_report_bt * bt ;
437469 /* Points to USB data payload in case for a USB report else NULL. */
438470 struct dualshock4_output_report_usb * usb ;
439471 /* Points to common section of report, so past any headers. */
@@ -1646,26 +1678,49 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
16461678 int ret = 0 ;
16471679 uint8_t * buf ;
16481680
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 ;
16521685
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+ }
16581703 }
16591704
16601705 gyro_pitch_bias = get_unaligned_le16 (& buf [1 ]);
16611706 gyro_yaw_bias = get_unaligned_le16 (& buf [3 ]);
16621707 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+ }
16691724 gyro_speed_plus = get_unaligned_le16 (& buf [19 ]);
16701725 gyro_speed_minus = get_unaligned_le16 (& buf [21 ]);
16711726 acc_x_plus = get_unaligned_le16 (& buf [23 ]);
@@ -1731,8 +1786,11 @@ static int dualshock4_get_firmware_info(struct dualshock4 *ds4)
17311786 if (!buf )
17321787 return - ENOMEM ;
17331788
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+ */
17341792 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 );
17361794 if (ret ) {
17371795 hid_err (ds4 -> base .hdev , "Failed to retrieve DualShock4 firmware info: %d\n" , ret );
17381796 goto err_free ;
@@ -1748,21 +1806,38 @@ static int dualshock4_get_firmware_info(struct dualshock4 *ds4)
17481806
17491807static int dualshock4_get_mac_address (struct dualshock4 * ds4 )
17501808{
1809+ struct hid_device * hdev = ds4 -> base .hdev ;
17511810 uint8_t * buf ;
17521811 int ret = 0 ;
17531812
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+ }
17571824
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 ]);
17641835
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+ }
17661841
17671842err_free :
17681843 kfree (buf );
@@ -1859,14 +1934,26 @@ static void dualshock4_init_output_report(struct dualshock4 *ds4,
18591934{
18601935 struct hid_device * hdev = ds4 -> base .hdev ;
18611936
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 */
18631949 struct dualshock4_output_report_usb * usb = buf ;
18641950
18651951 memset (usb , 0 , sizeof (* usb ));
18661952 usb -> report_id = DS4_OUTPUT_REPORT_USB ;
18671953
18681954 rp -> data = buf ;
18691955 rp -> len = sizeof (* usb );
1956+ rp -> bt = NULL ;
18701957 rp -> usb = usb ;
18711958 rp -> common = & usb -> common ;
18721959 }
@@ -1913,6 +2000,22 @@ static void dualshock4_output_worker(struct work_struct *work)
19132000
19142001 spin_unlock_irqrestore (& ds4 -> base .lock , flags );
19152002
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+
19162019 hid_hw_output_report (ds4 -> base .hdev , report .data , report .len );
19172020}
19182021
@@ -1940,6 +2043,19 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
19402043 ds4_report = & usb -> common ;
19412044 num_touch_reports = usb -> num_touch_reports ;
19422045 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 ;
19432059 } else {
19442060 hid_err (hdev , "Unhandled reportID=%d\n" , report -> id );
19452061 return -1 ;
@@ -2354,7 +2470,9 @@ static void ps_remove(struct hid_device *hdev)
23542470
23552471static const struct hid_device_id ps_devices [] = {
23562472 /* Sony DualShock 4 controllers for PS4 */
2473+ { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER ) },
23572474 { 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 ) },
23582476 { HID_USB_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 ) },
23592477 /* Sony DualSense controllers for PS5 */
23602478 { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER ) },
0 commit comments