# Pixel 3 (blueline) — microphone / SLIM TX capture bug

**Status:** 2026-07-18 — BUG HAS MOVED. Transport is now FIXED; still zeros.
The `CONNECT_SRC` timeout the rest of this doc chases **no longer happens**
(kernel is now `g8cbfbb939327`, was `g56b0a053bef8` when that was found).
Port-connect, channel activate, and q6afe port_start all succeed (ret=0), yet
capture is still pure zeros. The fault is now DOWNSTREAM of transport, in the
WCD934x SLIM-PGD data-plane. See "## 2026-07-18 UPDATE" below; the older
sections are kept for history but their root-cause conclusion is superseded.

## 2026-07-18 UPDATE — transport fixed, data-plane is the new fault

Re-ran on a clean 58-min-uptime boot, ADSP never restarted. Findings:

- **The SLIM CONNECT_SRC (MC 0x2c) timeout is GONE.** Every capture now logs
  `connect_port: dir=1 port_id=N ch_id=NNN la=0xcf ret=0`,
  `DEF_ACT_CHAN xfer ret=0`, and q6afe `port_start OK` (port 0x4001,
  cfg 0x10212). Zero `timed out` / `failed:-110` lines in dmesg.
- **Still 0/144000 nonzero samples** on every path tried:
  - DMIC4 → DEC7 → TX7 (enchilada recipe)
  - DMIC0 → DEC6 → TX6 (handset, via cleancap.sh)
  - **AMIC1 → ADC1 → DEC0 → TX0 (analog!) — also zeros.**
  So it is NOT DMIC-specific and NOT a DMIC-clock problem. Common to every
  decimator and every TX port.
- **Decimator path is fully powered and unmuted:** `decN POST_PMU`
  `TX_PATH_CTL=0x24 [clk_en=1 mute=0 rate=0x4]`, DEC6/DEC7 Volume = 84 (0 dB),
  MICB on. DAPM all On. So routing/gain/mute are ruled out.
- **The smoking gun is now IRQ 213.** `/proc/interrupts` line
  `213: 0 ... wcd934x_irq 0 Edge  slim` — the WCD934x's own SLIM/data
  interrupt has fired **0 times in the machine's entire life**, including
  across capture. (Contrast IRQ 212 `wcd934x_irq` control line = 18, so the
  codec IRQ domain is alive; button-detect 215 = 17.) The codec arms its TX
  PGD port (`PGD_TX_INT_STATUS=0x0000`, port `STATUS=0x00`) but never raises
  the data interrupt → port never actually streams → ADSP reads zeros.

### New working hypothesis
Control-plane port *connect* (NGD user messages) succeeds, but the WCD934x
**SLIM PGD port is never *enabled*/started** on the data side — the register
write that arms the port's data engine and its interrupt
(`SLIM_PGD_PORT_INT_EN*`, per-port `PORT_CFG`/enable) isn't happening or isn't
taking. That's why IRQ 213 stays 0 and the port emits zeros. This is a
codec-side (wcd934x.c) or CDC_IF data-lane issue, NOT an ADSP/satellite issue.

### The instrumentation gap (next patch)
The current MICDBG patch logs the decimator, connect_port, and DEF_ACT_CHAN,
but does NOT dump the SLIM PGD port-enable / port-interrupt registers — the
exact layer where the bug now lives. Next kernel patch should log, right after
"prepare CAPTURE armed":
  - `WCD934X_SLIM_PGD_PORT_INT_EN0` (0x341?) and INT_EN for the TX port
  - per-port `SLIM_PGD_TXn_CFG` / port enable bit
  - `SLIM_PGD_PORT_INT_SRC` / `_STATUS` DURING an active stream (not just at
    prepare — need a delayed read or a sysfs poke)
Then check: is the port-enable bit actually set? Is IRQ 213 masked at the
codec? Compare this whole sequence against enchilada (mic works) on 6.x.

### Verified-safe method notes (this session)
- Never touched remoteproc; ADSP stayed `running` throughout.
- `alsactl restore 0` does NOT fully clear AIF*_CAP SLIM TXn mixer bits —
  stale TX routes leak into the next run (saw map=[134 128 ...] = TX6+leftover
  TX0). Explicitly `cset ... 0` every AIF*_CAP SLIM TXn you touched.
- `cleancap.sh` (in ~) is the good harness: forces TX7 off (its comment flags
  TX7 as an "Android-replay wedge trigger"), sets the DMIC0/TX6 handset path,
  and measures IRQ 213 delta + nonzero-sample count. Use/extend it.

---
## (Historical — superseded) original 2026-07-12 root-cause

**Status:** ROOT CAUSE LOCALIZED 2026-07-12 — not fixed yet.
All capture sources record pure digital zeros because the SLIMbus
`CONNECT_SRC` port-connect message to the ADSP master **times out**, so the
WCD9340's TX port is never attached to the data channel. The DSP then
delivers a valid-but-empty stream. Control traffic (codec register
reads/writes over slimbus) works fine.
**(As of 2026-07-18 this timeout no longer occurs — see UPDATE above.)**

## The smoking gun

With dynamic debug on `drivers/slimbus/*`, every capture start logs 3×:

```
qcom,slim-ngd qcom,slim-ngd.1: TX timed out:MC:0x2c,mt:0x2
qcom,slim-ngd qcom,slim-ngd.1: Tx:MT:0x2, MC:0x2c, LA:0xcf failed:-110
```

- `MC 0x2c` = `SLIM_USR_MC_CONNECT_SRC` (qcom satellite user message that
  connects the codec TX port to the allocated data channel)
- Value-element messages (`MC 0x60` REQUEST_VALUE / `0x68` CHANGE_VALUE —
  i.e. regmap traffic to the codec) all succeed with no timeouts
- So: NGD hardware messaging works; the ADSP-side slimbus master/satellite
  service does not answer port-connect requests
- TODO: identify LA 0xcf — codec device or the ifd (ports live on the
  interface device `ifd@0,0`)?

Enable debug: `echo 'file drivers/slimbus/* +p' > /sys/kernel/debug/dynamic_debug/control`

## What was proven (2026-07-12, kernel 7.1.1-sdm845-g56b0a053bef8)

1. Capture streams open and run fine on hw:0,1 (MultiMedia2) and hw:0,0
   (MultiMedia1) routed from `SLIMBUS_0_TX` — but 100.0% of samples are
   exactly 0 (not noise floor; digital silence).
2. Swept EVERY input: AMIC ADC1-4 (via ADC MUX0→DEC0→SLIM TX0) and
   DMIC0-5, plus the enchilada-style TX7 slot layout
   (DMIC MUX7=DMIC4 → ADC MUX7=DMIC → CDC_IF TX7 MUX=DEC7 →
   AIF1_CAP Mixer SLIM TX7). All zeros.
3. DAPM (debugfs) during capture: entire codec path reports **On**
   (ADC, AMIC/ADC muxes, SLIM TX0 mixer, MIC BIAS1). So it's not routing.
4. DT declares 4 mics (`/proc/device-tree/sound/audio-routing`):
   AMIC1←MIC BIAS1, DMIC0←MIC BIAS1, DMIC3←MIC BIAS3, DMIC4←MIC BIAS4.
   Codec node has ifd@0,0 + codec@1,0 + slim-ifc-dev; micbias 1.8 V ×4;
   extclk 9.6 MHz. Structurally like working devices.
5. **pmOS never solved this either**: their blueline UCM
   (gitlab.com/sdm845-mainline/alsa-ucm-conf, ucm2/Google/blueline) has the
   whole mic section *commented out*. Their intended bottom-mic path:
   DMIC4 → DEC7 → SLIM TX7 → AIF1_CAP → SLIMBUS_0_TX → MultiMedia2,
   CaptureMixerElem "DEC7".
6. OnePlus 6 (enchilada) mic **works** on pmOS 6.x kernels with the same
   driver stack (AMIC4, TX7/DEC7, `AMIC4_5 SEL=AMIC4`) → this is either a
   6.x→7.x regression in slimbus/ngd/wcd934x, or blueline-specific
   (ADSP firmware? satellite service difference?).
7. WCD RX (playback) direction could NOT be verified: EAR PA powers on and
   streams (path: `SLIMBUS_0_RX Audio Mixer MultiMedia2`, `SLIM RX0 MUX=
   AIF1_PB`, `RX INT0_1 MIX1 INP0=RX0`, `RX INT0 DEM MUX=CLSH_DSM_OUT` —
   note EAR hangs off **RX INT0**, not INT8), but no sound heard — and the
   Pixel 3 has NO WCD-driven transducer to hear: both front speakers incl.
   the "earpiece" are CS35L36s on QUAT_TDM, and there's no 3.5mm jack.
   Inconclusive by hardware design. Whether CONNECT_SINK (MC 0x2d) also
   times out is STILL UNKNOWN — never got a clean dmesg on an RX stream.
8. QUAT_TDM_TX (would allow CS35L36 VMON/IMON digital loopback = objective
   transport test) is not a wired backend in the DT — stream open fails
   EINVAL. Could be added in DT to get an ear-free TDM capture reference.

## Hazards learned (do not repeat)

- **Do NOT restart the adsp remoteproc while debugging**: slim-ngd fails to
  re-handshake ("QMI wait timeout", no new "Rcvd master capability") and
  slimbus stays degraded until full reboot. Happened twice, reproducible.
- Don't leave MultiMedia2 with BOTH `SLIMBUS_0_RX` (playback) and
  `SLIMBUS_0_TX` (capture) routes enabled — ADM open starts failing
  (q6adm cmd 0x10325 error 2) and then q6asm sessions wedge (-22 on any
  further prepare).
- Restore baseline with `sudo alsactl restore 0` (HPH*/Impedance write
  errors are harmless read-only controls).
- Speaker README's rule still applies: volume 100% + unsuspended sink
  before trusting any "silent" result.

## Next steps

1. Fresh boot → repeat one capture with slimbus dyndbg on; confirm the
   0x2c timeout on a clean system (rule out long-uptime NGD state; uptime
   was ~23h when found).
2. Same boot: start a WCD RX playback stream and check whether
   CONNECT_SINK (`MC:0x2d`) times out too. Both-fail → all port-connects
   dead (satellite service issue); TX-only → look at TX-specific code.
3. Diff `drivers/slimbus/{qcom-ngd-ctrl.c,stream.c,messaging.c}` and
   `sound/soc/codecs/wcd934x.c` between pmOS linux-postmarketos-qcom-sdm845
   (6.x, mic works on enchilada) and this 7.1.1 tree. Focus: user-message
   port connect path, LA used for port ops (codec vs ifd), TX port
   numbering.
4. If an enchilada is handy: run this 7.1.1 kernel on it and test mic —
   cleanly separates "7.x regression" from "blueline-specific".
5. Ask in #sdm845-mainline / linux-arm-msm about the signature
   "Tx:MT:0x2, MC:0x2c failed:-110 while value messages work" — someone
   may recognize the satellite/ADSP state.
6. Longer shot: wire up QUAT_TDM_TX_0 in DT for VMON capture as a
   transport-known-good reference and UCM debugging aid.

## Quick repro

```sh
echo 'file drivers/slimbus/* +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
amixer -c 0 cset name='MultiMedia2 Mixer SLIMBUS_0_TX' 1
amixer -c 0 cset name='AIF1_CAP Mixer SLIM TX7' 1
amixer -c 0 cset name='CDC_IF TX7 MUX' DEC7
amixer -c 0 cset name='ADC MUX7' DMIC
amixer -c 0 cset name='DMIC MUX7' DMIC4
sudo dmesg -C
arecord -D hw:0,1 -f S16_LE -r 48000 -c 1 -d 2 /tmp/t.wav
sudo dmesg | grep 'timed out'      # -> MC:0x2c
# zeros check:
python3 -c "import wave,struct;w=wave.open('/tmp/t.wav');d=struct.unpack('<%dh'%w.getnframes(),w.readframes(w.getnframes()));print(max(map(abs,d)))"
# afterwards:
sudo alsactl restore 0
```

## References

- pmOS blueline UCM (mic commented out):
  https://gitlab.com/sdm845-mainline/alsa-ucm-conf → ucm2/Google/blueline/HiFi.conf
- enchilada UCM (working mic recipe): same repo, ucm2/OnePlus/enchilada/HiFi.conf
- Speaker fix project (methodology + amp/TDM background):
  ~/projects/unfinished/pixel3-speaker-routing/
