Skip to content

Commit 116d4f6

Browse files
Lawstorantgregkh
authored andcommitted
HID: pidff: Add FIX_WHEEL_DIRECTION quirk
[ Upstream commit 3051bf5 ] 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 <[email protected]> Reviewed-by: Michał Kopeć <[email protected]> Reviewed-by: Paul Dino Jones <[email protected]> Signed-off-by: Jiri Kosina <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent ed806fd commit 116d4f6

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

drivers/hid/usbhid/hid-pidff.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ static const u8 pidff_block_load_status[] = { 0x8c, 0x8d };
137137
#define PID_EFFECT_STOP 1
138138
static const u8 pidff_effect_operation_status[] = { 0x79, 0x7b };
139139

140+
/* Polar direction 90 degrees (North) */
141+
#define PIDFF_FIXED_WHEEL_DIRECTION 0x4000
142+
140143
struct pidff_usage {
141144
struct hid_field *field;
142145
s32 *value;
@@ -328,9 +331,12 @@ static void pidff_set_effect_report(struct pidff_device *pidff,
328331
pidff->set_effect[PID_GAIN].value[0] =
329332
pidff->set_effect[PID_GAIN].field->logical_maximum;
330333
pidff->set_effect[PID_DIRECTION_ENABLE].value[0] = 1;
331-
pidff->effect_direction->value[0] =
332-
pidff_rescale(effect->direction, 0xffff,
333-
pidff->effect_direction);
334+
335+
/* Use fixed direction if needed */
336+
pidff->effect_direction->value[0] = pidff_rescale(
337+
pidff->quirks & HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION ?
338+
PIDFF_FIXED_WHEEL_DIRECTION : effect->direction,
339+
0xffff, pidff->effect_direction);
334340

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

include/linux/hid.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, __u32 initial_quirks);
12331233
#define HID_PIDFF_QUIRK_MISSING_DELAY BIT(0)
12341234
#define HID_PIDFF_QUIRK_MISSING_PBO BIT(1)
12351235
#define HID_PIDFF_QUIRK_PERMISSIVE_CONTROL BIT(2)
1236+
#define HID_PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(3)
12361237

12371238
#define dbg_hid(fmt, ...) pr_debug("%s: " fmt, __FILE__, ##__VA_ARGS__)
12381239

0 commit comments

Comments
 (0)