Unverified Commit f949ed45 authored by Jerome Brunet's avatar Jerome Brunet Committed by Mark Brown
Browse files

ASoC: meson: axg-tdm-interface: manage formatters in trigger



So far, the formatters have been reset/enabled using the .prepare()
callback. This was done in this callback because walking the formatters use
a mutex. A mutex is used because formatter handling require dealing
possibly slow clock operation.

With the support of non-atomic, .trigger() callback may be used which also
allows to properly enable and disable formatters on start but also
pause/resume.

This solve a random shift on TDMIN as well repeated samples on for TDMOUT.

Fixes: d60e4f1e ("ASoC: meson: add tdm interface driver")
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20240426152946.3078805-4-jbrunet@baylibre.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent dcba52ac
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -349,24 +349,29 @@ static int axg_tdm_iface_hw_params(struct snd_pcm_substream *substream,
	return 0;
}

static int axg_tdm_iface_hw_free(struct snd_pcm_substream *substream,
static int axg_tdm_iface_trigger(struct snd_pcm_substream *substream,
				 int cmd,
				 struct snd_soc_dai *dai)
{
	struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);
	struct axg_tdm_stream *ts =
		snd_soc_dai_get_dma_data(dai, substream);

	/* Stop all attached formatters */
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		axg_tdm_stream_start(ts);
		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_STOP:
		axg_tdm_stream_stop(ts);

	return 0;
		break;
	default:
		return -EINVAL;
	}

static int axg_tdm_iface_prepare(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
{
	struct axg_tdm_stream *ts = snd_soc_dai_get_dma_data(dai, substream);

	/* Force all attached formatters to update */
	return axg_tdm_stream_reset(ts);
	return 0;
}

static int axg_tdm_iface_remove_dai(struct snd_soc_dai *dai)
@@ -412,8 +417,7 @@ static const struct snd_soc_dai_ops axg_tdm_iface_ops = {
	.set_fmt	= axg_tdm_iface_set_fmt,
	.startup	= axg_tdm_iface_startup,
	.hw_params	= axg_tdm_iface_hw_params,
	.prepare	= axg_tdm_iface_prepare,
	.hw_free	= axg_tdm_iface_hw_free,
	.trigger	= axg_tdm_iface_trigger,
};

/* TDM Backend DAIs */