[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20241231154731.1719919-4-tomasz.pakula.oficjalny@gmail.com>
Date: Tue, 31 Dec 2024 16:47:24 +0100
From: Tomasz Pakuła <tomasz.pakula.oficjalny@...il.com>
To: jikos@...nel.org,
bentiss@...nel.org
Cc: linux-kernel@...r.kernel.org,
linux-usb@...r.kernel.org,
oleg@...arenk.ooo,
paul@...cefreak18.xyz,
f.kardame@...jaro.org,
jules.noirant@...nge.fr
Subject: [PATCH 03/10] HID: pidff: Clamp PERIODIC effect period to device's logical range
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@...il.com>
---
drivers/hid/usbhid/hid-pidff.c | 36 +++++++++++++++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index e78fd68edda3..76e934649ee8 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -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);
--
2.47.1
Powered by blists - more mailing lists