Mark Brown broonie@kernel.org writes:
+static int acp3x_es83xx_speaker_power_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
+{
- struct acp3x_es83xx_private *priv = get_mach_priv(w->dapm->card);
- dev_dbg(priv->codec_dev, "speaker power event: %d\n", event);
- if (SND_SOC_DAPM_EVENT_ON(event))
acp3x_es83xx_set_gpios_values(priv, 1, 0);
- else
acp3x_es83xx_set_gpios_values(priv, 0, 1);
Why are these two GPIOs tied together like this?
These GPIOs represent the speaker and the headphone switches. When activating the speaker GPIO you have to deactivate the headphone GPIO and vice versa. The logic is taken from the discussion on the sofproject pull request: https://github.com/thesofproject/linux/pull/4112/commits/810d03e0aecdf0caf58... and https://github.com/thesofproject/linux/pull/4066
+static int acp3x_es83xx_suspend_pre(struct snd_soc_card *card) +{
- struct acp3x_es83xx_private *priv = get_mach_priv(card);
- dev_dbg(priv->codec_dev, "card suspend\n");
- snd_soc_component_set_jack(priv->codec, NULL, NULL);
- return 0;
+}
That's weird, why do that?
This is needed because if suspending the laptop with the headphones inserted, when resuming, the sound is not working anymore. Sound stops working on speakers and headphones. Reinsertion and removals of the headphone doesn't solve the problem.
This seems to be caused by the fact that the GPIO IRQ stops working in es8316_irq() after resume. Now the call to snd_soc_component_set_jack() in suspend disables the GPIO IRQ and in resume the GPIO IRQ is reactivated. By the way this sequence is also used in bytcht_es8316.c in suspend and resume:
static int byt_cht_es8316_suspend(struct snd_soc_card *card) { struct snd_soc_component *component;
for_each_card_components(card, component) { if (!strcmp(component->name, codec_name)) { dev_dbg(component->dev, "disabling jack detect before suspend\n"); snd_soc_component_set_jack(component, NULL, NULL); break; } }
return 0; }
static int byt_cht_es8316_resume(struct snd_soc_card *card) { struct byt_cht_es8316_private *priv = snd_soc_card_get_drvdata(card); struct snd_soc_component *component;
for_each_card_components(card, component) { if (!strcmp(component->name, codec_name)) { dev_dbg(component->dev, "re-enabling jack detect after resume\n"); snd_soc_component_set_jack(component, &priv->jack, NULL); break; } }