diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 170 | 
1 files changed, 123 insertions, 47 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3a8371990d7..c7730dbb9dd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1621,6 +1621,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 +1637,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},  	{ }  }; @@ -2532,8 +2539,6 @@ static int alc_build_controls(struct hda_codec *codec)  			return err;  	} -	alc_free_kctls(codec); /* no longer needed */ -  	/* assign Capture Source enums to NID */  	kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");  	if (!kctl) @@ -2602,6 +2607,9 @@ static int alc_build_controls(struct hda_codec *codec)  			}  		}  	} + +	alc_free_kctls(codec); /* no longer needed */ +  	return 0;  } @@ -4983,6 +4991,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)) @@ -6477,7 +6549,7 @@ static struct alc_config_preset alc260_presets[] = {  		.num_dacs = ARRAY_SIZE(alc260_dac_nids),  		.dac_nids = alc260_dac_nids,  		.num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), -		.adc_nids = alc260_adc_nids, +		.adc_nids = alc260_dual_adc_nids,  		.num_channel_mode = ARRAY_SIZE(alc260_modes),  		.channel_mode = alc260_modes,  		.input_mux = &alc260_capture_source, @@ -8397,9 +8469,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), @@ -9195,6 +9265,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),  	SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),  	SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), +	SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),  	SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),  	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),  	SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), @@ -9204,6 +9275,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),  	SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),  	SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), +	SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),  	SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),  	SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), @@ -9235,7 +9307,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),  	SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),  	SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), -	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), +	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),  	{}  }; @@ -10038,6 +10110,8 @@ 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 @@ -12453,11 +12527,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, @@ -13327,9 +13401,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 @@ -13476,11 +13550,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); @@ -13505,11 +13579,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); @@ -13640,11 +13714,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 */ @@ -13836,7 +13910,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); @@ -13860,18 +13933,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); @@ -14150,14 +14224,16 @@ 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) @@ -17109,9 +17185,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) @@ -17122,13 +17198,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) @@ -17139,13 +17215,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) @@ -17184,14 +17260,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);  	}  }  |