[PATCH 1/6] ASOC: Intel: sof_sdw: restore playback functionality with max98373 amps

Kai Vehmanen kai.vehmanen at linux.intel.com
Wed Sep 23 10:05:09 CEST 2020


From: Rander Wang <rander.wang at intel.com>

The Max98373 amplifier provides I/V feedback information, which keeps
a DAPM path active even when there is no playback happening. This
prevents entry in low-power mode. Rather than adding new controls and
require UCM/user interaction, the method previously applied is to
enable/disable the Speaker pin during the dailink trigger operations.

Recent changes in the SoundWire stream management moved the stream
trigger to the dailink trigger. This change removed the Maxim-specific
pin handling and resulted in a regression. This patch restores
functionality by combining the SoundWire stream trigger with the pin
enable/disable.

Fixes: 7eec07f389a60 ('ASOC: Intel: sof_sdw: add dailink .trigger callback')
Fixes: 5595f95c32650 ('ASOC: Intel: sof_sdw: add dailink .prepare and .hw_free callback').
Signed-off-by: Rander Wang <rander.wang at intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski at linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
Reviewed-by: Keyon Jie <yang.jie at linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen at linux.intel.com>
---
 sound/soc/intel/boards/sof_sdw.c          |  6 ++--
 sound/soc/intel/boards/sof_sdw_common.h   |  3 ++
 sound/soc/intel/boards/sof_sdw_max98373.c | 36 ++++++++++++++++++++++-
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index 210b66d1f9a2..efd96c9c6e39 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -225,7 +225,7 @@ int sdw_startup(struct snd_pcm_substream *substream)
 	return sdw_startup_stream(substream);
 }
 
-static int sdw_prepare(struct snd_pcm_substream *substream)
+int sdw_prepare(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct sdw_stream_runtime *sdw_stream;
@@ -244,7 +244,7 @@ static int sdw_prepare(struct snd_pcm_substream *substream)
 	return sdw_prepare_stream(sdw_stream);
 }
 
-static int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
+int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct sdw_stream_runtime *sdw_stream;
@@ -284,7 +284,7 @@ static int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
 	return ret;
 }
 
-static int sdw_hw_free(struct snd_pcm_substream *substream)
+int sdw_hw_free(struct snd_pcm_substream *substream)
 {
 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
 	struct sdw_stream_runtime *sdw_stream;
diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h
index 6a5d46589baf..f3cb6796363e 100644
--- a/sound/soc/intel/boards/sof_sdw_common.h
+++ b/sound/soc/intel/boards/sof_sdw_common.h
@@ -79,6 +79,9 @@ struct mc_private {
 extern unsigned long sof_sdw_quirk;
 
 int sdw_startup(struct snd_pcm_substream *substream);
+int sdw_prepare(struct snd_pcm_substream *substream);
+int sdw_trigger(struct snd_pcm_substream *substream, int cmd);
+int sdw_hw_free(struct snd_pcm_substream *substream);
 void sdw_shutdown(struct snd_pcm_substream *substream);
 
 /* generic HDMI support */
diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_max98373.c
index 905582aaf58c..cfdf970c5800 100644
--- a/sound/soc/intel/boards/sof_sdw_max98373.c
+++ b/sound/soc/intel/boards/sof_sdw_max98373.c
@@ -55,9 +55,43 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd)
 	return ret;
 }
 
+static int max98373_sdw_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	int ret;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		/* enable max98373 first */
+		ret = max98373_trigger(substream, cmd);
+		if (ret < 0)
+			break;
+
+		ret = sdw_trigger(substream, cmd);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		ret = sdw_trigger(substream, cmd);
+		if (ret < 0)
+			break;
+
+		ret = max98373_trigger(substream, cmd);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
 static const struct snd_soc_ops max_98373_sdw_ops = {
 	.startup = sdw_startup,
-	.trigger = max98373_trigger,
+	.prepare = sdw_prepare,
+	.trigger = max98373_sdw_trigger,
+	.hw_free = sdw_hw_free,
 	.shutdown = sdw_shutdown,
 };
 
-- 
2.27.0



More information about the Alsa-devel mailing list