ASOC: Intel: sof_sdw: restore playback functionality with max98373 amps
authorRander Wang <rander.wang@intel.com>
Wed, 23 Sep 2020 08:05:09 +0000 (11:05 +0300)
committerMark Brown <broonie@kernel.org>
Wed, 23 Sep 2020 17:13:17 +0000 (18:13 +0100)
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: ae3a3918edf57 ('ASoC: Intel: sof_sdw: add dailink .trigger callback')
Fixes: 06998d49bcac8 ('ASoC: Intel: sof_sdw: add dailink .prepare and .hw_free callback')
Signed-off-by: Rander Wang <rander.wang@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Keyon Jie <yang.jie@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200923080514.3242858-2-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_sdw.c
sound/soc/intel/boards/sof_sdw_common.h
sound/soc/intel/boards/sof_sdw_max98373.c

index 7fc6731aeb97f65ea27c6259f7572d2404374490..b56df04775c2e35ad761bf23f675f0731b347478 100644 (file)
@@ -165,7 +165,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;
@@ -184,7 +184,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;
@@ -224,7 +224,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;
index 6a5d46589baf70699feb195627b8537c6f098180..f3cb6796363e7fcb8ce024d437be7018d936e25c 100644 (file)
@@ -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 */
index 905582aaf58cd55e7af3a57d3e0cb55abeedc00c..cfdf970c5800fecbeee270bae96c14448a39f8a5 100644 (file)
@@ -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,
 };