Skip to content

Commit c759302

Browse files
Max StaudtJiri Kosina
authored andcommitted
HID: playstation: DS4: Parse minimal report 0x01
Some third-party controllers never switch to the full 0x11 report. They keep sending the short 0x01 report, so let's parse that instead. Signed-off-by: Max Staudt <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent a48a7cd commit c759302

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

drivers/hid/hid-playstation.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ 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_MINIMAL 0x01
291+
#define DS4_INPUT_REPORT_BT_MINIMAL_SIZE 10
290292
#define DS4_INPUT_REPORT_BT 0x11
291293
#define DS4_INPUT_REPORT_BT_SIZE 78
292294
#define DS4_OUTPUT_REPORT_USB 0x05
@@ -2196,6 +2198,7 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
21962198
int battery_status, i, j;
21972199
uint16_t sensor_timestamp;
21982200
unsigned long flags;
2201+
bool is_minimal = false;
21992202

22002203
/*
22012204
* DualShock4 in USB uses the full HID report for reportID 1, but
@@ -2223,6 +2226,18 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
22232226
ds4_report = &bt->common;
22242227
num_touch_reports = bt->num_touch_reports;
22252228
touch_reports = bt->touch_reports;
2229+
} else if (hdev->bus == BUS_BLUETOOTH &&
2230+
report->id == DS4_INPUT_REPORT_BT_MINIMAL &&
2231+
size == DS4_INPUT_REPORT_BT_MINIMAL_SIZE) {
2232+
/* Some third-party pads never switch to the full 0x11 report.
2233+
* The short 0x01 report is 10 bytes long:
2234+
* u8 report_id == 0x01
2235+
* u8 first_bytes_of_full_report[9]
2236+
* So let's reuse the full report parser, and stop it after
2237+
* parsing the buttons.
2238+
*/
2239+
ds4_report = (struct dualshock4_input_report_common *)&data[1];
2240+
is_minimal = true;
22262241
} else {
22272242
hid_err(hdev, "Unhandled reportID=%d\n", report->id);
22282243
return -1;
@@ -2256,6 +2271,9 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
22562271
input_report_key(ds4->gamepad, BTN_MODE, ds4_report->buttons[2] & DS_BUTTONS2_PS_HOME);
22572272
input_sync(ds4->gamepad);
22582273

2274+
if (is_minimal)
2275+
return 0;
2276+
22592277
/* Parse and calibrate gyroscope data. */
22602278
for (i = 0; i < ARRAY_SIZE(ds4_report->gyro); i++) {
22612279
int raw_data = (short)le16_to_cpu(ds4_report->gyro[i]);

0 commit comments

Comments
 (0)