Skip to content

Commit f345a47

Browse files
LawstorantJiri Kosina
authored andcommitted
HID: pidff: Use direction fix only for conditional effects
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>
1 parent b80a75c commit f345a47

3 files changed

Lines changed: 34 additions & 16 deletions

File tree

drivers/hid/hid-universal-pidff.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,25 +144,25 @@ static int universal_pidff_input_configured(struct hid_device *hdev,
144144

145145
static const struct hid_device_id universal_pidff_devices[] = {
146146
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3),
147-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
147+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
148148
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3_2),
149-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
149+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
150150
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5),
151-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
151+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
152152
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5_2),
153-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
153+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
154154
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9),
155-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
155+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
156156
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9_2),
157-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
157+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
158158
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12),
159-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
159+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
160160
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12_2),
161-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
161+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
162162
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21),
163-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
163+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
164164
{ HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21_2),
165-
.driver_data = HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION },
165+
.driver_data = HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION },
166166
{ HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C5) },
167167
{ HID_USB_DEVICE(USB_VENDOR_ID_CAMMUS, USB_DEVICE_ID_CAMMUS_C12) },
168168
{ HID_USB_DEVICE(USB_VENDOR_ID_VRS, USB_DEVICE_ID_VRS_DFP),

drivers/hid/usbhid/hid-pidff.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ struct pidff_device {
205205
u8 effect_count;
206206
};
207207

208+
static int pidff_is_effect_conditional(struct ff_effect *effect)
209+
{
210+
return effect->type == FF_SPRING ||
211+
effect->type == FF_DAMPER ||
212+
effect->type == FF_INERTIA ||
213+
effect->type == FF_FRICTION;
214+
}
215+
208216
/*
209217
* Clamp value for a given field
210218
*/
@@ -294,6 +302,20 @@ static void pidff_set_duration(struct pidff_usage *usage, u16 duration)
294302
pidff_set_time(usage, duration);
295303
}
296304

305+
static void pidff_set_effect_direction(struct pidff_device *pidff,
306+
struct ff_effect *effect)
307+
{
308+
u16 direction = effect->direction;
309+
310+
/* Use fixed direction if needed */
311+
if (pidff->quirks & HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION &&
312+
pidff_is_effect_conditional(effect))
313+
direction = PIDFF_FIXED_WHEEL_DIRECTION;
314+
315+
pidff->effect_direction->value[0] =
316+
pidff_rescale(direction, U16_MAX, pidff->effect_direction);
317+
}
318+
297319
/*
298320
* Send envelope report to the device
299321
*/
@@ -395,11 +417,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
395417
pidff->set_effect[PID_GAIN].field->logical_maximum;
396418
pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
397419

398-
/* Use fixed direction if needed */
399-
pidff->effect_direction->value[0] = pidff_rescale(
400-
pidff->quirks & HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION ?
401-
PIDFF_FIXED_WHEEL_DIRECTION : effect->direction,
402-
U16_MAX, pidff->effect_direction);
420+
pidff_set_effect_direction(pidff, effect);
403421

404422
/* Omit setting delay field if it's missing */
405423
if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DELAY))

drivers/hid/usbhid/hid-pidff.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#define HID_PIDFF_QUIRK_PERMISSIVE_CONTROL BIT(2)
1717

1818
/* Use fixed 0x4000 direction during SET_EFFECT report upload */
19-
#define HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(3)
19+
#define HID_PIDFF_QUIRK_FIX_CONDITIONAL_DIRECTION BIT(3)
2020

2121
/* Force all periodic effects to be uploaded as SINE */
2222
#define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY BIT(4)

0 commit comments

Comments
 (0)