From db0eb5244954560c86da15b2ddd14ad0a400b408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 2 Jul 2024 01:24:15 +0200 Subject: [PATCH] Add Moza periodic envelope and direction fixup --- hid-pidff.c | 49 +++++++++++++++++++++---- hid-pidff.h | 11 ++++-- hid-newpidff.c => hid-universal-pidff.c | 34 ++++++++--------- 3 files changed, 66 insertions(+), 28 deletions(-) rename hid-newpidff.c => hid-universal-pidff.c (77%) diff --git a/hid-pidff.c b/hid-pidff.c index 08a7c71..0411815 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -192,6 +192,7 @@ struct pidff_device { int pid_id[PID_EFFECTS_MAX]; unsigned quirks; + short autocenter_effect_ids[PID_AUTOCENTER_EFFECTS]; }; /* @@ -308,12 +309,8 @@ static void pidff_set_effect_report(struct pidff_device *pidff, /* check for device quirks */ unsigned short direction = effect->direction; - if ((effect->type == FF_DAMPER || - effect->type == FF_FRICTION || - effect->type == FF_SPRING || - effect->type == FF_INERTIA) && - pidff->quirks & PIDFF_QUIRK_FIX_WHEEL_DIRECTION) - direction = 0x3FFF; + if (pidff->quirks & PIDFF_QUIRK_FIX_WHEEL_DIRECTION) + direction = 0x4000; pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; @@ -637,6 +634,17 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, pidff_set_effect_report(pidff, effect); if (!old || pidff_needs_set_periodic(effect, old)) pidff_set_periodic_report(pidff, effect); + + if (pidff->quirks & PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE) + { + effect->u.periodic.envelope.attack_level = + effect->u.periodic.envelope.attack_level == 0 + ? 0x7fff : effect->u.periodic.envelope.attack_level; + + effect->u.periodic.envelope.fade_level = + effect->u.periodic.envelope.fade_level == 0 + ? 0x7fff : effect->u.periodic.envelope.fade_level; + } if (!old || pidff_needs_set_envelope(&effect->u.periodic.envelope, &old->u.periodic.envelope)) @@ -1264,7 +1272,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff, /* * Check if the device is PID and initialize it */ -int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id) +int hid_pidff_init(struct hid_device *hid) { struct pidff_device *pidff; struct hid_input *hidinput = list_entry(hid->inputs.next, @@ -1286,7 +1294,6 @@ int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id) return -ENOMEM; pidff->hid = hid; - pidff->quirks |= id->driver_data; hid_device_io_start(hid); @@ -1364,3 +1371,29 @@ int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id) kfree(pidff); return error; } + +/* + * Check if the device is PID and initialize it + * Add quirks after initialisation + */ +int hid_pidff_init_with_quirks(struct hid_device *hid, const struct hid_device_id *id) +{ + int error = hid_pidff_init(hid); + + if (error) + return error; + + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); + struct input_dev *dev = hidinput->input; + struct pidff_device *pidff = dev->ff->private; + + /* set quirks on the pidff device */ + hid_device_io_start(hid); + pidff->quirks |= id->driver_data; + hid_device_io_stop(hid); + + hid_dbg(dev, "Device quirks: %d\n", pidff->quirks); + + return 0; +} diff --git a/hid-pidff.h b/hid-pidff.h index 517683f..586ee96 100644 --- a/hid-pidff.h +++ b/hid-pidff.h @@ -5,8 +5,12 @@ /* PIDFF Quirks to solve issues with certain devices */ /* - * Ignore direction for spring/damping/friction/inertia effects - * and always set 16384 + * Always set a value > 0 for PERIODIC envelope attack and fade level +*/ +#define PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE BIT(0) + +/* + * Ignore direction and always set 16384 (0x4000) */ #define PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(1) @@ -16,6 +20,7 @@ #define PIDFF_QUIRK_NO_DELAY_EFFECT BIT(2) -int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id); +int hid_pidff_init(struct hid_device *hid); +int hid_pidff_init_with_quirks(struct hid_device *hid, const struct hid_device_id *id); #endif diff --git a/hid-newpidff.c b/hid-universal-pidff.c similarity index 77% rename from hid-newpidff.c rename to hid-universal-pidff.c index fde41a4..2b8dfb7 100644 --- a/hid-newpidff.c +++ b/hid-universal-pidff.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Improved HID PIDFF driver + * HID PIDFF wrapper * First of all targeting steering wheels and wheelbases * * Copyright (c) 2024 Makarenko Oleg @@ -14,15 +14,15 @@ static const struct hid_device_id pidff_wheel_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3), - .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_0_INFINITE_LENGTH }, + .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE }, { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5), - .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_0_INFINITE_LENGTH }, + .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE }, { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9), - .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_0_INFINITE_LENGTH }, + .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE }, { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12), - .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_0_INFINITE_LENGTH }, + .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE }, { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16_R21), - .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_0_INFINITE_LENGTH }, + .driver_data = PIDFF_QUIRK_FIX_WHEEL_DIRECTION | PIDFF_QUIRK_FIX_PERIODIC_ENVELOPE }, { } }; MODULE_DEVICE_TABLE(hid, pidff_wheel_devices); @@ -39,7 +39,7 @@ static u8 *moza_report_fixup(struct hid_device *hdev, __u8 *rdesc, } -static u8 *new_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc, +static u8 *universal_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (hdev->vendor == USB_VENDOR_ID_MOZA) { @@ -53,7 +53,7 @@ static u8 *new_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc, * Check if the device is PID and initialize it * Add quirks after initialisation */ -static int new_pidff_probe(struct hid_device *hdev, +static int universal_pidff_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; @@ -69,7 +69,7 @@ static int new_pidff_probe(struct hid_device *hdev, goto err; } - ret = hid_new_pidff_init(hdev, id); + ret = hid_pidff_init_with_quirks(hdev, id); if (ret) { hid_warn(hdev, "Force feedback not supported\n"); goto err; @@ -80,7 +80,7 @@ err: return ret; } -static int new_pidff_input_configured(struct hid_device *hdev, +static int universal_pidff_input_configured(struct hid_device *hdev, struct hid_input *hidinput) { struct input_dev *input = hidinput->input; @@ -90,15 +90,15 @@ static int new_pidff_input_configured(struct hid_device *hdev, return 0; } -static struct hid_driver new_pidff = { - .name = "new-pidff", +static struct hid_driver universal_pidff = { + .name = "hid-universal-pidff", .id_table = pidff_wheel_devices, - .probe = new_pidff_probe, - .input_configured = new_pidff_input_configured, - .report_fixup = new_pidff_report_fixup + .probe = universal_pidff_probe, + .input_configured = universal_pidff_input_configured, + .report_fixup = universal_pidff_report_fixup }; -module_hid_driver(new_pidff); +module_hid_driver(universal_pidff); MODULE_AUTHOR("Oleg Makarenko "); -MODULE_DESCRIPTION("Improved HID PIDFF Driver"); +MODULE_DESCRIPTION("Universal HID PIDFF Driver"); MODULE_LICENSE("GPL");