5 KiB
TASK 07 — WCD9340 mic: functional-pinned; unpin remains
Status: FUNCTIONAL; daily use confirmed 2026-08-07. Earlier capture tests passed 3/3 with real audio and zero SLIM errors, and Casey uses the microphone for STT. One real defect remains: the power pin that makes it work. The 2026-07-17 "diagnosed" text below the fold is history — kept because the trace method and dead-end ledger stop future sessions from re-deriving them.
Where the working code actually lives (fixed 2026-07-21)
The phone runs 7.1.1-sdm845-gf56b1ae0831c — that is commit
f56b1ae08 ("make prepare idempotent across PCM re-prepare",
2026-07-20), tip of branch mic-race-fix.
- Canonical tree:
~/Projects/Pixel3Arch/kernel/linux-blueline-current(worktree onmic-race-fix, now synced to f56b1ae08). - Build tree on archdev:
~/build/pixel3arch-kernel/src/linux-blueline-src, branchmakepkg— this is what actually built the running kernel. - Stale claimants, do not trust their STATUS.md:
linux-blueline-work(detached at 07-18),linux-blueline-mic-order-g56(broken worktree, parent .git moved), and the dirty 07-03 checkout atPostMarketOS-Blueline/references/linux-7.1.1-sdm845-CANONICAL.
The mic stack (07-14 → 07-20), newest first: prepare idempotency · sysclk+MICB2 pin at probe (cd7758eae) · CHAN_CTRL remove on stream disable · LN_BB_CLK3 extclk (the MCLK fix — codec was on the wrong PMIC clock buffer, root of the original eFuse/-110 era) · RCO SIDO buck · DMIC DAPM micbias · decimator clk at PRE_PMU · PGA unmute · ch pairing + AFE CDC_DEV_CFG.
Audio server truth: the phone runs PipeWire 1.6.8 (pipewire-pulse;
pulseaudio.service inactive — the old "pulseaudio MASKED" note is
history). UCM exposes alsa_input.platform-sound.HiFi__Mic__source,
s16le 1ch 48 kHz. Capture test:
pw-record --target <mic-source-id> /tmp/x.wav.
Retracted: "sample duplication" (false alarm, 2026-07-21)
A first look at pw-record output showed every sample doubled
(-1224, -1224, -190, -190, …) and this was briefly called a
half-bandwidth defect. Wrong: the WAV was stereo — those are L/R
pairs. pw-record defaults to a stereo client format and upmixes the
mono source by duplicating each sample; the ALSA PCM underneath was
open at 1ch 48 kHz the whole time (/proc/asound/card0/pcm1c), and the
de-interleaved channel is smooth, real 48 kHz audio (RMS 7179, rail
fraction 0.03%). The capture path has no fidelity defect. Record
with explicit format (pw-record --rate 16000 --channels 1) or through
the UCM source and it's clean. If the mic still sounds "a bit buggy" in
real use, capture a sample and characterize it — the raw path is not
the cause on current evidence.
The defect — the power pin (the "unpin test")
cd7758eae holds a permanent codec sysclk reference + MICB2 pull-up
from component probe. Why: capture only produces samples when it opens
against an already-powered codec. A capture whose own bring-up starts
from codec power-off reads zeros on every route until the next cold
boot. Working boots had merely won a race with MBHC's ~3 s probe-time
sysclk hold; losing boots lost it by ~1 s.
Cost: sysclk + SIDO buck + MICB2 pull-up burn from boot, forever — this is standing idle drain and pocket heat, and it blocks any real suspend story (TASK-08/15).
The unpin test (cold boots — Casey at the device):
- Build
mic-race-fixwith cd7758eae reverted plus a candidate ordering fix (start from what MBHC's probe path powers that the capture path doesn't: RCO/SIDO buck sequencing — see 3ac06ca49 — and clock-gate readbacks from 323b29715's instrumentation). - Cold boot. Wait >3 min before first capture so the MBHC hold has expired and the race can't be accidentally won.
pw-record→ non-zero samples? Repeat across 3 cold boots.- Zeros → the ordering fix is wrong; pin goes back; iterate. The pin is the fallback, never the end state.
Acceptance (task-level)
Unpinned kernel: first capture after a >3 min-idle cold boot returns real samples, three cold boots in a row. No -110/NACK storm in dmesg across repeated open/close.
History (2026-07-17, superseded)
The bus-wedge diagnosis that got us here: every TX-path setup write
succeeded; the bus died on the first read after arming TX7/TX8
(0x801 poll → 1.046 s timeout → NGD TX_NACKED_2 forever). Full
trace: linux-blueline-current/notes/MIC-WEDGE-TRACE-20260717.md. Dead
ends already falsified — do not re-derive: 0x0c96 was innocent; codec
regs match Android ground truth bit-for-bit; q6afe cdc_codec_config
already fires (ret=0); AFE_SLIMBUS_SLAVE_PORT_CONFIG is SLIMBUS_5_TX
only; ADSP file-serving complete (only adsp_avs_config.acdb requested);
adsp.mbn is stock Google-signed Android-11 era; slot B is wiped, no LOS
image on-device to diff. Post-mortem of the whole hunt:
linux-blueline-current/2026-07-19-FABLEWORK.txt.
Connects to
TASK-15 idle coordinator (the pin is its enemy), TASK-08 device state manager, upstream: LN_BB_CLK3 + CHAN_CTRL-remove + the eventual unpin ordering fix are mainline candidates once stable.