PAF becomes saf/device (history kept), STATE.md dissolves into saf/state.md with the dated era archived, the substrate SAF moves up from souveraine, and every agreement points at saf/INDEX.md and nowhere else. one map, nothing to remember
12 KiB
2026-07-19 LIVE Android reconciliation — READ THIS FIRST (supersedes the top of audio.md)
Historical capture. The reconciled current contract is
../../audio.md.
The ## 0x097/0x032/0x11c are 00 on a WORKING recording section currently at the
top of audio.md is partly WRONG — it was written after reading only the
regmap-cache node. A second live read minutes later (same confirmed-active
recording, user watching the phone) via the live-PGD node corrected it. This file
is the accurate version. Trust this, not that section.
⭐ VOICE-CALL reconciliation — 0x097 is voice-usecase-specific (the biggest finding)
Captured the working Android side LIVE via the live node
(/sys/kernel/debug/wcd9xxx_core/slimslave_reg_dump) under TWO different working
usecases, both user-confirmed-live (timer / wife on the call):
recorder capture VOICE CALL
0x032 irq_en_TX 0x80 0x80
0x057 TX7 port cfg 0x05 0x05
0x097 TX7 region 00 0x21 <-- voice ONLY
0x098 TX7 region 00 0x21 <-- voice ONLY
0x11c TX7 MULTI_CHNL 0x80 0x80
0x120 TX8 MULTI_CHNL 00 0x80 <-- voice ONLY (2nd mic, dual-mic)
Saved: android-reference/wcd9xxx_core-android-LIVE-voicecall-20260719.txt
(plus ...-LIVE-recording-20260719.txt).
THE RECONCILIATION: the 2026-07-03 ground-truth doc's 0x097=0x21 was RIGHT
— it was captured during a voice call (dual-mic handset+endfire, TX7+TX8), not
a multimedia recorder capture. The recorder path never sets 0x097/0x098 or TX8's
0x120. So 0x097 was never a "samples flow for multimedia capture" register —
it's set by the voice usecase's ADM topology (dual-mic, AANC/fluence).
Chasing 0x097 for the recorder/multimedia path was a category error.
This is strong evidence for the ADM/usecase hypothesis (see below): the working
Android side programs different DSP topology per usecase (recorder = single TX7
multimedia; voice = dual TX7+TX8 with AANC). 0x097/0x098 + TX8 0x120 are the
voice-topology footprint.
For our broken multimedia mic: our MultiMedia1/2 capture on Arch corresponds
to Android's recorder path. For THAT path the working registers are
0x032=0x80, 0x057=0x05, 0x11c=0x80 only — which we MATCH. So the multimedia-
capture register layer genuinely matches working↔broken. The bug for multimedia is
NOT in IFD/PGD registers (now confirmed for the recorder usecase specifically).
The voice path (VoiceMMode1/hw:0,2) is a separate, untested question — and if
voice is what's broken, 0x097/0x098/0x120 become relevant again, but as voice
topology, not as a general "samples flow" reg.
Do NOT chase 0x097 for the multimedia/recorder mic.
What actually happened
Two debug nodes on Android (LineageOS 22, slot B) read LIVE during a confirmed-active recording (LineageOS Recorder, timer counting up, user at the phone said "recording"):
regmap/tavil-slim-pgd/registers wcd9xxx_core/slimslave_reg_dump
(regmap CACHE — reads 00/stale) (live PGD read over SLIMbus)
0x032 PGD irq_en_TX 00 0x80
0x057 TX7 port cfg 00 0x05
0x097 "mystery" TX7 reg 00 00
0x11c TX7 MULTI_CHNL_0 00 0x80
The two nodes read different things. regmap/.../registers reads the regmap
CACHE (all 00, not live). wcd9xxx_core/slimslave_reg_dump reads the live PGD and
shows the real recording values.
What this means (correct conclusions)
-
The original 2026-07-03 ground-truth doc was RIGHT about 0x032/0x057/0x11c (it used
wcd9xxx_core, the live node): working recording =0x032=0x80,0x057=0x05,0x11c=0x80. Those are real. -
The doc's
0x097=0x21claim was RIGHT — but it was a VOICE call, not a recorder capture. See the ⭐ VOICE-CALL section above:0x097/0x098=0x21and TX80x120=0x80are voice-usecase-specific. They are00during a recorder capture (which is the usecase our multimedia mic maps to). So0x097is NOT a multimedia-capture register at all — stop chasing it for the recorder path. -
Our side (Arch / SouveraineOS) matches the working side on 0x032/0x057/0x11c (measured this session after the MCLK fix: our IFD shows
0x032=0x80,0x057=0x05,0x11c=0x80). So the IFD/PGD register layer genuinely matches between working Android and our broken capture. The differentiator is NOT in the IFD/PGD register layer. -
Methodological correction for our side: when reading PGD regs, do NOT trust
regmap/.../registers(it's the cache — lies with 00s). Use the live equivalent. Several "this reg is never set" conclusions on our side this session were probably cache-read artifacts, not real states.
Saved artifacts (both LIVE, same recording, 2026-07-19)
PostMarketOS-Blueline/android-reference/tavil-pgd-android-LIVE-recording-20260719.txt(regmap cache view — the misleading 00s)PostMarketOS-Blueline/android-reference/wcd9xxx_core-android-LIVE-recording-20260719.txt(live PGD — the real recording state)
Verified-correct stack as of 2026-07-19 (live-confirmed)
- MCLK to codec: FIXED (LN_BB_CLK2→LN_BB_CLK3 in
sdm845-google-common.dtsi&wcd9340override, uncommitted; live on DTB). eFuse sense completes (status=0x01, version0x401) — no more-110. - Codec init/capture regs: bit-for-bit identical to Android ground truth.
- Codec DAPM power-up: fires (
0x0601/0x0626/0x0aa1toggle on capture). - SLIMbus NGD DEF_ACT_CHAN: sent (qcom-ngd-ctrl.c:1020).
- AFE slave-config send (
AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG+ REG_PAGE + REG_INIT): already built in mainline asq6afe_send_cdc_codec_config()(q6afe.c:1854), sent with correct codec enum addrea=0x21702500100,ret=0. DSP accepts (no "DSP returned error"). A prior session already built the "port the missing slave-config" fix — do NOT re-derive/re-port it. - IFD/PGD regs (0x032/0x057/0x11c): MATCH between working and broken (via live
node).
0x097: 00 on both — ruled out. - ADSP file-serving: PD requests only
adsp_avs_config.acdb, served. OEM ACDB tree not requested via FastRPC — not the gap (falsified).
Where the differentiator actually is (still open)
Everything the kernel can observe/send/serve — codec regs, SLIMbus NGD, AFE command ack, IFD/PGD regs, file-serving — is identical between working Android and our broken capture. The fault is past all of those.
Top hypothesis (NOT yet tested) — ADM usecase routing, not AFE:
On Android, opening the Recorder app goes through the Android audio HAL:
adev_open_input_stream → platform HAL → audio_extn → adm_open with a
usecase + device + flags, which programs the ADM (Audio Dynamic Mixer) topology
on the DSP that actually routes capture data into the AFE port. Without an ADM
usecase the DSP has an open AFE port with nothing routed into it → samples never
flow, every command ACKs. That fits the exact signature.
We are Arch / SouveraineOS — there is no Android audio HAL in our stack at
all. We drive ALSA directly (PulseAudio → ALSA hw:0,0). No userspace ever
calls adm_open. No usecase is ever set. Either the kernel does it or it
doesn't — and mainline's q6adm.c is much thinner than downstream's
(pixel3-downstream-audio/techpack/audio/dsp/q6adm.c).
This is the unexplored-at-this-depth difference, unlike the AFE slave-config
which was already ported.
Concrete next move on our side: check whether our kernel/driver has a q6adm
path wired for capture usecases, and whether opening capture sends ANY
ADM_CMD_ASM / ADM commands at all. If zero — that's the gap.
Secondary candidates (also not falsified):
- AFE/APR command sequence on the WIRE (payload bytes), not register state.
No payload-bearing APR capture exists on either side. The one glink trace
(
PAF/captures/glink_trace_pmos-20260702.txt) is framing-only AND modem-context (qmi-proxy traffic), not a mic capture — no AFE opcodes. The Android side hasmsm_apr_debug+ipc_logging/aprnodes but they returned empty even during a live recording on this LOS build (APR packet logging not enabled in this image). Getting a payload-bearing APR trace needs either a different LOS build with APR debug enabled, or a kernel tracepoint patch on our side. - On Android, APR debug nodes exist but were empty live:
/sys/kernel/debug/ msm_apr_debug(0 bytes),/sys/kernel/debug/ipc_logging/apr/{log,log_cont}(0 bytes even while recording). Glink lpass edge was moving real bytes (TX/RX fifo nonzero) — traffic flows, just not logged at APR layer on this image. - Android's silent/vibrate/sound/airplane modes are audio-policy/stream-mute states, NOT hardware triggers — but they shape WHICH ADM usecase the HAL opens, which is why the usecase-routing question matters.
System identity (don't mislabel — this was called "pmOS" by mistake earlier)
- Our phone runs Arch / SouveraineOS, NOT pmOS. pmOS is only the historical
lineage of the kernel/DTB. The running userspace is Arch + SouveraineOS shell
- PulseAudio driving ALSA directly. No Android audio HAL, no
audio_extn.
- PulseAudio driving ALSA directly. No Android audio HAL, no
- Android/LineageOS reference is slot B (boots fine; user was in it this session recording). The mic works there.
⚠️ METHODOLOGICAL WARNING — some historical "wedges" were a real radio/mode switch, not a driver fault
Casey flagged 2026-07-19: at least some of the recurring "wedge" / "seizure" / "the modem grabbed the card" / "SLIM -110 wedge" / "capture wedge" / "chip-wide wedge" events in the audio/mic/modem docs were NOT kernel/codec/SLIM faults at all — they were the phone having switched to airplane mode (or an equivalent radio-off / audio-policy-reroute state), and the resulting silence / dead bus / NACK was misread as a driver-level hang.
This means:
- Some "wedge" investigations across multiple sessions may have been chasing a mode toggle, not a bug. Treat any historical "wedge" / "seizure" / "poison" conclusion as suspect until reconciled against the mode/radio state at the time.
- We do NOT know exactly which wedges were real faults vs mode swaps. Both kinds exist. Don't assume all wedges were phantom — and don't assume all were real.
- BEFORE logging a wedge / NACK / seizure / dead-bus / silence on our side, check and record: is the phone in airplane mode? Is the modem/radio off (check rfkill, modem state, ofono/ModemManager, the cellular/quickshell overlay)? Is an audio policy rerouting happening? Rule the mode out FIRST, every time.
- On Arch/SouveraineOS a radio-off / airplane-equivalent state may be less obvious than Android's UI toggle (a Souveraine service, the cellular overlay, a quickshell switch, a default). It could be getting toggled accidentally or by default, which would explain how it kept biting us unnamed.
- Relevant docs to revisit with this lens:
PAF/audio.md("SLIM wedge", "chip-wide wedge", "TZ-poison"),docs/mic-slim-findings-2026-07-17.md("the SLIM -110 wedge", "capture wedge", "TX7-contaminated wedge", "status-read NACK → 1 Hz wedge loop"). Not all of these are phantom — but the possibility that some are must be checked before re-investigating.
Process note for the resuming session
- The codec/SLIM/AFE/file-serving layers are exhaustively ruled out (with the wedge caveat above — if a "ruled out" result was taken during a mode-swap, it is NOT valid). Do not re-investigate them UNLESS a prior test's mode state wasn't recorded.
- Do NOT re-port the SLIMBUS_SLAVE_CONFIG send (already done, ret=0).
- Do NOT chase
0x097. - Top lead: ADM usecase routing — mainline q6adm vs downstream, and whether our capture sends any ADM commands. We have no HAL to do it, so the kernel must.
- Secondary: payload-bearing APR/glink wire capture during a capture on BOTH sides, then byte-diff. That artifact does not exist yet.
- Record mode/radio state with every test going forward. No more unattributed "wedge" logs.
- Android access (airplanemode kills the NCM gadget):
adb(device serial 89JX0AAJP),adb shell 'su -c "..."'(magisk root works). Our-side access: ssh~/.ssh/anito the USB gadget IP or WiFi10.10.20.234.