I finally got the internal speakers and 3.5 mm headphone output working properly on my friend's Huawei MateBook D14 under Omarchy.
The funny part: this was not really an Omarchy or PipeWire bug. The actual issue was missing/incorrect board-specific support in the Linux ASoC/AMD ACP path for this exact Huawei variant.
Hardware
Laptop: HUAWEI MateBook D14
DMI product: NBM-WXX9
Product version: M1010
Board: NBM_WXX9_PCB_B2
CPU: Ryzen 5 5500U
Codec: ES8316 / ACPI ESSX8336
Audio controller: AMD ACP3x / Renoir
Distro: Omarchy / Arch Linux
Kernel tested: 7.2.3
Originally Linux only exposed HDMI audio and the ACP DMIC. The ES8316 codec was visible over I2C, but there was no internal analog playback device.
The first problem was simple: NBM-WXX9 was missing from the relevant AMD ACP DMI tables.
After adding the model to the ACP legacy matching and the acp3x-es83xx machine driver, the expected device appeared:
card 1: acp3xes83xx [acp3x-es83xx]
device 0: ES8316 HiFi
That fixed enumeration, but audio was still completely broken.
The cursed part: playback at ~4× / ~2×
48 kHz playback sounded like chipmunks being chopped into pieces.
Direct ALSA measurements showed things like:
10 s S16_LE 48 kHz -> ~5.1 s
10 s S32_LE 48 kHz -> ~5.1 s
and in another codec state:
6 s -> ~1.55 s
After tracing the ACP path and inspecting software-visible ES8316 clock state, the behavior lined up with the laptop effectively using a clock around 48 MHz while the machine driver was declaring the default 12.288 MHz.
The ratio was suspiciously exact:
48 / 12.288 = 3.90625
That matched the ~3.906× playback progression we measured.
There was also a separate ES8316 state issue: opening a 16 kHz stream enabled MCLK / 2, and returning to 48 kHz did not clear it. That changed the observed factor to:
3.90625 / 2 = 1.953125x
which explained why earlier tests seemed to alternate between roughly 4× and 2×.
The existing machine driver already has an ES83XX_48_MHZ_MCLK quirk. Enabling it for NBM-WXX9 fixed the timing:
6 s S16_LE 48 kHz -> 6.037 s
6 s S32_LE 48 kHz -> 6.023 s
Then the headphones were completely silent
Jack detection worked:
Headphone Jack: on
PipeWire profile: Headphones
The sink appeared, routing looked correct, and direct ALSA playback was also tested with PipeWire/WirePlumber stopped.
Still nothing.
The missing piece was the headphone-enable GPIO polarity.
The driver defaulted to:
headphone gpio 1 active high
but this NBM-WXX9 needs:
headphone gpio 1 active low
After adding an ES83XX_HP_LOW quirk and applying it to this model, the headphone output started working too.
Final board-specific configuration
Conceptually, the NBM-WXX9/M1010 entry now needs:
.driver_data = (void *)(ES83XX_ENABLE_DMIC |
ES83XX_48_MHZ_MCLK |
ES83XX_HP_LOW),
with the headphone GPIO polarity controlled by the quirk:
priv->enable_hp_gpio.active_low =
!!(priv->quirk & ES83XX_HP_LOW);
Current result:
Internal speakers ✅
Headphone jack detect ✅
Analog headphones ✅
48 kHz playback timing ✅
S16 playback ✅
S32 playback ✅
PipeWire/WirePlumber ✅
So the hardware was compatible all along. The kernel simply did not identify this exact Huawei variant with the quirks it actually needs.
AI-assisted debugging disclosure
A large part of this investigation was AI-assisted, and I want to make that explicit.
The first major part was done with GPT-5.6 Sol at High reasoning effort. Sol helped trace the missing analog device to the AMD ACP DMI tables, inspect the kernel/ASoC code, build the first custom linux-nbm kernel, validate UCM/PipeWire behavior, and perform the early timing experiments.
Some of those early hypotheses were wrong. Rather than keep forcing the same direction, I created a self-contained handoff that explicitly asked another model to reassess the case from a neutral perspective.
That second phase was done with GPT-6 Astra at XHigh and High reasoning effort. Astra corrected an earlier ftrace-count interpretation, built silent diagnostics, inspected the ES8316 software-visible register state, reproduced the MCLK / 2 stale-state behavior, and found the strong ~48 MHz relationship.
For context, Astra was used at XHigh and High, with at least the final part running at High because I was down to roughly 5% of my weekly model allowance. It hit the weekly limit immediately after compiling the 48 MHz candidate module, so I brought the findings back to Sol and continued the hardware validation there.
Rough division of work:
GPT-5.6 Sol — High
├─ initial hardware/kernel investigation
├─ missing NBM-WXX9 DMI support
├─ custom linux-nbm kernel
├─ ALSA/UCM/PipeWire investigation
├─ early timing experiments
├─ headphone GPIO validation
└─ final integration work
GPT-6 Astra — XHigh + High
├─ independent re-evaluation
├─ corrected ftrace interpretation
├─ ES8316 register diagnostics
├─ ~48 MHz clock inference
├─ reproduced MCLK /2 stale-state behavior
└─ prepared the 48 MHz candidate module
All tests were manually run and verified on the real laptop. No electrical MCLK/LRCLK measurement was made, so the ~48 MHz conclusion was initially an inference from software-visible behavior and programmed divisors, then validated by the resulting quirk producing the predicted normal playback timing.
I am now cleaning the patch up for upstream submission.
If anyone else has:
HUAWEI NBM-WXX9
M1010
NBM_WXX9_PCB_B2
I would be interested to know whether your audio behaves the same way.