diff mbox series

[v5,09/12] HID: pidff: Stop all effects before enabling actuators

Message ID 20250119131356.1006582-10-tomasz.pakula.oficjalny@gmail.com (mailing list archive)
State New
Headers show
Series HID: Upgrade the generic pidff driver and add hid-universal-pidff | expand

Commit Message

Tomasz Pakuła Jan. 19, 2025, 1:13 p.m. UTC
Some PID compliant devices automatically play effects after boot (i.e.
autocenter spring) that prevent the rendering of other effects since
it is done outside the kernel driver.

This makes sure all the effects currently played are stopped after
resetting the device.
It brings compatibility to the Brunner CLS-P joystick and others

Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
---
 drivers/hid/usbhid/hid-pidff.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Comments

Oliver Neukum Jan. 21, 2025, 10:10 a.m. UTC | #1
On 19.01.25 14:13, Tomasz Pakuła wrote:
> Some PID compliant devices automatically play effects after boot (i.e.
> autocenter spring) that prevent the rendering of other effects since
> it is done outside the kernel driver.
> 
> This makes sure all the effects currently played are stopped after
> resetting the device.
> It brings compatibility to the Brunner CLS-P joystick and others

Hi,

it seems to me that the same thing would happen upon resumption
from S4. Will this be handled?

	Regards
		Oliver
Tomasz Pakuła Jan. 21, 2025, 1:18 p.m. UTC | #2
On Tue, 21 Jan 2025 at 11:10, Oliver Neukum <oneukum@suse.com> wrote:
>
> On 19.01.25 14:13, Tomasz Pakuła wrote:
> > Some PID compliant devices automatically play effects after boot (i.e.
> > autocenter spring) that prevent the rendering of other effects since
> > it is done outside the kernel driver.
> >
> > This makes sure all the effects currently played are stopped after
> > resetting the device.
> > It brings compatibility to the Brunner CLS-P joystick and others
>
> Hi,
>
> it seems to me that the same thing would happen upon resumption
> from S4. Will this be handled?
>
>         Regards
>                 Oliver
>

(Terribly sorry for double mailing, I mistakenly hit reply instead of reply all)

I just tested this with my devices and it sadly doesn't handle sleep properly.
If a device is powered off then back on during sleep, the driver seems to be
unaware of it and keeps on chugging along like nothing happened.

This causes two things to happen:
1. FFB breaks in programs that have been running when going to sleep
2. Possible auto centering forces are back on and won't go away without a
   power cycle or a disconnect/connect.

Moreover, I noticed that the PID reset routine is only called upon during
device initialisation, while most other PID driver implementations don't do it
during device init and only call:
1. reset + enable actuators if an application initialises force feedback.
2. reset + stop all effects + disable actuators if there aren't any more
   effects left on the device after effect removal.

I'll update the reset function and access it differently, to better manage
device state and maybe hook up .suspend, .resume and .reset_resume
in the universal driver.

Managing this in the generic way will necessitate more extensive changes in the
hid-core but resetting every time when an application actually takes control
should be enough for now.

This driver is very old and I plan on chipping away at it more in the future
to make it less strict and work even better with all sorts of USB PID devices.

Tomasz
diff mbox series

Patch

diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c
index 6b4c4ecf4943..25ae80f68507 100644
--- a/drivers/hid/usbhid/hid-pidff.c
+++ b/drivers/hid/usbhid/hid-pidff.c
@@ -109,8 +109,9 @@  static const u8 pidff_pool[] = { 0x80, 0x83, 0xa9 };
 /* Special field key tables used to put special field keys into arrays */
 
 #define PID_ENABLE_ACTUATORS	0
-#define PID_RESET		1
-static const u8 pidff_device_control[] = { 0x97, 0x9a };
+#define PID_STOP_ALL_EFFECTS	1
+#define PID_RESET		2
+static const u8 pidff_device_control[] = { 0x97, 0x99, 0x9a };
 
 #define PID_CONSTANT	0
 #define PID_RAMP	1
@@ -1240,6 +1241,10 @@  static void pidff_reset(struct pidff_device *pidff)
 	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
 	hid_hw_wait(hid);
 
+	pidff->device_control->value[0] = pidff->control_id[PID_STOP_ALL_EFFECTS];
+	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);
+	hid_hw_wait(hid);
+
 	pidff->device_control->value[0] =
 		pidff->control_id[PID_ENABLE_ACTUATORS];
 	hid_hw_request(hid, pidff->reports[PID_DEVICE_CONTROL], HID_REQ_SET_REPORT);