@@ -46,6 +46,7 @@ struct ps_device {
4646 uint32_t fw_version ;
4747
4848 int (* parse_report )(struct ps_device * dev , struct hid_report * report , u8 * data , int size );
49+ void (* remove )(struct ps_device * dev );
4950};
5051
5152/* Calibration data for playstation motion sensors. */
@@ -107,6 +108,9 @@ struct ps_led_info {
107108#define DS_STATUS_CHARGING GENMASK(7, 4)
108109#define DS_STATUS_CHARGING_SHIFT 4
109110
111+ /* Feature version from DualSense Firmware Info report. */
112+ #define DS_FEATURE_VERSION (major , minor ) ((major & 0xff) << 8 | (minor & 0xff))
113+
110114/*
111115 * Status of a DualSense touch point contact.
112116 * Contact IDs, with highest bit set are 'inactive'
@@ -125,6 +129,7 @@ struct ps_led_info {
125129#define DS_OUTPUT_VALID_FLAG1_RELEASE_LEDS BIT(3)
126130#define DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE BIT(4)
127131#define DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE BIT(1)
132+ #define DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 BIT(2)
128133#define DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE BIT(4)
129134#define DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT BIT(1)
130135
@@ -142,6 +147,9 @@ struct dualsense {
142147 struct input_dev * sensors ;
143148 struct input_dev * touchpad ;
144149
150+ /* Update version is used as a feature/capability version. */
151+ uint16_t update_version ;
152+
145153 /* Calibration data for accelerometer and gyroscope. */
146154 struct ps_calibration_data accel_calib_data [3 ];
147155 struct ps_calibration_data gyro_calib_data [3 ];
@@ -152,6 +160,7 @@ struct dualsense {
152160 uint32_t sensor_timestamp_us ;
153161
154162 /* Compatible rumble state */
163+ bool use_vibration_v2 ;
155164 bool update_rumble ;
156165 uint8_t motor_left ;
157166 uint8_t motor_right ;
@@ -174,6 +183,7 @@ struct dualsense {
174183 struct led_classdev player_leds [5 ];
175184
176185 struct work_struct output_worker ;
186+ bool output_worker_initialized ;
177187 void * output_report_dmabuf ;
178188 uint8_t output_seq ; /* Sequence number for output report. */
179189};
@@ -299,6 +309,7 @@ static const struct {int x; int y; } ps_gamepad_hat_mapping[] = {
299309 {0 , 0 },
300310};
301311
312+ static inline void dualsense_schedule_work (struct dualsense * ds );
302313static void dualsense_set_lightbar (struct dualsense * ds , uint8_t red , uint8_t green , uint8_t blue );
303314
304315/*
@@ -789,6 +800,7 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
789800 return ret ;
790801}
791802
803+
792804static int dualsense_get_firmware_info (struct dualsense * ds )
793805{
794806 uint8_t * buf ;
@@ -808,6 +820,15 @@ static int dualsense_get_firmware_info(struct dualsense *ds)
808820 ds -> base .hw_version = get_unaligned_le32 (& buf [24 ]);
809821 ds -> base .fw_version = get_unaligned_le32 (& buf [28 ]);
810822
823+ /* Update version is some kind of feature version. It is distinct from
824+ * the firmware version as there can be many different variations of a
825+ * controller over time with the same physical shell, but with different
826+ * PCBs and other internal changes. The update version (internal name) is
827+ * used as a means to detect what features are available and change behavior.
828+ * Note: the version is different between DualSense and DualSense Edge.
829+ */
830+ ds -> update_version = get_unaligned_le16 (& buf [44 ]);
831+
811832err_free :
812833 kfree (buf );
813834 return ret ;
@@ -878,7 +899,7 @@ static int dualsense_player_led_set_brightness(struct led_classdev *led, enum le
878899 ds -> update_player_leds = true;
879900 spin_unlock_irqrestore (& ds -> base .lock , flags );
880901
881- schedule_work ( & ds -> output_worker );
902+ dualsense_schedule_work ( ds );
882903
883904 return 0 ;
884905}
@@ -922,6 +943,16 @@ static void dualsense_init_output_report(struct dualsense *ds, struct dualsense_
922943 }
923944}
924945
946+ static inline void dualsense_schedule_work (struct dualsense * ds )
947+ {
948+ unsigned long flags ;
949+
950+ spin_lock_irqsave (& ds -> base .lock , flags );
951+ if (ds -> output_worker_initialized )
952+ schedule_work (& ds -> output_worker );
953+ spin_unlock_irqrestore (& ds -> base .lock , flags );
954+ }
955+
925956/*
926957 * Helper function to send DualSense output reports. Applies a CRC at the end of a report
927958 * for Bluetooth reports.
@@ -960,7 +991,10 @@ static void dualsense_output_worker(struct work_struct *work)
960991 if (ds -> update_rumble ) {
961992 /* Select classic rumble style haptics and enable it. */
962993 common -> valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT ;
963- common -> valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION ;
994+ if (ds -> use_vibration_v2 )
995+ common -> valid_flag2 |= DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 ;
996+ else
997+ common -> valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION ;
964998 common -> motor_left = ds -> motor_left ;
965999 common -> motor_right = ds -> motor_right ;
9661000 ds -> update_rumble = false;
@@ -1082,7 +1116,7 @@ static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *r
10821116 spin_unlock_irqrestore (& ps_dev -> lock , flags );
10831117
10841118 /* Schedule updating of microphone state at hardware level. */
1085- schedule_work ( & ds -> output_worker );
1119+ dualsense_schedule_work ( ds );
10861120 }
10871121 ds -> last_btn_mic_state = btn_mic_state ;
10881122
@@ -1197,10 +1231,22 @@ static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_ef
11971231 ds -> motor_right = effect -> u .rumble .weak_magnitude / 256 ;
11981232 spin_unlock_irqrestore (& ds -> base .lock , flags );
11991233
1200- schedule_work ( & ds -> output_worker );
1234+ dualsense_schedule_work ( ds );
12011235 return 0 ;
12021236}
12031237
1238+ static void dualsense_remove (struct ps_device * ps_dev )
1239+ {
1240+ struct dualsense * ds = container_of (ps_dev , struct dualsense , base );
1241+ unsigned long flags ;
1242+
1243+ spin_lock_irqsave (& ds -> base .lock , flags );
1244+ ds -> output_worker_initialized = false;
1245+ spin_unlock_irqrestore (& ds -> base .lock , flags );
1246+
1247+ cancel_work_sync (& ds -> output_worker );
1248+ }
1249+
12041250static int dualsense_reset_leds (struct dualsense * ds )
12051251{
12061252 struct dualsense_output_report report ;
@@ -1237,7 +1283,7 @@ static void dualsense_set_lightbar(struct dualsense *ds, uint8_t red, uint8_t gr
12371283 ds -> lightbar_blue = blue ;
12381284 spin_unlock_irqrestore (& ds -> base .lock , flags );
12391285
1240- schedule_work ( & ds -> output_worker );
1286+ dualsense_schedule_work ( ds );
12411287}
12421288
12431289static void dualsense_set_player_leds (struct dualsense * ds )
@@ -1260,7 +1306,7 @@ static void dualsense_set_player_leds(struct dualsense *ds)
12601306
12611307 ds -> update_player_leds = true;
12621308 ds -> player_leds_state = player_ids [player_id ];
1263- schedule_work ( & ds -> output_worker );
1309+ dualsense_schedule_work ( ds );
12641310}
12651311
12661312static struct ps_device * dualsense_create (struct hid_device * hdev )
@@ -1299,7 +1345,9 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
12991345 ps_dev -> battery_capacity = 100 ; /* initial value until parse_report. */
13001346 ps_dev -> battery_status = POWER_SUPPLY_STATUS_UNKNOWN ;
13011347 ps_dev -> parse_report = dualsense_parse_report ;
1348+ ps_dev -> remove = dualsense_remove ;
13021349 INIT_WORK (& ds -> output_worker , dualsense_output_worker );
1350+ ds -> output_worker_initialized = true;
13031351 hid_set_drvdata (hdev , ds );
13041352
13051353 max_output_report_size = sizeof (struct dualsense_output_report_bt );
@@ -1320,6 +1368,21 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
13201368 return ERR_PTR (ret );
13211369 }
13221370
1371+ /* Original DualSense firmware simulated classic controller rumble through
1372+ * its new haptics hardware. It felt different from classic rumble users
1373+ * were used to. Since then new firmwares were introduced to change behavior
1374+ * and make this new 'v2' behavior default on PlayStation and other platforms.
1375+ * The original DualSense requires a new enough firmware as bundled with PS5
1376+ * software released in 2021. DualSense edge supports it out of the box.
1377+ * Both devices also support the old mode, but it is not really used.
1378+ */
1379+ if (hdev -> product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ) {
1380+ /* Feature version 2.21 introduced new vibration method. */
1381+ ds -> use_vibration_v2 = ds -> update_version >= DS_FEATURE_VERSION (2 , 21 );
1382+ } else if (hdev -> product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 ) {
1383+ ds -> use_vibration_v2 = true;
1384+ }
1385+
13231386 ret = ps_devices_list_add (ps_dev );
13241387 if (ret )
13251388 return ERR_PTR (ret );
@@ -1436,7 +1499,8 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
14361499 goto err_stop ;
14371500 }
14381501
1439- if (hdev -> product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ) {
1502+ if (hdev -> product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ||
1503+ hdev -> product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 ) {
14401504 dev = dualsense_create (hdev );
14411505 if (IS_ERR (dev )) {
14421506 hid_err (hdev , "Failed to create dualsense.\n" );
@@ -1461,13 +1525,18 @@ static void ps_remove(struct hid_device *hdev)
14611525 ps_devices_list_remove (dev );
14621526 ps_device_release_player_id (dev );
14631527
1528+ if (dev -> remove )
1529+ dev -> remove (dev );
1530+
14641531 hid_hw_close (hdev );
14651532 hid_hw_stop (hdev );
14661533}
14671534
14681535static const struct hid_device_id ps_devices [] = {
14691536 { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER ) },
14701537 { HID_USB_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER ) },
1538+ { HID_BLUETOOTH_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 ) },
1539+ { HID_USB_DEVICE (USB_VENDOR_ID_SONY , USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 ) },
14711540 { }
14721541};
14731542MODULE_DEVICE_TABLE (hid , ps_devices );
0 commit comments