All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
To: Jaroslav Kysela <perex@perex.cz>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>, Takashi Iwai <tiwai@suse.com>
Cc: alsa-devel@alsa-project.org
Subject: [PATCH 1/4] ASoC: add new trigger ordering method
Date: Wed, 7 Jun 2023 23:43:52 +0000	[thread overview]
Message-ID: <873532hm8a.wl-kuninori.morimoto.gx@renesas.com> (raw)
In-Reply-To: <874jnihm8y.wl-kuninori.morimoto.gx@renesas.com>

Current ASoC is assuming that trigger starting order is
Link -> Component -> DAI as default, and its reverse order for stopping.
But some Driver / Card want to reorder it for some reasons.
We have such flags, but is unbalance like below.

	struct snd_soc_component_driver	:: start_dma_last
	struct snd_soc_dai_link		:: stop_dma_first

We want to have more flexible, and more generic method.
This patch adds new snd_soc_trigger_order for start/stop at
component / DAI-link.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 include/sound/soc-component.h |   9 +++
 include/sound/soc.h           |  17 +++++
 sound/soc/soc-pcm.c           | 115 +++++++++++++++++++---------------
 3 files changed, 91 insertions(+), 50 deletions(-)

diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h
index 0b47603c9db2..c7733382757b 100644
--- a/include/sound/soc-component.h
+++ b/include/sound/soc-component.h
@@ -158,6 +158,15 @@ struct snd_soc_component_driver {
 	int probe_order;
 	int remove_order;
 
+	/*
+	 * soc_pcm_trigger() start/stop sequence.
+	 * see also
+	 *	snd_soc_dai_link
+	 *	soc_pcm_trigger()
+	 */
+	enum snd_soc_trigger_order trigger_start;
+	enum snd_soc_trigger_order trigger_stop;
+
 	/*
 	 * signal if the module handling the component should not be removed
 	 * if a pcm is open. Setting this would prevent the module
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 10e4ea0664af..49442583d46d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -607,6 +607,14 @@ int snd_soc_get_strobe(struct snd_kcontrol *kcontrol,
 int snd_soc_put_strobe(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol);
 
+enum snd_soc_trigger_order {
+						/* start			stop		     */
+	SND_SOC_TRIGGER_ORDER_DEFAULT	= 0,	/* Link->Component->DAI		DAI->Component->Link */
+	SND_SOC_TRIGGER_ORDER_LDC,		/* Link->DAI->Component		Component->DAI->Link */
+
+	SND_SOC_TRIGGER_ORDER_MAX,
+};
+
 /* SoC PCM stream information */
 struct snd_soc_pcm_stream {
 	const char *stream_name;
@@ -707,6 +715,15 @@ struct snd_soc_dai_link {
 	const struct snd_soc_ops *ops;
 	const struct snd_soc_compr_ops *compr_ops;
 
+	/*
+	 * soc_pcm_trigger() start/stop sequence.
+	 * see also
+	 *	snd_soc_component_driver
+	 *	soc_pcm_trigger()
+	 */
+	enum snd_soc_trigger_order trigger_start;
+	enum snd_soc_trigger_order trigger_stop;
+
 	/* Mark this pcm with non atomic ops */
 	unsigned int nonatomic:1;
 
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index f16402ee5a19..08b3cbd1754e 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1071,49 +1071,78 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
 	return ret;
 }
 
+#define TRIGGER_MAX 3
+const static
+int (*trigger[][TRIGGER_MAX])(struct snd_pcm_substream *substream, int cmd, int rollback) = {
+	[SND_SOC_TRIGGER_ORDER_DEFAULT] = {
+		snd_soc_link_trigger,
+		snd_soc_pcm_component_trigger,
+		snd_soc_pcm_dai_trigger,
+	},
+	[SND_SOC_TRIGGER_ORDER_LDC] = {
+		snd_soc_link_trigger,
+		snd_soc_pcm_dai_trigger,
+		snd_soc_pcm_component_trigger,
+	},
+};
+
 static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct snd_soc_component *component;
-	int ret = -EINVAL, _ret = 0, start_dma_last = 0, i;
+	int ret = 0, r = 0, i;
 	int rollback = 0;
+	int start = 0, stop = 0;
 
+	/*
+	 * select START/STOP sequence
+	 */
+	for_each_rtd_components(rtd, i, component) {
+		if (component->driver->trigger_start)
+			start = component->driver->trigger_start;
+		if (component->driver->trigger_stop)
+			stop = component->driver->trigger_stop;
+	}
+	if (rtd->dai_link->trigger_start)
+		start = rtd->dai_link->trigger_start;
+	if (rtd->dai_link->trigger_stop)
+		stop  = rtd->dai_link->trigger_stop;
+
+	if (start < 0 || start >= SND_SOC_TRIGGER_ORDER_MAX ||
+	    stop  < 0 || stop  >= SND_SOC_TRIGGER_ORDER_MAX)
+		return -EINVAL;
+
+	/* REMOVE ME */
+	for_each_rtd_components(rtd, i, component) {
+		if (component->driver->start_dma_last) {
+			start = SND_SOC_TRIGGER_ORDER_LDC;
+			break;
+		}
+	}
+	if (rtd->dai_link->stop_dma_first)
+		stop = SND_SOC_TRIGGER_ORDER_LDC;
+
+	/*
+	 * START
+	 */
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		/* Do we need to start dma last? */
-		for_each_rtd_components(rtd, i, component) {
-			if (component->driver->start_dma_last) {
-				start_dma_last = 1;
+		for (i = 0; i < TRIGGER_MAX; i++) {
+			r = trigger[start][i](substream, cmd, 0);
+			if (r < 0)
 				break;
-			}
-		}
-
-		ret = snd_soc_link_trigger(substream, cmd, 0);
-		if (ret < 0)
-			goto start_err;
-
-		if (start_dma_last) {
-			ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
-			if (ret < 0)
-				goto start_err;
-
-			ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
-		} else {
-			ret = snd_soc_pcm_component_trigger(substream, cmd, 0);
-			if (ret < 0)
-				goto start_err;
-
-			ret = snd_soc_pcm_dai_trigger(substream, cmd, 0);
 		}
-start_err:
-		if (ret < 0)
-			rollback = 1;
 	}
 
-	if (rollback) {
-		_ret = ret;
+	/*
+	 * Rollback if START failed
+	 * find correspond STOP command
+	 */
+	if (r < 0) {
+		rollback = 1;
+		ret = r;
 		switch (cmd) {
 		case SNDRV_PCM_TRIGGER_START:
 			cmd = SNDRV_PCM_TRIGGER_STOP;
@@ -1127,34 +1156,20 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 		}
 	}
 
+	/*
+	 * STOP
+	 */
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		if (rtd->dai_link->stop_dma_first) {
-			ret = snd_soc_pcm_component_trigger(substream, cmd, rollback);
-			if (ret < 0)
-				break;
-
-			ret = snd_soc_pcm_dai_trigger(substream, cmd, rollback);
-			if (ret < 0)
-				break;
-		} else {
-			ret = snd_soc_pcm_dai_trigger(substream, cmd, rollback);
-			if (ret < 0)
-				break;
-
-			ret = snd_soc_pcm_component_trigger(substream, cmd, rollback);
-			if (ret < 0)
-				break;
+		for (i = TRIGGER_MAX; i > 0; i--) {
+			r = trigger[stop][i - 1](substream, cmd, rollback);
+			if (r < 0)
+				ret = r;
 		}
-		ret = snd_soc_link_trigger(substream, cmd, rollback);
-		break;
 	}
 
-	if (_ret)
-		ret = _ret;
-
 	return ret;
 }
 
-- 
2.25.1


  reply	other threads:[~2023-06-07 23:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-07 23:43 [PATCH 0/4] ASoC: add new trigger ordering method Kuninori Morimoto
2023-06-07 23:43 ` Kuninori Morimoto [this message]
2023-06-08  1:22   ` [PATCH 1/4] " kernel test robot
2023-06-08  1:48   ` kernel test robot
2023-06-07 23:44 ` [PATCH 2/4] ASoC: amd: use use " Kuninori Morimoto
2023-06-07 23:44 ` [PATCH 3/4] ASoC: atmel: " Kuninori Morimoto
2023-06-07 23:44 ` [PATCH 4/4] ASoC: remove old " Kuninori Morimoto
2023-06-08  1:46 ` [PATCH 0/4] ASoC: add new " Kuninori Morimoto

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=873532hm8a.wl-kuninori.morimoto.gx@renesas.com \
    --to=kuninori.morimoto.gx@renesas.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.