The GPIO thing on Huawei Intel platform is too complicated, they use two GPIOs for headphone and speaker, and the headphone GPIO is inverted, which means low means on and high means off. Luckily there should be only one hardware config for the AMD acp3x platform GPIO and you may just choose the correct one.
There being two different GPIOs sounds like it just allows the headphone and speaker to be controlled separately - that seems more flexible, not a problem?
Yes it's called multi stream in Windows. However, extra GPIO causes more confusion in the driver.
There is no such situation, and the system doesn't produce sound from speaker when headphones are plugged in. The user may manually open speaker using amixer sset 'Speaker' on or pavucontrol.
Again, you're describing a specific configuration - someone might want to do something different.
Hi Marian Postevca you may want to separate the GPIO control by adding Headphone Power SND_SOC_DAPM_SUPPLY. You may also want to change the gpio handling function in the acp3x_es83xx_jack_events function.
static const struct snd_soc_dapm_widget acp3x_es83xx_widgets[] = { SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Internal Mic", NULL),
+ SND_SOC_DAPM_SUPPLY("Headphone Power", SND_SOC_NOPM, 0, 0, + acp3x_es83xx_headphone_power_event, + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0, acp3x_es83xx_speaker_power_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), };
static const struct snd_soc_dapm_route acp3x_es83xx_audio_map[] = { {"Headphone", NULL, "HPOL"}, {"Headphone", NULL, "HPOR"}, + {"Headphone", NULL, "Headphone Power"},
{"Speaker", NULL, "HPOL"}, {"Speaker", NULL, "HPOR"}, {"Speaker", NULL, "Speaker Power"}, };
+static int acp3x_es83xx_headphone_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)) + gpiod_set_value_cansleep(priv->gpio_headphone, true); + else + gpiod_set_value_cansleep(priv->gpio_headphone, false); + + return 0; +} + +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)) + gpiod_set_value_cansleep(priv->gpio_speakers, true); + else + gpiod_set_value_cansleep(priv->gpio_speakers, false); + + return 0; +}