OSDN Git Service

ASoC: Intel: Boards: tgl_max98373: add dai_trigger function
authorDharageswari R <dharageswari.r@intel.com>
Thu, 25 Jun 2020 19:12:58 +0000 (14:12 -0500)
committerMark Brown <broonie@kernel.org>
Fri, 26 Jun 2020 12:35:17 +0000 (13:35 +0100)
Speaker amplifier feedback is not modeled as being dependent on any
active output. Even when there is no playback happening, parts of the
graph, specifically the IV sense->speaker protection->output remains
active and this prevents the DSP from entering low-power states.

This patch suggests a machine driver level approach where the speaker
pins are enabled/disabled dynamically depending on stream start/stop
events. DPAM graph representations show the feedback loop is indeed
disabled and low-power states can be reached.

Signed-off-by: Dharageswari R <dharageswari.r@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20200625191308.3322-8-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_maxim_common.c
sound/soc/intel/boards/sof_rt5682.c

index 1a549b3..b7014c4 100644 (file)
@@ -9,6 +9,8 @@
 #include <uapi/sound/asound.h>
 #include "sof_maxim_common.h"
 
+#define MAX_98373_PIN_NAME 16
+
 static const struct snd_soc_dapm_route max_98373_dapm_routes[] = {
        /* speaker */
        { "Left Spk", NULL, "Left BE_OUT" },
@@ -57,8 +59,51 @@ static int max98373_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
+static int max98373_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai;
+       int j;
+       int ret = 0;
+
+       for_each_rtd_codec_dais(rtd, j, codec_dai) {
+               struct snd_soc_component *component = codec_dai->component;
+               struct snd_soc_dapm_context *dapm =
+                               snd_soc_component_get_dapm(component);
+               char pin_name[MAX_98373_PIN_NAME];
+
+               snprintf(pin_name, ARRAY_SIZE(pin_name), "%s Spk",
+                        codec_dai->component->name_prefix);
+
+               switch (cmd) {
+               case SNDRV_PCM_TRIGGER_START:
+               case SNDRV_PCM_TRIGGER_RESUME:
+               case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+                       ret = snd_soc_dapm_enable_pin(dapm, pin_name);
+                       if (!ret)
+                               snd_soc_dapm_sync(dapm);
+                       break;
+               case SNDRV_PCM_TRIGGER_STOP:
+               case SNDRV_PCM_TRIGGER_SUSPEND:
+               case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+                       /* Make sure no streams are active before disable pin */
+                       if (snd_soc_dai_active(codec_dai) != 1)
+                               break;
+                       ret = snd_soc_dapm_disable_pin(dapm, pin_name);
+                       if (!ret)
+                               snd_soc_dapm_sync(dapm);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       return ret;
+}
+
 struct snd_soc_ops max_98373_ops = {
        .hw_params = max98373_hw_params,
+       .trigger = max98373_trigger,
 };
 
 int max98373_spk_codec_init(struct snd_soc_pcm_runtime *rtd)
index f80ed62..20ab266 100644 (file)
@@ -318,6 +318,7 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 {
        struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
        struct snd_soc_component *component = NULL;
+       struct snd_soc_dapm_context *dapm = &card->dapm;
        char jack_name[NAME_SIZE];
        struct sof_hdmi_pcm *pcm;
        int err;
@@ -356,6 +357,14 @@ static int sof_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
+       if (sof_rt5682_quirk & SOF_MAX98373_SPEAKER_AMP_PRESENT) {
+               /* Disable Left and Right Spk pin after boot */
+               snd_soc_dapm_disable_pin(dapm, "Left Spk");
+               snd_soc_dapm_disable_pin(dapm, "Right Spk");
+               err = snd_soc_dapm_sync(dapm);
+               if (err < 0)
+                       return err;
+       }
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }