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 <max@enpas.org> Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
parent
46089080a8
commit
a48a7cd85f
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err_free:
|
|
||||||
kfree(buf);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user