kernel r162 routed capture strictly mono 48k; undeclared UCM Mic probe failed, no profiles formed at boot, card fell to pro-audio. CaptureChannels/CaptureRate in both Mic devices restores the probe; probe mechanics recorded for the next time.
51 KiB
Audio — WCD9340 / SLIMbus
Current — 2026-08-07
This is a working phone audio stack, not an active microphone bring-up.
- Runtime: PipeWire + WirePlumber + pipewire-pulse + pipewire-alsa. Native PulseAudio and the ABI-provider shims are historical experiments, not the running authority.
- HiFi: both CS35L36 speakers play; the WCD9340 microphone captures clean mono audio through DMIC4 → DEC5/TX5. Casey uses it regularly for STT.
- Calls: the
Voice CallUCM profile,souveraine-callaudio,souveraine-q6voiced, andsouveraine-callaudiodcarry real two-way calls and the earpiece/speaker path. - Persistence: WirePlumber restores volumes and the selected profile. Do not add another volume writer; role policy remains TASK-39.
- One hardware debt remains: the kernel permanently holds codec sysclk and MICB2 from probe. Audio works, but the hold costs idle power and blocks a clean suspend story. TASK-07 owns removing it.
The July “UN-PIN TEST PASSED” below removed the userspace always-open mic
pin. It did not remove kernel commit cd7758eae's sysclk + MICB2 hold; that
similar noun is the likely source of the remembered “we resolved it.”
The implementation lives in Pixel3Arch under pkgs/souveraine-ucm-blueline,
pkgs/souveraine-wireplumber-blueline (which packages the canonical
WirePlumber policy from rootfs-overlay/), pkgs/blueline-callaudio (package
name souveraine-callaudio), pkgs/souveraine-callaudiod, and
pkgs/q6voiced (package name souveraine-q6voiced).
Everything below is the evidence ledger. Headings such as “still open” describe the date beneath them unless the current block above repeats the defect.
UCM PROFILE GONE AT BOOT — 2026-08-16, fixed same day
Boot-time music died after kernel 7.1.1.r162.g457a667bd3eb (installed
2026-08-13, first boot 08-16 00:46): the card came up with only off and
pro-audio, no UCM profiles, so no HiFi sink existed at boot. In-session
audio (calls, STT mic) kept working — the regression only hit the fresh-boot
state, which is why it surfaced as “music at boot”.
Measured chain, all on-device:
- Kernel made routed capture strictly mono 48k. The wcd934x
recorder-state work in r162 (
b30e849be“program all DMIC interface pads”,9610ef9cf“replay complete blueline recorder state”) rejects stereo capture hw_params on the routed MultiMedia2 (CHANNELS: [1 4]advertised, butarecord -c 2→ -EINVAL,-c 1→ fine). - ACP probes with declared UCM values. The Mic devices declared no
CaptureChannels/CaptureRate, so ACP assumed stereo at the FE-default rate → capture probe failed -EINVAL → every profile “not supported” → ACP fell back topro-audio(priority 1) at boot. - Secondary lock, not the cause:
90-blueline.confsetssession.suspend-timeout-seconds = 0on~alsa_output.*, so the pro-audio sink never released hw:0,0; later probes died “Device or resource busy”. The persisteddefault-profilestate (wireplumber saves the selected profile, by design) then re-pinnedpro-audioeach boot. - Fix: declared
CaptureChannels 1+CaptureRate 48000in both Mic devices (HiFi + VoiceCall). ACP probe now succeeds; all three UCM profiles form; card activates HiFi at boot. Tone verified audible on glass; mic capture nonzero through the UCM source. Shipped assouveraine-ucm-blueline 0.1.0-2(commit9f0f103, CI run 1696); rootfs-overlay UCM copies kept identical to the package. - Not shipped, known hardening: scope the never-suspend output rule to
~alsa_output.platform-sound.*__sink(the UCM sinks) so a stray pro-audio fallback can never hold hw:0,0 forever.
Probe mechanics learned (canonical, 2026-08-16):
spa-acp-tool -v -v hw:0is the ACP probe; “Probing profile X” with no failure lines after it = supported. The trailing “unknown command hw:0” is a harmless arg-parsing quirk.alsaucm -c hw:0 set _verb HiFiis the real-card UCM branch; it runs the verb EnableSequence (and enables devices — TX5 mapping included).-c G3and-c "Google Pixel 3"hit the no-hw branch (conf.virt.d / legacy paths) and fail ENOENT even when UCM is healthy — red herrings.alsaucm list profiles/get _verbsfail with ENOENT quirks on this box; they are not valid probes.cat /proc/asound/card0/pcm*p/sub0/statusshowsowner_pid— the way to find who holds a PCM.- Raw
arecord -D hw:0,1only works while the verb routes are applied;spa-acp-toolruns DisableSequence on exit and tears them. Re-apply the verb before raw capture tests.
PIPEWIRE RESTORED — 2026-07-19 late evening
The PA-native arrangement is retired. Live state, all verified on-device:
- Stack: pipewire 1.6.8 + wireplumber 0.5.15 + pipewire-pulse +
pipewire-alsa. The shims (
pipewire-abi-provider,pulse-native-provider) and the patchedpulseaudio-q6are removed (rollback pkg kept at~/build/pulseaudio-q6-r3/;/etc/pulsebacked up as/etc/pulse.bak-20260719). Theenable-pipewiregate drop-ins were deleted — PipeWire is unconditional now. - UCM discovery works under ACP/wireplumber. HiFi verb → Speaker sink +
Mic source appear named from the UCM comments. The old
alsaucm -c G3-2failure is an id-vs-longname CLI quirk;-c "Google Pixel 3"parses both verbs fine. Real clients are unaffected. - Playback:
51-blueline-audio-s16.conf(S16LE + disable-mmap + generous periods, recovered verbatim from8920c3c) reinstated; chime confirmed audible on glass. - Capture: mic source pinned mono S16LE 48k, suspend disabled,
period 4800 / headroom 9600 (
90-blueline.conf). Nonzero on every test capture. - UN-PIN TEST PASSED. With the kernel sysclk hold (
cd7758eae) and no loopback hold, two consecutive same-map reopens both captured nonzero (451k/470k nonzero samples). The userspace mic pin is DELETED — kernel hold alone is sufficient. Cold-boot confirmation pending. - New kernel bug found and fixed: any xrun → userspace
snd_pcm_prepare()re-enters wcd934x prepare without shutdown →slim_stream_prepare-EINVAL "Stream already Prepared" retried ~50/s forever (PipeWire recover loop starved the whole graph). Fixf56b1ae08onmic-race-fix: per-daipreparedflag, re-prepare no-ops, stream stays armed (alternation-law friendly). Wireplumber headroom masks the common case until the kernel is installed. - VoiceCall.conf
hw:0,5→hw:0,2fixed on-device + repo. - Voice-call discovery: VoiceMMode1 (
hw:0,2) open fails -EINVAL until the voice BE routes (SLIMBUS_0_RX Voice Mixer VoiceMMode1,VoiceMMode1 Capture Mixer SLIMBUS_0_TX) are applied — DPCM no-backend rejection. With routes applied the PCM opens. This is why q6voiced logged "Failed to open tx/rx: Invalid argument".Because the PCM is unprobeable, ACP can never synthesize a VoiceCall profile, so callaudiod's profile-switching path is structurally dead on this card.Wrong — see 2026-07-29. ACP never probeshw:0,2; it probes the PCMs the verb declares, and the profile was lost for two reasons of our own making. Shippedblueline-callaudio-hook(system service): MMCallAdded→ UCM voice verb, last call terminating → HiFi verb restore. q6voiced then opens an already-routed PCM.
PHONE CALLS WORK — TWO-WAY AUDIO ON A REAL BEARER — 2026-07-29
Incoming call, answered, audio both directions, confirmed by ear at both ends. Five defects had to fall, every one of them ours:
- Verb named
VoiceCall. alsa-lib'sSND_USE_CASE_VERB_VOICECALLis"Voice Call", with the space, and callaudiod accepts only a profile carrying that prefix (cad-pulse.c:508). Renamed. - The voice verb gave MultiMedia1 no backend. HiFi routes it through
QUAT_TDM_RX_0; the voice verb routed nothing, so openinghw:0,0under the verb returned -EINVAL and ACP dropped the profile — "Profile 'Voice Call' mapping 'Voice Call: Speaker: sink': output PCM open failed",spa-acp-tool -v -v. That, not an unprobeablehw:0,2, is why no voice profile ever appeared. The card carries one now. - Downlink went to
SLIMBUS_0_RX. blueline's earpiece and loudspeaker are both CS35L36 amps onQUAT_TDM_RX_0; the WCD9340 is the uplink and the headset jack. Voice sent to the codec reached nothing — audible as a call the far end heard perfectly while this end heard silence. - A front-end takes exactly one backend. These mixers are not additive:
enabling a second silently clears the first, measured in both directions.
Setting
QUATandSLIMBUStogether is not belt-and-braces, it is a no-op. - q6voiced latches a failed open. tinyalsa's
pcm_open()returns a non-NULL handle on failure andq6voiced_open()guards onif (v->tx), so one lost race silences the whole call. Reachable on any outgoing call:mm_state_is_active()counts DIALING, emitted in the same instant asCallAdded. Incoming calls are safe only by accident — RINGING_IN is not counted active, so their open lands well after the routes. Patched insouveraine-q6voicedto release and retry.
Two further findings:
- The mic died after every call, not just occasionally.
alsaucmholds its UCM context in-process, so a one-shotset _verb HiFihas no previous verb to dismantle and never runs itsDisableSequence. TX5 and TX7 both stayed mapped intoAIF1_CAP, SLIM_0_TX carried two channels into a mono front-end, and capture read exact zeros. The hook now unmaps the outgoing leg explicitly. - callaudiod cannot own earpiece/speaker on this card. It switches a sink
port (
cad-pulse.c:961) and needs both port types on one sink, but ACP models UCM devices as one profile per combination —Voice Call (Earpiece, Mic)andVoice Call (Mic, Speaker).ConflictingDevicesdoes not change it. enchilada sidesteps this by giving each transducer its own PCM; blueline has both amps behind one. The toggle is thereforeblueline-callaudio-hook speaker on|off, writing the amps directly.
ROOT CAUSE FOUND AND FIXED — MICS CAPTURE REAL AUDIO — 2026-07-19
The wall was the codec master clock. Mainline DT fed the WCD9340's extclk
from RPMH_LN_BB_CLK2 (inherited from the reference-board dtsi). On blueline,
Android's own DT gives LN_BB_CLK2 to the Pixel Visual Core (mnh-sm) and
feeds the codec from clock_rpmh index 4 = LN_BB_CLK3 (verified by
decompiling the phone's dtbo_b; audio_ext_clk_lnbb → <&clock_rpmh 0x04>).
The RPMh vote on the wrong buffer succeeds, so nothing errors — the codec just
never receives 19.2 MHz. That single fault explained the entire residue:
- eFuse sensing timed out every boot (
-110,status=0x0) — needs MCLK, no ports involved. After the fix:eFuse sense complete: status=0x01 out14=0xda out15=0x01— first time ever on mainline. - Analog AND digital capture read zeros (whole audio core unclocked) while every SLIM control write ACKed (SLIMbus clock is separate).
- IRQ 213 (codec SLIM data line) never fired in the machine's life; after the fix it fires on every capture.
- MBHC read garbage impedance at probe.
Fix: &wcd9340 { clocks = <&rpmhcc RPMH_LN_BB_CLK3>; } in
sdm845-google-common.dtsi (committed in the kernel tree). Deployed initially
as a verified one-byte DTB patch (/boot/dtbs/sdm845-google-blueline.dtb,
backup .lnbb2-orig beside it; kexec chain reads the DTB from /boot, NOT
from the boot_a image — see below).
Live capture results after the fix (kernel g8cbfbb939327, same boot):
- AMIC1 → ADC1 → DEC0 → TX0: 121,724 / 144,000 nonzero samples
- DMIC0 → DEC7 → TX7 (
hw:0,1): 94,198 nonzero - DMIC4 → DEC5 → TX5 (Android triple-mic route): 81,545 nonzero
- DMIC3 → DEC6 → TX6 (Android triple-mic route): 92,216 nonzero
- DMIC4 → DEC7 → TX7 (Android handset-mic route): 124,050 nonzero
All three physical mics (DMIC0/3/4 per Android's triple-mic path) and the
analog path produce real ambient audio through plain ALSA hw:0,1 —
no HAL, no ADM usecase, no ACDB OEM tree in the loop. This falsifies the
"ADM usecase routing is required for samples to flow" hypothesis from the
2026-07-19 live-reconciliation doc, and retroactively confirms every "codec
registers are bit-perfect but silent" audit: the registers were right; the
silicon was unclocked.
Boot chain discovery (why kernel deploys "never landed")
boot_a holds pocketboot (LinuxBoot, a 7.2.0-rc1 first-stage kernel). It
kexecs /boot/vmlinuz-blueline + /boot/dtbs/sdm845-google-blueline.dtb per
/boot/extlinux/extlinux.conf on Arch_root (linux,booted-from-kexec in the
live chosen node). Flashing boot_a via fastboot does NOT change the running
kernel/DTB — install to /boot on the rootfs instead.
Then-open capture intermittency — superseded later on 2026-07-19
- Ordering effect observed on the first post-fix boot: DMIC3/4 through
MUX6/MUX7 read zero until the DEC5/DEC6 (Android-native) routes ran once;
after that, the previously-dead MUX7+DMIC4 handset route worked. Some
first-use state sticks. Full codec+IFD regmap snapshots of the known-good
state saved on-phone (
/tmp/codec-good-state.txt,/tmp/ifd-good-state.txt— copy off before they evaporate; /tmp is tmpfs). - The last test of the session (speaker-tone loopback) read all-zero again right after a string of successes — cause unestablished. Per the live-reconciliation doc's warning, record airplane/radio/mode state before interpreting ANY zero capture from now on.
- Android runtime parity notes for the diff: Android recording state has
0xd25 = 0x11(ADC MUX3/7 mode reg) where ours reads 0x00 even while working; pads0x8015-0x8018 = 0x00,0x8019/1a = 0x0a— identical to what our kernel programs (my in-session debugfs pad pokes don't persist). - Regmap-cache caveat from the reconciliation doc applies to OUR debugfs reads of IFD/PGD registers too: prefer live-read paths when auditing those.
THE ALTERNATION LAW — exact zombie mechanism (2026-07-19, evening)
Every capture result from all three boots today reduces to ONE deterministic rule: a SLIM TX capture produces samples only when its channel map differs from the previous capture session's map. Re-opening with the identical map always reads zeros. Verified live: TX5→TX5 = work,zero; TX5→TX6→TX5 = work,work,work; boot-first TX7 always zero (ch135 is pre-touched by ADSP boot/cal state, so the first TX7 session counts as a same-map reopen). Everything earlier read as input-specific (DMIC3/4 dead), power-related (PA holding sysclk), or "priming" was test-order artifact of this law.
- Codec side is fully correct per-session (DEF_ACT_CHAN wbuf identical between dead and working sessions except TID; teardown calls slim_stream_unprepare which sends DEACTIVATE/REMOVE/RECONFIGURE per drivers/slimbus/stream.c).
- Clock gates during a zombie capture are bit-identical to Android's working recording (0x711=0x91 0xd41=0x01 0xd42=0x0d).
- Conclusion: the ADSP's SLIM-master/AFE side treats an identical re-DEFINE as a no-op and never re-arms the data path. Android never hits this because its HAL/ADM re-arms per session (the reconciliation doc's ADM hypothesis, refined: not "ADM required for routing" but "ADM masks the stale-restart").
- NEXT INSTRUMENTATION: log outgoing MCs in qcom_slim_ngd xfer path and diff same-map vs changed-map session teardown/setup on the wire; then candidate kernel fix = force a map perturbation or explicit port disconnect+reconnect on every SLIM capture start.
- Userspace mitigation shipped meanwhile (see 90-blueline-alsa.pa): a null-sink loopback holds blueline_mic open from PA start — the boot-time open is on virgin TX5 (works), and a held-open source never re-opens, so the law is never violated. VALIDATED on true cold boot 2026-07-19 12:09: blueline_mic RUNNING at boot, 262k/263k nonzero samples first client, two back-to-back client sessions both live (peaks 5256/5590/26044). Costs continuous capture power (remove once the kernel fix lands).
THE BOOT RACE — pinned boot capture is a coin flip; kernel + config were red herrings (2026-07-19 evening)
Journal survey of ALL 9 boots of 2026-07-19 (journalctl -b -8 .. -b 0,
MICDBG sysclk lines at the pin's boot-time capture open):
| boots | kernel | at pin open | MICB2 | outcome |
|---|---|---|---|---|
| -7 | g323b297 | users=2 skip (joined a live hold) |
0x50 | 262k WORKING |
| -3 | gbdf098937 | users=2 skip |
0x50 | never tested (!) |
| -8 | g323b297 | users=1 full bring-up after users=0 HW POWER-OFF |
0x10 | zero |
| -6 -5 -4, 0 | gbdf098937 | same losing pattern | 0x10 | zero |
| -2 -1 | gfdb22e5 | same losing pattern | 0x10 | zero |
An early boot-time actor grabs codec sysclk ~3s after boot, holds ~3s, and has MICB2's 0x40 bit up while it holds. If PA's pin lands INSIDE that window the capture joins as user 2 and samples flow; if it lands after the release (codec did a HW POWER-OFF), capture does its own full bring-up and reads zero on every route for the rest of the boot — the same persistent zombie the PA-stop experiment produced. Same kernel both wins and loses (g323b297: won -7, lost -8; gbdf098937: won -3, lost four). Therefore:
- QRTR=y (
fdb22e5/f245323) is exonerated. Every "dead on fdb22e5" observation was a lost race, sampled. Config stays QRTR=m / PD_MAPPER=m (Kconfig forces PD_MAPPER ≤ QRTR anyway); it is orthogonal to the mic. - The CHAN_CTRL-remove commit (
bdf098937) is exonerated for "dead at boot" — its code path is open-inert (only addsdisable_stream, verified by diff) and it won the race on boot -3. - The un-pin question is STILL unanswered. It needs a race-winning boot:
pinned baseline nonzero,
pactl unload-modulethe loopback, then same-map reopen; nonzero reopen = pin can be deleted. - The early holder is unidentified; MBHC headset-detect is the prime suspect (boot-time codec user, raises MICB2 for impedance sensing). MICB2 0x50-vs-0x10 tracks outcome 8/8 but is NOT yet proven causal — it may just fingerprint the hold. Verify before building on it: read Android's ANA_MICB2 during a working slot-B recording, and/or set the 0x40 bit via debugfs during a fresh lost-race boot's capture.
- Kernel fix direction (pick after causality check): wire the DMIC supply (micbias) into the capture DAPM path, or hold sysclk from probe until first capture so the boot window cannot close early.
Afternoon findings — zombie state + wedge reproduction (2026-07-19)
- Cold-boot experiment (radios all on, recorded): first
arecordafter boot opened ONLY the FE — zero kernel-side codec/BE activity, zeros. Second and third captures (any route) worked. The morning "DEC5 unlocks MUX7" story is partly this: two distinct zero-classes exist — (a) BE-never-opened, (b) BE-open-but-silent. - Stopping PulseAudio (releasing the card → last sysclk user drops →
wcd934x_disable_ana_bias_and_syclkpowers the codec down) put capture into a persistent all-zero state on EVERY route, and restarting PA did not recover it. Mixer state is bit-identical PA-up vs PA-down (diff empty), so it is a power-lifecycle effect, not mixer state. - In the zombie state, live volatile reads DURING capture show the analog
domain healthy:
ANA_BIAS=0x80 BUCK=0x07 MICB4=0x90. The bias/buck theory is dead. Codec-internal clock gates (0xd41/0xd42) were not yet live-readable — instrumented build323b29715makes them volatile and logs enable/disable/sido lifecycle + per-capture clock-gate reads. - Manually zeroing
CLK_SYS_MCLK_PRG(0x711) via debugfs wedged the SLIM bus into the historical-110NACK loop (Failed to read IRQ status: -110,Error Interrupt 0x82000000, 1 Hz). One historical "SLIM wedge" class is therefore reproducible as pure codec-clock-state loss — consistent with the 2026-07-19 warning that not every wedge was a bus/driver fault. Phone needs a cold boot after this (self-inflicted, cause exactly known). - Upstream comparison:
enable_ana_bias_and_sysclk/disableand the sido-cache skip are upstream-inherited structure, not our divergence; our only body change is the Android-parity buck sequence (captures work with it). No structural smoking gun found by code audit — hence instrumentation.
SLIM NACK loop confirmed boot-invariant on a real cold boot — 2026-07-15
- Fixed three misidentified raw-hex register writes in
wcd934x_apply_blueline_android_tx7_capture_setup()(kernel5199244ee0ee):0x0b07-0x0b3fwere RX playback companderCTL6registers (not TX per-path enables),0x0c96isWCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS(a status register, not a TX enable — writing it was the suspected cause of a SLIM wedge seen on the prior build9610ef9cf45a), and0x0d1e/0x0d25areADC_MUX0_CFG1/ADC_MUX3_CFG1(TX0/TX3, not TX7/TX8 as the old comment claimed). Verified against downstreamtechpack/include/asoc/wcd934x_registers.h. This fix did NOT resolve the SLIM wedge — see below. - The recurring error is a genuine NACK, not a bus hang:
qcom,slim-ngd-ctrl: Error Interrupt received 0x82000000decodes toNGD_INT_TX_MSG_SENT (BIT 31) | NGD_INT_TX_NACKED_2 (BIT 25)— the message transmitted and the target actively refused it. The target isLA:0xcf(the WCD934x codec's assigned logical address, confirmed notSLIM_LA_MGR/0xff), message code0x60=SLIM_MSG_MC_REQUEST_VALUE. The read isregmap-irq's genericregmap_irq_thread()polling the codec's IRQ status registers (drivers/base/regmap/regmap-irq.c) — the codec's IRQ line isIRQF_TRIGGER_HIGH(level), so a failed status read never clears it and it refires every ~1s, forever, from ~1-2min post-boot onward. - Tested with a user-operated true power-off (
shutdown -h now, notfastboot reboot) followed by manual power-on, specifically to rule out the in-place-ADSP-restart degradationb0b813fwarned about. Result: the NACK loop reproduces identically on this real cold boot (confirmed climbing at 110s uptime, sameMC:0x60,LA:0xcfsignature). This is not a warm-reboot or ADSP-restart artifact — it is boot-invariant, matching the entry below from earlier the same day. blueline-hexagonrpcd-adsp.service(b0b813f, still uncommitted to gitea as of this entry) attaches cleanly on this same cold boot — no fluence/ECNS/AVS module errors, only the unrelatedlowi_lp.confmiss. So the ADSP audio-PD HexagonFS gap is fixed and not the current blocker; capture still fails at the ALSAhw_paramslayer (arecord"Unable to install hw params") before the ADSP module question is even reachable, because the SLIM NACK loop blocks it upstream.- Current standing blocker, plainly: the SLIM NACK loop on
LA:0xcf. Not yet root-caused. Two real, separate bugs were found and fixed tonight (the register-write bug above, and the ADSP HexagonFS gap inb0b813f); this is a third, still-open one.
Cold-boot SLIM-NGD correction — 2026-07-14
- A user-operated full power-off while unplugged, followed by power-on, still
logs
qcom,slim-ngd-ctrl ... QMI wait timeoutat 12:29:52, immediately after ADSP boot/WCD934x probe, followed by repeatedSLIM SAT: Rcvd master capability. This happened before any ALSA/Pulse microphone client opened. - Therefore the timeout/capability loop is not merely a warm-reboot or
long-uptime artifact. ADSP, CDSP, SLPI, and MSS all reach
running, so the fault is specifically in the ADSP↔NGD SLIM initialization exchange and is now the primary boot-invariant microphone lead. Do not restart ADSP or NGD while investigating; preserve this state for tracing. - The adjacent WCD MBHC threshold/impedance messages concern headset/accessory detection (including the available USB-to-mic adapter), not the target internal DMIC4 → DEC7 → TX7 capture path.
Q6 VoiceMMode1 call path — staged 2026-07-14
- This is deliberately separate from the still-silent raw
MultiMedia1/2capture path. Android proves the board microphone works; normal PCM remains an ADM/calibration problem, while modem calls use the hostless Q6Voice path. - The missing board wiring was real:
sdm845.dtsileft Q6 MVM/CVS/CVP disabled and blueline had noVoiceMMode1DAI/card link. Kernel commit551d3bb1benables those services and instantiates the link on the tested Type-C baseline. Its matching module tree is installed on the phone at7.1.1-sdm845-g551d3bb1bd35; its boot image is staged locally. - The preserved prior device package, found at
archive/pmos-20260709/pmaports/device/testing/device-google-blueline/, is the authoritative board data:VoiceMMode1enumerates ashw:0,5, not the raw MultiMedia devices. Its exactVoiceCall.confrouting (SLIMBUS_0_RX Voice Mixer VoiceMMode1,VoiceMMode1 Capture Mixer SLIMBUS_0_TX, DMIC4→DEC7→TX7) is installed in the Arch UCM overlay. q6voiced-bluelinewas built and installed natively, with that exact PCM-5 configuration. Its system unit is deliberately disabled until the new kernel cold-boot confirms00-05: VoiceMMode1; enabling it on the old kernel would create meaningless restart noise. First test must be a clean cold boot and an actual ModemManager call before any HiFi/raw-capture experiment, because the historical second call failure was SLIMBUS RX already claimed by earlier HiFi activity.
Live state — 2026-07-12 evening (mic)
Live Android Recorder ground truth — 2026-07-14: On the rooted Lineage
slot-B reference system (4.9.337-gb929452c5c49), an ordinary
org.lineageos.recorder recording was observed live, not inferred from XML.
It opens MultiMedia1 / PCM device 0 (not MultiMedia2): its userspace input
is mono S16_LE at 8 kHz, while the active backend is
SLIMBUS_0_TX, mono S16_LE at 48 kHz. The downstream HAL enables
DMIC4 -> DEC7 -> TX7; SLIM_0_TX Channels=One; and its active capture
app-type control is [69938, 4, 48000, 3]: downstream's documented field
order makes that app_type=69938 (the Qualcomm default TX-path app type),
acdb_dev_id=4, sample_rate=48000, backend_id=3. The capture track was active and
non-silent in AudioFlinger. Crucially, Android's dedicated WCD SLIM-interface
debug dump during that recording read 0x032=0x80, 0x057=0x05,
0x097=0x21, and 0x11c=0x80. (tavil-slim-pgd regmap is codec register
space, not this interface-device space.) Every earlier Arch microphone
negative test targeted hw:0,1 / MultiMedia2 at 48 kHz. The exact
MultiMedia1 hw:0,0 8-kHz FE / 48-kHz SLIMBUS backend retest then ran on
Arch with TX7/DMIC4 and the active speaker RX route preserved: its 8-second
raw payload was 128,000 bytes / zero non-zero samples. (An earlier
apparent 19-sample result was immediately identified as arecord's 44-byte
WAV header and corrected with -t raw.) This closes the FE/rate mismatch as a
microphone fix. The Android HAL's ADM identity and ACDB path is now the
leading differential: it programs this FE's app type, topology, and device
calibration, whereas mainline q6routing passes zeros.
DEF_ACT_CHAN client-field test — 2026-07-13: The Android downstream NGD
driver encodes the first DEF_ACT_CHAN payload byte as
(data_fmt << 5) | (laddr & 0x1f); mainline had sent the full WCD9340 logical
address (0xcf) and consequently put its high bits into the data-format field.
The one-line correction was built on the current Type-C/G56 test base as
3ceab71eded0, its matching module tree was installed before flashing, and
the resulting 7.1.1-sdm845-g3ceab71eded0 boot was verified on glass. A
controlled single-direction DMIC4 → DEC7 → TX7 → MultiMedia2 48 kHz mono
capture (TX6 disabled) produced 384000 bytes / 192000 samples, with 0
non-zero bytes and signed-16 range 0..0. ALSA state restored (only the
known read-only HPH controls complained); no new SLIM/Q6/NGD timeout or audio
error appeared. This fix is a valid protocol correction and must remain, but
it is not sufficient to make blueline microphone capture work.
Android DMIC-pad + analog split test — 2026-07-13: Android's WCD9340
initial register table writes DMIC3_CLK_PINCFG/DMIC3_DATA_PINCFG
(0x8019/0x801a) to 0x0a; mainline defined but never programmed those
registers. That exact pair was added to WCD934x component initialization,
built as 959f0d5e6, and booted as
7.1.1-sdm845-g959f0d5e65fc. The normal Android handset route
DMIC4 -> DEC7 -> TX7 -> SLIMBUS_0_TX -> MultiMedia2 remained exactly zero
(384000 bytes / 192000 signed-16 samples / zero non-zero bytes), without a
capture-time SLIM, Q6, or ADSP error. A separate reversible replay of
Android's analog fallback AMIC1 -> ADC1 -> DEC6 -> TX6 also produced the
same exact zero stream. Thus neither the DMIC3 pad configuration nor a
bottom-DMIC/flex-only fault can explain the failure: the common remaining
boundary is codec TX channel activation and/or the ADM/ADSP capture path.
The only ALSA restore errors were the known read-only HPH impedance/type
controls.
ADM/calibration lead — 2026-07-13 (refined 2026-07-14): Mainline q6routing_stream_open()
unconditionally passes NULL_COPP_TOPOLOGY and app/acdb values of zero to
q6adm_open(). Pixel Android's msm-pcm-routing-v2.c starts with that
fallback but looks up topology, app type, and ACDB device ID by FE/BE/session
from audio-calibration tables before opening ADM. Do not replace the topology
with a guessed constant: the live Android MultiMedia1 + SLIMBUS_0_TX
recorder has now identified app_type=69938, acdb_dev_id=4,
sample_rate=48000 (and backend ID 3). The exact ADM topology was decoded
from the extracted board-matched ACDB on 2026-07-14; see the next entry.
ADM identity-only test — 2026-07-14 (negative): Kernel
7.1.1-sdm845-g3b9cf346af3a passed Android's observed app_type=69938 and
acdb_dev_id=4 only for live SLIMBUS_0_TX capture, leaving the topology
NULL rather than inventing one. The matching modules were installed before
the pmOS-chain boot_a image was flashed; the running kernel and modules
matched. A controlled MultiMedia1 / hw:0,0, mono S16_LE 8 kHz raw capture
with the Android-equivalent DMIC4 -> DEC7 -> TX7 route yielded 128,000 bytes
with zero non-zero samples. ALSA state was restored (only the known
read-only HPH controls refused writes). This eliminates the two ADM identity
numbers alone as a microphone fix. The remaining Android differential is the
calibration-selected ADM topology and/or downstream codec-side programming.
Board ACDB topology decoded — 2026-07-14: The local Lineage vendor blob
blobs/los-vendor/etc/acdbdata/OEM/sdm845-tavil-b1-snd-card/Handset_cal.acdb
is not merely a future reference: acdb-ldp decodes its HANDSET_MIC device
4 configuration map as 69938 -> 0x00010315 (at 48 kHz). Downstream's
apr_audio-v2.h names 0x00010315 as
ADM_CMD_COPP_OPENOPOLOGY_ID_MIC_MONO_AUDIO_COPP; it is the specific Android
mono-microphone COPP, rather than the mainline null passthrough
0x00010312 or a guessed default. This explains why the identity-only test
was necessarily incomplete. The present 7.1.1 tree also contains q6core's
optional ACDB topology-registration code, but blueline's q6core DT node has
no qcom,acdb-name and no Global_cal.acdb is installed as firmware, so that
path is currently dormant.
ADM topology + AudProc test — 2026-07-14 (negative): The current kernel
opens SLIMBUS_0_TX capture with topology 0x10315, app type 69938, and ACDB
device 4, then parses and sends the board ACDB's complete 524-byte AudProc
table. Live dmesg confirms SLIMBUS_0_TX applied ACDB AudProc calibration: device=4 rate=48000 app=69938 (524 bytes), but capture remains exactly zero.
This eliminates the selected COPP topology plus AudProc table as a complete
fix; Android also sends the separate AudVol table.
AFE calibration delivery audit — 2026-07-14: All three local Pixel
Handset ACDB variants agree. Device 4 has no AFECLUT0 common-calibration
row, and its AFE_CMN_TOPID_V2 device property is 0x000112fb, Qualcomm's
AFE_TX_TOPOLOGY_ID_NONE. The only device-4 AFE datum is a 48-kHz AV-sync
delay of 578, which cannot account for an all-zero stream. Qualcomm's SDM670
ACDB loader passes the same device ID 4 to AFE (there is no hidden remap to
the unrelated AFE-common IDs 100/128/130/149), tries topology, common table,
then hardware delay. Therefore adding an AFE common/topology sender here
would deliver no microphone payload. Do not revisit AFE delivery without new
Android evidence.
ADM AudVol + explicit SLIM-error test — 2026-07-14 (negative): Device 4,
app type 69938, volume index 0 decodes to a 40-byte table: soft-volume
stepping parameters and mono gain 0x2000 (unity). Kernel
7.1.1-sdm845-gfb8f067e12f2 parses AVOLLUT0/AVOLCDFT/AVOLCDOT with the
same validated generic table builder and sends AudProc then AudVol, matching
Android's order. The same build propagates previously ignored failures from
SLIM port connection and WCD934x stream prepare/enable. A controlled 5-second
DMIC4 -> DEC7 -> TX7 -> MultiMedia2 mono 48-kHz capture completed normally
and produced 480,000 bytes / 240,000 samples, all exactly zero. Live dmesg
confirms SLIMBUS_0_TX applied ACDB AudProc/AudVol calibration: device=4 rate=48000 app=69938 (524/40 bytes) and contains no capture-time SLIM
connect/prepare/enable, WCD934x, Q6, permission, or missing-file error.
Therefore neither the missing AudVol table nor a silently discarded SLIM
setup failure explains the zero stream.
Do not stream the ADSP-owned 217:250:0:0 debugfs regmap registers file
during capture: a filtered read blocked after the capture had completed and
had to be killed. This is consistent with the earlier observation that IFD
0x097 is controlled by the ADSP SLIM master; it is not a safe codec-style
bulk register snapshot path and yielded no new state evidence.
True cold-boot re-validation — 2026-07-13: Kernel
7.1.1-sdm845-g44d43e6ef336 includes the WCD934x .prepare/.shutdown
stream-lifecycle experiment. On a physical shutdown/power-on with native WCN
boot healthy, the controlled DMIC4 → DEC7 → TX7 → MultiMedia2 raw capture was
again exactly zero (192000 bytes, 0 non-zero bytes). The temporary
mic-ngd trace proves the entire kernel-visible sequence ran successfully:
q6afe_port_start ret=0, slim_stream_enable entered,
qcom_slim_ngd_enable_stream entered and returned 0. There was no SLIM/Q6
timeout. ALSA was restored immediately; the three HPH-impedance restore errors
are documented read-only controls. This falsifies the prepare-order patch as
a microphone fix and makes silent ADSP-side channel activation (not userspace,
Q6 return handling, or NGD error propagation) the current boundary.
Stable-SLPI follow-up capture — 2026-07-13: After the repaired sensor
registry cleared CHRE's five-minute watchdog and the SSC desktop sensor clients
were exercised successfully, the same safe single-direction TX7/DMIC4 route
was captured as 48 kHz mono raw audio for five seconds. It produced 480,000
bytes / 240,000 samples, all exactly zero. ALSA state was restored by trap;
SLPI, hexagonrpcd, and iio-sensor-proxy stayed active, with no MC:0x2c,
-110, or CHRE fatal. The sensor repair therefore improves platform stability
but does not open the microphone path.
NGD/update audit — 2026-07-13: The running 7.1.1 source already contains
the complete upstream May-2026 NGD probe/SSR race-fix series that landed for
7.2-rc: deferred IRQ enable, controller-owned workqueue initialization, safe
SSR/PDR cleanup, and the tx_lock ABBA deadlock fix. It therefore must not be
re-applied as a speculative microphone patch. This boot still logged one
QMI wait timeout; that is the driver's one-second wait for the remote QMI
service, not an EPERM or file-access failure. It remains a boot-stability
lead, but the subsequent raw capture's core CONNECT_SOURCE transaction
returned 0 and the audio data was still all zero.
- The on-device session's mic doc (collected to
docs/tasks/mic-slim-tx-20260712.md, source phone~/projects/unfinished/pixel3-microphone/) found every capture start at ~23h uptime logging 3xTX timed out:MC:0x2c/failed:-110— the SLIMbusCONNECT_SRCuser message to the ADSP master never answered — and called that the localized root cause. - Re-test after a WARM reboot (same day, laptop-driven): the 0x2c
timeout did not reproduce — but the boot was NOT clean. That boot was
produced by
sudo reboot(warm), and its dmesg showsQMI wait timeoutat 8.1s plus the repeating "Rcvd master capability" retry loop — the documented degraded slim-ngd state that warm reboots carry over (same TZ-poison family as the WiFi MSA issue; only an UNPLUGGED cold power-off clears it). Within that caveat: ahw:0,1capture with the doc's exact TX7/DMIC4 arming logged 37 slim transfers — all MC0x60/0x68value messages, zero errors, zero timeouts — and was still bit-for-bit zero, with IFD0097/0320/0330/0970all00mid-capture. Both datapoints (0x2c timeout at 23h uptime; silent no-activation here) need re-validation on a true cold boot before either is trusted. - No root-cause conclusion is valid yet. The
-110may be a degraded-NGD artifact of long uptime / remoteproc restarts, while the silent all-zero capture may be a separate normal-state failure; the only attempted contrast was tainted by a warm reboot. Kernel-visible Q6 and NGD success plus Android'sIFD 0x097=21versus mainline00remain observations, not a proven boot-invariant activation failure. - Note:
0320/0330read00here vsc0/01in the 07-11 canonical 2ch trace — arming differed (single TX7 vs TX7+TX8); observation only. - What the phone doc contributes regardless: OnePlus 6 (enchilada) mic
works on pmOS 6.x kernels with this same driver stack (6.x->7.x
regression candidate in slimbus/ngd/wcd934x, or blueline-specific ADSP
behavior); pmOS's blueline UCM ships with the whole mic section
commented out (nobody has solved this on mainline); operational
hazards — never restart the adsp remoteproc while debugging slim (NGD
stays degraded until reboot, reproducible), never leave MultiMedia2
with both
SLIMBUS_0_RXandSLIMBUS_0_TXroutes enabled (q6adm/q6asm wedge); QUAT_TDM_TX_0 in DT would give a WCD-free CS35L36 VMON/IMON capture reference. - Refined next steps: trace the
qcom_slim_ngd_enable_streamuser-message exchange on a fresh boot (is CONNECT_SRC sent and ACKed, or skipped?); diffdrivers/slimbus/{qcom-ngd-ctrl.c,stream.c,messaging.c}+wcd934x.cagainst pmOS's 6.x sdm845 tree; if an enchilada is handy, boot this 7.1.1 kernel on it to split regression vs blueline-specific; ask #sdm845-mainline about silent no-activation with working value messages.
Upstream/device-branch archaeology — 2026-07-12 (no phone test)
- The current
sdm845/7.1-devupstream line is active (its tip is two months newer than our 7.1.1 base) but its audio delta is the CS35L36 speaker DTS support already mined for the working speaker route; it contains no WCD934x microphone/SLIM-TX fix. Do not hold a cold-boot test for an imagined pending 7.1 microphone update. - Real candidate to test after a true cold baseline: historical
joel/op6-audio-fixes-wipcommit1d5776cachanges WCD934x SLIM lifecycle from.trigger(enable on PCM START) to.prepareplus.shutdown(enable before START, disable on close). Our currentwcd934x.cstill has the old.triggerimplementation. This is not upstream and not proof of a fix, but it moves theslim_stream_enable()/ CONNECT_SRC exchange out of PCM START into the backend prepare phase. Static inspection confirms the Q6 SLIM DAI starts its AFE port in.prepare, while DPCM prepares BEs before the FE; that makes this a concrete stream-ordering hypothesis rather than a generic codec tweak. First make an instrumentation-only patch or trace plan that establishes the exact per-DAI callback order; only then consider a rollback-approved kernel test. - Related branch commits were inspected and are not default candidates for
blueline DMIC capture:
75ad5bb0adds separate AIF2/AIF3 SLIM DAI links for OnePlus use cases (our AIF1SLIMBUS_0_TXlink already matches its AIF1 portion);4a05bee2and beryllium07078b5crepair MBHC/MIC_BIAS2 headset handling, not the DMIC4/MIC_BIAS4 path. Keep them as topology references, not a grab-bag patch series. - Candidate build/deploy and cold-boot result (2026-07-13): the lifecycle
change was ported exactly onto the running Type-C-bisect base
(
56b0a053b) as44d43e6ef/ Gitea branchmic-slim-prepare-order-g56, built on ArchDev, module tree installed, and boot image flashed to slot A. Casey then performed an unplugged shutdown and power-on; on7.1.1-sdm845-g44d43e6ef336, the controlledDMIC4 → DEC7 → TX7 → MultiMedia2hw:0,1capture still contained only zero samples. NoMC:0x2c/-110occurred during that capture. Thus the prepare-order hypothesis is a valid deployed negative result, not an untested lead; retain the kernel as the current microphone-test baseline.
Live state — 2026-07-12 (speakers)
- BOTH speakers now fire: the earlier "speaker playback works" state was in
fact top-speaker-only — both CS35L36 amps had
Channel Mux = RX1, so the bottom loudspeaker never received a channel. Fixed with the pmOS backup image's routing (Left=RX1 top, Right=RX2 bottom, plus LDM select / PDM ramps / zero-cross / per-amp ASPTX sources) in the overlay UCM (commit 2f39c06), installed on-device and persisted viaalsactl store. Verified by ear: distinct left/right/stereo tones. - Phone-side handoff doc
~/projects/unfinished/pixel3-speaker-routing/(README + baseline state + test tones) documents the diagnosis trail; its "next step" (pmOS MRs online) was superseded by reading the local pmos-20260703 rootfs image directly (debugfs, no mount needed). - Regression and guardrail — 2026-07-13: the live TDM split was still
correct (
Left Channel Mux=RX1,Right Channel Mux=RX2), but both amp and boost switches were off. Re-enabled all four and stored the corrected state on the phone.docs/tasks/asound-baseline-20260712.stateis a pre-fix diagnostic snapshot (Right Channel Mux=RX1); it must never be passed toalsactl restore, because doing so regresses the bottom speaker. Use the deployed UCM and current/var/lib/alsa/asound.stateas the restore source.
Prior live state — 2026-07-11
- Speaker playback works end-to-end through PipeWire, UCM, QUAT TDM and the CS35L36 amplifiers (top speaker only — see above).
arecord -D hw:0,1 -f S16_LE -r 48000 -c 2(the canonical MultiMedia2 front-end, whoseSLIMBUS_0_TXlink is enabled) opens and runs, but capture is bit-for-bit zero. This is a hardware/ASoC transport investigation, not a PipeWire source-selection failure; no PipeWire source can exist until ALSA produces samples.- This work did not start
iio-sensor-proxy. There is no evidence that the sensor-client HACK or SLPI wake-lockup mechanism gates this audio path.
Verified zero-capture path — historical 2026-07-11
The controlled route is Android's documented handset/endfire pair:
- DMIC4 -> DEC7 -> SLIM TX7 and DMIC3 -> DEC8 -> SLIM TX8.
- Q6 function tracing during
arecordobserved, in order:q6slim_set_channel_map,wcd934x_hw_params,q6afe_slim_port_prepare,q6afe_port_start, andwcd934x_trigger. - A temporary argument probe observed the two expected shared-channel IDs
delivered to Q6 when TX6 is off:
tx_num=2,0x87,0x88(135, 136). The resulting 478,078 signed-16 samples onhw:0,1were all zero. - The WCD9340 interface device (
217:250:0:0,WCD9340-IFC-DEV) receives the expected driver writes for both ports: TX7 map/config0x11c=80,0x11d=01,0x57=05; TX80x120=80,0x121=01,0x58=05. Its live interrupt enables are0x32=c0and0x33=01, so their absence is not the explanation for silence. - On that same canonical front-end,
q6afe_port_start()returns0, thenslim_stream_enable()invokesqcom_slim_ngd_enable_stream(), which returns0after the controller'sDEF_ACT_CHANandRECONFIG_NOWoperations. Kernel-visible Q6 and NGD schedule activation therefore succeeded. - Corrected DAPM observation: a clean live
hw:0,1capture powers codec-sideAIF1 CAPandAIF1_CAP Mixer. Its prepare phase callswcd934x_codec_enable_slimand twowcd934x_codec_enable_decevents. The earlier report that these callbacks never fired was false: the trace missed the prepare-phase calls. Do not use that earlier result as evidence. - The persistent mixer state leaves
CDC_IF TX7 MUXandCDC_IF TX8 MUXatZERO, despite the corresponding AIF mixer switches and DMIC muxes being selected. Consequently the TX7/TX8 branch is off during an ordinary capture and nowcd934x_codec_enable_dmicevent occurs. This is a real UCM route omission, not an ADSP conclusion. - A controlled, automatically reverted test set those muxes to
DEC7andDEC8and disabled stray TX6. It powered the entire intended branch and invokedwcd934x_codec_enable_dmictwice (with matching shutdown calls). The independent two-second PCM capture was nevertheless 384,000 zero bytes. Thus the codec DAPM path and physical DMIC endpoints are viable once the muxes are selected, but that route omission is not the final silence cause. - This is not a missing FE-to-BE connection: runtime ASoC state reports
MultiMedia2 Capture: startwithSLIM Capture 1: startas its active backend, and the codec's AIF/decimator event callbacks run. With the CDC muxes selected, the DMIC callbacks run too; the unresolved point at that date was after the fully powered codec capture path. - Reducing the route to the downstream-style single TX7/DMIC4 channel did not
change the result: a four-second
hw:0,1mono capture contained 192,000 zero samples. Channel count/configuration is therefore not the activation trigger.
What the 2026-07-11 evidence did and did not say
Android's captured recording state has IFD 0x097=21; mainline reads 00.
During a five-second live TX7/TX8 capture, writing 0097 21 through the
debugfs regmap returned success but read back 0097: 00, and all 478,078
samples remained zero. This confirms that a userspace register replay cannot
enable that state on this path. It does not establish what 0x097 means
or prove that it is the root cause. Do not turn it into an unconditional
codec write or call it an “ADSP-master fix” without an implementation-level
source or Android-side transition capture.
TX6 is enabled by the current mixer default alongside TX7/TX8. It makes the
unconstrained map three channels (0x86, 0x87, 0x88), while disabling it
produces the correct TX7/TX8 pair above. That is a real UCM/machine-routing
cleanup item, but it did not restore capture and is not the root cause.
Proposed next work on 2026-07-11 — superseded
- Capture the working Android interface-device transition, or find the
downstream owner/meaning of IFD
0x097; compare the actual write sequence, not just idle/recording register snapshots. - Add the TX7/TX8
CDC_IFmux selections to the eventual microphone UCM enable sequence (and keep TX6 off for this two-channel route). Do not expose a broken PipeWire source before its capture is non-zero. - Repeat the WCD9340 interface/ADSP comparison only with that fully powered
codec path. The still-zero full-path test strengthens, but does not prove,
the relevance of the non-sticking Android IFD
0x097=21delta. Capture an Android transition or find the downstream owner before making a firmware or register claim. Do not flash a kernel test without an explicit rollback-approved deployment plan. - Only after that, compare the remaining post-activation state with Android at the firmware boundary. Q6 and NGD success alone do not show that the codec/ADSP hardware emits decimator samples.
- Fix the stray TX6 default separately in the persistent UCM/machine route, then verify it with the channel-map probe. Do not claim mic support until a live capture contains non-zero samples.
Instrumentation
/usr/local/sbin/blueline-lockup-trace is a root helper deployed from
rootfs-overlay/. mic-start traces the Q6/WCD stream functions and the
three WCD codec DAPM event callbacks; mic-map-start, mic-ifc-start, and
mic-ngd-start collect Q6 channel-map, WCD interface-register-write, and
Q6/NGD return traces respectively. Trace sessions are temporary and must
always be paired with the matching *-stop command; the current phone was
checked clean afterwards (tracing_on=0, tracer nop, no kprobes).
2026-07-18 full Android power-state reconciliation
A clean, single-channel PulseAudio/UCM capture on kernel 4c3a94153 proved
that the intended TX7/DMIC4 path is selected and fully ACKed, but every one of
55,680 S16 samples is exactly zero. A simultaneous live codec dump exposed
two remaining Android/mainline power-state differences which earlier tests had
not actually eliminated:
ANA_MICB4is0x50on mainline versus0x90during Android recording. The DT opt-inqcom,blueline-dmic-micbias-pullupis on thecodec@1,0node, butwcd934x_codec_parse_data()querieddev->parent->of_node(the SLIM controller). Thereforemicbias_pullupwas always false and the earlier claim that pull-up mode had been tested is invalid. The code now queriesdev->of_node, selecting Qualcomm's downstreamMICB_PULLUP_ENABLEpath (0x90).ANA_BUCK_CTLis0x00on mainline versus0x07on Android. Qualcomm's resource manager sets RCO followed by buckPRE_EN1,PRE_EN2, andHIGH_ACCURACY_EN, with 100 us between stages. The mainline driver had dropped this sequence. It is restored as ordered masked writes, including the reverse transition; this is not the harmful unsequenced Android end-state replay removed earlier.
The same correction (a75371b49) also matches Android's board state by
programming only DMIC interface 3 pads (the real DMIC3/4 inputs) and avoids
leaving TX7 at the transient 150 Hz HPF setting (CFG0=0xd0) indefinitely;
Android's steady recording state is CFG0=0x90. One boot-time log reports
whether pull-up mode was parsed, and the capture log reports live BUCK and all
MICB registers so the next capture validates the complete state in one pass.
2026-07-18 eFuse initialization regression and cache fix
On the clean 3b85e688f boot, the complete downstream AFE codec-control map
registered successfully and TX7 again reached port_start, CONNECT_SOURCE,
DEF_ACT_CHAN, and RECONFIG_NOW with positive ACKs. PulseAudio captured 760,318
raw bytes (380,159 S16 samples), all exactly zero. The journal exposed a real
codec boot failure: wcd934x_enable_efuse_sensing read EFUSE_STATUS=0 and
reported that sensing never completed.
History showed that 1c095f7a7 had added the downstream-required
internal-SIDO start before eFuse sensing, but c1b6371c6 removed the call while
dropping unrelated experiments. The exact downstream SIDO/buck transition
helper was later restored by a75371b49 without reconnecting it to eFuse init.
The audit also found that downstream treats EFUSE_CTL, all eFuse value
outputs, and status as volatile, while mainline cached them in REGCACHE_MAPLE.
Commit 82355eac0 batches the complete correction: internal SIDO before the
sense enable, the required 5 ms delay before RCO/BG, downstream-parity volatile
register handling for the eFuse/clock/buck sequence, live completion polling,
register error propagation, and explicit status/out14/out15 logging. Do not
interpret another zero capture until a cold boot proves the codec prints
eFuse sense complete; otherwise the physical codec trim/version state is
still uninitialized even though SLIM management commands ACK normally.