Unverified Commit 94d2d089 authored by Dharageswari R's avatar Dharageswari R Committed by Mark Brown
Browse files

ASoC: Intel: Boards: tgl_max98373: add dai_trigger function



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: default avatarDharageswari R <dharageswari.r@intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20200625191308.3322-8-pierre-louis.bossart@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2697f3af
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -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)
+9 −0
Original line number Diff line number Diff line
@@ -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);
}