Skip to content

HID: hid-oxp: fix and extend X2-family controller support - #13

Open
Grippy98 wants to merge 15 commits into
OpenGamingCollective:masterfrom
Grippy98:oxp3-fixup
Open

HID: hid-oxp: fix and extend X2-family controller support#13
Grippy98 wants to merge 15 commits into
OpenGamingCollective:masterfrom
Grippy98:oxp3-fixup

Conversation

@Grippy98

Copy link
Copy Markdown

This four-patch series fixes button mapping and extends RGB support for
ONEXPLAYER X2-family controllers, including the ONEXPLAYER 3 and X2 Mini Pro.

  • Correct the default M1/M2 mappings to F15/F16.
  • Support the three-page button-mapping format used by these controllers.
  • Add joystick-ring RGB control for zones 0x01, 0x02, and 0x07.
  • Add independent RGB devices for the Guide button and rear logo using
    zones 0x05 and 0x06.
  • Restore controller and RGB state after suspend/resume.
  • Restrict configuration ownership to USB interface 2 so additional FE00
    interfaces cannot overwrite the active driver state.
  • Improve transaction serialization, acknowledgement validation, retry
    handling, and teardown safety.

Testing

Tested on an ONEXPLAYER 3 running Bazzite 44 with kernel
7.2.0-ogc6.1.fc44.x86_64.

Verified:

  • Front controls and both rear paddles.
  • Correct Steam and Quick Access menu behavior.
  • Independent solid, breathing, brightness, and off control for the Guide
    button and rear logo.
  • Joystick-ring RGB control.
  • Simultaneous independent RGB states.
  • RGB restoration after suspend/resume.
  • Module build with W=1.
  • git diff --check and checkpatch.pl.

The X2 Mini Pro uses the same controller protocol and interface layout, but
this series has not yet been tested on physical X2 Mini Pro hardware.

AI assistance disclosure

An LLM assisted with protocol analysis, implementation, documentation, code
review, and test orchestration. I reviewed and signed off on the resulting
changes and performed the physical ONEXPLAYER 3 testing described above.

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nit for patch 2

With that addressed for v2,
Reviewed-by: Derek J. Clark derekjohn.clark@gmail.com

Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For patch 1, please add a fixes tag when up-streaming/

Reviewed-by: Derek J. Clark derekjohn.clark@gmail.com

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of comments for patch 3 but overall it isn't bad. The summary is

  • Make each individual fix for an issue a fixes patch. use a fixes tag with the sha of the patch that added the feature.
  • Instead of branching in gen 2, identify gen 3 early and make new paths, leaving as much existing code in place. This is to avoid regressions in hardware that is difficult to get tested.

Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For patch 4, I'd like to break it into 2 patches. The first will refactor the existing RGB to use a common LED array for all LEDS, so that they are all handled the same way. Use a void pointer for the state and a new type enum for the switch case for casting. The second patch can then expand on the new format to add the aux zones

Comment thread Documentation/ABI/testing/sysfs-driver-hid-oxp
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread Documentation/ABI/testing/sysfs-driver-hid-oxp
@Grippy98

Grippy98 commented Sep 3, 2026

Copy link
Copy Markdown
Author

Thanks for the review again - to make it easier to review I rebuilt it like you suggested as per-fix commits for the most part. So 1-10 are fixes, 11 is some group declarations and protocol definitions and then 12-15 is all X2/OXP3 changes.

Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c Outdated
Comment thread drivers/hid/hid-oxp.c
Comment thread drivers/hid/hid-oxp.c Outdated

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple nits before upstreaming, but none blocking for merging here. I still need to review the last 2 patches in detail but so far looks good.

Comment thread drivers/hid/hid-oxp.c

@pastaq pastaq left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good enough for now. I have a few nits remaining but nothing that can't be brought up on LKML. I'll do some testing on the F1 pro.

Please rebase the pr to clean up the extra 500 commits.

The default button map intends to assign F15 and F16 to M1 and M2, but
the selected mapping table indexes resolve to F16 and F17. Use indexes
47 and 48 so the programmed usages match the existing comments.

Assisted-by: LLM
Fixes: e4c850a ("HID: hid-oxp: Add Button Mapping Interface")
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Check the short Gen2 status header before reading its command, and require
a complete RGB status report before reading either generation's fields.
Use the supplied input length for the debug dump as well, so a short
report cannot cause an out-of-bounds read while logging.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Multiply the hardware brightness level by the LED brightness range before
dividing by four. Dividing first reported every intermediate hardware
level as zero instead of 25, 50 or 75 percent.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Do not replace the cached RGB state with a Gen2 status report whose enable,
speed or hardware brightness fields are outside the supported ranges.

Fixes: 252c4bf ("HID: hid-oxp: Add Second Generation RGB Control")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
The controller accepts eight-bit RGB components, but the sub-LED channel
maximum currently inherits the 0-100 overall brightness range. This
prevents userspace from selecting channel intensities above 100.

Set each channel maximum to 255 and use the multicolor LED core helper to
scale components with the requested brightness. This also replaces the
private truncating calculation with the LED core's rounded calculation.

Keep the existing Gen1 and Gen2 color packet layouts unchanged.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
The transport mutex protects one report at a time, but changing an RGB
effect requires a status command followed by a color or effect command.
Serialize whole RGB transactions so sysfs and delayed brightness work do
not interleave these command sequences.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Set the requested effect before constructing its status command, since
monocolor uses maximum hardware brightness and software intensity scaling.
Previously entering or leaving monocolor used the old effect's brightness
policy. Restore the cached effect if either output command fails.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Configuration callbacks can queue delayed RGB, button-mapping, and MCU
initialization work. Normal removal previously closed the HID transport
without synchronously stopping that work, while a later configuration
probe failure could leave work queued as devres released its objects.

Track which work items have been initialized, reject new output once
teardown begins, disable initialized work synchronously, and drain an
in-flight transport write before closing the device. Use the same
shutdown path for normal removal and every probe-error unwind after work
can have been exposed.

This also avoids operating on uninitialized work for HID interfaces that
do not own configuration state.

Fixes: 84910c4 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Replace the shared driver state and mutable LED object with devm-managed
state owned by each configuration HID. Resolve callbacks through their
HID, LED or embedded work object instead of the last interface probed.

Hybrid devices have distinct Gen1 RGB and Gen2 controller interfaces.
Sharing the transport pointer and work state lets one overwrite the other.
Keep the HID drvdata pointer valid until LED and sysfs objects have been
released, then clear it before freeing the configuration allocation.

Fixes: 252c4bf ("HID: hid-oxp: Add Second Generation RGB Control")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
A Gen2 monocolor reply uses the same command value as the asynchronous MCU
reset notification. Treating every such report as a reset can schedule a
spurious controller reinitialization.

Track an outstanding monocolor write by command and zone under a per-HID
spinlock, and consume its matching acknowledgment before considering the
report a reset notification. Clear pending reply state during suspend and
teardown. A missing reply does not change legacy transport success
semantics.

For system suspend, disable and drain initialized configuration work and
reject new output while the device is suspended. Re-enable work on resume
and queue a fallback reinitialization after the documented MCU reset
interval. A qualifying reset notification can still bring that work
forward. Leave runtime autosuspend unchanged.

Fixes: 2f424f2 ("HID: hid-oxp: Add Second Generation Gamepad Mode Switch")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Collect protocol definitions and helper macros at the top of the file,
place the quirk structure with the other type declarations, and tidy
configuration field ordering and callback declaration formatting.

Keep this cleanup separate from the preceding behavioral fixes and the
new-controller feature patches.

Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
The ONEXPLAYER 3 and X2 Mini Pro need mapping format 0x02 and a third
page preserving the extra buttons' factory mappings. Use exact DMI
matches and select configuration interface 2; the other HID interfaces
remain available without duplicate configuration or LED registration.

Initialize each page with the selected format. Page three is fixed because
its factory encodings have no entries in the public mapping table.
Legacy devices keep their two-page format 0x20 transaction.

Fixes: e4c850a ("HID: hid-oxp: Add Button Mapping Interface")
Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Move the existing joystick-ring class device, color components, delayed
work, and cached settings into a per-LED wrapper owned by each HID
configuration. Use a tagged state pointer so later LED types can share
registration and work management without duplicating the lifecycle.

Track only fully initialized work items and walk that count when
quiescing, suspending, or resuming the configuration. Resolve LED callbacks
through their containing wrapper, preserving the LED core's drvdata.

Keep a single FULL joystick-ring LED and retain the existing Gen1/Gen2
55/57-byte RGB payloads, controls, and defaults. This commit adds no new
hardware protocol or lighting zones.

Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Select the X2/Gen3 RGB protocol early for the ONEXPLAYER 3 and X2 Mini Pro.
These controllers share the Gen2 HID usage page but require a 59-byte
color payload and writes to ring zones 1, 2 and 7. Keep the Gen1 55-byte
and legacy Gen2 57-byte color builders separate and unchanged.

Add dedicated Gen3 status, color, effect and brightness paths. Check its
known command/zone acknowledgments, retain cached color and effect when
status cannot report them, and retry one complete ring pass on failure.
Legacy transport success does not depend on receiving an acknowledgment.

Restore cached X2 RGB once after the final controller-mode change. Generic
ACK discrimination and suspend work management are preceding fixes; this
patch does not add RGB replay to older controllers.

Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
Add separate multicolor LED devices for the X2 guide button and rear logo
using Gen3 zones 5 and 6. Each LED retains independent color, brightness,
and monocolor or breathing effect state.

Use the common LED array and type-tagged state introduced earlier.
Protect auxiliary state snapshots with scoped spinlocks, serialize output
with other RGB operations, and retry a failed command once. Do not alter
an auxiliary zone until userspace has supplied valid state, and restore
valid cached settings after resume.

Expose these zones only on the matched ONEXPLAYER 3 and X2 Mini Pro.
Physical validation of the latter remains outstanding.

Document the auxiliary effects together with the existing joystick-ring
effects and add the previously omitted controller, mapping, rumble, and
ring-lighting ABI. Add the ABI file to the ONEXPLAYER HID maintainer
pattern.

Assisted-by: LLM
Signed-off-by: Andrei Aldea <andrei1998@gmail.com>
@Grippy98

Copy link
Copy Markdown
Author

Rebased, should be ready to merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants