[PATCH v2] Input: xpad - fix button mapping on Razer Atrox Xbox One
Vernon Di Carlo <[email protected]> Fri, 7 Aug 2026 09:41:53 -0500
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
The Razer Atrox Arcade Stick for Xbox One (1532:0a00) does not use the standard Xbox One input layout for its shoulder and trigger buttons. USB captures show that LB and RB are reported in bits 5 and 4 of byte 5 respectively, opposite to the standard Xbox One mapping. The digital LT and RT states are reported in bits 7 and 6 of byte 22 instead of the standard analog trigger fields. As a result, xpad currently reports LB and RB swapped and does not report LT or RT at all. Add an Atrox-specific mapping quirk to swap LB/RB and report LT/RT from their actual locations. Tested with a Razer Atrox Arcade Stick for Xbox One, USB ID 1532:0a00. Signed-off-by: Vernon Di Carlo <[email protected]> --- Notes: Changes in v2: - Reject short Atrox input packets instead of falling back to the standard Xbox One trigger layout. drivers/input/joystick/xpad.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index feb8f368f..00de9145e 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -50,6 +50,7 @@ #define MAP_PADDLES BIT(4) #define MAP_PROFILE_BUTTON BIT(5) #define MAP_SHARE_OFFSET BIT(6) +#define MAP_ATROX BIT(7) #define DANCEPAD_MAP_CONFIG (MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) @@ -280,7 +281,8 @@ static const struct xpad_device { { 0x1430, 0xf801, "RedOctane Controller", 0, XTYPE_XBOX360 }, { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 }, { 0x146b, 0x0604, "Bigben Interactive DAIJA Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, - { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, + { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", + MAP_TRIGGERS_TO_BUTTONS | MAP_ATROX, XTYPE_XBOXONE }, { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, { 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE }, { 0x1532, 0x0a57, "Razer Wolverine V3 Pro (Wired)", 0, XTYPE_XBOX360 }, @@ -1079,6 +1081,9 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char error); } } else if (data[0] == GIP_CMD_INPUT) { /* The main valid packet type for inputs */ + if ((xpad->mapping & MAP_ATROX) && len <= 22) + return; + /* menu/view buttons */ input_report_key(dev, BTN_START, data[4] & BIT(2)); input_report_key(dev, BTN_SELECT, data[4] & BIT(3)); @@ -1110,8 +1115,13 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char } /* TL/TR */ - input_report_key(dev, BTN_TL, data[5] & BIT(4)); - input_report_key(dev, BTN_TR, data[5] & BIT(5)); + if (xpad->mapping & MAP_ATROX) { + input_report_key(dev, BTN_TL, data[5] & BIT(5)); + input_report_key(dev, BTN_TR, data[5] & BIT(4)); + } else { + input_report_key(dev, BTN_TL, data[5] & BIT(4)); + input_report_key(dev, BTN_TR, data[5] & BIT(5)); + } /* stick press left/right */ input_report_key(dev, BTN_THUMBL, data[5] & BIT(6)); @@ -1133,10 +1143,15 @@ static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char /* triggers left/right */ if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { - input_report_key(dev, BTN_TL2, - (__u16) le16_to_cpup((__le16 *)(data + 6))); - input_report_key(dev, BTN_TR2, - (__u16) le16_to_cpup((__le16 *)(data + 8))); + if (xpad->mapping & MAP_ATROX) { + input_report_key(dev, BTN_TL2, data[22] & BIT(7)); + input_report_key(dev, BTN_TR2, data[22] & BIT(6)); + } else { + input_report_key(dev, BTN_TL2, + (__u16) le16_to_cpup((__le16 *)(data + 6))); + input_report_key(dev, BTN_TR2, + (__u16) le16_to_cpup((__le16 *)(data + 8))); + } } else { input_report_abs(dev, ABS_Z, (__u16) le16_to_cpup((__le16 *)(data + 6))); -- 2.53.0