]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: meson: aiu: fifo-spdif: soft reset the S/PDIF datapath on start/stop
authorChristian Hewitt <christianshewitt@gmail.com>
Sat, 27 Jun 2026 13:12:05 +0000 (13:12 +0000)
committerMark Brown <broonie@kernel.org>
Tue, 7 Jul 2026 22:01:44 +0000 (23:01 +0100)
The I2S FIFO soft-resets its fast domain on start (AIU_RST_SOFT bit 0 +
AIU_I2S_SYNC read in aiu_fifo_i2s_trigger), mirroring the downstream
vendor driver's audio_out_i2s_enable(). The S/PDIF FIFO has no equivalent:
it only toggles the IEC958 DCU, so a stale datapath FIFO can be replayed,
producing the "machine gun noise" buffer underrun - on start when switching
outputs, and on stop when playback ends. The latter is audible on devices
with an always-on S/PDIF-fed DAC (e.g. the ES7144 on the WeTek Play2).

The vendor driver resets the IEC958 fast domain (AIU_RST_SOFT bit 2) on
both enable and disable (audio_hw_958_enable), and when reconfiguring
(audio_hw_958_reset clears AIU_958_DCU_FF_CTRL then resets). Do the same:
reset before enabling the DCU on start, and before disabling on stop.

Fixes: 6ae9ca9ce986bf ("ASoC: meson: aiu: add i2s and spdif support")
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Link: https://patch.msgid.link/20260627131205.808800-1-christianshewitt@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/meson/aiu-fifo-spdif.c

index e0e00ec026dcc478c014d7771f9aead9fc003f0b..a9861c5d663745e54657a20e613e6de262f9c3f9 100644 (file)
@@ -24,6 +24,7 @@
 #define AIU_MEM_IEC958_CONTROL_MODE_16BIT      BIT(7)
 #define AIU_MEM_IEC958_CONTROL_MODE_LINEAR     BIT(8)
 #define AIU_MEM_IEC958_BUF_CNTL_INIT           BIT(0)
+#define AIU_RST_SOFT_958_FAST                  BIT(2)
 
 #define AIU_FIFO_SPDIF_BLOCK                   8
 
@@ -68,11 +69,15 @@ static int fifo_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
        case SNDRV_PCM_TRIGGER_START:
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               snd_soc_component_write(component, AIU_RST_SOFT,
+                                       AIU_RST_SOFT_958_FAST);
                fifo_spdif_dcu_enable(component, true);
                break;
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
        case SNDRV_PCM_TRIGGER_STOP:
+               snd_soc_component_write(component, AIU_RST_SOFT,
+                                       AIU_RST_SOFT_958_FAST);
                fifo_spdif_dcu_enable(component, false);
                break;
        default: