@@ -755,6 +755,21 @@ static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
}
}
+static void fsl_sai_tx_fill_fifo(struct fsl_sai *sai,
+ struct snd_pcm_runtime *runtime)
+{
+ u32 slots, slot_width, pins;
+ int i;
+
+ slot_width = sai->slot_width ?: snd_pcm_format_physical_width(runtime->format);
+
+ slots = fsl_sai_get_tdm_slots(sai, runtime->channels, slot_width);
+ pins = DIV_ROUND_UP(runtime->channels, slots);
+
+ for (i = 0; i < runtime->channels; i++)
+ regmap_write(sai->regmap, FSL_SAI_TDR(i % pins), 0x0);
+}
+
static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *cpu_dai)
{
@@ -784,6 +799,9 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ /* Fill FIFO to avoid initial underruns */
+ if (tx)
+ fsl_sai_tx_fill_fifo(sai, substream->runtime);
regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
@@ -34,6 +34,7 @@
#define FSL_SAI_TDR5 0x34 /* SAI Transmit Data 5 */
#define FSL_SAI_TDR6 0x38 /* SAI Transmit Data 6 */
#define FSL_SAI_TDR7 0x3C /* SAI Transmit Data 7 */
+#define FSL_SAI_TDR(ofs) (FSL_SAI_TDR0 + (ofs) * 4)
#define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO 0 */
#define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO 1 */
#define FSL_SAI_TFR2 0x48 /* SAI Transmit FIFO 2 */