Skip to content

HID: asus: fix BTN_TYPE_KB remap code table (set-2 scancodes, hw-validated) - #8

Open
jlobue10 wants to merge 14 commits into
NeroReflex:allyfrom
jlobue10:ally-kb-code-table
Open

HID: asus: fix BTN_TYPE_KB remap code table (set-2 scancodes, hw-validated)#8
jlobue10 wants to merge 14 commits into
NeroReflex:allyfrom
jlobue10:ally-kb-code-table

Conversation

@jlobue10

@jlobue10 jlobue10 commented Aug 3, 2026

Copy link
Copy Markdown

Summary

The ally_btn_codes BTN_TYPE_KB values are PS/2 set-2 scancodes of the key the MCU will emit — the MCU synthesizes a real keyboard-page usage on the keyboard interface when a kb-remapped button is pressed. Six entries in the table do not match set-2, so six KB_* names emit the wrong key (or nothing), and three useful names are missing. This PR fixes the table only; every changed entry was hardware-validated before and after on an Xbox Ally X (DMI RC73XA, MCU FW FGA80100.RC73XA.325), on eb5d9d5 built against 7.2.0-rc4.

How it was found

A full remap matrix (all 16 buttons remapped to KB_F14, expecting F14) failed 16/16 with a perfectly uniform wrong result: every button emitted KEY_F15 — as a real usage 0x7006a on the keyboard interface, not the 0xff3100a5 vendor fallback, so the remap applied and only the code translation was off. Pad/mouse/media remap types, sysfs round-trips and restores all passed in the same run, exonerating the CMD_SET_MAPPING packet path.

Probing more names pinned the semantics:

name written code sent emitted usage key seen set-2 meaning of code
KB_F14 0x18 0x6a KEY_F15 F15
KB_F15 0x10 0x69 KEY_F14 F14
KB_F12 0x07 0x45 KEY_F12 F12 (correct)
KB_F1 0x50 0x71 KEY_PROG1 F22
KB_F3 0x40 0x6f KEY_F20 F20
KB_F2 0x60 nothing not a set-2 code
KB_LEFT_ARROW 0x91 0x48 KEY_PAUSE duplicates KB_PAUSE

All observations match set-2 exactly. The KB_F1 case is the nastiest: the emitted usage 0x71 (F22) is the same usage the right-front-button long-press rides, so the driver's own asus_input_mapping handling turns "remap to F1" into KEY_PROG1 — a remap that silently triggers the front-button path.

Everything else in the table — letters, digits, punctuation, ESC, F4–F6, F8–F12, the entire numpad — is textbook set-2 and correct.

The fix

Changed entries:

KB_F1          0x50 -> 0x05
KB_F2          0x60 -> 0x06
KB_F3          0x40 -> 0x04
KB_F14         0x18 -> 0x10
KB_F15         0x10 -> 0x18
KB_LEFT_ARROW  0x91 -> 0x9A

Added: KB_F13 (0x08), KB_I (0x43 — the letter I was missing), KB_SLASH (0x4A — main-row / was missing). Inserted after existing entries so the hardcoded ally_btn_codes[18]/[19] KB_M2/KB_M1 references keep their indices.

KB_F7 (0x80) deliberately left unchanged: it does not match set-2 (0x83) but is hardware-verified to emit F7 correctly — it appears to live in the vendor-custom (≥0x80) range.

Validation of the fix

Fixed build swapped in live on the same boot; button A remapped through every affected name — 9/9 correct: KB_F14→F14 (usage 0x69), KB_F15→F15 (0x6a), KB_F13→F13 (0x68), KB_F1→F1 (0x3a), KB_F2→F2 (0x3b), KB_F3→F3 (0x3c), KB_LEFT_ARROW→Left (0x50), KB_SLASH→/ (0x38), KB_I→I (0x0c).

Same-boot regression matrix on plain eb5d9d5 (in-tree): full button matrix 25/25 (side-attributed front buttons: left F16 short / F17 long, right PROG1 short and long), suspend/resume ×3 s2idle 41/41, ×2 with MCU powersave (reset_resume path) 29/29, kmsg clean throughout.

Two corrections to our 2026-07-24 reports (PR #2 era)

  1. Paddle side attribution: btn_m1 is the LEFT paddle, btn_m2 the RIGHT. Settled by remapping only btn_m1 to KB_F12 and pressing each paddle (left emitted F12; right stayed on its default F15 / vendor 0xa5). Our July claim that M1 was the right paddle came from a run contaminated by this very table bug: with M1→KB_F14 / M2→KB_F15 remapped, the swapped F14/F15 codes made correct pressing look like the paddles were crossed.
  2. Our suggestion back then that the M2-first pair ordering in Luke Jones' driver was wrong for this hardware should be disregarded — it rested on the same contaminated run.

Unchanged and still true: at their KB_M1/KB_M2 defaults both paddles emit the identical vendor event (5a a5 → KEY_F15), so sysfs remap remains the only way to distinguish them.

Suggested doc comment for the table

BTN_TYPE_KB values are PS/2 set-2 make codes of the key to emit (the MCU translates to a HID keyboard usage on the keyboard interface); values ≥0x80 are ASUS-custom assignments for modifiers/nav/paddles.

Happy to re-run any of this or extend coverage on request — full logs available.

🤖 Generated with Claude Code

NeroReflex and others added 14 commits July 28, 2026 17:34
The ROG ally needs to have the EC string sent back after resuming from
s2idle since the USB device can be turned completely off by the firmware
when mcu_powersave firmware-attribute is set to 1.

This may also be true for other laptops and certain features might stop
working after the device exit from sleep.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Implement the core functionality for ASUS handhelds:
- extend functionality of hid-asus if driver is enabled
- initialise the device to a "ready" state
- implement Ally X input mapping
- emit a single proper event for AC button long press

Assisted-by: Claude:claude-fable-5
Signed-off-by: Khamunetri Clark <khamunetriclark@gmail.com>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
Add the base configuration structures for the gamepad configuration,
detect capabilities and initialize the device in a known state.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
ASUS ROG Ally handhelds support the vibration strength to be configured:
add sysfs attributes to allow userspace configure motors vibration
intensity.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
ROG Ally devices supports configuring joysticks inner and outer range:
add sysfs attributes to allow userspace modifying the sensitivity
of those controllers.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
ROG Ally devices allows configuring inner and outer ranges for triggers
buttons on the back: allow userspace to configure the sesitivity by
exposing sysfs attributes.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
ROG Ally devices allow configuring the anti-deadzone parameter for
the resistive joysticks devices as over time those develops drift,
therefore allow userspace to configure the anti-deadzone by exposing
relevant sysfs attributes.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
ROG ally devices allows configuring the response curve of both joysticks,
therefore add the ability of userspace to modify the response curve by
exposing relevant sysfs attributes.

Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke Jones <luke@ljones.dev>
ROG ally devices supports a feature called turbo buttons that allows
the user to quickly toggle button state by keeping a button pressed,
therefore allow userspace to configure the feature by exposing
relevant sysfs attributes.

Assisted-by: claude-fable-5
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Khamunetri Clark <khamunetriclark@gmail.com>
Signed-off-by: Luke Jones <luke@ljones.dev>
Signed-off-by: Jonathan LoBue <jlobue10@gmail.com>
Add support for buttons remapping: the ability to assign different
button events to each one of the physical button on the device.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Luke Jones <luke@ljones.dev>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: John LoBue Jonathan LoBue <jlobue10@gmail.com>
ROG Ally devices can emulate either a mouse+keyboard (desktop mode)
or an gamepad device (xbox360 controller in ROG ally and a custom
DInput device on newer models): add support for switching the current
controller mode.

Signed-off-by: Luke Jones <luke@ljones.dev>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Unlike ROG ally the X version and following ones uses DInput protocol
and the force feedback needs to be implemented as its protocol is
vendor-specific, therefore add support for FF_RUMBLE with magnitude
scaling on a work-queue based approach to avoid using possibly
sleeping calls in atomic context.

Assisted-by: gpt-5.3-codex
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Khamunetri Clark <khamunetriclark@gmail.com>
Signed-off-by: Luke Jones <luke@ljones.dev>
ASUS ROG laptops supports a protocol called Aura to control LEDs over
multiple zones: this protocol allows changing effects, colors,
brightness and transitioning speed across different colors on certain
effects.

Add support for said protocol to allow complete customization of
LEDs mounted on the ROG ally and laid out the foundation for all
other laptops.

Assisted-by: glm-5.2
Assisted-by: claude-fable-5
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Khamunetri Clark <khamunetriclark@gmail.com>
The ally_btn_codes BTN_TYPE_KB values are PS/2 set-2 make codes of the
key the MCU emits (as a real keyboard-page usage on the keyboard
interface) when a kb-remapped button is pressed. Six entries did not
match set-2, so the corresponding KB_* names emitted the wrong key or
nothing, hardware-verified on an Xbox Ally X (MCU FW FGA80100.RC73XA.325):

  KB_F1  0x50 -> 0x05  (emitted F22; usage 0x71 then collides with the
                        front-button long-press handling -> KEY_PROG1)
  KB_F2  0x60 -> 0x06  (emitted nothing; 0x60 is not a valid code)
  KB_F3  0x40 -> 0x04  (emitted F20)
  KB_F14 0x18 -> 0x10  (emitted F15; swapped with KB_F15)
  KB_F15 0x10 -> 0x18  (emitted F14; swapped with KB_F14)
  KB_LEFT_ARROW 0x91 -> 0x9A  (duplicated KB_PAUSE and emitted Pause;
                        arrow block is 0x98/0x99/0x9A/0x9B)

Add missing entries KB_F13 (0x08), KB_I (0x43) and KB_SLASH (0x4A),
inserted after existing entries so the hardcoded ally_btn_codes[18]/[19]
KB_M2/KB_M1 references keep their indices. KB_F7 (0x80) is deliberately
left unchanged: it does not match set-2 (0x83) but is hardware-verified
to emit F7 correctly.

All 9 changed/added names validated on hardware after the fix, each
emitting exactly the expected usage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NeroReflex

Copy link
Copy Markdown
Owner

m1 being left I already spotted it and was silently correcting it while doing the fixing XD

Anyway... thanks. Integrated.

Now only AC/CC are missing

@kndclark

kndclark commented Aug 7, 2026

Copy link
Copy Markdown

Reproduced on a ROG Ally X (RC72LA)

  btn_a = KB_F8. Enter, then press A a few times... 
    >>> press the A button (5s)...
        event9: KEY_F8
        expected KEY_F8: MATCH

  btn_a = KB_F14. Enter, then press A a few times... 
    >>> press the A button (5s)...
        event9: KEY_F15
        expected KEY_F14: MISMATCH

  btn_a = KB_F15. Enter, then press A a few times... 
    >>> press the A button (5s)...
        event9: KEY_F14
        expected KEY_F15: MISMATCH

[2] PADDLE SLOT - btn_m1 only, identified by position
    Using KB_F8, whose code is verified correct on this device.

  Enter, then press the LEFT back paddle... 
    >>> press the LEFT paddle (5s)...
        event8: KEY_F15

  Enter, then press the RIGHT back paddle... 
    >>> press the RIGHT paddle (5s)...
        event9: KEY_F8

KB_F8 passing each time confirms the remap path and the measurement are sound. Same swap, second model.

Worth adding that this bites harder than it looks: I used KB_F15/KB_F14 as the probe codes in a test to determine which physical paddle btn_m1 drives, got an inverted result, and reverted a correct patch because of it. Re-running with KB_F8 gave the opposite answer. Anyone using those two names as test probes will silently get backwards results.

@jlobue10

jlobue10 commented Aug 7, 2026

Copy link
Copy Markdown
Author

Correction to item 1 of the "Corrections to earlier reports" section above — I got it backwards, and the original July attribution was right:

btn_m1 is the physically RIGHT rear paddle, btn_m2 the physically LEFT one. Re-verified on hardware 2026-08-07. The test run behind the "M1 = left" claim in this PR body was the contaminated one (paddles pressed opposite the prompt), not the July run.

This is also consistent across Ally generations — ROG Ally, ROG Ally X, and Xbox Ally X all put M1 on the right — so it matches ASUS's own labeling and the M1/M2 comments now on the ally branch (ALLY_BTN_M1 /* right rear paddle */, KB_M2 /* left rear paddle */) are correct as-is. Nothing in the code needs to change for this; it only affects documentation/comments.

Still true and unaffected: at their KB_M1/KB_M2 defaults both paddles emit the identical vendor event (5a a5 → KEY_F15), so sysfs remap remains the only way to tell them apart, and the set-2 table fixes in this PR stand as validated.

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.

3 participants