@@ -205,6 +205,36 @@ static int pidff_rescale_signed(int i, struct hid_field *field)
field->logical_minimum / -0x8000;
}
+/*
+ * Clamp minimum value for the given field
+ */
+static int pidff_clamp_min(int i, struct hid_field *field)
+{
+ int ret = i < field->logical_minimum ? field->logical_minimum : i;
+ pr_debug("clamped min value from %d to %d\n", i, ret);
+ return ret;
+}
+
+/*
+ * Clamp maximum value for the given field
+ */
+static int pidff_clamp_max(int i, struct hid_field *field)
+{
+ int ret = i > field->logical_maximum ? field->logical_maximum : i;
+ pr_debug("clamped max value from %d to %d\n", i, ret);
+ return ret;
+}
+
+/*
+ * Clamp value for the given field
+ */
+static int pidff_clamp(int i, struct hid_field *field)
+{
+ i = pidff_clamp_min(i, field);
+ i = pidff_clamp_max(i, field);
+ return i;
+}
+
static void pidff_set(struct pidff_usage *usage, u16 value)
{
usage->value[0] = pidff_rescale(value, 0xffff, usage->field);
@@ -357,7 +387,11 @@ static void pidff_set_periodic_report(struct pidff_device *pidff,
pidff_set_signed(&pidff->set_periodic[PID_OFFSET],
effect->u.periodic.offset);
pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase);
- pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period;
+
+ // Clamp period to ensure the device can play the effect
+ pidff->set_periodic[PID_PERIOD].value[0] =
+ pidff_clamp(effect->u.periodic.period,
+ pidff->set_periodic[PID_PERIOD].field);
hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC],
HID_REQ_SET_REPORT);
This ensures the effect can actually be played on the connected force feedback device. Adds clamping functions used instead of rescaling, as we don't want to change the characteristics of the periodic effects. Fixes edge cases found on Moza Racing and some other hardware where the effects would not play if the period is outside the defined logical range. Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> --- drivers/hid/usbhid/hid-pidff.c | 36 +++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-)