[PATCH AUTOSEL 6.18] ALSA: hda/realtek: Fix headphone output on ASUS ROG Ally X
From: Sasha Levin
Date: Mon Aug 31 2026 - 12:32:29 EST
From: Matthew Schwartz <matthew.schwartz@xxxxxxxxx>
[ Upstream commit 335f7860846732477a9ce24f0db04dd253ba268c ]
The ASUS ROG Ally X (RC72LA, PCI SSID 0x1043:0x1eb3) with an ALC294
codec produces no sound from the headphone jack, and unplugging the
headphones can leave the speakers muted too.
The device uses ALC287_FIXUP_TAS2781_I2C, which chains into the
ThinkPad fixup chain. alc285_fixup_thinkpad_x1_gen7() makes the
headphone (pin 0x21) and speaker (pin 0x17) share DAC 0x03. That is
correct for a ThinkPad, but here the shared DAC is exposed as a
"Line Out" control that defaults to zero, so the headphones stay
silent when plugged in.
Add a dedicated fixup chain for the Ally X that sets up the TAS2781
amplifier and the headset jack without the ThinkPad DAC sharing, and
routes the speaker to DAC 0x02 so the headphone and speaker get
independent DACs.
Also, fixup the wrong product code (it's RC72LA, not RCLA72).
Signed-off-by: Matthew Schwartz <matthew.schwartz@xxxxxxxxx>
Link: https://patch.msgid.link/20260707005615.52889-1-matthew.schwartz@xxxxxxxxx
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
LLM Generated explanations, may be completely bogus:
# Stable Backport Analysis: ALSA HDA Realtek — ASUS ROG Ally X Headphone
Fix
**Local tree:** Linux **6.18.44** (`git describe HEAD` →
`v6.18.44-1-g2736c32da98b9`)
---
## PHASE 1: COMMIT MESSAGE FORENSICS
### Step 1.1: Subject Line
**Record:** `[ALSA: hda/realtek]` `[Fix]` — Fix headphone output on ASUS
ROG Ally X (RC72LA, PCI SSID 0x1043:0x1eb3).
### Step 1.2: Tags
**Record:**
| Tag | Value |
|-----|-------|
| Signed-off-by | Matthew Schwartz \<matthew.schwartz@xxxxxxxxx\>
(author) |
| Link | https://patch.msgid.link/20260707005615.52889-1-
matthew.schwartz@xxxxxxxxx |
| Signed-off-by | Takashi Iwai \<tiwai@xxxxxxx\> (ALSA maintainer merge)
|
| Fixes: | **Absent** (expected for manual review) |
| Cc: stable | **Absent** (expected) |
| Reported-by | **Absent** |
| Reviewed-by | **Absent** |
Notable: maintainer (Iwai) Signed-off-by is a quality signal. No
syzbot/fuzzer involvement.
### Step 1.3: Body Analysis
**Record:**
- **Bug:** ASUS ROG Ally X (RC72LA, ALC294 codec, SSID 0x1043:0x1eb3)
has no headphone jack audio; unplugging headphones can leave speakers
muted.
- **Symptom:** Silent headphones; speakers stuck muted after headphone
unplug.
- **Root cause:** Device matched to `ALC287_FIXUP_TAS2781_I2C`, which
chains into the ThinkPad fixup (`alc285_fixup_thinkpad_x1_gen7()`).
That fixup makes headphone pin 0x21 and speaker pin 0x17 share DAC
0x03 — correct for ThinkPads, wrong here. The shared DAC appears as a
"Line Out" control defaulting to zero, silencing headphones.
- **Fix approach:** Dedicated fixup chain routing speaker to DAC 0x02
(independent DACs), TAS2781 I2C amp setup, and generic headset jack
(not ThinkPad chain). Also corrects product name (RC72LA, not RCLA72).
### Step 1.4: Hidden Bug Fix?
**Record:** No — this is an explicit hardware audio routing bug fix, not
disguised cleanup.
---
## PHASE 2: DIFF ANALYSIS
### Step 2.1: Inventory
**Record:**
- **File:** `sound/hda/codecs/realtek/alc269.c` only
- **Scope:** ~20 lines added/changed; 2 new enum entries, 2 new fixup
table entries, 1 quirk table entry modified
- **Functions referenced (not modified):**
`alc285_fixup_speaker2_to_dac1`, `tas2781_fixup_tias_i2c`,
`alc_fixup_headset_jack` (via `ALC225_FIXUP_HEADSET_JACK`)
- **Classification:** Single-file, surgical hardware quirk fix
### Step 2.2: Code Flow Change
**Record:**
| Hunk | Before | After |
|------|--------|-------|
| Enum | No `ALC287_FIXUP_ASUS_ALLY_X*` entries | Two new fixup IDs
added |
| Fixup table | `ALC287_FIXUP_TAS2781_I2C` → ThinkPad headset chain |
New chain: `ALC287_FIXUP_ASUS_ALLY_X` → `alc285_fixup_speaker2_to_dac1`
→ `ALC287_FIXUP_ASUS_ALLY_X_I2C` → `tas2781_fixup_tias_i2c` →
`ALC225_FIXUP_HEADSET_JACK` |
| Quirk table | `0x1eb3` → `ALC287_FIXUP_TAS2781_I2C` ("ASUS Ally
RCLA72") | `0x1eb3` → `ALC287_FIXUP_ASUS_ALLY_X` ("ASUS Ally RC72LA") |
**Execution path:** Codec probe → PCI quirk match → fixup chain during
`HDA_FIXUP_ACT_PRE_PROBE` / build.
### Step 2.3: Bug Mechanism
**Record:** **Category (h): Hardware workaround / audio codec quirk.**
Wrong DAC routing from an inappropriate ThinkPad-derived fixup chain
causes zero-volume headphone output and broken speaker automute
behavior.
### Step 2.4: Fix Quality
**Record:**
- **Obviously correct:** Yes — mirrors established patterns in the same
file (e.g., `ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1` uses
`alc285_fixup_speaker2_to_dac1` + separate headset chain).
- **Minimal:** Yes — reuses existing fixup functions, no new logic.
- **Regression risk:** Very low — only affects PCI SSID 0x1043:0x1eb3;
other `ALC287_FIXUP_TAS2781_I2C` devices unchanged.
---
## PHASE 3: GIT HISTORY INVESTIGATION
### Step 3.1: Blame
**Record:** `git blame` on line 7162 shows the quirk was introduced in
commit `5d324e5159d9e` (2025-11-28, merge bringing in `alc269.c` for
6.18-rc8). Buggy assignment `0x1eb3 → ALC287_FIXUP_TAS2781_I2C` has been
present since `alc269.c` entered this tree.
### Step 3.2: Fixes: Tag
**Record:** No `Fixes:` tag. The buggy quirk assignment dates to initial
`alc269.c` import in 6.18. Not applicable to follow a Fixes: SHA.
### Step 3.3: Related File History
**Record:** Recent related commits in this tree:
- `5060592025103` — Fixed headphone jack on ASUS Xbox Ally
(RC73XA/RC73YA) by introducing `ALC287_FIXUP_TXNW2781_I2C_ASUS` (Cc:
stable)
- `819268882628f` — TAS2781 UEFI calibration skip for Xbox Ally X (Cc:
stable # 6.18)
- `acacb5b7109ac` — Initial Xbox Ally TAS2781 binding (Cc: stable #
6.17)
Same author (Matthew Schwartz) has prior Ally-family audio fixes.
Standalone fix, not part of a multi-patch series.
### Step 3.4: Author Context
**Record:** Matthew Schwartz is an active ALSA/HDA contributor with
multiple Ally-related fixes. Takashi Iwai (subsystem maintainer) merged
the patch.
### Step 3.5: Dependencies
**Record:** All required symbols exist in this tree:
- `alc285_fixup_speaker2_to_dac1` (line 2533)
- `tas2781_fixup_tias_i2c` (line 3245)
- `ALC225_FIXUP_HEADSET_JACK` (line 5214)
- `ALC287_FIXUP_TAS2781_I2C` (unchanged, still used by other devices)
**Can apply standalone:** Yes.
---
## PHASE 4: MAILING LIST AND EXTERNAL RESEARCH
### Step 4.1: Original Discussion
**Record:** `b4 dig -c <sha>` could not be run — commit hash is not
present as a commit object in this tree (only provided as candidate
diff). Link in commit message: https://patch.msgid.link/20260707005615.5
2889-1-matthew.schwartz@xxxxxxxxx. Lore.kernel.org and patch.msgid.link
both blocked by Anubis bot protection — **could not retrieve thread
content.**
### Step 4.2: Reviewers
**Record:** UNVERIFIED — could not fetch mailing list thread. Commit
message shows Iwai merge SOB only; no explicit Reviewed-by in provided
message.
### Step 4.3: Bug Report
**Record:** No external bug report links. Bug described in commit
message from hardware testing on the device itself.
### Step 4.4: Related Patches
**Record:** Related but independent Ally-family fixes exist in tree
(RC73XA calibration, RC73XA/YA TAS quirk). This patch targets RC72LA
(ROG Ally X), a different SSID.
### Step 4.5: Stable List History
**Record:** UNVERIFIED — lore.kernel.org inaccessible. Prior Ally fixes
in this tree were explicitly nominated for stable (Cc: stable tags on
`acacb5b7109ac`, `5060592025103`, `819268882628f`).
---
## PHASE 5: CODE SEMANTIC ANALYSIS
### Step 5.1: Key Functions
**Record:** Modified: fixup enum, `alc269_fixups[]`,
`alc269_fixup_tbl[]`. Called (unchanged):
`alc285_fixup_speaker2_to_dac1`, `tas2781_fixup_tias_i2c`,
`alc_fixup_headset_jack`.
### Step 5.2: Callers
**Record:** Fixup chain invoked during HDA codec probe/initialization
for matched PCI device 0x1043:0x1eb3 only. Triggered at boot/module load
on affected hardware.
### Step 5.3: Callees
**Record:**
- `alc285_fixup_speaker2_to_dac1` — overrides NID 0x17 connection list
to DAC 0x02 only
- `tas2781_fixup_tias_i2c` — binds TAS2781 I2C amplifier component
- `alc_fixup_headset_jack` — standard headset jack detection setup
### Step 5.4: Reachability
**Record:** Triggered automatically on every boot for ASUS ROG Ally X
users with this PCI SSID. Not userspace-triggerable, but affects all
users of this device.
### Step 5.5: Similar Patterns
**Record:** Identical pattern used for other ASUS devices:
- `ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1` →
`alc285_fixup_speaker2_to_dac1` + separate headset chain
- `ALC287_FIXUP_TXNW2781_I2C_ASUS` → TAS amp + `ALC294_FIXUP_ASUS_SPK`
(fix for Xbox Ally headphone breakage, commit `5060592025103`)
---
## PHASE 6: CROSS-REFERENCE AGAINST LOCAL TREE (6.18.44)
### Step 6.1: Buggy Code Exists?
**Record:** **YES.** Current tree at line 7162:
```
SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72",
ALC287_FIXUP_TAS2781_I2C),
```
`ALC287_FIXUP_ASUS_ALLY_X` does **not** exist. Fix is needed in this
tree.
### Step 6.2: Backport Complications
**Record:** Expected **clean apply**. Enum/fixup/quirk context in this
tree matches the provided diff (line numbers differ but content aligns).
No conflicting recent changes to the `0x1eb3` entry.
### Step 6.3: Related Fixes Already Present?
**Record:** `git log --grep="ASUS_ALLY_X"` — no match. Fix not yet
applied. Related Xbox Ally fixes (`5060592025103`, `819268882628f`) are
present but address different SSIDs/issues.
---
## PHASE 7: SUBSYSTEM CONTEXT
### Step 7.1: Subsystem
**Record:** `sound/hda/codecs/realtek` — ALSA HDA Realtek codec driver.
**Criticality: PERIPHERAL** (device-specific), but HDA quirks are high-
value for affected hardware users.
### Step 7.2: Activity
**Record:** Actively maintained — multiple quirk additions/fixes in 2026
(Legion Pro 7, Lunnen Ground 14, TongFang, HP Dragonfly, etc.).
---
## PHASE 8: IMPACT AND RISK ASSESSMENT
### Step 8.1: Who Is Affected
**Record:** Users of **ASUS ROG Ally X** (RC72LA, PCI SSID
0x1043:0x1eb3) running kernel 6.18.x with HDA Realtek support enabled.
Narrow hardware scope, but 100% of those users have broken headphone
audio with current quirk.
### Step 8.2: Trigger Conditions
**Record:** Every boot / codec initialization on this device.
Plugging/unplugging headphones triggers the speaker-mute side effect.
Common, deterministic usage pattern.
### Step 8.3: Failure Mode Severity
**Record:** **MEDIUM** — No kernel crash, no data corruption, no
security issue. Complete loss of headphone audio; speakers can remain
muted after unplug. Significant functional impairment for a gaming
handheld where headphone use is common.
### Step 8.4: Risk-Benefit
**Record:**
- **Benefit:** Restores headphone and speaker audio on Ally X — real
user-visible fix for a popular device.
- **Risk:** Very low — ~20 lines, single PCI ID, reuses proven fixup
functions, no API changes.
- **Ratio:** Strong benefit, minimal risk. Falls squarely in the
**hardware quirk exception** category for stable.
---
## PHASE 9: FINAL SYNTHESIS
### Step 9.1: Evidence Summary
**FOR backport:**
- Fixes real, reproducible hardware audio bug (silent headphones, stuck
speaker mute)
- Small, surgical, obviously correct fix reusing established patterns
- All prerequisites present in 6.18.44 tree
- Buggy code confirmed present in this tree since `alc269.c` import
- ALSA maintainer (Iwai) merged; author has track record on Ally audio
- Same class of fix as `5060592025103` (Xbox Ally headphone fix, Cc:
stable)
- Explicit hardware quirk/workaround — stable exception category
**AGAINST backport:**
- Not a crash, security, or corruption issue
- Affects only one PCI ID (narrow scope)
- No external bug report or syzbot validation
- Mailing list review discussion unverified
**UNRESOLVED:**
- Full lore review thread content
- Whether reviewers explicitly nominated for stable
### Step 9.2: Stable Rules Checklist
| Criterion | Result |
|-----------|--------|
| 1. Obviously correct and tested? | **PASS** — pattern proven on other
ASUS devices; commit describes hardware testing |
| 2. Fixes real bug affecting users? | **PASS** — broken headphone audio
on Ally X |
| 3. Important issue? | **PASS** (as hardware quirk) — complete audio
loss on affected device; not crash-level but functionally critical for
users |
| 4. Small and contained? | **PASS** — ~20 lines, one file, one PCI ID |
| 5. No new features/APIs? | **PASS** — quirk table entries only, no
userspace-visible API |
| 6. Can apply to local tree? | **PASS** — prerequisites present, clean
expected apply |
### Step 9.3: Exception Category
**Record:** **Hardware quirk/workaround** (audio codec quirk) —
explicitly listed as stable-appropriate.
### Step 9.4: Decision Rationale
For Linux **6.18.44**, the buggy quirk assignment exists and causes
broken headphone output on the ASUS ROG Ally X. The fix is minimal,
self-contained, follows established patterns in the same driver, and
addresses a real functional defect on consumer hardware. While not a
crash or security issue, audio codec hardware quirks are routinely and
appropriately backported to stable — precedent exists in this very tree
for Ally-family audio fixes. Benefit clearly outweighs risk.
---
## Verification
- **[Phase 1]** Parsed commit message and tags from user-provided diff
- **[Phase 1]** Confirmed no Fixes:, Reported-by, Cc: stable, or
Reviewed-by tags
- **[Phase 2]** Diff analysis: 1 file, ~20 lines, enum + fixup table +
quirk table changes
- **[Phase 2]** Read `alc285_fixup_speaker2_to_dac1` at line 2533 —
routes NID 0x17 to DAC 0x02
- **[Phase 2]** Read `alc285_fixup_thinkpad_x1_gen7` at line 2605 —
shares DAC 0x03 for pins 0x17 and 0x21
- **[Phase 2]** Read current `ALC287_FIXUP_TAS2781_I2C` chain at lines
6285–6289 — chains to ThinkPad headset jack
- **[Phase 3]** `git describe HEAD` → v6.18.44-1-g2736c32da98b9; `make
kernelversion` → 6.18.44
- **[Phase 3]** `git blame -L 7162,7162` → quirk introduced in
5d324e5159d9e (2025-11-28)
- **[Phase 3]** `git log -S '0x1eb3'` → only in alc269.c since tree
import
- **[Phase 3]** `git show 5060592025103` — prior Xbox Ally headphone fix
with Cc: stable
- **[Phase 3]** `git show 819268882628f` — related Ally X TAS2781 fix by
same author
- **[Phase 3]** `git log --author="Matthew Schwartz"` — author has Ally
audio commits in tree
- **[Phase 4]** `b4 dig` — commit not in tree as commit object; could
not run
- **[Phase 4]** UNVERIFIED: lore.kernel.org and patch.msgid.link blocked
by Anubis
- **[Phase 5]** `grep` confirmed all prerequisite fixup functions and
enum values exist
- **[Phase 5]** Verified `ALC225_FIXUP_HEADSET_JACK` at line 5214 —
standalone headset jack, no ThinkPad chain
- **[Phase 6]** `grep 0x1eb3` — buggy quirk present at line 7162;
`ALC287_FIXUP_ASUS_ALLY_X` absent
- **[Phase 6]** `git log --grep="ASUS_ALLY_X"` — fix not yet applied
- **[Phase 7]** `git log --oneline -5 -- sound/hda/codecs/realtek/` —
active subsystem
- **[Phase 8]** Assessed failure mode as functional audio loss (MEDIUM),
not crash (CRITICAL)
**YES**
sound/hda/codecs/realtek/alc269.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index a07f40e9541ee..1bbaabbe99263 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -3955,6 +3955,8 @@ enum {
ALC236_FIXUP_DELL_DUAL_CODECS,
ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
ALC287_FIXUP_TAS2781_I2C,
+ ALC287_FIXUP_ASUS_ALLY_X,
+ ALC287_FIXUP_ASUS_ALLY_X_I2C,
ALC295_FIXUP_DELL_TAS2781_I2C,
ALC245_FIXUP_TAS2781_SPI_2,
ALC287_FIXUP_TXNW2781_I2C,
@@ -6288,6 +6290,18 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC285_FIXUP_THINKPAD_HEADSET_JACK,
},
+ [ALC287_FIXUP_ASUS_ALLY_X] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc285_fixup_speaker2_to_dac1,
+ .chained = true,
+ .chain_id = ALC287_FIXUP_ASUS_ALLY_X_I2C,
+ },
+ [ALC287_FIXUP_ASUS_ALLY_X_I2C] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = tas2781_fixup_tias_i2c,
+ .chained = true,
+ .chain_id = ALC225_FIXUP_HEADSET_JACK,
+ },
[ALC245_FIXUP_TAS2781_SPI_2] = {
.type = HDA_FIXUP_FUNC,
.v.func = tas2781_fixup_spi,
@@ -7164,7 +7178,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE),
- SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
+ SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RC72LA", ALC287_FIXUP_ASUS_ALLY_X),
SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1),
SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2),
--
2.53.0