From: Siarhei Vishniakou svv@google.com
[ Upstream commit e9143268d259d98e111a649affa061acb8e13c5b ]
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@google.com Reviewed-by: Benjamin Tissoires bentiss@kernel.org Signed-off-by: Benjamin Tissoires bentiss@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Analysis of Commit: "HID: playstation: Center initial joystick axes to prevent spurious events"
### 1. COMMIT MESSAGE ANALYSIS
The commit describes a clear, specific bug: - PlayStation gamepads (DualShock 4, DualSense) have joysticks that rest at value 128 (0x80) - The kernel initializes the axis value to 0 by default - When the first HID report arrives with the resting value of 128, the kernel interprets this as actual movement - This generates spurious EV_ABS events for non-existent movement - The problem causes Android CTS test failures and potentially confuses userspace applications
The bug has user-visible impact ("Reported-by" pattern implied through CTS test context).
### 2. CODE CHANGE ANALYSIS
**The fix is minimal and surgical:** ```c gamepad->absinfo[ABS_X].value = 128; gamepad->absinfo[ABS_Y].value = 128; gamepad->absinfo[ABS_RX].value = 128; gamepad->absinfo[ABS_RY].value = 128; ```
- 5 lines added (1 comment + 4 value assignments) - Single file: `drivers/hid/hid-playstation.c` - Single function: `ps_gamepad_create()` - Only affects joystick axes (ABS_X, ABS_Y, ABS_RX, ABS_RY), correctly leaves triggers (ABS_Z, ABS_RZ) at 0
**Technical correctness:** The fix is obviously correct. After `input_set_abs_params()` sets up the axis with range 0-255, manually setting `.value = 128` aligns the kernel's initial state with the hardware's physical resting position at center (128).
### 3. CLASSIFICATION
- **Type:** Bug fix (not a feature) - **Category:** Input device initialization fix - **No new API or behavior change:** Just corrects initial state values - **No new features:** Purely corrects existing incorrect behavior
### 4. SCOPE AND RISK ASSESSMENT
| Factor | Assessment | |--------|------------| | Lines changed | 5 (very small) | | Files changed | 1 | | Complexity | Trivial | | Subsystem | HID - PlayStation driver (mature) | | Risk of regression | Very low |
The change is confined to initialization code and cannot affect any existing logic paths. Setting an initial value cannot break anything because: 1. The value 128 is within the valid range (0-255) 2. The hardware reports 128 at rest anyway 3. This aligns kernel state with reality
### 5. USER IMPACT
**Who is affected:** - All users of DualShock 4 and DualSense controllers - Android users (CTS compliance) - Applications that validate initial input state
**Severity:** Medium - Not a crash or data corruption, but: - Causes spurious input events at device connect - Breaks CTS conformance tests - May confuse input-sensitive applications
### 6. STABILITY INDICATORS
- **Reviewed-by:** Benjamin Tissoires (HID maintainer) ✓ - **Signed-off-by:** Maintainer sign-off ✓ - The fix is simple enough to verify correctness by inspection
### 7. DEPENDENCY CHECK
- No dependencies on other commits - `ps_gamepad_create()` has existed since the driver was introduced - Uses standard input subsystem patterns (`absinfo[].value`) - Should apply cleanly to any stable tree containing this driver
### STABLE KERNEL CRITERIA EVALUATION
| Criterion | Status | |-----------|--------| | Obviously correct and tested | ✓ Reviewed by maintainer | | Fixes a real bug | ✓ Spurious input events | | Important issue | ✓ Breaks CTS, affects popular hardware | | Small and contained | ✓ 5 lines, 1 file | | No new features | ✓ Pure correctness fix | | No new APIs | ✓ |
### RISK VS BENEFIT
**Benefits:** - Fixes spurious input events on popular consumer hardware - Fixes Android CTS test failures - Aligns kernel state with hardware reality - Affects millions of PlayStation controller users
**Risks:** - Essentially zero - the change is trivially correct - No logic changes, just initialization values
### CONCLUSION
This commit is an excellent candidate for stable backporting:
1. **Fixes a real bug** that causes spurious input events and test failures 2. **Small and surgical** - only 5 lines in one function 3. **Obviously correct** - aligns initial value with hardware's physical state 4. **Low risk** - cannot introduce regressions 5. **Well-reviewed** - HID maintainer reviewed and signed off 6. **Widely applicable** - affects popular consumer hardware (PlayStation controllers) 7. **No dependencies** - self-contained fix
The fix meets all stable kernel criteria: it's obviously correct, fixes a real bug, is small in scope, and introduces no new features. The fact that it fixes CTS compliance issues makes it particularly valuable for Android device manufacturers using stable kernels.
**YES**
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 128aa6abd10be..e4dfcf26b04e7 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -753,11 +753,16 @@ 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(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);