Skip to content

Commit 9fecab2

Browse files
Roderick Colenbranderbentiss
authored andcommitted
HID: playstation: support updated DualSense rumble mode.
Newer DualSense firmware supports a revised classic rumble mode, which feels more similar to rumble as supported on previous PlayStation controllers. It has been made the default on PlayStation and non-PlayStation devices now (e.g. iOS and Windows). Default to this new mode when supported. Signed-off-by: Roderick Colenbrander <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b8a968e commit 9fecab2

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

drivers/hid/hid-playstation.c

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ struct ps_led_info {
108108
#define DS_STATUS_CHARGING GENMASK(7, 4)
109109
#define DS_STATUS_CHARGING_SHIFT 4
110110

111+
/* Feature version from DualSense Firmware Info report. */
112+
#define DS_FEATURE_VERSION(major, minor) ((major & 0xff) << 8 | (minor & 0xff))
113+
111114
/*
112115
* Status of a DualSense touch point contact.
113116
* Contact IDs, with highest bit set are 'inactive'
@@ -126,6 +129,7 @@ struct ps_led_info {
126129
#define DS_OUTPUT_VALID_FLAG1_RELEASE_LEDS BIT(3)
127130
#define DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE BIT(4)
128131
#define DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE BIT(1)
132+
#define DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 BIT(2)
129133
#define DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE BIT(4)
130134
#define DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT BIT(1)
131135

@@ -143,6 +147,9 @@ struct dualsense {
143147
struct input_dev *sensors;
144148
struct input_dev *touchpad;
145149

150+
/* Update version is used as a feature/capability version. */
151+
uint16_t update_version;
152+
146153
/* Calibration data for accelerometer and gyroscope. */
147154
struct ps_calibration_data accel_calib_data[3];
148155
struct ps_calibration_data gyro_calib_data[3];
@@ -153,6 +160,7 @@ struct dualsense {
153160
uint32_t sensor_timestamp_us;
154161

155162
/* Compatible rumble state */
163+
bool use_vibration_v2;
156164
bool update_rumble;
157165
uint8_t motor_left;
158166
uint8_t motor_right;
@@ -812,6 +820,15 @@ static int dualsense_get_firmware_info(struct dualsense *ds)
812820
ds->base.hw_version = get_unaligned_le32(&buf[24]);
813821
ds->base.fw_version = get_unaligned_le32(&buf[28]);
814822

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+
815832
err_free:
816833
kfree(buf);
817834
return ret;
@@ -974,7 +991,10 @@ static void dualsense_output_worker(struct work_struct *work)
974991
if (ds->update_rumble) {
975992
/* Select classic rumble style haptics and enable it. */
976993
common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT;
977-
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;
978998
common->motor_left = ds->motor_left;
979999
common->motor_right = ds->motor_right;
9801000
ds->update_rumble = false;
@@ -1348,6 +1368,21 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
13481368
return ERR_PTR(ret);
13491369
}
13501370

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+
13511386
ret = ps_devices_list_add(ps_dev);
13521387
if (ret)
13531388
return ERR_PTR(ret);

0 commit comments

Comments
 (0)