Skip to content

Commit a48a7cd

Browse files
Max StaudtJiri Kosina
authored andcommitted
HID: playstation: DS4: Don't fail on calibration data request
Some third-party controllers can't report calibration data for the gyro/accelerometer. We can still use the gamepad as-is, so let's do that. Signed-off-by: Max Staudt <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 4608908 commit a48a7cd

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

drivers/hid/hid-playstation.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,8 +1778,10 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
17781778
int retries;
17791779

17801780
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL);
1781-
if (!buf)
1782-
return -ENOMEM;
1781+
if (!buf) {
1782+
ret = -ENOMEM;
1783+
goto no_buffer_tail_check;
1784+
}
17831785

17841786
/* We should normally receive the feature report data we asked
17851787
* for, but hidraw applications such as Steam can issue feature
@@ -1796,26 +1798,27 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
17961798
continue;
17971799
}
17981800

1799-
hid_err(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
1801+
hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
18001802
ret = -EILSEQ;
1801-
goto err_free;
18021803
} else {
18031804
break;
18041805
}
18051806
}
18061807
} else { /* Bluetooth */
18071808
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, GFP_KERNEL);
1808-
if (!buf)
1809-
return -ENOMEM;
1809+
if (!buf) {
1810+
ret = -ENOMEM;
1811+
goto no_buffer_tail_check;
1812+
}
18101813

18111814
ret = ps_get_report(hdev, DS4_FEATURE_REPORT_CALIBRATION_BT, buf,
18121815
DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, true);
1813-
if (ret) {
1814-
hid_err(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
1815-
goto err_free;
1816-
}
1816+
1817+
if (ret)
1818+
hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
18171819
}
18181820

1821+
/* Parse buffer. If the transfer failed, this safely copies zeroes. */
18191822
gyro_pitch_bias = get_unaligned_le16(&buf[1]);
18201823
gyro_yaw_bias = get_unaligned_le16(&buf[3]);
18211824
gyro_roll_bias = get_unaligned_le16(&buf[5]);
@@ -1867,6 +1870,11 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
18671870
ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) +
18681871
abs(gyro_roll_minus - gyro_roll_bias);
18691872

1873+
/* Done parsing the buffer, so let's free it. */
1874+
kfree(buf);
1875+
1876+
no_buffer_tail_check:
1877+
18701878
/*
18711879
* Sanity check gyro calibration data. This is needed to prevent crashes
18721880
* during report handling of virtual, clone or broken devices not implementing
@@ -1919,8 +1927,6 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
19191927
}
19201928
}
19211929

1922-
err_free:
1923-
kfree(buf);
19241930
return ret;
19251931
}
19261932

@@ -2568,8 +2574,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev)
25682574

25692575
ret = dualshock4_get_calibration_data(ds4);
25702576
if (ret) {
2571-
hid_err(hdev, "Failed to get calibration data from DualShock4\n");
2572-
goto err;
2577+
hid_warn(hdev, "Failed to get calibration data from DualShock4\n");
2578+
hid_warn(hdev, "Gyroscope and accelerometer will be inaccurate.\n");
25732579
}
25742580

25752581
ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect);

0 commit comments

Comments
 (0)