diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 336 | 
1 files changed, 272 insertions, 64 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a23444e9e7..7404dba16f8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -230,6 +230,7 @@ enum {  	ALC888_ACER_ASPIRE_7730G,  	ALC883_MEDION,  	ALC883_MEDION_MD2, +	ALC883_MEDION_WIM2160,  	ALC883_LAPTOP_EAPD,  	ALC883_LENOVO_101E_2ch,  	ALC883_LENOVO_NB0763, @@ -1389,22 +1390,31 @@ struct alc_fixup {  static void alc_pick_fixup(struct hda_codec *codec,  			   const struct snd_pci_quirk *quirk, -			   const struct alc_fixup *fix) +			   const struct alc_fixup *fix, +			   int pre_init)  {  	const struct alc_pincfg *cfg;  	quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);  	if (!quirk)  		return; -  	fix += quirk->value;  	cfg = fix->pins; -	if (cfg) { +	if (pre_init && cfg) { +#ifdef CONFIG_SND_DEBUG_VERBOSE +		snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", +			    codec->chip_name, quirk->name); +#endif  		for (; cfg->nid; cfg++)  			snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);  	} -	if (fix->verbs) +	if (!pre_init && fix->verbs) { +#ifdef CONFIG_SND_DEBUG_VERBOSE +		snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", +			    codec->chip_name, quirk->name); +#endif  		add_verb(codec->spec, fix->verbs); +	}  }  static int alc_read_coef_idx(struct hda_codec *codec, @@ -1621,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {   */  static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { +/* Route to built-in subwoofer as well as speakers */ +	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, +	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, +	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, +	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  /* Bias voltage on for external mic port */  	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},  /* Front Mic: set to PIN_IN (empty by default) */ @@ -1632,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {  /* Enable speaker output */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, +	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  /* Enable headphone output */  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},  	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, +	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; @@ -4126,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),  	SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),  	SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), -	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), +	SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),  	SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),  	SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),  	SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), @@ -4801,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)  	}  } +static void alc880_auto_init_input_src(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	int c; + +	for (c = 0; c < spec->num_adc_nids; c++) { +		unsigned int mux_idx; +		const struct hda_input_mux *imux; +		mux_idx = c >= spec->num_mux_defs ? 0 : c; +		imux = &spec->input_mux[mux_idx]; +		if (!imux->num_items && mux_idx > 0) +			imux = &spec->input_mux[0]; +		if (imux) +			snd_hda_codec_write(codec, spec->adc_nids[c], 0, +					    AC_VERB_SET_CONNECT_SEL, +					    imux->items[0].index); +	} +} +  /* parse the BIOS configuration and set up the alc_spec */  /* return 1 if successful, 0 if the proper config is not found,   * or a negative error code @@ -4879,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec)  	alc880_auto_init_multi_out(codec);  	alc880_auto_init_extra_out(codec);  	alc880_auto_init_analog_input(codec); +	alc880_auto_init_input_src(codec);  	if (spec->unsol_event)  		alc_inithook(codec);  } @@ -4984,6 +5021,70 @@ static void set_capture_mixer(struct hda_codec *codec)  	}  } +/* fill adc_nids (and capsrc_nids) containing all active input pins */ +static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, +				 int num_nids) +{ +	struct alc_spec *spec = codec->spec; +	int n; +	hda_nid_t fallback_adc = 0, fallback_cap = 0; + +	for (n = 0; n < num_nids; n++) { +		hda_nid_t adc, cap; +		hda_nid_t conn[HDA_MAX_NUM_INPUTS]; +		int nconns, i, j; + +		adc = nids[n]; +		if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) +			continue; +		cap = adc; +		nconns = snd_hda_get_connections(codec, cap, conn, +						 ARRAY_SIZE(conn)); +		if (nconns == 1) { +			cap = conn[0]; +			nconns = snd_hda_get_connections(codec, cap, conn, +							 ARRAY_SIZE(conn)); +		} +		if (nconns <= 0) +			continue; +		if (!fallback_adc) { +			fallback_adc = adc; +			fallback_cap = cap; +		} +		for (i = 0; i < AUTO_PIN_LAST; i++) { +			hda_nid_t nid = spec->autocfg.input_pins[i]; +			if (!nid) +				continue; +			for (j = 0; j < nconns; j++) { +				if (conn[j] == nid) +					break; +			} +			if (j >= nconns) +				break; +		} +		if (i >= AUTO_PIN_LAST) { +			int num_adcs = spec->num_adc_nids; +			spec->private_adc_nids[num_adcs] = adc; +			spec->private_capsrc_nids[num_adcs] = cap; +			spec->num_adc_nids++; +			spec->adc_nids = spec->private_adc_nids; +			if (adc != cap) +				spec->capsrc_nids = spec->private_capsrc_nids; +		} +	} +	if (!spec->num_adc_nids) { +		printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" +		       " using fallback 0x%x\n", +		       codec->chip_name, fallback_adc); +		spec->private_adc_nids[0] = fallback_adc; +		spec->adc_nids = spec->private_adc_nids; +		if (fallback_adc != fallback_cap) { +			spec->private_capsrc_nids[0] = fallback_cap; +			spec->capsrc_nids = spec->private_adc_nids; +		} +	} +} +  #ifdef CONFIG_SND_HDA_INPUT_BEEP  #define set_beep_amp(spec, nid, idx, dir) \  	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) @@ -6326,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)  	}  } +#define alc260_auto_init_input_src	alc880_auto_init_input_src +  /*   * generic initialization of ADC, input mixers and output mixers   */ @@ -6412,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	alc260_auto_init_multi_out(codec);  	alc260_auto_init_analog_input(codec); +	alc260_auto_init_input_src(codec);  	if (spec->unsol_event)  		alc_inithook(codec);  } @@ -8384,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {  	{ } /* end */  }; +static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { +	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), +	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), +	HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), +	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), +	HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), +	HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), +	{ } /* end */ +}; + +static struct hda_verb alc883_medion_wim2160_verbs[] = { +	/* Unmute front mixer */ +	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, +	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + +	/* Set speaker pin to front mixer */ +	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + +	/* Init headphone pin */ +	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, +	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, +	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, +	{0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + +	{ } /* end */ +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc883_medion_wim2160_setup(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; + +	spec->autocfg.hp_pins[0] = 0x1a; +	spec->autocfg.speaker_pins[0] = 0x15; +} +  static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -8398,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {  static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), -	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), -	HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),  	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -9095,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {  	[ALC888_ACER_ASPIRE_7730G]	= "acer-aspire-7730g",  	[ALC883_MEDION]		= "medion",  	[ALC883_MEDION_MD2]	= "medion-md2", +	[ALC883_MEDION_WIM2160]	= "medion-wim2160",  	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",  	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",  	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763", @@ -9211,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),  	SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), +	SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),  	SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),  	SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),  	SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), @@ -9749,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = {  		.setup = alc883_medion_md2_setup,  		.init_hook = alc_automute_amp,  	}, +	[ALC883_MEDION_WIM2160] = { +		.mixers = { alc883_medion_wim2160_mixer }, +		.init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, +		.num_dacs = ARRAY_SIZE(alc883_dac_nids), +		.dac_nids = alc883_dac_nids, +		.dig_out_nid = ALC883_DIGOUT_NID, +		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids), +		.adc_nids = alc883_adc_nids, +		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), +		.channel_mode = alc883_3ST_2ch_modes, +		.input_mux = &alc883_capture_source, +		.unsol_event = alc_automute_amp_unsol_event, +		.setup = alc883_medion_wim2160_setup, +		.init_hook = alc_automute_amp, +	},  	[ALC883_LAPTOP_EAPD] = {  		.mixers = { alc883_base_mixer },  		.init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, @@ -10041,13 +10196,12 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,  	int idx;  	alc_set_pin_output(codec, nid, pin_type); +	if (dac_idx >= spec->multiout.num_dacs) +		return;  	if (spec->multiout.dac_nids[dac_idx] == 0x25)  		idx = 4; -	else { -		if (spec->multiout.num_dacs >= dac_idx) -			return; +	else  		idx = spec->multiout.dac_nids[dac_idx] - 2; -	}  	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);  } @@ -10295,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec)  		board_config = ALC882_AUTO;  	} -	alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); +	if (board_config == ALC882_AUTO) +		alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);  	if (board_config == ALC882_AUTO) {  		/* automatic parse from the BIOS config */ @@ -10368,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec)  	set_capture_mixer(codec);  	set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); +	if (board_config == ALC882_AUTO) +		alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); +  	spec->vmaster_nid = 0x0c;  	codec->patch_ops = alc_patch_ops; @@ -12459,11 +12617,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)  	unsigned char bits;  	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? AMP_IN_MUTE(0) : 0; +	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  }  static void alc268_acer_lc_unsol_event(struct hda_codec *codec, @@ -12748,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,  		dac = 0x02;  		break;  	case 0x15: +	case 0x21: /* ALC269vb has this pin, too */  		dac = 0x03;  		break;  	default: @@ -13333,9 +13492,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = {  	0x22,  }; -/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), - *       not a mux! - */ +static hda_nid_t alc269_adc_candidates[] = { +	0x08, 0x09, 0x07, +};  #define alc269_modes		alc260_modes  #define alc269_capture_source	alc880_lg_lw_capture_source @@ -13482,11 +13641,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)  	unsigned char bits;  	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? AMP_IN_MUTE(0) : 0; +	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -			AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -			AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_write(codec, 0x20, 0,  			AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13511,11 +13670,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)  	/* Check port replicator headphone socket */  	present |= snd_hda_jack_detect(codec, 0x1a); -	bits = present ? AMP_IN_MUTE(0) : 0; +	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -			AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -			AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_write(codec, 0x20, 0,  			AC_VERB_SET_COEF_INDEX, 0x0c); @@ -13646,11 +13805,11 @@ static void alc269_speaker_automute(struct hda_codec *codec)  	unsigned char bits;  	present = snd_hda_jack_detect(codec, nid); -	bits = present ? AMP_IN_MUTE(0) : 0; +	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  }  /* unsolicited event for HP jack sensing */ @@ -13667,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec,  	}  } -static void alc269_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_amic_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0; -	spec->int_mic.pin = 0x12; -	spec->int_mic.mux_idx = 5; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1;  	spec->auto_mic = 1;  } -static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +static void alc269_laptop_dmic_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x15; @@ -13687,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x12; -	spec->int_mic.mux_idx = 6; +	spec->int_mic.mux_idx = 5;  	spec->auto_mic = 1;  } -static void alc269_laptop_amic_setup(struct hda_codec *codec) +static void alc269vb_laptop_amic_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.hp_pins[0] = 0x21;  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0; @@ -13703,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } +static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x12; +	spec->int_mic.mux_idx = 6; +	spec->auto_mic = 1; +} +  static void alc269_laptop_inithook(struct hda_codec *codec)  {  	alc269_speaker_automute(codec); @@ -13842,7 +14013,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	int err;  	static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; -	hda_nid_t real_capsrc_nids;  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc269_ignore); @@ -13866,18 +14036,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec)  	if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {  		add_verb(spec, alc269vb_init_verbs); -		real_capsrc_nids = alc269vb_capsrc_nids[0];  		alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);  	} else {  		add_verb(spec, alc269_init_verbs); -		real_capsrc_nids = alc269_capsrc_nids[0];  		alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);  	}  	spec->num_mux_defs = 1;  	spec->input_mux = &spec->private_imux[0]; +	fillup_priv_adc_nids(codec, alc269_adc_candidates, +			     sizeof(alc269_adc_candidates)); +  	/* set default input source */ -	snd_hda_codec_write_cache(codec, real_capsrc_nids, +	snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],  				  0, AC_VERB_SET_CONNECT_SEL,  				  spec->input_mux->items[0].index); @@ -13907,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec)  		alc_inithook(codec);  } +enum { +	ALC269_FIXUP_SONY_VAIO, +}; + +const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { +	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, +	{} +}; + +static const struct alc_fixup alc269_fixups[] = { +	[ALC269_FIXUP_SONY_VAIO] = { +		.verbs = alc269_sony_vaio_fixup_verbs +	}, +}; + +static struct snd_pci_quirk alc269_fixup_tbl[] = { +	SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), +	{} +}; + +  /*   * configuration and preset   */ @@ -13966,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {  		      ALC269_DMIC),  	SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),  	SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), -	SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), +	SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),  	SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),  	SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),  	SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), @@ -14040,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes,  		.unsol_event = alc269_laptop_unsol_event, -		.setup = alc269_laptop_amic_setup, +		.setup = alc269vb_laptop_amic_setup,  		.init_hook = alc269_laptop_inithook,  	},  	[ALC269VB_DMIC] = { @@ -14120,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec)  		board_config = ALC269_AUTO;  	} +	if (board_config == ALC269_AUTO) +		alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); +  	if (board_config == ALC269_AUTO) {  		/* automatic parse from the BIOS config */  		err = alc269_parse_auto_config(codec); @@ -14156,20 +14351,25 @@ static int patch_alc269(struct hda_codec *codec)  	spec->stream_digital_playback = &alc269_pcm_digital_playback;  	spec->stream_digital_capture = &alc269_pcm_digital_capture; -	if (!is_alc269vb) { -		spec->adc_nids = alc269_adc_nids; -		spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); -		spec->capsrc_nids = alc269_capsrc_nids; -	} else { -		spec->adc_nids = alc269vb_adc_nids; -		spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); -		spec->capsrc_nids = alc269vb_capsrc_nids; +	if (!spec->adc_nids) { /* wasn't filled automatically? use default */ +		if (!is_alc269vb) { +			spec->adc_nids = alc269_adc_nids; +			spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); +			spec->capsrc_nids = alc269_capsrc_nids; +		} else { +			spec->adc_nids = alc269vb_adc_nids; +			spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); +			spec->capsrc_nids = alc269vb_capsrc_nids; +		}  	}  	if (!spec->cap_mixer)  		set_capture_mixer(codec);  	set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); +	if (board_config == ALC269_AUTO) +		alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); +  	spec->vmaster_nid = 0x02;  	codec->patch_ops = alc_patch_ops; @@ -15258,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec)  		board_config = ALC861_AUTO;  	} -	alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); +	if (board_config == ALC861_AUTO) +		alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);  	if (board_config == ALC861_AUTO) {  		/* automatic parse from the BIOS config */ @@ -15295,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec)  	spec->vmaster_nid = 0x03; +	if (board_config == ALC861_AUTO) +		alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); +  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC861_AUTO) {  		spec->init_hook = alc861_auto_init; @@ -16229,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec)  		board_config = ALC861VD_AUTO;  	} -	alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); +	if (board_config == ALC861VD_AUTO) +		alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);  	if (board_config == ALC861VD_AUTO) {  		/* automatic parse from the BIOS config */ @@ -16277,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec)  	spec->vmaster_nid = 0x02; +	if (board_config == ALC861VD_AUTO) +		alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); +  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC861VD_AUTO) @@ -17115,9 +17323,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec)  	present = snd_hda_jack_detect(codec, 0x21);  	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  }  static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) @@ -17128,13 +17336,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)  	present = snd_hda_jack_detect(codec, 0x21);  	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  }  static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) @@ -17145,13 +17353,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)  	present = snd_hda_jack_detect(codec, 0x15);  	bits = present ? HDA_AMP_MUTE : 0;  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, -				AMP_IN_MUTE(0), bits); +				 HDA_AMP_MUTE, bits);  }  static void alc662_f5z_speaker_automute(struct hda_codec *codec) @@ -17190,14 +17398,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)  	if (present1 || present2) {  		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), AMP_IN_MUTE(0)); +					 HDA_AMP_MUTE, HDA_AMP_MUTE);  		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), AMP_IN_MUTE(0)); +					 HDA_AMP_MUTE, HDA_AMP_MUTE);  	} else {  		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				AMP_IN_MUTE(0), 0); +					 HDA_AMP_MUTE, 0);  		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				AMP_IN_MUTE(0), 0); +					 HDA_AMP_MUTE, 0);  	}  }  |