mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 18:30:06 +00:00
![Michal Malý](/assets/img/avatar_default.png)
Range limiting command for the Driving Force Pro wheel is only a FF_SPRING effect so that the wheel creates resistance when the user tries to turn it past the limit. It is however possible to overpower the FFB motors quite easily which leads to the X axis value exceeding the expected limit. This confuses games which dynamically adjust calibration using the highest/lowest min and max values reported by the wheel. Joydev device driver also doesn't take in account any changes in an axis range after the joystick device is created. This patch recalculates received ABS_X axis value so it is always in <0; 16383> range where 0 is the left limit and 16383 the right limit. Logitech driver for Windows does the same thing. As for any concerns about possible loss of precision, I compared a large set of raw/adjusted values generated by "mult_frac" to values returned by the Windows driver and I got a 100% match. Other Logitech wheels will probably need a similar fix, but I currently lack the information needed to write one. Signed-off-by: Michal Malý <madcatxster@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
39 lines
1.2 KiB
C
39 lines
1.2 KiB
C
#ifndef __HID_LG_H
|
|
#define __HID_LG_H
|
|
|
|
struct lg_drv_data {
|
|
unsigned long quirks;
|
|
void *device_props; /* Device specific properties */
|
|
};
|
|
|
|
#ifdef CONFIG_LOGITECH_FF
|
|
int lgff_init(struct hid_device *hdev);
|
|
#else
|
|
static inline int lgff_init(struct hid_device *hdev) { return -1; }
|
|
#endif
|
|
|
|
#ifdef CONFIG_LOGIRUMBLEPAD2_FF
|
|
int lg2ff_init(struct hid_device *hdev);
|
|
#else
|
|
static inline int lg2ff_init(struct hid_device *hdev) { return -1; }
|
|
#endif
|
|
|
|
#ifdef CONFIG_LOGIG940_FF
|
|
int lg3ff_init(struct hid_device *hdev);
|
|
#else
|
|
static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
|
|
#endif
|
|
|
|
#ifdef CONFIG_LOGIWHEELS_FF
|
|
int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
|
|
struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data);
|
|
int lg4ff_init(struct hid_device *hdev);
|
|
int lg4ff_deinit(struct hid_device *hdev);
|
|
#else
|
|
static inline int lg4ff_adjust_input_event(struct hid_device *hid, struct hid_field *field,
|
|
struct hid_usage *usage, __s32 value, struct lg_drv_data *drv_data) { return 0; }
|
|
static inline int lg4ff_init(struct hid_device *hdev) { return -1; }
|
|
static inline int lg4ff_deinit(struct hid_device *hdev) { return -1; }
|
|
#endif
|
|
|
|
#endif
|