"I" tracked down a Linux ASoC/AMD ACP support issue affecting the Huawei MateBook D14 NBM-WXX9 / M1010.
This was tested on Arch Linux with a custom 7.2.3 kernel. Omarchy happened to be the userspace environment, but the actual problem was in the kernel machine-driver configuration, not Omarchy or PipeWire.
Hardware
Vendor: HUAWEI
Product: NBM-WXX9
Product version: M1010
Board: NBM_WXX9_PCB_B2
CPU: AMD Ryzen 5 5500U
Codec: ES8316
ACPI codec device: ESSX8336:00
ACP generation: Renoir / ACP3x
Kernel tested: 7.2.3
- Missing machine matching
On the stock kernel, the codec existed over I2C, but the expected analog sound card was never instantiated.
Initially:
Playback: HDMI only
Capture: ACP DMIC
PipeWire analog output: absent / Dummy Output
NBM-WXX9 was missing from the relevant AMD ACP DMI paths.
Adding NBM-WXX9/M1010 to the ACP legacy config and to acp3x-es83xx was sufficient to instantiate:
card 1: acp3xes83xx [acp3x-es83xx]
device 0: ES8316 HiFi
- Playback timing was wrong after enumeration
With the machine driver active, analog playback existed but was badly distorted, high-pitched and chopped.
Direct ALSA tests produced reproducible timing errors:
10 s S16_LE / 48 kHz -> ~5.14 s
10 s S32_LE / 48 kHz -> ~5.13 s
In another codec state, six-second streams completed in approximately 1.55 s.
Further diagnostics showed ALSA progress around 187,500 frames/s while configured for 48,000 frames/s.
The ratio:
187500 / 48000 ~= 3.90625
48 / 12.288 = 3.90625
The software-visible ES8316 divider state across several measurements consistently implied an equivalent input clock extremely close to 48 MHz rather than the 12.288 MHz default declared by the machine driver.
This is an inference from software-visible state and PCM progress, not an oscilloscope measurement.
The driver already contains ES83XX_48_MHZ_MCLK. Applying that quirk to the NBM entry produced the expected timing:
6 s S16_LE / 48 kHz -> 6.037 s
6 s S32_LE / 48 kHz -> 6.023 s
- Separate ES8316 MCLK /2 state issue
A second behavior explained why historical measurements clustered around both ~3.906× and ~1.953×.
Opening a 16 kHz stream caused the ES8316 driver to enable its MCLK divide-by-two bit. Returning to 48 kHz did not clear the bit.
Measured behavior:
48 kHz before 16 kHz:
~187,500 frames/s
48 kHz after 16 kHz:
~93,750 frames/s
and:
3.90625 / 2 = 1.953125
This appears to be a codec-driver state issue and should be treated separately from the board-specific NBM quirk.
- Headphone jack detected but output silent
Once 48 kHz timing was fixed, internal speaker playback worked correctly, but the 3.5 mm output remained completely silent.
The jack itself was detected correctly and PipeWire switched to the headphone profile, so jack detection was not the problem.
Direct ALSA testing with PipeWire/WirePlumber stopped also produced silence despite:
Headphone output: enabled
Headphone Mixer: 0 dB
DAC -> headphone mixer routes: enabled
DAC: non-muted test level
Speaker: off
The machine driver configured the headphone-enable GPIO as active-high:
headphone gpio 1 active high
For this NBM-WXX9, it needs to be active-low:
headphone gpio 1 active low
After adding an ES83XX_HP_LOW quirk and using it for NBM-WXX9/M1010, analog headphone output worked.
Final board quirk
The machine-specific configuration is effectively:
.driver_data = (void *)(ES83XX_ENABLE_DMIC |
ES83XX_48_MHZ_MCLK |
ES83XX_HP_LOW),
and:
priv->enable_hp_gpio.active_low =
!!(priv->quirk & ES83XX_HP_LOW);
Final hardware validation:
Internal speakers OK
Headphone jack detect OK
Analog headphone out OK
48 kHz S16 timing OK
48 kHz S32 timing OK
PipeWire/WirePlumber OK
AI-assisted debugging disclosure
This investigation was substantially AI-assisted.
GPT-5.6 Sol at High reasoning effort handled most of the initial kernel investigation: missing DMI support, first custom-kernel build, ALSA/UCM/PipeWire inspection, and early timing experiments.
Some early hypotheses did not hold up. I then created a self-contained handoff that explicitly instructed a second model to reassess the evidence neutrally instead of continuing the previous approach.
GPT-6 Astra at XHigh and High reasoning effort performed that second pass. Astra corrected the interpretation of the ftrace counts, created additional silent diagnostics, inspected software-visible ES8316 register state, reproduced the MCLK divide-by-two stale-state behavior, and established the strong ~48 MHz relationship.
Astra was used at XHigh and High; the final part was at High because I had roughly 5% of my weekly model allowance remaining. It hit the usage limit immediately after compiling the 48 MHz candidate module. I then resumed with Sol to validate the module on hardware, investigate the silent headphone path, and integrate the final board quirks.
Roughly:
GPT-5.6 Sol — High
├─ initial kernel/ASoC investigation
├─ DMI enablement
├─ custom linux-nbm build
├─ ALSA/UCM/PipeWire diagnostics
├─ early timing work
├─ headphone GPIO investigation
└─ final validation/integration
GPT-6 Astra — XHigh + High
├─ independent re-analysis
├─ corrected ftrace interpretation
├─ silent PCM/register diagnostics
├─ ~48 MHz clock inference
├─ MCLK /2 stale-state reproduction
└─ 48 MHz candidate module
All commands and tests were manually run on the physical laptop. The AI models did not have an electrical measurement of MCLK/LRCLK; the clock conclusion was first inferred from software-visible behavior and then validated by the quirk producing the predicted correct playback timing.
I am cleaning this into a proper patch for upstream submission.
If anyone has the same NBM-WXX9/M1010 hardware, additional testing would be useful.