Commit 7cc3b56f authored by Rander Wang's avatar Rander Wang Committed by Mark Brown

ASOC: Intel: sof_sdw: restore playback functionality with max98373 amps

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: ae3a3918 ('ASoC: Intel: sof_sdw: add dailink .trigger callback')
Fixes: 06998d49 ('ASoC: Intel: sof_sdw: add dailink .prepare and .hw_free callback')
Signed-off-by: default avatarRander Wang <rander.wang@intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarGuennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarKeyon Jie <yang.jie@linux.intel.com>
Signed-off-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200923080514.3242858-2-kai.vehmanen@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent e787f5b5
...@@ -165,7 +165,7 @@ int sdw_startup(struct snd_pcm_substream *substream) ...@@ -165,7 +165,7 @@ int sdw_startup(struct snd_pcm_substream *substream)
return sdw_startup_stream(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 snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sdw_stream_runtime *sdw_stream; struct sdw_stream_runtime *sdw_stream;
...@@ -184,7 +184,7 @@ static int sdw_prepare(struct snd_pcm_substream *substream) ...@@ -184,7 +184,7 @@ static int sdw_prepare(struct snd_pcm_substream *substream)
return sdw_prepare_stream(sdw_stream); 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 snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sdw_stream_runtime *sdw_stream; struct sdw_stream_runtime *sdw_stream;
...@@ -224,7 +224,7 @@ static int sdw_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -224,7 +224,7 @@ static int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
return ret; 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 snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sdw_stream_runtime *sdw_stream; struct sdw_stream_runtime *sdw_stream;
......
...@@ -79,6 +79,9 @@ struct mc_private { ...@@ -79,6 +79,9 @@ struct mc_private {
extern unsigned long sof_sdw_quirk; extern unsigned long sof_sdw_quirk;
int sdw_startup(struct snd_pcm_substream *substream); 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); void sdw_shutdown(struct snd_pcm_substream *substream);
/* generic HDMI support */ /* generic HDMI support */
......
...@@ -55,9 +55,43 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd) ...@@ -55,9 +55,43 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd)
return ret; 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 = { static const struct snd_soc_ops max_98373_sdw_ops = {
.startup = sdw_startup, .startup = sdw_startup,
.trigger = max98373_trigger, .prepare = sdw_prepare,
.trigger = max98373_sdw_trigger,
.hw_free = sdw_hw_free,
.shutdown = sdw_shutdown, .shutdown = sdw_shutdown,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment