diff mbox

ALSA: hda - Fix headset mic and mic-in for a Dell desktop

Message ID 1431434295-22766-1-git-send-email-david.henningsson@canonical.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Henningsson May 12, 2015, 12:38 p.m. UTC
ALC662 does not need any special verbs to change the jack functionality,
and enables mic in through the headphone jack mode by changing the
direction of the headphone pin node.

BugLink: https://bugs.launchpad.net/bugs/1454235
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
---
 sound/pci/hda/patch_realtek.c | 46 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

Comments

Takashi Iwai May 18, 2015, 7:53 a.m. UTC | #1
At Tue, 12 May 2015 14:38:15 +0200,
David Henningsson wrote:
> 
> ALC662 does not need any special verbs to change the jack functionality,
> and enables mic in through the headphone jack mode by changing the
> direction of the headphone pin node.
> 
> BugLink: https://bugs.launchpad.net/bugs/1454235
> Signed-off-by: David Henningsson <david.henningsson@canonical.com>

Applied, thanks.


Takashi

> ---
>  sound/pci/hda/patch_realtek.c | 46 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 45 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
> index ce41271..30ec30f 100644
> --- a/sound/pci/hda/patch_realtek.c
> +++ b/sound/pci/hda/patch_realtek.c
> @@ -3674,6 +3674,10 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
>  		alc_process_coef_fw(codec, coef0293);
>  		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
>  		break;
> +	case 0x10ec0662:
> +		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
> +		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
> +		break;
>  	case 0x10ec0668:
>  		alc_write_coef_idx(codec, 0x11, 0x0001);
>  		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
> @@ -4012,7 +4016,7 @@ static void alc_update_headset_mode(struct hda_codec *codec)
>  	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
>  		snd_hda_set_pin_ctl_cache(codec, hp_pin,
>  					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
> -		if (spec->headphone_mic_pin)
> +		if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
>  			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
>  						  PIN_VREFHIZ);
>  	}
> @@ -4215,6 +4219,18 @@ static void alc_fixup_dell_xps13(struct hda_codec *codec,
>  	}
>  }
>  
> +static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
> +				const struct hda_fixup *fix, int action)
> +{
> +	struct alc_spec *spec = codec->spec;
> +
> +	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
> +		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
> +		spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
> +	} else
> +		alc_fixup_headset_mode(codec, fix, action);
> +}
> +
>  static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
>  				const struct hda_fixup *fix, int action)
>  {
> @@ -6080,7 +6096,9 @@ enum {
>  	ALC662_FIXUP_NO_JACK_DETECT,
>  	ALC662_FIXUP_ZOTAC_Z68,
>  	ALC662_FIXUP_INV_DMIC,
> +	ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
>  	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
> +	ALC662_FIXUP_HEADSET_MODE,
>  	ALC668_FIXUP_HEADSET_MODE,
>  	ALC662_FIXUP_BASS_MODE4_CHMAP,
>  	ALC662_FIXUP_BASS_16,
> @@ -6273,6 +6291,20 @@ static const struct hda_fixup alc662_fixups[] = {
>  		.chained = true,
>  		.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
>  	},
> +	[ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
> +		.type = HDA_FIXUP_PINS,
> +		.v.pins = (const struct hda_pintbl[]) {
> +			{ 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
> +			/* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
> +			{ }
> +		},
> +		.chained = true,
> +		.chain_id = ALC662_FIXUP_HEADSET_MODE
> +	},
> +	[ALC662_FIXUP_HEADSET_MODE] = {
> +		.type = HDA_FIXUP_FUNC,
> +		.v.func = alc_fixup_headset_mode_alc662,
> +	},
>  	[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
>  		.type = HDA_FIXUP_PINS,
>  		.v.pins = (const struct hda_pintbl[]) {
> @@ -6432,6 +6464,18 @@ static const struct hda_model_fixup alc662_fixup_models[] = {
>  	{0x1f, 0x411111f0}
>  
>  static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
> +	SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
> +		{0x12, 0x4004c000},
> +		{0x14, 0x01014010},
> +		{0x15, 0x411111f0},
> +		{0x16, 0x411111f0},
> +		{0x18, 0x01a19020},
> +		{0x19, 0x411111f0},
> +		{0x1a, 0x0181302f},
> +		{0x1b, 0x0221401f},
> +		{0x1c, 0x411111f0},
> +		{0x1d, 0x4054c601},
> +		{0x1e, 0x411111f0}),
>  	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
>  		ALC668_STANDARD_PINS,
>  		{0x12, 0x99a30130},
> -- 
> 1.9.1
>
diff mbox

Patch

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ce41271..30ec30f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3674,6 +3674,10 @@  static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
 		alc_process_coef_fw(codec, coef0293);
 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
 		break;
+	case 0x10ec0662:
+		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+		break;
 	case 0x10ec0668:
 		alc_write_coef_idx(codec, 0x11, 0x0001);
 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
@@ -4012,7 +4016,7 @@  static void alc_update_headset_mode(struct hda_codec *codec)
 	if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
 		snd_hda_set_pin_ctl_cache(codec, hp_pin,
 					  AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
-		if (spec->headphone_mic_pin)
+		if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
 			snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
 						  PIN_VREFHIZ);
 	}
@@ -4215,6 +4219,18 @@  static void alc_fixup_dell_xps13(struct hda_codec *codec,
 	}
 }
 
+static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
+				const struct hda_fixup *fix, int action)
+{
+	struct alc_spec *spec = codec->spec;
+
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
+		spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
+	} else
+		alc_fixup_headset_mode(codec, fix, action);
+}
+
 static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
 				const struct hda_fixup *fix, int action)
 {
@@ -6080,7 +6096,9 @@  enum {
 	ALC662_FIXUP_NO_JACK_DETECT,
 	ALC662_FIXUP_ZOTAC_Z68,
 	ALC662_FIXUP_INV_DMIC,
+	ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
 	ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
+	ALC662_FIXUP_HEADSET_MODE,
 	ALC668_FIXUP_HEADSET_MODE,
 	ALC662_FIXUP_BASS_MODE4_CHMAP,
 	ALC662_FIXUP_BASS_16,
@@ -6273,6 +6291,20 @@  static const struct hda_fixup alc662_fixups[] = {
 		.chained = true,
 		.chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
 	},
+	[ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = (const struct hda_pintbl[]) {
+			{ 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
+			/* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
+			{ }
+		},
+		.chained = true,
+		.chain_id = ALC662_FIXUP_HEADSET_MODE
+	},
+	[ALC662_FIXUP_HEADSET_MODE] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc_fixup_headset_mode_alc662,
+	},
 	[ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
 		.type = HDA_FIXUP_PINS,
 		.v.pins = (const struct hda_pintbl[]) {
@@ -6432,6 +6464,18 @@  static const struct hda_model_fixup alc662_fixup_models[] = {
 	{0x1f, 0x411111f0}
 
 static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
+	SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
+		{0x12, 0x4004c000},
+		{0x14, 0x01014010},
+		{0x15, 0x411111f0},
+		{0x16, 0x411111f0},
+		{0x18, 0x01a19020},
+		{0x19, 0x411111f0},
+		{0x1a, 0x0181302f},
+		{0x1b, 0x0221401f},
+		{0x1c, 0x411111f0},
+		{0x1d, 0x4054c601},
+		{0x1e, 0x411111f0}),
 	SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
 		ALC668_STANDARD_PINS,
 		{0x12, 0x99a30130},