]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: pidff: Use direction fix only for conditional effects
authorTomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
Wed, 13 Aug 2025 20:09:49 +0000 (22:09 +0200)
committerJiri Kosina <jkosina@suse.com>
Fri, 15 Aug 2025 13:58:01 +0000 (15:58 +0200)
The already fixed bug in SDL only affected conditional effects. This
should fix FFB in Forza Horizion 4/5 on Moza Devices as Forza Horizon
flips the constant force direction instead of using negative magnitude
values.

Changing the direction in the effect directly in pidff_upload_effect()
would affect it's value in further operations like comparing to the old
effect and/or just reading the effect values in the user application.

This, in turn, would lead to constant PID_SET_EFFECT spam as the effect
direction would constantly not match the value that's set by the
application.

This way, it's still transparent to any software/API.

Only affects conditional effects now so it's better for it to explicitly
state that in the name. If any HW ever needs fixed direction for other
effects, we'll add more quirks.

Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
Reviewed-by: Oleg Makarenko <oleg@makarenk.ooo>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-universal-pidff.c
drivers/hid/usbhid/hid-pidff.c
drivers/hid/usbhid/hid-pidff.h

index 554a6559aeb73acb24f4b3616f70cfa3249488b0..70fce0f88e82545315e38f3730555db64033122b 100644 (file)
@@ -144,25 +144,25 @@ static int universal_pidff_input_configured(struct hid_device *hdev,
 
 static const struct hid_device_id universal_pidff_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3_2),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5_2),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9_2),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12_2),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21_2),
-               .driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
+               .driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
        { HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C5) },
        { HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C12) },
        { HID_USB_DEVICE(USB_VENDOR_ID_VRS, USB_DEVICE_ID_VRS_DFP),
index 614a20b62023199bc87e56f0f5d8e73f85e16051..c6b4f61e535d59cb44d29be2ca38fb4e0b2c9221 100644 (file)
@@ -205,6 +205,14 @@ struct pidff_device {
        u8 effect_count;
 };
 
+static int pidff_is_effect_conditional(struct ff_effect *effect)
+{
+       return effect->type == FF_SPRING  ||
+              effect->type == FF_DAMPER  ||
+              effect->type == FF_INERTIA ||
+              effect->type == FF_FRICTION;
+}
+
 /*
  * Clamp value for a given field
  */
@@ -294,6 +302,20 @@ static void pidff_set_duration(struct pidff_usage *usage, u16 duration)
        pidff_set_time(usage, duration);
 }
 
+static void pidff_set_effect_direction(struct pidff_device *pidff,
+                                      struct ff_effect *effect)
+{
+       u16 direction = effect->direction;
+
+       /* Use fixed direction if needed */
+       if (pidff->quirks & HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION &&
+           pidff_is_effect_conditional(effect))
+               direction = PIDFF_FIXED_WHEEL_DIRECTION;
+
+       pidff->effect_direction->value[0] =
+               pidff_rescale(direction, U16_MAX, pidff->effect_direction);
+}
+
 /*
  * Send envelope report to the device
  */
@@ -395,11 +417,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
                pidff->set_effect[PID_GAIN].field->logical_maximum;
        pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
 
-       /* 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,
-               U16_MAX, pidff->effect_direction);
+       pidff_set_effect_direction(pidff, effect);
 
        /* Omit setting delay field if it's missing */
        if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))
index a53a8b436baa6fa1b022341a8cc8cccbb26af450..f321f675e13183ddc36369f08f5e4d1403a69d4a 100644 (file)
@@ -16,7 +16,7 @@
 #define HID_PIDFF_QUIRK_PERMISSIVE_CONTROL     BIT(2)
 
 /* Use fixed 0x4000 direction during SET_EFFECT report upload */
-#define HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION    BIT(3)
+#define HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION      BIT(3)
 
 /* Force all periodic effects to be uploaded as SINE */
 #define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY     BIT(4)