I2S MEMS mic (SPH0645) — same symptom as #264, FlatBuild link expired

Hi team,

I’m hitting exactly the same I2S MEMS microphone issue described in this earlier thread, but on a fresh stock Rubik Pi 3 image where the fix has not been applied yet. Posting a new topic because that thread is marked solved and the attached FlatBuild_Ru…335.zip link has expired, so I can’t take the easy path to verify.

I’ve already done a fairly deep static analysis on my side and want to share what I found so other users hitting this on the stock image don’t have to repeat the work, and so the team can advise me on the cleanest next step.

Environment

  • Board: Rubik Pi 3 (Thundercomm), stock first-shipped image
  • uname -a: Linux rubikpi 6.6.90 #1 SMP PREEMPT Fri Sep 5 10:41:44 CST 2025 aarch64 GNU/Linux
  • Sensor: Adafruit SPH0645LM4H (same Adafruit I2S MEMS family as the ICS-43434 used in #264; identical I2S timing — 24-bit MSB-justified in a 32-bit slot, BCLK min 2 MHz)
  • Audio stack on this image: PulseAudio + PAL (no PipeWire, so the pw-pal-plugin part of 0002-…patch.txt does not apply here)

Wiring (same as the OP of #264)

40-pin physical pin SPH0645
1 3V3
6 GND
12 BCLK
35 LRCL
38 DOUT
SEL → GND (left channel)

Symptom

  • arecord -D hw:0,9 -d 3 -c 2 -r 48000 -f S16_LE x.wav → succeeds, but the wav is all zero (max_abs = 0)
  • arecord -D hw:0,9 ... -f S32_LESample format non available, Available: S16_LE
  • parecord --device=regular0 ... → produces wav of zeros as well
  • dmesg is completely clean during the failed reads — no ASoC errors are logged

Root cause confirmed by static analysis of stock snd-soc-qcm6490.ko

I disassembled the qcm6490 ASoC machine driver shipped on this image (/lib/modules/6.6.90/kernel/sound/soc/qcom/snd-soc-qcm6490.ko, sha256 fc0b92c894a128410c7dbd3469adafa2919523ff1c694df983f441105676c151). The TERTIARY MI2S branch in qcm6490_snd_startup hardcodes:

snd_soc_dai_set_sysclk(cpu_dai, 0x104 /* TER_MI2S_IBIT */, 0x177 << 12)

0x177 << 12 = 1,536,000 Hz = 1.536 MHz, which is below the SPH0645/ICS-43434 minimum BCLK of 2 MHz — so the sensor never leaves standby and the data line stays low. Captured DMA contents are all zero. arecord --dump-hw-params -D hw:0,9 also confirms the kernel only exposes S16_LE for that backend.

The two .patch.txt files attached on Jan-15-2026 in #264 address exactly this:

  • DT (0001): adds the tert-formats-high-bit property on the sound card and adds the ICS-43434 codec node + binds it on the TERTIARY-MI2S-TX dai-link
  • AGM (0002): backend_conf.xml, <device name="MI2S-LPAIF-TX-TERTIARY" … bits="16" />bits="32"
  • PAL (0002): resourcemanager_qcm6490_idp.xml, <PAL_DEVICE_IN_HANDSET_MIC> backend changed from CODEC_DMA-LPAIF_VA-TX-0MI2S-LPAIF-TX-TERTIARY, 1ch, 32-bit
  • PipeWire (0002): pw-pal-plugin exposes pal_source_handset_mic (only relevant on PipeWire-based images)

In-place verification on this stock image

To narrow down what’s strictly required, I applied just the userspace XML changes in place (since DT and any kernel C change require a rebuild):

  1. AGM: MI2S-LPAIF-TX-TERTIARY set to bits="32" in both /etc/backend_conf.xml and /usr/etc/backend_conf.xml
  2. PAL: PAL_DEVICE_IN_HANDSET_MIC backend repointed to MI2S-LPAIF-TX-TERTIARY, 1ch, 32-bit, max_channels=2
  3. Restarted PulseAudio

After this, PA’s regular0 source reports Active Port: handset-mic (so the route is wired up correctly at the PA/PAL layer). But the capture still yields zeros, and LPASS_CLK_ID_TER_MI2S_IBIT stays at enable=0 in /sys/kernel/debug/clk/clk_summary during the read attempt. The kernel still only exposes S16_LE on hw:0,9 regardless of the AGM/PAL XML.

So in short — the userspace XML changes alone are not sufficient on this kernel. The kernel side needs to honor the new tert-formats-high-bit property (or otherwise unlock S32_LE on TERTIARY), which I can’t see in the two .patch.txt files but the symptom shows must be needed somewhere in the kernel C source. I’ve reverted all in-place changes; backups are preserved on the device for further testing.

Asks

  1. Could you re-share FlatBuild_Ru…335.zip (or any equivalent prebuilt image with this fix applied)? That would be the fastest path for me to verify the fix on my board and confirm the sensor wiring is good.
  2. Are the two .patch.txt files in #264 the complete patchset, or is there a separate kernel C patch (e.g., adding the tert-formats-high-bit reader and 32-bit format support in snd-soc-qcm6490.c) that also needs to be applied? If there’s an additional kernel patch, could you attach it here as well?
  3. If the cleanest path is a full local build, is the manifest from #264 (rubikpi-6.6.97-QLI.1.6-Ver.1.3_qim-product-sdk-2.1.1.xml) still the recommended starting point, or has it been superseded?

Happy to share the full diagnostic bundle (disassembly snippets of qcm6490_snd_startup, arecord --dump-hw-params, pactl list output, clk_summary deltas) if it’s useful for documenting this on the stock image side. Hopefully this helps the next person hitting the same symptom on an un-updated board find the right thread faster.

Thanks!