Commit a48a7cd8 authored by Max Staudt's avatar Max Staudt Committed by Jiri Kosina

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: default avatarMax Staudt <max@enpas.org>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.com>
parent 46089080
...@@ -1778,8 +1778,10 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ...@@ -1778,8 +1778,10 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
int retries; int retries;
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL); buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL);
if (!buf) if (!buf) {
return -ENOMEM; ret = -ENOMEM;
goto no_buffer_tail_check;
}
/* We should normally receive the feature report data we asked /* We should normally receive the feature report data we asked
* for, but hidraw applications such as Steam can issue feature * for, but hidraw applications such as Steam can issue feature
...@@ -1796,26 +1798,27 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ...@@ -1796,26 +1798,27 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
continue; continue;
} }
hid_err(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
ret = -EILSEQ; ret = -EILSEQ;
goto err_free;
} else { } else {
break; break;
} }
} }
} else { /* Bluetooth */ } else { /* Bluetooth */
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, GFP_KERNEL); buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, GFP_KERNEL);
if (!buf) if (!buf) {
return -ENOMEM; ret = -ENOMEM;
goto no_buffer_tail_check;
}
ret = ps_get_report(hdev, DS4_FEATURE_REPORT_CALIBRATION_BT, buf, ret = ps_get_report(hdev, DS4_FEATURE_REPORT_CALIBRATION_BT, buf,
DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, true); DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, true);
if (ret) {
hid_err(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret); if (ret)
goto err_free; hid_warn(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
}
} }
/* Parse buffer. If the transfer failed, this safely copies zeroes. */
gyro_pitch_bias = get_unaligned_le16(&buf[1]); gyro_pitch_bias = get_unaligned_le16(&buf[1]);
gyro_yaw_bias = get_unaligned_le16(&buf[3]); gyro_yaw_bias = get_unaligned_le16(&buf[3]);
gyro_roll_bias = get_unaligned_le16(&buf[5]); gyro_roll_bias = get_unaligned_le16(&buf[5]);
...@@ -1867,6 +1870,11 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ...@@ -1867,6 +1870,11 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) + ds4->gyro_calib_data[2].sens_denom = abs(gyro_roll_plus - gyro_roll_bias) +
abs(gyro_roll_minus - gyro_roll_bias); abs(gyro_roll_minus - gyro_roll_bias);
/* Done parsing the buffer, so let's free it. */
kfree(buf);
no_buffer_tail_check:
/* /*
* Sanity check gyro calibration data. This is needed to prevent crashes * Sanity check gyro calibration data. This is needed to prevent crashes
* during report handling of virtual, clone or broken devices not implementing * during report handling of virtual, clone or broken devices not implementing
...@@ -1919,8 +1927,6 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ...@@ -1919,8 +1927,6 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
} }
} }
err_free:
kfree(buf);
return ret; return ret;
} }
...@@ -2568,8 +2574,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev) ...@@ -2568,8 +2574,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev)
ret = dualshock4_get_calibration_data(ds4); ret = dualshock4_get_calibration_data(ds4);
if (ret) { if (ret) {
hid_err(hdev, "Failed to get calibration data from DualShock4\n"); hid_warn(hdev, "Failed to get calibration data from DualShock4\n");
goto err; hid_warn(hdev, "Gyroscope and accelerometer will be inaccurate.\n");
} }
ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect); ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment