#define SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK     BIT(4)
 #define SOF_ES8336_ENABLE_DMIC                 BIT(5)
 #define SOF_ES8336_JD_INVERTED                 BIT(6)
+#define SOF_ES8336_HEADPHONE_GPIO              BIT(7)
 
 static unsigned long quirk;
 
 
 struct sof_es8336_private {
        struct device *codec_dev;
-       struct gpio_desc *gpio_speakers;
+       struct gpio_desc *gpio_speakers, *gpio_headphone;
        struct snd_soc_jack jack;
        struct list_head hdmi_pcm_list;
        bool speaker_en;
        int device;
 };
 
-static const struct acpi_gpio_params speakers_enable_gpio0 = { 0, 0, true };
+static const struct acpi_gpio_params enable_gpio0 = { 0, 0, true };
+static const struct acpi_gpio_params enable_gpio1 = { 1, 0, true };
+
 static const struct acpi_gpio_mapping acpi_speakers_enable_gpio0[] = {
-       { "speakers-enable-gpios", &speakers_enable_gpio0, 1 },
+       { "speakers-enable-gpios", &enable_gpio0, 1 },
        { }
 };
 
-static const struct acpi_gpio_params speakers_enable_gpio1 = { 1, 0, true };
 static const struct acpi_gpio_mapping acpi_speakers_enable_gpio1[] = {
-       { "speakers-enable-gpios", &speakers_enable_gpio1, 1 },
+       { "speakers-enable-gpios", &enable_gpio1, 1 },
+};
+
+static const struct acpi_gpio_mapping acpi_enable_both_gpios[] = {
+       { "speakers-enable-gpios", &enable_gpio0, 1 },
+       { "headphone-enable-gpios", &enable_gpio1, 1 },
+       { }
+};
+
+static const struct acpi_gpio_mapping acpi_enable_both_gpios_rev_order[] = {
+       { "speakers-enable-gpios", &enable_gpio1, 1 },
+       { "headphone-enable-gpios", &enable_gpio0, 1 },
        { }
 };
 
                dev_info(dev, "quirk DMIC enabled\n");
        if (quirk & SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK)
                dev_info(dev, "Speakers GPIO1 quirk enabled\n");
+       if (quirk & SOF_ES8336_HEADPHONE_GPIO)
+               dev_info(dev, "quirk headphone GPIO enabled\n");
        if (quirk & SOF_ES8336_JD_INVERTED)
                dev_info(dev, "quirk JD inverted enabled\n");
 }
        struct snd_soc_card *card = w->dapm->card;
        struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
 
+       if (priv->speaker_en == !SND_SOC_DAPM_EVENT_ON(event))
+               return 0;
+
+       priv->speaker_en = !SND_SOC_DAPM_EVENT_ON(event);
+
        if (SND_SOC_DAPM_EVENT_ON(event))
-               priv->speaker_en = false;
-       else
-               priv->speaker_en = true;
+               msleep(70);
 
        gpiod_set_value_cansleep(priv->gpio_speakers, priv->speaker_en);
 
+       if (!(quirk & SOF_ES8336_HEADPHONE_GPIO))
+               return 0;
+
+       if (SND_SOC_DAPM_EVENT_ON(event))
+               msleep(70);
+
+       gpiod_set_value_cansleep(priv->gpio_headphone, priv->speaker_en);
+
        return 0;
 }
 
 
        /*
         * There is no separate speaker output instead the speakers are muxed to
-        * the HP outputs. The mux is controlled by the "Speaker Power" supply.
+        * the HP outputs. The mux is controlled Speaker and/or headphone switch.
         */
        {"Speaker", NULL, "HPOL"},
        {"Speaker", NULL, "HPOR"},
 {
        quirk = (unsigned long)id->driver_data;
 
-       if (quirk & SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK)
+       if (quirk & SOF_ES8336_HEADPHONE_GPIO) {
+               if (quirk & SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK)
+                       gpio_mapping = acpi_enable_both_gpios;
+               else
+                       gpio_mapping = acpi_enable_both_gpios_rev_order;
+       } else if (quirk & SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK) {
                gpio_mapping = acpi_speakers_enable_gpio1;
+       }
 
        return 1;
 }
                goto err_put_codec;
        }
 
+       priv->gpio_headphone = gpiod_get_optional(codec_dev, "headphone-enable", GPIOD_OUT_LOW);
+       if (IS_ERR(priv->gpio_headphone)) {
+               ret = dev_err_probe(dev, PTR_ERR(priv->gpio_headphone),
+                                   "could not get headphone-enable GPIO\n");
+               goto err_put_codec;
+       }
+
        INIT_LIST_HEAD(&priv->hdmi_pcm_list);
 
        snd_soc_card_set_drvdata(card, priv);