Reporter / AI-assistance disclosure
I encountered this problem on my own Raspberry Pi 5 + HiFiBerry DAC8x system and personally ran the commands, reboot/recovery trials, and listening checks described below.
I used AI-assisted tools (ChatGPT, Codex and Claude) to help:
- inspect and compare kernel source,
- organize hypotheses,
- interpret logs and traces,
- prepare the test patch,
- and structure this report.
Therefore, I do not claim that I personally wrote the kernel analysis or independently discovered the root cause. The hardware observations and test results are from my system; the analysis and patch preparation were AI-assisted.
I am reporting the result because it may help other Raspberry Pi / DAC8x users and the kernel maintainers.
Describe the bug
On Raspberry Pi 5, 8-channel playback through RP1 DesignWare I2S and a HiFiBerry DAC8x can recover at the ALSA/CamillaDSP software level after an XRUN/underrun while the physical DAC outputs are no longer trustworthy: some physical stereo pairs can disappear or appear to carry audio intended for a different logical pair.
The failure is intermittent and is associated with STOP/PREPARE/START recovery activity. In the affected state, ALSA can report the DAC8x PCM as RUNNING, hw_ptr/appl_ptr continue to advance, CamillaDSP remains Running, and the logical mixer/output channels still contain signal, but the physical RCA outputs can be wrong.
I am reporting this upstream at the request of HiFiBerry support. HiFiBerry confirmed that their DAC8x driver relies on the kernel I2S infrastructure and asked that the issue and tested patch be provided to the Raspberry Pi kernel team.
With AI-assisted analysis, a small playback-side test patch was prepared that makes the STOP path fully tear down the transmitter/DMA state. I tested that patch on my system. With it installed, repeated XRUN/recovery trials no longer reproduced the physical-channel fault in my listening checks.
I am not claiming that the internal TXDMA selector hypothesis below is proven. The patch result is evidence that STOP/restart state handling is involved, but I have not directly instrumented the internal TXDMA channel selector or objectively measured the exact bad logical-to-physical permutation.
Platform
- Raspberry Pi 5 Model B Rev 1.0
- Kernel:
6.18.34+rpt-rpi-2712
- Debian kernel package:
1:6.18.34-1+rpt1
- Raspberry Pi kernel source revision used for the source-level investigation:
c8c7494100e99ee05b11aaa4f0588a223a63d1af
- Audio output: HiFiBerry DAC8x
- ALSA format:
S32_LE, RW_INTERLEAVED, 8 channels
- Native rates used: 44.1 / 48 / 88.2 / 96 / 176.4 / 192 kHz
- Playback stack:
CamillaDSP -> ALSA PCM -> snd_pcm_dmaengine -> snd_soc_core -> snd_soc_rpi_simple_soundcard -> designware_i2s -> RP1 I2S0 -> DAC8x
- RP1 TX DMA observed:
dma2chan2 -> 1f000a0000.i2s:tx
8-channel physical topology
This is not an 8-slot single-data-line TDM configuration.
The DAC8x uses four stereo transmit lanes sharing SCLK/WS:
TER0 / SDO0 / GPIO21 -> channels 1/2
TER1 / SDO1 / GPIO23 -> channels 3/4
TER2 / SDO2 / GPIO25 -> channels 5/6
TER3 / SDO3 / GPIO27 -> channels 7/8
SCLK -> GPIO18
WS -> GPIO19
All four stereo lanes are fed from the same cyclic TX DMA stream.
Failure observation
A representative event on 2026-08-30 showed approximately 15 playback prepare/recovery cycles within about 1.15 seconds while the UAC2 capture side was not reopened.
During failure investigation I observed cases where:
- DAC8x ALSA PCM was still RUNNING
hw_ptr / appl_ptr were advancing
- CamillaDSP was Running
- logical output signal/routing remained present
- physical DAC output pairs were nevertheless missing or appeared to contain the wrong band/channel
The exact bad permutation was not instrumented and should be treated as an observation, not a proven mapping.
There are also recovery logs containing:
dma dma2chan2: dma2chan2 failed to stop
and repeated:
PB: Prepare playback after buffer underrun
The issue is therefore more than a simple application routing problem: the software-visible PCM state can look healthy while the physical multi-lane output state is not.
Source-level finding
The following source-level findings were obtained with AI-assisted analysis and then checked against the exact Raspberry Pi source revision listed above.
In the Raspberry Pi rpi-6.18.y DesignWare I2S driver, i2s_stop() currently clears IRQ state and disables IRQs, but does not:
- disable
ITER for playback
- disable the TX DMA handshake
- write
I2S_RTXDMA = 1
- disable
CER when the last stream stops
- disable
IER when the last stream stops
However, the existing i2s_disable_dma() function already performs the important TX DMA reset operation:
- clears
I2S_DMAEN_TXBLOCK
- writes
I2S_RTXDMA = 1
By comparison, current upstream Linux sound/soc/dwc/dwc-i2s.c performs a substantially stronger stop sequence: it disables the stream (ITER/IRER), calls i2s_disable_dma() on DMA paths, masks IRQs, and disables CER/IER when no stream remains active.
This downstream/upstream difference is why the playback-only test change was tried.
Tested patch
The attached patch is the exact functional playback-side change that was tested on my hardware. It was prepared with AI assistance based on the observed source differences. Diagnostic instrumentation used during the experiment is intentionally not part of the patch attachment.
The tested playback STOP sequence does:
- clear IRQs
- set
ITER = 0
- call
i2s_disable_dma() for DMA playback
- this clears the TX block handshake and writes
I2S_RTXDMA = 1
- disable IRQs
- if no stream remains active, set
CER = 0 and IER = 0
I am not proposing that maintainers must merge this exact patch shape; current mainline already has a broader playback/capture form.
Test result
The instrumented patched module used for the field test had:
- module path:
/lib/modules/6.18.34+rpt-rpi-2712/updates/cdsp/designware_i2s.ko
srcversion:
682B459B61FF9821F859F2A
- SHA256:
079602643846e9b215f23ac951f08f08fd6d19d7a104cd83b00d0eb367763695
Note: this module hash includes the functional PATCH1 plus diagnostic instrumentation, so it is not the hash of a clean functional-patch-only build.
At the recorded audit point:
- 18 trial START markers were present
- 15 trials had explicit user-confirmed
RESULT=GOOD markers
- no
RESULT=BAD marker was present in that captured test log
- 88 PREPARE_ENTER / 88 PREPARE_EXIT events
- 86 START_ENTER / 86 START_EXIT events
- 86 STOP_ENTER / 86 STOP_EXIT events
- all 86 observed STOP_EXIT states passed the instrumentation's "fully sanitized" check
The system also went through repeated XRUN/underrun recovery cycles after patching, with the DAC returning to RUNNING/8/44100 in the captured 44.1 kHz test sequence.
Physical channel correctness in these trials was confirmed by listening, not by an automated multi-channel measurement fixture. I want to be explicit about that limitation.
Working hypothesis (not proven)
AI-assisted analysis suggested one possible mechanism: stale state in the DW_apb_i2s TX DMA channel-cycling machinery across the four enabled transmit pairs.
The existing i2s_disable_dma() writes I2S_RTXDMA = 1, while the Raspberry Pi downstream i2s_stop() does not call it. If an XRUN terminates/restarts the external RP1 cyclic DMA while the I2S TX/DMA state remains enabled, a stale multi-lane transmit state could plausibly survive into the next descriptor.
This is a hypothesis only. I have not directly observed the internal selector, and I do not want the issue to depend on that theory. The reproducible field result is that the stronger STOP teardown changed the behaviour on my system.
Possibly related Raspberry Pi issues
Request to maintainers
Could you please review whether Raspberry Pi rpi-6.18.y should pick up the current upstream DesignWare I2S stop-state teardown (or an equivalent safe fix), particularly for RP1 multi-channel/multi-lane playback?
I can provide additional traces or test a maintainer-provided patch if needed. Because this Pi is connected to a multi-amplified loudspeaker system, I would prefer read-only tracing first and will apply any new kernel module only with the amplifiers muted/off.
Attachments
02_PATCH1_TESTED_PLAYBACK_STOP_FIX.patch
03_SELECTED_BEFORE_AFTER_EVIDENCE.txt
05_PUBLIC_REPO_CROSSCHECK.txt
Reporter / AI-assistance disclosure
I encountered this problem on my own Raspberry Pi 5 + HiFiBerry DAC8x system and personally ran the commands, reboot/recovery trials, and listening checks described below.
I used AI-assisted tools (ChatGPT, Codex and Claude) to help:
Therefore, I do not claim that I personally wrote the kernel analysis or independently discovered the root cause. The hardware observations and test results are from my system; the analysis and patch preparation were AI-assisted.
I am reporting the result because it may help other Raspberry Pi / DAC8x users and the kernel maintainers.
Describe the bug
On Raspberry Pi 5, 8-channel playback through RP1 DesignWare I2S and a HiFiBerry DAC8x can recover at the ALSA/CamillaDSP software level after an XRUN/underrun while the physical DAC outputs are no longer trustworthy: some physical stereo pairs can disappear or appear to carry audio intended for a different logical pair.
The failure is intermittent and is associated with STOP/PREPARE/START recovery activity. In the affected state, ALSA can report the DAC8x PCM as RUNNING, hw_ptr/appl_ptr continue to advance, CamillaDSP remains Running, and the logical mixer/output channels still contain signal, but the physical RCA outputs can be wrong.
I am reporting this upstream at the request of HiFiBerry support. HiFiBerry confirmed that their DAC8x driver relies on the kernel I2S infrastructure and asked that the issue and tested patch be provided to the Raspberry Pi kernel team.
With AI-assisted analysis, a small playback-side test patch was prepared that makes the STOP path fully tear down the transmitter/DMA state. I tested that patch on my system. With it installed, repeated XRUN/recovery trials no longer reproduced the physical-channel fault in my listening checks.
I am not claiming that the internal TXDMA selector hypothesis below is proven. The patch result is evidence that STOP/restart state handling is involved, but I have not directly instrumented the internal TXDMA channel selector or objectively measured the exact bad logical-to-physical permutation.
Platform
6.18.34+rpt-rpi-27121:6.18.34-1+rpt1c8c7494100e99ee05b11aaa4f0588a223a63d1afS32_LE,RW_INTERLEAVED, 8 channelsCamillaDSP -> ALSA PCM -> snd_pcm_dmaengine -> snd_soc_core -> snd_soc_rpi_simple_soundcard -> designware_i2s -> RP1 I2S0 -> DAC8xdma2chan2 -> 1f000a0000.i2s:tx8-channel physical topology
This is not an 8-slot single-data-line TDM configuration.
The DAC8x uses four stereo transmit lanes sharing SCLK/WS:
TER0 / SDO0 / GPIO21 -> channels 1/2TER1 / SDO1 / GPIO23 -> channels 3/4TER2 / SDO2 / GPIO25 -> channels 5/6TER3 / SDO3 / GPIO27 -> channels 7/8SCLK -> GPIO18WS -> GPIO19All four stereo lanes are fed from the same cyclic TX DMA stream.
Failure observation
A representative event on 2026-08-30 showed approximately 15 playback prepare/recovery cycles within about 1.15 seconds while the UAC2 capture side was not reopened.
During failure investigation I observed cases where:
hw_ptr/appl_ptrwere advancingThe exact bad permutation was not instrumented and should be treated as an observation, not a proven mapping.
There are also recovery logs containing:
dma dma2chan2: dma2chan2 failed to stopand repeated:
PB: Prepare playback after buffer underrunThe issue is therefore more than a simple application routing problem: the software-visible PCM state can look healthy while the physical multi-lane output state is not.
Source-level finding
The following source-level findings were obtained with AI-assisted analysis and then checked against the exact Raspberry Pi source revision listed above.
In the Raspberry Pi
rpi-6.18.yDesignWare I2S driver,i2s_stop()currently clears IRQ state and disables IRQs, but does not:ITERfor playbackI2S_RTXDMA = 1CERwhen the last stream stopsIERwhen the last stream stopsHowever, the existing
i2s_disable_dma()function already performs the important TX DMA reset operation:I2S_DMAEN_TXBLOCKI2S_RTXDMA = 1By comparison, current upstream Linux
sound/soc/dwc/dwc-i2s.cperforms a substantially stronger stop sequence: it disables the stream (ITER/IRER), callsi2s_disable_dma()on DMA paths, masks IRQs, and disablesCER/IERwhen no stream remains active.This downstream/upstream difference is why the playback-only test change was tried.
Tested patch
The attached patch is the exact functional playback-side change that was tested on my hardware. It was prepared with AI assistance based on the observed source differences. Diagnostic instrumentation used during the experiment is intentionally not part of the patch attachment.
The tested playback STOP sequence does:
ITER = 0i2s_disable_dma()for DMA playbackI2S_RTXDMA = 1CER = 0andIER = 0I am not proposing that maintainers must merge this exact patch shape; current mainline already has a broader playback/capture form.
Test result
The instrumented patched module used for the field test had:
/lib/modules/6.18.34+rpt-rpi-2712/updates/cdsp/designware_i2s.kosrcversion:682B459B61FF9821F859F2A079602643846e9b215f23ac951f08f08fd6d19d7a104cd83b00d0eb367763695Note: this module hash includes the functional PATCH1 plus diagnostic instrumentation, so it is not the hash of a clean functional-patch-only build.
At the recorded audit point:
RESULT=GOODmarkersRESULT=BADmarker was present in that captured test logThe system also went through repeated XRUN/underrun recovery cycles after patching, with the DAC returning to
RUNNING/8/44100in the captured 44.1 kHz test sequence.Physical channel correctness in these trials was confirmed by listening, not by an automated multi-channel measurement fixture. I want to be explicit about that limitation.
Working hypothesis (not proven)
AI-assisted analysis suggested one possible mechanism: stale state in the DW_apb_i2s TX DMA channel-cycling machinery across the four enabled transmit pairs.
The existing
i2s_disable_dma()writesI2S_RTXDMA = 1, while the Raspberry Pi downstreami2s_stop()does not call it. If an XRUN terminates/restarts the external RP1 cyclic DMA while the I2S TX/DMA state remains enabled, a stale multi-lane transmit state could plausibly survive into the next descriptor.This is a hypothesis only. I have not directly observed the internal selector, and I do not want the issue to depend on that theory. The reproducible field result is that the stronger STOP teardown changed the behaviour on my system.
Possibly related Raspberry Pi issues
designware_i2s BCM2712: trigger(STOP) permanently breaks DMA restartdw_axi_dma/ dmaengine ALSA playback crashRequest to maintainers
Could you please review whether Raspberry Pi
rpi-6.18.yshould pick up the current upstream DesignWare I2S stop-state teardown (or an equivalent safe fix), particularly for RP1 multi-channel/multi-lane playback?I can provide additional traces or test a maintainer-provided patch if needed. Because this Pi is connected to a multi-amplified loudspeaker system, I would prefer read-only tracing first and will apply any new kernel module only with the amplifiers muted/off.
Attachments
02_PATCH1_TESTED_PLAYBACK_STOP_FIX.patch03_SELECTED_BEFORE_AFTER_EVIDENCE.txt05_PUBLIC_REPO_CROSSCHECK.txt