From fb5c25ccf58d7b38718ad1bb1aa9534bedaea1ae Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:38:00 +0300 Subject: [PATCH 01/26] Move MOZA id's --- hid-ids.h | 12 ++++++++++++ hid-moza.h | 13 ------------- 2 files changed, 12 insertions(+), 13 deletions(-) create mode 100644 hid-ids.h delete mode 100644 hid-moza.h diff --git a/hid-ids.h b/hid-ids.h new file mode 100644 index 0000000..1115543 --- /dev/null +++ b/hid-ids.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __HID_IDS_H +#define __HID_IDS_H + +#define USB_VENDOR_ID_MOZA 0x346e +#define USB_DEVICE_ID_MOZA_R3 0x0005 +#define USB_DEVICE_ID_MOZA_R5 0x0004 +#define USB_DEVICE_ID_MOZA_R9 0x0002 +#define USB_DEVICE_ID_MOZA_R12 0x0006 +#define USB_DEVICE_ID_MOZA_R16_R21 0x0000 + +#endif diff --git a/hid-moza.h b/hid-moza.h deleted file mode 100644 index b3c4adb..0000000 --- a/hid-moza.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __HID_MOZA_H -#define __HID_MOZA_H - -#define USB_VENDOR_ID_MOZA 0x346e -#define USB_DEVICE_ID_MOZA_R3 0x0005 -#define USB_DEVICE_ID_MOZA_R5 0x0004 -#define USB_DEVICE_ID_MOZA_R9 0x0002 -#define USB_DEVICE_ID_MOZA_R12 0x0006 -#define USB_DEVICE_ID_MOZA_R16 0x0000 -#define USB_DEVICE_ID_MOZA_R21 0x0000 - -#endif From 377eb942bf0299fbc2d5dd2fd532d43a9f229170 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:38:16 +0300 Subject: [PATCH 02/26] Rename Moza to newpidff --- hid-moza.c | 89 ------------------------------------------ hid-newpidff.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 89 deletions(-) delete mode 100644 hid-moza.c create mode 100644 hid-newpidff.c diff --git a/hid-moza.c b/hid-moza.c deleted file mode 100644 index 8e6e963..0000000 --- a/hid-moza.c +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * HID driver for Moza Steering Wheels - * - * Copyright (c) 2024 Makarenko Oleg - */ - -#include -#include -#include -#include "hid-moza.h" -#include "hid-pidff.h" - -static const struct hid_device_id moza_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R3) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R5) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R9) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R12) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R16) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MOZA, USB_DEVICE_ID_MOZA_R21) }, - { } -}; -MODULE_DEVICE_TABLE(hid, moza_devices); - -// Fix data type on PID Device Control -static u8 *moza_report_fixup(struct hid_device *hdev, __u8 *rdesc, - unsigned int *rsize) -{ - if (rdesc[1002] == 0x91 && rdesc[1003] == 0x02) { - rdesc[1003] = 0x00; // Fix header, it needs to be Array. - } - return rdesc; -} - - -static int moza_probe(struct hid_device *hdev, - const struct hid_device_id *id) -{ - int ret; - ret = hid_parse(hdev); - if (ret) { - hid_err(hdev, "parse failed\n"); - goto err; - } - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); - if (ret) { - hid_err(hdev, "hw start failed\n"); - goto err; - } - - /* set PIDFF quirks for moza wheelbases */ - unsigned quirks = 0; - quirks |= PIDFF_QUIRK_FIX_0_INFINITE_LENGTH; - quirks |= PIDFF_QUIRK_FIX_WHEEL_DIRECTION; - - ret = hid_pidff_init_with_quirks(hdev, quirks); - if (ret) { - hid_warn(hdev, "Force feedback not supported\n"); - goto err; - } - - return 0; -err: - return ret; -} - -static int moza_input_configured(struct hid_device *hdev, - struct hid_input *hidinput) -{ - struct input_dev *input = hidinput->input; - input_set_abs_params(input, ABS_X, - input->absinfo[ABS_X].minimum, input->absinfo[ABS_X].maximum, 0, 0); - - return 0; -} - -static struct hid_driver moza_ff = { - .name = "moza-ff", - .id_table = moza_devices, - .probe = moza_probe, - .input_configured = moza_input_configured, - .report_fixup = moza_report_fixup -}; -module_hid_driver(moza_ff); - -MODULE_AUTHOR("Oleg Makarenko "); -MODULE_DESCRIPTION("MOZA HID FF Driver"); -MODULE_LICENSE("GPL"); diff --git a/hid-newpidff.c b/hid-newpidff.c new file mode 100644 index 0000000..7784dca --- /dev/null +++ b/hid-newpidff.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Improved HID PIDFF driver + * First of all targeting steering wheels and wheelbases + * + * Copyright (c) 2024 Makarenko Oleg + */ + +#include +#include +#include +#include "hid-ids.h" +#include "hid-pidff.h" + +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { } +}; +MODULE_DEVICE_TABLE(hid, pidff_wheel_devices); + + +static u8 *moza_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + // Fix data type on PID Device Control + if (rdesc[1002] == 0x91 && rdesc[1003] == 0x02) { + rdesc[1003] = 0x00; // Fix header, it needs to be Array. + } + return rdesc; +} + + +static u8 *new_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + if (hdev->vendor == USB_VENDOR_ID_MOZA) { + return moza_report_fixup(hdev, rdesc, rsize) + } + return rdesc; +} + + +/* + * Check if the device is PID and initialize it + * Add quirks after initialisation + */ +static int new_pidff_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto err; + } + + ret = hid_pidff_init(hdev, id); + if (ret) { + hid_warn(hdev, "Force feedback not supported\n"); + goto err; + } + + return 0; +err: + return ret; +} + +static int new_pidff_input_configured(struct hid_device *hdev, + struct hid_input *hidinput) +{ + struct input_dev *input = hidinput->input; + input_set_abs_params(input, ABS_X, + input->absinfo[ABS_X].minimum, input->absinfo[ABS_X].maximum, 0, 0); + + return 0; +} + +static struct hid_driver new_pidff = { + .name = "new-pidff", + .id_table = pidff_wheel_devices, + .probe = new_pidff_probe, + .input_configured = new_pidff_input_configured, + .report_fixup = new_pidff_report_fixup +}; +module_hid_driver(new_pidff); + +MODULE_AUTHOR("Oleg Makarenko "); +MODULE_DESCRIPTION("Improved HID PIDFF Driver"); +MODULE_LICENSE("GPL"); From 23255595f7630a1b4925f62bd08b596cf88a5ce1 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:38:38 +0300 Subject: [PATCH 03/26] Small changes to initialization of quirks --- hid-pidff.c | 30 ++---------------------------- hid-pidff.h | 13 +++++++++---- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/hid-pidff.c b/hid-pidff.c index 608c15e..c0493b6 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -1250,7 +1250,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff, /* * Check if the device is PID and initialize it */ -int hid_pidff_init(struct hid_device *hid) +int hid_pidff_init(struct hid_device *hid, const struct hid_device_id *id) { struct pidff_device *pidff; struct hid_input *hidinput = list_entry(hid->inputs.next, @@ -1272,7 +1272,7 @@ int hid_pidff_init(struct hid_device *hid) return -ENOMEM; pidff->hid = hid; - pidff->quirks = 0; + pidff->quirks |= id->device_data; hid_device_io_start(hid); @@ -1350,29 +1350,3 @@ int hid_pidff_init(struct hid_device *hid) 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, unsigned quirks) -{ - 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 |= quirks; - 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 90eab45..1690f47 100644 --- a/hid-pidff.h +++ b/hid-pidff.h @@ -8,15 +8,20 @@ * Substitute 0 length with 0xffff to resolve issues with * infinite effects coming from windows API */ -#define PIDFF_QUIRK_FIX_0_INFINITE_LENGTH BIT(0) +#define PIDFF_QUIRK_FIX_0_INFINITE_LENGTH BIT(0) /* * Ignore direction for spring/damping/friction/inertia effects * and always set 16384 */ -#define PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(1) +#define PIDFF_QUIRK_FIX_WHEEL_DIRECTION BIT(1) -int hid_pidff_init(struct hid_device *hid); -int hid_pidff_init_with_quirks(struct hid_device *hid, unsigned quirks); +/* + * Skip initialization of 0xA7 descriptor (Delay effect) +*/ +#define PIDFF_QUIRK_NO_DELAY_EFFECT BIT(2) + + +int hid_pidff_init(struct hid_device *hid, const struct hid_device_id *id); #endif From b5f60153040e5d8ffda269297e3caca303c2f4d9 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:38:46 +0300 Subject: [PATCH 04/26] Fix build --- Kbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kbuild b/Kbuild index 28a70a7..c60539e 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,3 @@ -obj-m := hid-moza-ff.o -hid-moza-ff-y := hid-moza.o hid-pidff.o +obj-m := hid-new_pidff.o +hid-new_pidff-y := hid-newpidff.o hid-pidff.o ccflags-y := -Idrivers/hid From 2a63e469ea1653c6a01373102c6b4f0ea1a17197 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:40:37 +0300 Subject: [PATCH 05/26] Fix missing semicolon --- hid-newpidff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hid-newpidff.c b/hid-newpidff.c index 7784dca..1bbafcc 100644 --- a/hid-newpidff.c +++ b/hid-newpidff.c @@ -43,7 +43,7 @@ static u8 *new_pidff_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (hdev->vendor == USB_VENDOR_ID_MOZA) { - return moza_report_fixup(hdev, rdesc, rsize) + return moza_report_fixup(hdev, rdesc, rsize); } return rdesc; } From e5c6f7079c4024329a7c44a1b89f7c27015a10e4 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:44:21 +0300 Subject: [PATCH 06/26] Rename pidff function --- hid-newpidff.c | 2 +- hid-pidff.c | 4 ++-- hid-pidff.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hid-newpidff.c b/hid-newpidff.c index 1bbafcc..fde41a4 100644 --- a/hid-newpidff.c +++ b/hid-newpidff.c @@ -69,7 +69,7 @@ static int new_pidff_probe(struct hid_device *hdev, goto err; } - ret = hid_pidff_init(hdev, id); + ret = hid_new_pidff_init(hdev, id); if (ret) { hid_warn(hdev, "Force feedback not supported\n"); goto err; diff --git a/hid-pidff.c b/hid-pidff.c index c0493b6..9bb4f73 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -1250,7 +1250,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff, /* * Check if the device is PID and initialize it */ -int hid_pidff_init(struct hid_device *hid, const struct hid_device_id *id) +int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id) { struct pidff_device *pidff; struct hid_input *hidinput = list_entry(hid->inputs.next, @@ -1272,7 +1272,7 @@ int hid_pidff_init(struct hid_device *hid, const struct hid_device_id *id) return -ENOMEM; pidff->hid = hid; - pidff->quirks |= id->device_data; + pidff->quirks |= id->driver_data; hid_device_io_start(hid); diff --git a/hid-pidff.h b/hid-pidff.h index 1690f47..5c78e15 100644 --- a/hid-pidff.h +++ b/hid-pidff.h @@ -22,6 +22,6 @@ #define PIDFF_QUIRK_NO_DELAY_EFFECT BIT(2) -int hid_pidff_init(struct hid_device *hid, const struct hid_device_id *id); +int hid_new_pidff_init(struct hid_device *hid, const struct hid_device_id *id); #endif From ceaf164adf04b4ba05a043b30835d51f341914a1 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:45:05 +0300 Subject: [PATCH 07/26] Change naming --- Kbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kbuild b/Kbuild index c60539e..02cf0ff 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,3 @@ -obj-m := hid-new_pidff.o -hid-new_pidff-y := hid-newpidff.o hid-pidff.o +obj-m := hid-new-pidff.o +hid-new-pidff-y := hid-newpidff.o hid-pidff.o ccflags-y := -Idrivers/hid From 50a4b4fcd5461752a9383373bc1ebc47352f625a Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:46:34 +0300 Subject: [PATCH 08/26] Update README.md --- README.md | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index e4e8074..503be39 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,11 @@ And that's basically it ## What devices are supported? ### Bases: -1. MOZA R3 -1. MOZA R5 -1. MOZA R9 -1. MOZA R12 -1. MOZA R16 -1. MOZA R21 +1. MOZA R3, R5, R9, R12, R16, R21 +1. ... ### Wheel rims (others yet untested): -1. MOZA RS V2 +1. MOZA RS V2 (with Moza wheelbases) ## What works? 1. FFB (all effects from device descriptor) @@ -25,7 +21,7 @@ And that's basically it ## What does not work? -1. Telemetry functions (Shift lights, etc), mostly because telemetry works only with proprietary soft, which can't get access to shared memory chunks from games. +1. Telemetry functions (Shift lights, displays, SimHub, etc), mostly because telemetry works only with proprietary soft, which can't get access to shared memory chunks from games. 2. `Firmware Update` function. Use Windows PC or Windows VM at the moment. 3. Setup through MOZA PitHouse even with [some tweaking](#how-to-set-up-a-base-parameters)) @@ -56,35 +52,10 @@ To unload module: ## How to set up a base parameters? +### MOZA For now, please, use [Android App](https://play.google.com/store/apps/details?id=com.gudsen.mozapithouse) -### Non working method -You can try to setup MOZA PitHouse with Wine. You need to tweak Wine prefix for them. - -That soft uses hidraw to set up a base. You need to create `udev` rule for allow access to hidraw device: -``` -echo 'KERNEL=="hidraw*", ATTRS{idVendor}=="346e", MODE="0660", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/11-moza.rules - -udevadm control --reload-rules && udevadm trigger -``` - -Then you need to force MOZA soft to use hidraw, not SDL, to find devices: -1. Create new Wine prefix for them: - - `mkdir ~/moza-wine` -2. Launch regedit in prefix: - - `WINEPREFIX=$HOME/moza-wine wine regedit` -3. Create two keys in - `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\winebus`: - - * `DisableInput` (DWORD) - set to `1`; - * `Enable SDL` (DWORD) - set to `0`; (yes, variable name contains space) -4. Now you can launch soft through that WINEPREFIX: - - `WINEPREFIX=$HOME/moza-wine wine MOZA\ Pit\ House.exe` - launch your PitHouse from installation directory. - ## Known issues with the driver 1. Firmware update does not work. Please use Windows machine or Windows VM for any firmware updates From fe6100696e3a19d55503d320585a7f320e24d624 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 29 May 2024 23:53:08 +0300 Subject: [PATCH 09/26] Update dkms.conf --- dkms.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dkms.conf b/dkms.conf index 0b193b1..0f32716 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,8 +1,8 @@ -PACKAGE_NAME="moza-ff" -PACKAGE_VERSION="0.0.1" +PACKAGE_NAME="new-pidff" +PACKAGE_VERSION="0.0.2" MAKE[0]="make KVERSION=$kernelver" CLEAN="make clean" -BUILT_MODULE_NAME[0]="hid-moza-ff" -DEST_MODULE_NAME[0]="hid-moza-ff" +BUILT_MODULE_NAME[0]="hid-new-pidff" +DEST_MODULE_NAME[0]="hid-new-pidff" DEST_MODULE_LOCATION[0]="/kernel/drivers/hid" AUTOINSTALL="yes" \ No newline at end of file From 4826a9d4ef752383d39e0669794ae629482dba9f Mon Sep 17 00:00:00 2001 From: Oleg Date: Thu, 30 May 2024 11:42:36 +0300 Subject: [PATCH 10/26] Remove infinite length quirk --- hid-pidff.c | 7 ++----- hid-pidff.h | 6 ------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/hid-pidff.c b/hid-pidff.c index 9bb4f73..e338b3a 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -303,10 +303,6 @@ static void pidff_set_effect_report(struct pidff_device *pidff, { /* check for device quirks */ unsigned short direction = effect->direction; - unsigned short length = effect->replay.length; - - if (pidff->quirks & PIDFF_QUIRK_FIX_0_INFINITE_LENGTH && length == 0) - length = 0xffff; if ((effect->type == FF_DAMPER || effect->type == FF_FRICTION || @@ -319,7 +315,8 @@ static void pidff_set_effect_report(struct pidff_device *pidff, pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; pidff->set_effect_type->value[0] = pidff->create_new_effect_type->value[0]; - pidff->set_effect[PID_DURATION].value[0] = length; + pidff->set_effect[PID_DURATION].value[0] = + effect->replay.length == 0 ? 0xffff : effect->replay.length; pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button; pidff->set_effect[PID_TRIGGER_REPEAT_INT].value[0] = diff --git a/hid-pidff.h b/hid-pidff.h index 5c78e15..517683f 100644 --- a/hid-pidff.h +++ b/hid-pidff.h @@ -4,12 +4,6 @@ /* PIDFF Quirks to solve issues with certain devices */ -/* - * Substitute 0 length with 0xffff to resolve issues with - * infinite effects coming from windows API -*/ -#define PIDFF_QUIRK_FIX_0_INFINITE_LENGTH BIT(0) - /* * Ignore direction for spring/damping/friction/inertia effects * and always set 16384 From 93a696d1c877807c29f41c080b6c8f0ef7b1a299 Mon Sep 17 00:00:00 2001 From: Oleg Date: Thu, 30 May 2024 12:06:14 +0300 Subject: [PATCH 11/26] Added code for no_delay quirk --- hid-pidff.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/hid-pidff.c b/hid-pidff.c index e338b3a..08a7c71 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -65,6 +65,10 @@ static const u8 pidff_set_effect[] = { 0x22, 0x50, 0x52, 0x53, 0x54, 0x56, 0xa7 }; +static const u8 pidff_set_effect_without_delay[] = { + 0x22, 0x50, 0x52, 0x53, 0x54, 0x56 +}; + #define PID_ATTACK_LEVEL 1 #define PID_ATTACK_TIME 2 #define PID_FADE_LEVEL 3 @@ -1084,10 +1088,23 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) { int envelope_ok = 0; - if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) { - hid_err(pidff->hid, "unknown set_effect report layout\n"); - return -ENODEV; + if (pidff->quirks & PIDFF_QUIRK_NO_DELAY_EFFECT) { + hid_dbg(pidff->hid, "Find fields for set_effect without delay\n"); + if (pidff_find_fields(pidff->set_effect, + pidff_set_effect_without_delay, + pidff->reports[PID_SET_EFFECT], \ + sizeof(pidff_set_effect_without_delay), 1)) { + hid_err(pidff->hid, "unknown set_effect report layout\n"); + return -ENODEV; + } } + else { + if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) { + hid_err(pidff->hid, "unknown set_effect report layout\n"); + return -ENODEV; + } + } + PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0); if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) { 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 12/26] 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"); From a6ec74f90d11d97f11098ed0b468d38750b8d2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 2 Jul 2024 10:47:22 +0200 Subject: [PATCH 13/26] Remove unneeded paramaters --- hid-pidff.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hid-pidff.c b/hid-pidff.c index 0411815..7551253 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -192,7 +192,6 @@ struct pidff_device { int pid_id[PID_EFFECTS_MAX]; unsigned quirks; - short autocenter_effect_ids[PID_AUTOCENTER_EFFECTS]; }; /* @@ -316,7 +315,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff, pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; pidff->set_effect_type->value[0] = pidff->create_new_effect_type->value[0]; - pidff->set_effect[PID_DURATION].value[0] = + pidff->set_effect[PID_DURATION].value[0] = effect->replay.length == 0 ? 0xffff : effect->replay.length; pidff->set_effect[PID_TRIGGER_BUTTON].value[0] = effect->trigger.button; @@ -1098,7 +1097,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) if (pidff->quirks & PIDFF_QUIRK_NO_DELAY_EFFECT) { hid_dbg(pidff->hid, "Find fields for set_effect without delay\n"); - if (pidff_find_fields(pidff->set_effect, + if (pidff_find_fields(pidff->set_effect, pidff_set_effect_without_delay, pidff->reports[PID_SET_EFFECT], \ sizeof(pidff_set_effect_without_delay), 1)) { @@ -1112,7 +1111,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) return -ENODEV; } } - + PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0); if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) { From 9d9e4c47bde79ab97ab7f2615fcfe8e19f150662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 2 Jul 2024 10:45:44 +0200 Subject: [PATCH 14/26] Update build configs --- Kbuild | 2 +- dkms.conf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Kbuild b/Kbuild index 02cf0ff..acd2cc0 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,3 @@ obj-m := hid-new-pidff.o -hid-new-pidff-y := hid-newpidff.o hid-pidff.o +hid-new-pidff-y := hid-universal-pidff.o hid-pidff.o ccflags-y := -Idrivers/hid diff --git a/dkms.conf b/dkms.conf index 0f32716..6beaf8c 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,8 +1,8 @@ -PACKAGE_NAME="new-pidff" +PACKAGE_NAME="universal-pidff" PACKAGE_VERSION="0.0.2" MAKE[0]="make KVERSION=$kernelver" CLEAN="make clean" -BUILT_MODULE_NAME[0]="hid-new-pidff" -DEST_MODULE_NAME[0]="hid-new-pidff" +BUILT_MODULE_NAME[0]="hid-univesal-pidff" +DEST_MODULE_NAME[0]="hid-universal-pidff" DEST_MODULE_LOCATION[0]="/kernel/drivers/hid" -AUTOINSTALL="yes" \ No newline at end of file +AUTOINSTALL="yes" From 33a99c7458ee154f18b20f6db15d73397a1a7b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 2 Jul 2024 11:52:46 +0200 Subject: [PATCH 15/26] Add field value clamping functionality --- hid-pidff.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/hid-pidff.c b/hid-pidff.c index 7551253..710f6a5 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -213,6 +213,36 @@ static int pidff_rescale_signed(int i, struct hid_field *field) field->logical_minimum / -0x8000; } +/* + * Clamp minimum value for the given field + */ +static int pidff_clamp_min(int i, struct hid_field *field) +{ + int ret = i < field->logical_minimum ? field->logical_minimum : i; + pr_debug("clamped min value from %d to %d\n", i, ret); + return ret; +} + +/* + * Clamp maximum value for the given field + */ +static int pidff_clamp_max(int i, struct hid_field *field) +{ + int ret = i > field->logical_maximum ? field->logical_maximum : i; + pr_debug("clamped max value from %d to %d\n", i, ret); + return ret; +} + +/* + * Clamp value for the given field + */ +static int pidff_clamp(int i, struct hid_field *field) +{ + i = pidff_clamp_min(i, field); + i = pidff_clamp_max(i, field); + return i; +} + static void pidff_set(struct pidff_usage *usage, u16 value) { usage->value[0] = pidff_rescale(value, 0xffff, usage->field); @@ -359,7 +389,7 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_periodic[PID_OFFSET], effect->u.periodic.offset); pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); - pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; + pidff->set_periodic[PID_PERIOD].value[0] = pidff_clamp(effect->u.periodic.period, pidff->set_periodic[PID_PERIOD].field); hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC], HID_REQ_SET_REPORT); From ffa4a05a1b295ba0cf8e90ba57fa1883ef457598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Paku=C5=82a?= Date: Tue, 2 Jul 2024 11:55:36 +0200 Subject: [PATCH 16/26] Update attack/fade logging --- hid-pidff.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hid-pidff.c b/hid-pidff.c index 710f6a5..0954721 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -285,7 +285,11 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length; pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length; - hid_dbg(pidff->hid, "attack %u => %d\n", + hid_dbg(pidff->hid, "attack level %u => %d\n", + envelope->attack_level, + pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); + + hid_dbg(pidff->hid, "fade level %u => %d\n", envelope->attack_level, pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); From 1da641aee464cbb38ad3cb0c05d2c61c4c998c39 Mon Sep 17 00:00:00 2001 From: Lawstorant Date: Fri, 12 Jul 2024 15:46:42 +0200 Subject: [PATCH 17/26] Explain WHEEL_DIRECTION_FIX value --- hid-pidff.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hid-pidff.c b/hid-pidff.c index 0954721..5174036 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -25,6 +25,14 @@ #define PID_EFFECTS_MAX 64 +/* + * This is 16384 or 90 degrees in polar coordinates (up) + * Racing games exclusively use polar coordinates but sometimes + * SDL/Proton mess with this value as they try to do + * some conversions to fix FFB for flight sticks + */ +#define PIDFF_FIXED_DIRECTION 0x4000 + /* Report usage table used to put reports into an array */ #define PID_SET_EFFECT 0 @@ -343,7 +351,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff, unsigned short direction = effect->direction; if (pidff->quirks & PIDFF_QUIRK_FIX_WHEEL_DIRECTION) - direction = 0x4000; + direction = PIDFF_FIXED_DIRECTION; pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; From 83d1374b63618051078e85e608c3f5a85c183172 Mon Sep 17 00:00:00 2001 From: Lawstorant Date: Fri, 12 Jul 2024 15:47:24 +0200 Subject: [PATCH 18/26] Mention Boxflat in the README --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 503be39..cddbe27 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,7 @@ And that's basically it ## What devices are supported? ### Bases: 1. MOZA R3, R5, R9, R12, R16, R21 -1. ... - -### Wheel rims (others yet untested): -1. MOZA RS V2 (with Moza wheelbases) +2. ... ## What works? 1. FFB (all effects from device descriptor) @@ -51,13 +48,13 @@ To unload module: `sudo rmmod hid_moza_ff` ## How to set up a base parameters? - ### MOZA -For now, please, use [Android App](https://play.google.com/store/apps/details?id=com.gudsen.mozapithouse) +**[Boxflat](https://github.com/Lawstorant/boxflat)** is a Linux Pit House alternative made by [@Lawstorant](https://github.com/Lawstorant) +**[Android App](https://play.google.com/store/apps/details?id=com.gudsen.mozapithouse)** ## Known issues with the driver -1. Firmware update does not work. Please use Windows machine or Windows VM for any firmware updates +- Buttons above 80 simply don't show up. This is a Linux limitation and we're trying to fix that in the upstream ## Known issues with the firmware You tell me please From dea4e51be58471c1c03ddb0c4eec55867c423144 Mon Sep 17 00:00:00 2001 From: Lawstorant Date: Sat, 13 Jul 2024 15:59:13 +0200 Subject: [PATCH 19/26] Fix dkms build --- dkms.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dkms.conf b/dkms.conf index 6beaf8c..49f8865 100644 --- a/dkms.conf +++ b/dkms.conf @@ -1,8 +1,8 @@ PACKAGE_NAME="universal-pidff" -PACKAGE_VERSION="0.0.2" +PACKAGE_VERSION="0.0.3" MAKE[0]="make KVERSION=$kernelver" CLEAN="make clean" -BUILT_MODULE_NAME[0]="hid-univesal-pidff" -DEST_MODULE_NAME[0]="hid-universal-pidff" +BUILT_MODULE_NAME[0]="hid-new-pidff" +DEST_MODULE_NAME[0]="hid-universal-ff" DEST_MODULE_LOCATION[0]="/kernel/drivers/hid" AUTOINSTALL="yes" From b0867e2e6ce6cb50ded971086c82bdcc067c99bf Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:26:34 +0300 Subject: [PATCH 20/26] Fix BUILD_MODULE_NAME in dkms.conf --- dkms.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dkms.conf b/dkms.conf index 49f8865..6a67a4e 100644 --- a/dkms.conf +++ b/dkms.conf @@ -2,7 +2,7 @@ PACKAGE_NAME="universal-pidff" PACKAGE_VERSION="0.0.3" MAKE[0]="make KVERSION=$kernelver" CLEAN="make clean" -BUILT_MODULE_NAME[0]="hid-new-pidff" +BUILT_MODULE_NAME[0]="hid-universal-pidff" DEST_MODULE_NAME[0]="hid-universal-ff" DEST_MODULE_LOCATION[0]="/kernel/drivers/hid" AUTOINSTALL="yes" From 03d7fe30c7014d5c957894b9d8c19c772a6fc1b6 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:26:50 +0300 Subject: [PATCH 21/26] Rename main source file, fix KBuild --- Kbuild | 4 ++-- hid-universal-pidff.c => hid-pidff-wrapper.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) rename hid-universal-pidff.c => hid-pidff-wrapper.c (99%) diff --git a/Kbuild b/Kbuild index acd2cc0..b46b92c 100644 --- a/Kbuild +++ b/Kbuild @@ -1,3 +1,3 @@ -obj-m := hid-new-pidff.o -hid-new-pidff-y := hid-universal-pidff.o hid-pidff.o +obj-m := hid-universal-pidff.o +hid-universal-pidff-y := hid-pidff-wrapper.o hid-pidff.o ccflags-y := -Idrivers/hid diff --git a/hid-universal-pidff.c b/hid-pidff-wrapper.c similarity index 99% rename from hid-universal-pidff.c rename to hid-pidff-wrapper.c index 2b8dfb7..ab53744 100644 --- a/hid-universal-pidff.c +++ b/hid-pidff-wrapper.c @@ -83,6 +83,7 @@ err: static int universal_pidff_input_configured(struct hid_device *hdev, struct hid_input *hidinput) { + // Remove fuzz and deadzone struct input_dev *input = hidinput->input; input_set_abs_params(input, ABS_X, input->absinfo[ABS_X].minimum, input->absinfo[ABS_X].maximum, 0, 0); From 79f47bd686ade915165d747b1bb80496ffb51f43 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:27:01 +0300 Subject: [PATCH 22/26] Universal README file --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cddbe27..ce0cc8e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Force feedback support for MOZA steering wheels +# Patched PIDFF driver for Linux -Linux module driver for MOZA driving wheels. +Linux PIDFF driver with useful patches. Primarily targeting Direct Drive wheelbases. -MOZA wheels are basically DirectInput wheels. -In that repository - copy of pidff driver from 6.6 kernel with some changes around infinite length effects (like that https://github.com/berarma/ffbtools/issues/26) +Most DirectDrive wheelbases are basically DirectInput wheels. +In that repository - pidff driver with some changes, which allows most of the direct drive wheels to work And that's basically it @@ -20,32 +20,32 @@ And that's basically it ## What does not work? 1. Telemetry functions (Shift lights, displays, SimHub, etc), mostly because telemetry works only with proprietary soft, which can't get access to shared memory chunks from games. 2. `Firmware Update` function. Use Windows PC or Windows VM at the moment. -3. Setup through MOZA PitHouse even with [some tweaking](#how-to-set-up-a-base-parameters)) +3. Setup through proprietary software. May require [some tweaking](#how-to-set-up-a-base-parameters)) ## How to use this driver? -There's an [AUR packege](https://aur.archlinux.org/packages/moza-ff-dkms-git) for Arch Linux maintained by @Lawstorant +There's an [AUR packege](https://aur.archlinux.org/packages/universal-ff-dkms-git) for Arch Linux maintained by @Lawstorant Alternatively, you can install it through DKMS or manually. ### DKMS 1. Install `dkms` -2. Clone repository to `/usr/src/moza-ff` +2. Clone repository to `/usr/src/universal-pidff` 3. Install the module: -`sudo dkms install /usr/src/moza-ff` +`sudo dkms install /usr/src/universal-pidff` 4. Update initramfs: `sudo update-initramfs -u` 5. Reboot To remove module: -`sudo dkms remove moza-ff/ --all` +`sudo dkms remove universal-ff/ --all` ### Manually 1. Install `linux-headers-$(uname -r)` 2. Clone repository 3. `make` -4. `sudo insmod hid-moza-ff.ko` +4. `sudo insmod hid-universal-ff.ko` To unload module: -`sudo rmmod hid_moza_ff` +`sudo rmmod hid_universal_ff` ## How to set up a base parameters? ### MOZA From d449f45904e1479fcfc2aa40ed4b8ffa3e927167 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:34:10 +0300 Subject: [PATCH 23/26] Clarify pidff_clamp function usage --- hid-pidff.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hid-pidff.c b/hid-pidff.c index 5174036..2e7516c 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -401,7 +401,12 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_periodic[PID_OFFSET], effect->u.periodic.offset); pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); - pidff->set_periodic[PID_PERIOD].value[0] = pidff_clamp(effect->u.periodic.period, pidff->set_periodic[PID_PERIOD].field); + // Actually we just can use clamp macro here + // include/linux/kernel.h#L59 + // But for the debug purposes we're leaving it as is + pidff->set_periodic[PID_PERIOD].value[0] = + pidff_clamp(effect->u.periodic.period, + pidff->set_periodic[PID_PERIOD].field); hid_hw_request(pidff->hid, pidff->reports[PID_SET_PERIODIC], HID_REQ_SET_REPORT); From 94547c9bfc81aa41672a7904da7e2f94f2ba8cce Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:38:33 +0300 Subject: [PATCH 24/26] Pretty comments --- hid-pidff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hid-pidff.c b/hid-pidff.c index 2e7516c..6657731 100644 --- a/hid-pidff.c +++ b/hid-pidff.c @@ -401,8 +401,8 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, pidff_set_signed(&pidff->set_periodic[PID_OFFSET], effect->u.periodic.offset); pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); - // Actually we just can use clamp macro here - // include/linux/kernel.h#L59 + // Actually we just can use clamp macro + // from include/linux/kernel.h#L59 // But for the debug purposes we're leaving it as is pidff->set_periodic[PID_PERIOD].value[0] = pidff_clamp(effect->u.periodic.period, From b3ab9e9989a3b715a63e34e61a65311b8659d2f0 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 03:59:02 +0300 Subject: [PATCH 25/26] More clarifications in README.md --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ce0cc8e..55dbf06 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,15 @@ -# Patched PIDFF driver for Linux +# Universal Force Feedback driver for Linux -Linux PIDFF driver with useful patches. Primarily targeting Direct Drive wheelbases. +Linux PIDFF driver with useful patches for initialization of FFB devices. Primarily targeting Direct Drive wheelbases. -Most DirectDrive wheelbases are basically DirectInput wheels. -In that repository - pidff driver with some changes, which allows most of the direct drive wheels to work +## What's different between this and native pidff driver? +That driver allows most DirectDrive wheelbases to initialize and work. +Most of the DirectDrive wheelbases are basically DirectInput wheels, but with some caveats, which Windows allows, but pidff doesn't. +In that repository - pidff driver with some changes, which allows most of the DirectDrive wheelbases to work. + +1. Added quirks for better initialization rules for different wheelbases (MOZA, VRS, Cammus) +2. Fixes for infinite-length effects +3. Fixes for out-of-bounds values (no more spam in kernel logs) And that's basically it From d9ac2dbbb1122145d08d5d79e708796527101023 Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 15 Jul 2024 04:01:19 +0300 Subject: [PATCH 26/26] Fix DEST_MODULE_NAME --- dkms.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dkms.conf b/dkms.conf index 6a67a4e..aebd3b5 100644 --- a/dkms.conf +++ b/dkms.conf @@ -3,6 +3,6 @@ PACKAGE_VERSION="0.0.3" MAKE[0]="make KVERSION=$kernelver" CLEAN="make clean" BUILT_MODULE_NAME[0]="hid-universal-pidff" -DEST_MODULE_NAME[0]="hid-universal-ff" +DEST_MODULE_NAME[0]="hid-universal-pidff" DEST_MODULE_LOCATION[0]="/kernel/drivers/hid" AUTOINSTALL="yes"