SND_JACK_BTN_2 | SND_JACK_BTN_3);
 }
 
+static void rt5659_jack_detect_intel_hd_header(struct work_struct *work)
+{
+       struct rt5659_priv *rt5659 =
+               container_of(work, struct rt5659_priv, jack_detect_work.work);
+       unsigned int value;
+       bool hp_flag, mic_flag;
+
+       if (!rt5659->hs_jack)
+               return;
+
+       /* headphone jack */
+       regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+       hp_flag = (!(value & 0x8)) ? true : false;
+
+       if (hp_flag != rt5659->hda_hp_plugged) {
+               rt5659->hda_hp_plugged = hp_flag;
+
+               if (hp_flag) {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                               0x10, 0x0);
+                       rt5659->jack_type |= SND_JACK_HEADPHONE;
+               } else {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                               0x10, 0x10);
+                       rt5659->jack_type = rt5659->jack_type &
+                               (~SND_JACK_HEADPHONE);
+               }
+
+               snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+                       SND_JACK_HEADPHONE);
+       }
+
+       /* mic jack */
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+       regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+       mic_flag = (value & 0x2000) ? true : false;
+
+       if (mic_flag != rt5659->hda_mic_plugged) {
+               rt5659->hda_mic_plugged = mic_flag;
+               if (mic_flag) {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                               0x2, 0x2);
+                       rt5659->jack_type |= SND_JACK_MICROPHONE;
+               } else {
+                       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                               0x2, 0x0);
+                       rt5659->jack_type = rt5659->jack_type
+                               & (~SND_JACK_MICROPHONE);
+               }
+
+               snd_soc_jack_report(rt5659->hs_jack, rt5659->jack_type,
+                       SND_JACK_MICROPHONE);
+       }
+}
+
 static const struct snd_kcontrol_new rt5659_snd_controls[] = {
        /* Speaker Output Volume */
        SOC_DOUBLE_TLV("Speaker Playback Volume", RT5659_SPO_VOL,
        regmap_write(rt5659->regmap, RT5659_HP_CHARGE_PUMP_1, 0x0c16);
 }
 
+void rt5659_intel_hd_header_probe_setup(struct rt5659_priv *rt5659)
+{
+       int value;
+
+       regmap_read(rt5659->regmap, RT5659_GPIO_STA, &value);
+       if (!(value & 0x8)) {
+               rt5659->hda_hp_plugged = true;
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                       0x10, 0x0);
+       } else {
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_1,
+                       0x10, 0x10);
+       }
+
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+               RT5659_PWR_VREF2 | RT5659_PWR_MB,
+               RT5659_PWR_VREF2 | RT5659_PWR_MB);
+       msleep(20);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_1,
+               RT5659_PWR_FV2, RT5659_PWR_FV2);
+
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_3, RT5659_PWR_LDO2,
+               RT5659_PWR_LDO2);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_ANLG_2, RT5659_PWR_MB1,
+               RT5659_PWR_MB1);
+       regmap_update_bits(rt5659->regmap, RT5659_PWR_VOL, RT5659_PWR_MIC_DET,
+               RT5659_PWR_MIC_DET);
+       msleep(20);
+
+       regmap_update_bits(rt5659->regmap, RT5659_4BTN_IL_CMD_2,
+               RT5659_4BTN_IL_MASK, RT5659_4BTN_IL_EN);
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+       regmap_write(rt5659->regmap, RT5659_4BTN_IL_CMD_1, value);
+       regmap_read(rt5659->regmap, RT5659_4BTN_IL_CMD_1, &value);
+
+       if (value & 0x2000) {
+               rt5659->hda_mic_plugged = true;
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                       0x2, 0x2);
+       } else {
+               regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+                       0x2, 0x0);
+       }
+
+       regmap_update_bits(rt5659->regmap, RT5659_IRQ_CTRL_2,
+               RT5659_IL_IRQ_MASK, RT5659_IL_IRQ_EN);
+}
+
 static int rt5659_i2c_probe(struct i2c_client *i2c,
                    const struct i2c_device_id *id)
 {
                                RT5659_PWR_MB, RT5659_PWR_MB);
                regmap_write(rt5659->regmap, RT5659_PWR_ANLG_2, 0x0001);
                regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_2, 0x0040);
+               INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+                       rt5659_jack_detect_work);
                break;
-       case RT5659_JD_NULL:
+       case RT5659_JD_HDA_HEADER:
+               regmap_write(rt5659->regmap, RT5659_GPIO_CTRL_3, 0x8000);
+               regmap_write(rt5659->regmap, RT5659_RC_CLK_CTRL, 0x0900);
+               regmap_write(rt5659->regmap, RT5659_EJD_CTRL_1,  0x70c0);
+               regmap_write(rt5659->regmap, RT5659_JD_CTRL_1,   0x2000);
+               regmap_write(rt5659->regmap, RT5659_IRQ_CTRL_1,  0x0040);
+               INIT_DELAYED_WORK(&rt5659->jack_detect_work,
+                       rt5659_jack_detect_intel_hd_header);
+               rt5659_intel_hd_header_probe_setup(rt5659);
                break;
        default:
-               dev_warn(&i2c->dev, "Currently, support JD3 only\n");
                break;
        }
 
-       INIT_DELAYED_WORK(&rt5659->jack_detect_work, rt5659_jack_detect_work);
-
        if (i2c->irq) {
                ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
                        rt5659_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING