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>
This commit is contained in:
committed by
Jiri Kosina
parent
b80a75cf69
commit
f345a4798d
@@ -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),
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user