From dc92f0be1352ba5a27239f451e5f0161e48f14e6 Mon Sep 17 00:00:00 2001 From: Alain Carlucci Date: Fri, 30 Dec 2022 18:52:06 +0100 Subject: [PATCH 2/3] HID: sony: sanity check DS4 calibration data This patch prevents a crash when the DS4 reports invalid calibration data for the IMUs. It checks if the denominator is zero, and in that case fallback to a default value. --- drivers/hid/hid-sony.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 13125997a..d25e84e35 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1714,6 +1714,7 @@ static int dualshock4_get_calibration_data(struct sony_sc *sc) short acc_z_plus, acc_z_minus; int speed_2x; int range_2g; + int i; /* For Bluetooth we use a different request, which supports CRC. * Note: in Bluetooth mode feature report 0x02 also changes the state @@ -1858,6 +1859,30 @@ static int dualshock4_get_calibration_data(struct sony_sc *sc) sc->ds4_calib_data[5].sens_numer = 2*DS4_ACC_RES_PER_G; sc->ds4_calib_data[5].sens_denom = range_2g; + /* Sanity check gyro calibration data. This is needed for clone devices, + * which poorly implement support. Some devices appear to return zeros + * for all data, while some hardcode all the same values and for some + * use the wrong sign (the delta is then 0). + * When we detect something fishy, just disable the calibration logic + * altogether as nothing can be trusted for that axis. + */ + for (i = 0; i < 6; i++) { + if (sc->ds4_calib_data[i].sens_denom == 0) { + hid_warn(sc->hdev, "Invalid calibration data for axis (%d), disabling calibration.", + sc->ds4_calib_data[i].abs_code); + + if (i < 3) { + /* Gyroscope */ + sc->ds4_calib_data[i].sens_numer = DS4_GYRO_RES_PER_DEG_S; + } else { + /* Accelerometer */ + sc->ds4_calib_data[i].sens_numer = DS4_ACC_RES_PER_G; + } + sc->ds4_calib_data[i].bias = 0; + sc->ds4_calib_data[i].sens_denom = 1; + } + } + err_stop: kfree(buf); return ret; -- 2.39.0