summaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorMax Staudt <max@enpas.org>2024-02-08 01:36:45 +0900
committerJiri Kosina <jkosina@suse.com>2024-04-03 21:53:39 +0200
commita48a7cd85f5518d21525642391602ec734cb100f (patch)
tree157479b1096b616c988072f0bf53792dd763fb60 /drivers/hid
parent46089080a8e1c9a16c5967063986f31031bd218f (diff)
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>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-playstation.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index df50ca4dab90..53bfc2828a61 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -1778,8 +1778,10 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
int retries;
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
+ if (!buf) {
+ ret = -ENOMEM;
+ goto no_buffer_tail_check;
+ }
/* We should normally receive the feature report data we asked
* for, but hidraw applications such as Steam can issue feature
@@ -1796,26 +1798,27 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4)
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;
- goto err_free;
} else {
break;
}
}
} else { /* Bluetooth */
buf = kzalloc(DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
+ if (!buf) {
+ ret = -ENOMEM;
+ goto no_buffer_tail_check;
+ }
ret = ps_get_report(hdev, DS4_FEATURE_REPORT_CALIBRATION_BT, buf,
DS4_FEATURE_REPORT_CALIBRATION_BT_SIZE, true);
- if (ret) {
- hid_err(hdev, "Failed to retrieve DualShock4 calibration info: %d\n", ret);
- goto err_free;
- }
+
+ if (ret)
+ 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_yaw_bias = get_unaligned_le16(&buf[3]);
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) +
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
* 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;
}
@@ -2568,8 +2574,8 @@ static struct ps_device *dualshock4_create(struct hid_device *hdev)
ret = dualshock4_get_calibration_data(ds4);
if (ret) {
- hid_err(hdev, "Failed to get calibration data from DualShock4\n");
- goto err;
+ hid_warn(hdev, "Failed to get calibration data from DualShock4\n");
+ hid_warn(hdev, "Gyroscope and accelerometer will be inaccurate.\n");
}
ds4->gamepad = ps_gamepad_create(hdev, dualshock4_play_effect);