Re: [PATCH v2] HID: playstation: Center initial joystick axes to prevent spurious events
From: Siarhei Vishniakou
Date: Tue Feb 24 2026 - 17:48:40 EST
вт, 24 февр. 2026 г. в 13:10, Guenter Roeck <linux@xxxxxxxxxxxx>:
>
> On Tue, Nov 11, 2025 at 03:45:19PM -0800, Siarhei Vishniakou wrote:
> > When a new PlayStation gamepad (DualShock 4 or DualSense) is initialized,
> > the input subsystem sets the default value for its absolute axes (e.g.,
> > ABS_X, ABS_Y) to 0.
> >
> > However, the hardware's actual neutral/resting state for these joysticks
> > is 128 (0x80). This creates a mismatch.
> >
> > When the first HID report arrives from the device, the driver sees the
> > resting value of 128. The kernel compares this to its initial state of 0
> > and incorrectly interprets this as a delta (0 -> 128). Consequently, it
> > generates EV_ABS events for this initial, non-existent movement.
> >
> > This behavior can fail userspace 'sanity check' tests (e.g., in
> > Android CTS) that correctly assert no motion events should be generated
> > from a device that is already at rest.
> >
> > This patch fixes the issue by explicitly setting the initial value of the
> > main joystick axes (e.g., ABS_X, ABS_Y, ABS_RX, ABS_RY) to 128 (0x80)
> > in the common ps_gamepad_create() function.
> >
> > This aligns the kernel's initial state with the hardware's expected
> > neutral state, ensuring that the first report (at 128) produces no
> > delta and thus, no spurious event.
> >
> > Signed-off-by: Siarhei Vishniakou <svv@xxxxxxxxxx>
> > Reviewed-by: Benjamin Tissoires <bentiss@xxxxxxxxxx>
> > ---
> > drivers/hid/hid-playstation.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
> > index 1468fb11e39d..a145b5ea4405 100644
> > --- a/drivers/hid/hid-playstation.c
> > +++ b/drivers/hid/hid-playstation.c
> > @@ -718,11 +718,16 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
> > if (IS_ERR(gamepad))
> > return ERR_CAST(gamepad);
> >
> > + /* Set initial resting state for joysticks to 128 (center) */
> > input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
> > + gamepad->absinfo[ABS_X].value = 128;
>
> input_set_abs_params() can fail to allocate absinfo. If that happens,
> this will crash. AI suggests setting the value with input_abs_set_val()
> to ensure that the value is checked before dereferencing.
>
> Guenter
>
> > input_set_abs_params(gamepad, ABS_Y, 0, 255, 0, 0);
> > + gamepad->absinfo[ABS_Y].value = 128;
> > input_set_abs_params(gamepad, ABS_Z, 0, 255, 0, 0);
> > input_set_abs_params(gamepad, ABS_RX, 0, 255, 0, 0);
> > + gamepad->absinfo[ABS_RX].value = 128;
> > input_set_abs_params(gamepad, ABS_RY, 0, 255, 0, 0);
> > + gamepad->absinfo[ABS_RY].value = 128;
> > input_set_abs_params(gamepad, ABS_RZ, 0, 255, 0, 0);
> >
> > input_set_abs_params(gamepad, ABS_HAT0X, -1, 1, 0, 0);
> > --
> > 2.51.2.1041.gc1ab5b90ca-goo
The function `input_set_abs_params` is ill-formed. If this call can
fail, then it should return some kind of error result instead of void.
In addition, the function name doesn't suggest that it's going to be
doing any allocations.
So the (short-term) fix should be something like this:
/* Set initial resting state for joysticks to 128 (center) */
input_set_abs_params(gamepad, ABS_X, 0, 255, 0, 0);
+ if (gamepad->absinfo == NULL) {
+ // input_set_abs_params allocates "absinfo" struct, which could fail.
+ return ERR_CAST(gamepad);
+ }
A better long-term option would be to change the signature of
input_set_abs_params to return a bool, or to add an explicit
allocation step (looking at code search, there aren't too many places
using this API today, but this might break 3-rd party stuff).
Curious to hear maintainers' opinions on this.