You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On a Raspberry Pi 4B using an I2S sound card in clock-consumer (slave) mode — a HiFiBerry Digi+ I/O, whose WM8804 S/PDIF receiver provides BCLK/LRCLK recovered from the optical input — opening a capture stream while the external bit clock is absent (source off/unplugged, or the receiver not locked yet) silently corrupts the RX path instead of failing:
arecord "completes" absurdly fast (a 10 s capture returns in ~20 ms) with a file of the correct size filled with one repeated DC value;
once this happens, the state persists across later, correctly-clocked opens — subsequent captures keep free-running even with the receiver locked and clocks present. Occasionally a later open recovers it (timing-dependent); a reboot always does.
Root cause (from sound/soc/bcm/bcm2835-i2s.c):
the FIFO clear (BCM2835_I2S_RXCLR) needs at least 2 PCM clock cycles to take effect — with no external BCLK it silently never completes;
the SYNC round-trip wait carries a literal FIXME: This does not seem to work for slave mode! and, on timeout, only logs "I2S SYNC error!" and continues;
with stale data at/above the RX DREQ threshold left in the FIFO, DREQ sticks asserted and the DMA re-reads the same dead word at bus speed (tens of MB/s observed) — hence the instant "successful" capture full of garbage;
hw_params returns early when TXON/RXON is set and prepare only clears a FIFO it can clock, so the poisoned state survives stream cycles.
Steps to reproduce the behaviour
Raspberry Pi 4B + HiFiBerry Digi+ I/O (dtoverlay=hifiberry-digi), dtparam=audio=on disabled; no signal connected to the S/PDIF input (or source powered off);
Observe it return in tens of milliseconds with a full-size file containing a single repeated value (instead of blocking or failing);
Connect a valid PCM source and confirm the WM8804 locks (SPDSTAT via i2c);
Repeat the arecord: on most attempts it still free-runs despite the receiver being locked — the FIFO poison from step 2 persists. A reboot restores normal behaviour.
Also reproducible the other way around: with everything healthy, unplugging the source while capture cycles run eventually leaves the same stuck state.
Device (s)
Raspberry Pi 4 Mod. B
System
cat /etc/os-release: Debian GNU/Linux 13 (trixie) — Raspberry Pi OS 64-bit
Measured free-run signature: 10 s capture returning in 0.02 s wall-clock; continuous capture producing ~40–80 MB/s of a single repeated 16-bit value; /proc/asound/.../status cycling through XRUN.
Additional context
Interplay warning: pigpiod's default DMA timing source is also the PCM peripheral; with pigpiod running under default flags this race is lost on virtually every first open (moving pigpiod to -t 0/PWM restores normal behaviour). Users combining pigpio with I2S capture likely hit this and misattribute it.
A second, separate problem found while attempting recovery: modprobe -r snd_soc_rpi_wm8804_soundcard snd_soc_wm8804_i2c snd_soc_bcm2835_i2s oopsed in wm8804_i2c_driver_exit on this kernel, so module-reload recovery is not viable (trace available on request).
I have a patch validated on this hardware: make bcm2835_i2s_clear_fifos() return an error on SYNC timeout and propagate it in .prepare for the capture-with-stale-RX-data branch, while keeping the hw_params-time clear tolerant (it legitimately runs before a clock consumer's provider is up). Results on the rig: source unplugged + capture open → clean -EIO in ~0.6 s with zero bogus data; source reconnected → very next capture healthy (no reboot); no regressions observed on normal boots/playback. PR to follow.
Describe the bug
On a Raspberry Pi 4B using an I2S sound card in clock-consumer (slave) mode — a HiFiBerry Digi+ I/O, whose WM8804 S/PDIF receiver provides BCLK/LRCLK recovered from the optical input — opening a capture stream while the external bit clock is absent (source off/unplugged, or the receiver not locked yet) silently corrupts the RX path instead of failing:
arecord"completes" absurdly fast (a 10 s capture returns in ~20 ms) with a file of the correct size filled with one repeated DC value;Root cause (from
sound/soc/bcm/bcm2835-i2s.c):BCM2835_I2S_RXCLR) needs at least 2 PCM clock cycles to take effect — with no external BCLK it silently never completes;FIXME: This does not seem to work for slave mode!and, on timeout, only logs "I2S SYNC error!" and continues;hw_paramsreturns early when TXON/RXON is set andprepareonly clears a FIFO it can clock, so the poisoned state survives stream cycles.Steps to reproduce the behaviour
dtoverlay=hifiberry-digi),dtparam=audio=ondisabled; no signal connected to the S/PDIF input (or source powered off);arecord -D hw:CARD=sndrpihifiberry -f S16_LE -r 48000 -c 2 -d 10 test.wavAlso reproducible the other way around: with everything healthy, unplugging the source while capture cycles run eventually leaves the same stuck state.
Device (s)
Raspberry Pi 4 Mod. B
System
cat /etc/os-release: Debian GNU/Linux 13 (trixie) — Raspberry Pi OS 64-bituname -a: Linux pi 6.18.34+rpt-rpi-v8 var->green.length may be left uninitialized #1 SMP PREEMPT Debian 1:6.18.34-1+rpt1 (2026-06-09) aarch64vcgencmd version: May 21 2026 11:20:25Logs
On each affected open:
Measured free-run signature: 10 s capture returning in 0.02 s wall-clock; continuous capture producing ~40–80 MB/s of a single repeated 16-bit value;
/proc/asound/.../statuscycling through XRUN.Additional context
-t 0/PWM restores normal behaviour). Users combining pigpio with I2S capture likely hit this and misattribute it.modprobe -r snd_soc_rpi_wm8804_soundcard snd_soc_wm8804_i2c snd_soc_bcm2835_i2soopsed inwm8804_i2c_driver_exiton this kernel, so module-reload recovery is not viable (trace available on request).bcm2835_i2s_clear_fifos()return an error on SYNC timeout and propagate it in.preparefor the capture-with-stale-RX-data branch, while keeping thehw_params-time clear tolerant (it legitimately runs before a clock consumer's provider is up). Results on the rig: source unplugged + capture open → clean-EIOin ~0.6 s with zero bogus data; source reconnected → very next capture healthy (no reboot); no regressions observed on normal boots/playback. PR to follow.