Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/docs/tasks/07-mic-wcd9340-slim-tx.md
2026-08-10 17:00:23 -04:00

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 on mic-race-fix, now synced to f56b1ae08).
  • Build tree on archdev: ~/build/pixel3arch-kernel/src/linux-blueline-src, branch makepkg — 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 at PostMarketOS-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):

  1. Build mic-race-fix with 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).
  2. Cold boot. Wait >3 min before first capture so the MBHC hold has expired and the race can't be accidentally won.
  3. pw-record → non-zero samples? Repeat across 3 cold boots.
  4. 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.