diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index b077bb6..a96c56b 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -2097,14 +2097,21 @@ static int create_extra_out(struct hda_codec *codec, int path_idx,
 {
 	struct nid_path *path;
 	int err;
+	struct hda_gen_spec *spec = codec->spec;
 
 	path = snd_hda_get_path_from_idx(codec, path_idx);
 	if (!path)
 		return 0;
-	err = add_stereo_vol(codec, pfx, cidx, path);
+	if ((strcmp(pfx, "Headphone") == 0) && spec->hs_mic_use_hp_sense)
+		err = add_stereo_vol(codec, "Headset", cidx, path);
+	else
+		err = add_stereo_vol(codec, pfx, cidx, path);
 	if (err < 0)
 		return err;
-	err = add_stereo_sw(codec, pfx, cidx, path);
+	if ((strcmp(pfx, "Headphone") == 0) && spec->hs_mic_use_hp_sense)
+		err = add_stereo_sw(codec, "Headset", cidx, path);
+	else
+		err = add_stereo_sw(codec, pfx, cidx, path);
 	if (err < 0)
 		return err;
 	return 0;
@@ -4665,7 +4672,9 @@ static int check_auto_mic_availability(struct hda_codec *codec)
 			if (!spec->line_in_auto_switch &&
 			    cfg->inputs[i].type != AUTO_PIN_MIC)
 				return 0; /* only mic is allowed */
-			if (!is_jack_detectable(codec, nid))
+			if (!is_jack_detectable(codec, nid) &&
+				!(spec->hs_mic_use_hp_sense &&
+				cfg->inputs[i].is_headset_mic))
 				return 0; /* no unsol support */
 			break;
 		}
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 56e4139..96f8214 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -236,6 +236,7 @@ struct hda_gen_spec {
 	unsigned int indep_hp_enabled:1; /* independent HP enabled */
 	unsigned int have_aamix_ctl:1;
 	unsigned int hp_mic_jack_modes:1;
+	unsigned int hs_mic_use_hp_sense:1;
 
 	/* additional mute flags (only effective with auto_mute_via_amp=1) */
 	u64 mute_bits;
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 366efbf..2f308a5 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -19,6 +19,7 @@
 #include "hda_local.h"
 #include "hda_auto_parser.h"
 #include "hda_jack.h"
+#include "hda_generic.h"
 
 /**
  * is_jack_detectable - Check whether the given pin is jack-detectable
@@ -157,7 +158,15 @@ static void jack_detect_update(struct hda_codec *codec,
 	if (jack->phantom_jack)
 		jack->pin_sense = AC_PINSENSE_PRESENCE;
 	else
-		jack->pin_sense = read_pin_sense(codec, jack->nid);
+		jack->pin_sense = read_pin_sense(codec,
+				jack->sense_nid ? jack->sense_nid : jack->nid);
+
+	if (jack->slave_nid) {
+		struct hda_jack_tbl *slave =
+			snd_hda_jack_tbl_get(codec, jack->slave_nid);
+		if (slave)
+			slave->pin_sense = jack->pin_sense;
+	}
 
 	/* A gating jack indicates the jack is invalid if gating is unplugged */
 	if (jack->gating_jack && !snd_hda_jack_detect(codec, jack->gating_jack))
@@ -209,6 +218,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
 		jack_detect_update(codec, jack);
 		return jack->pin_sense;
 	}
+	if (jack->sense_nid)
+		return read_pin_sense(codec, jack->sense_nid);
 	return read_pin_sense(codec, nid);
 }
 EXPORT_SYMBOL_GPL(snd_hda_pin_sense);
@@ -384,7 +395,7 @@ static void hda_free_jack_priv(struct snd_jack *jack)
  * will have the given name and index.
  */
 static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
-			  const char *name, bool phantom_jack)
+		  const char *name, bool phantom_jack, hda_nid_t sense_nid)
 {
 	struct hda_jack_tbl *jack;
 	int err, state, type;
@@ -405,6 +416,7 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 	jack->type = type;
 	jack->jack->private_data = jack;
 	jack->jack->private_free = hda_free_jack_priv;
+	jack->sense_nid = sense_nid;
 	state = snd_hda_jack_detect(codec, nid);
 	snd_jack_report(jack->jack, state ? jack->type : 0);
 
@@ -422,7 +434,7 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
 			  const char *name)
 {
-	return __snd_hda_jack_add_kctl(codec, nid, name, false);
+	return __snd_hda_jack_add_kctl(codec, nid, name, false, nid);
 }
 EXPORT_SYMBOL_GPL(snd_hda_jack_add_kctl);
 
@@ -451,7 +463,7 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
 	if (phantom_jack)
 		/* Example final name: "Internal Mic Phantom Jack" */
 		strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
-	err = __snd_hda_jack_add_kctl(codec, nid, name, phantom_jack);
+	err = __snd_hda_jack_add_kctl(codec, nid, name, phantom_jack, nid);
 	if (err < 0)
 		return err;
 
@@ -469,6 +481,9 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
 			   const struct auto_pin_cfg *cfg)
 {
 	const hda_nid_t *p;
+	struct hda_jack_tbl *jack;
+	hda_nid_t headset_mic_nid = 0;
+	struct hda_gen_spec *spec = codec->spec;
 	int i, err;
 
 	for (i = 0; i < cfg->num_inputs; i++) {
@@ -482,6 +497,13 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
 				err = add_jack_kctl(codec, cfg->inputs[i].pin,
 						    cfg, "Headphone Mic");
 		} else
+	    if (cfg->inputs[i].is_headset_mic &&
+			spec->hs_mic_use_hp_sense &&
+			!is_jack_detectable(codec, cfg->inputs[i].pin)) {
+			headset_mic_nid = cfg->inputs[i].pin;
+			err = __snd_hda_jack_add_kctl(codec, cfg->inputs[i].pin,
+				"Headset Mic", false, auto_cfg_hp_pins(cfg)[0]);
+		} else
 			err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg,
 					    NULL);
 		if (err < 0)
@@ -489,7 +511,10 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
 	}
 
 	for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
-		err = add_jack_kctl(codec, *p, cfg, NULL);
+		if ((cfg->line_outs == 2) && (i == 1))
+			err = add_jack_kctl(codec, *p, cfg, "External Subwoofer");
+		else
+			err = add_jack_kctl(codec, *p, cfg, NULL);
 		if (err < 0)
 			return err;
 	}
@@ -499,6 +524,11 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
 		err = add_jack_kctl(codec, *p, cfg, NULL);
 		if (err < 0)
 			return err;
+	    if ((i == 0) && spec->hs_mic_use_hp_sense) {
+			jack = snd_hda_jack_tbl_get(codec, *p);
+		    if (jack)
+				jack->slave_nid = headset_mic_nid;
+		}
 	}
 	for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
 		if (*p == *cfg->line_out_pins) /* might be duplicated */
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 387d309..ef3d162 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -41,6 +41,8 @@ struct hda_jack_tbl {
 	hda_nid_t gated_jack;		/* gated is dependent on this jack */
 	int type;
 	struct snd_jack *jack;
+	hda_nid_t sense_nid;
+	hda_nid_t slave_nid;
 };
 
 struct hda_jack_tbl *
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index c456c04..a402ed5 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -104,6 +104,7 @@ struct alc_spec {
 	hda_nid_t headphone_mic_pin;
 	int current_headset_mode;
 	int current_headset_type;
+	int alc668_combo_type;
 
 	/* hooks */
 	void (*init_hook)(struct hda_codec *codec);
@@ -3984,6 +3985,15 @@ static void alc_update_headset_mode(struct hda_codec *codec)
 
 	int new_headset_mode;
 
+	if (codec->core.vendor_id == 0x10ec0668 &&
+		spec->alc668_combo_type) {
+		if (spec->alc668_combo_type == ALC_HEADSET_MODE_HEADSET &&
+		    spec->gen.auto_mic) {
+			snd_hda_gen_mic_autoswitch(codec, NULL);
+		    mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
+		}
+	}
+
 	if (!snd_hda_jack_detect(codec, hp_pin))
 		new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
 	else if (mux_pin == spec->headset_mic_pin)
@@ -6232,6 +6242,37 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
 	}
 }
 
+static void alc668_fixup_asus_headset(struct hda_codec *codec,
+				    const struct hda_fixup *fix, int action)
+{
+	const struct hda_pintbl pincfgs[] = {
+	    { 0x1a, 0x04110011 }, /* external subwoofer */
+		{ 0x1b, 0x03a1113c }, /* headset mic */
+		{ }
+	};
+
+	struct alc_spec *spec = codec->spec;
+
+	switch (action) {
+	case HDA_FIXUP_ACT_PRE_PROBE:
+		snd_hda_apply_pincfgs(codec, pincfgs);
+	    spec->gen.hs_mic_use_hp_sense = 1;
+		spec->alc668_combo_type = ALC_HEADSET_MODE_HEADSET;
+		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
+		break;
+	case HDA_FIXUP_ACT_PROBE:
+		alc_probe_headset_mode(codec);
+		break;
+	case HDA_FIXUP_ACT_INIT:
+		spec->current_headset_mode = 0;
+		alc_update_headset_mode(codec);
+		break;
+	case HDA_FIXUP_ACT_BUILD:
+		alc_fixup_bass_chmap(codec, fix, action);
+		break;
+	}
+}
+
 /* avoid D3 for keeping GPIO up */
 static unsigned int gpio_led_power_filter(struct hda_codec *codec,
 					  hda_nid_t nid,
@@ -6313,6 +6354,7 @@ enum {
 	ALC662_FIXUP_INV_DMIC,
 	ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
 	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
+	ALC668_FIXUP_ASUS_HEADSET,
 	ALC662_FIXUP_HEADSET_MODE,
 	ALC668_FIXUP_HEADSET_MODE,
 	ALC662_FIXUP_BASS_MODE4_CHMAP,
@@ -6530,6 +6572,10 @@ static const struct hda_fixup alc662_fixups[] = {
 		.chained = true,
 		.chain_id = ALC668_FIXUP_HEADSET_MODE
 	},
+	[ALC668_FIXUP_ASUS_HEADSET] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc668_fixup_asus_headset,
+	},
 	[ALC668_FIXUP_HEADSET_MODE] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc_fixup_headset_mode_alc668,
@@ -6667,6 +6713,7 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
 	{.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
 	{.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
 	{.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
+	{.id = ALC668_FIXUP_ASUS_HEADSET, .name = "asus-headset"},
 	{}
 };
 
