aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
authorTomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>2025-02-01 12:38:52 +0100
committerJiri Kosina <jkosina@suse.com>2025-02-03 15:16:56 +0100
commit3051bf5ec773b803c474ea556b57d678a8885be3 (patch)
tree320c09df1a0bcd7977b6707c02deac589dba108f /drivers/hid
parent36de0164bbaff1484288e84ac5df5cff00580263 (diff)
downloadath-3051bf5ec773b803c474ea556b57d678a8885be3.tar.gz
HID: pidff: Add FIX_WHEEL_DIRECTION quirk
Most steering wheels simply ignore DIRECTION field, but some try to be compliant with the PID standard and use it in force calculations. Games often ignore setting this field properly and/or there can be issues with dinput8 -> wine -> SDL -> Linux API translation, and this value can be incorrect. This can lead to partial/complete loss of Force Feedback or even unexpected force reversal. Sadly, this quirk can't be detected automatically without sending out effects that would move an axis. This fixes FFB on Moza Racing devices and others where effect direction is not simply ignored. Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> Reviewed-by: Michał Kopeć <michal@nozomi.space> Reviewed-by: Paul Dino Jones <paul@spacefreak18.xyz> Signed-off-by: Jiri Kosina <jkosina@suse.com>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/usbhid/hid-pidff.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index 298a971c63fdc..9e03dfb2b1e7e 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -136,6 +136,9 @@ static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
#define PID_EFFECT_STOP 1
static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
+/* Polar direction 90 degrees (North) */
+#define PIDFF_FIXED_WHEEL_DIRECTION 0x4000
+
struct pidff_usage {
struct hid_field *field;
s32 *value;
@@ -337,9 +340,12 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
pidff->set_effect[PID_GAIN].value[0] =
pidff->set_effect[PID_GAIN].field->logical_maximum;
pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
- pidff->effect_direction->value[0] =
- pidff_rescale(effect->direction, 0xffff,
- pidff->effect_direction);
+
+ /* Use fixed direction if needed */
+ pidff->effect_direction->value[0] = pidff_rescale(
+ pidff->quirks & HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION ?
+ PIDFF_FIXED_WHEEL_DIRECTION : effect->direction,
+ 0xffff, pidff->effect_direction);
/* Omit setting delay field if it's missing */
if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))