diff options
| author | Takashi Iwai <tiwai@suse.de> | 2011-03-16 17:38:46 +0100 | 
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2011-03-16 17:38:46 +0100 | 
| commit | 433e8327caf9f7c0432b2f2f6684a5b79cfe18e9 (patch) | |
| tree | 515e7bb9b0169fc4f8c1422ef6c926d4bd63e808 /sound/pci/hda/patch_realtek.c | |
| parent | 27b92d4ff2be2359a21ff4acde5b63563ff720e2 (diff) | |
| parent | cc90fd725e14020607c5a6ba3ea02a0ddec5655f (diff) | |
| download | olio-linux-3.10-433e8327caf9f7c0432b2f2f6684a5b79cfe18e9.tar.xz olio-linux-3.10-433e8327caf9f7c0432b2f2f6684a5b79cfe18e9.zip  | |
Merge branch 'topic/hda' into for-linus
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 204 | 
1 files changed, 79 insertions, 125 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4261bb8eec1..639d2746713 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -282,12 +282,6 @@ struct alc_mic_route {  	unsigned char amix_idx;  }; -struct alc_jack { -	hda_nid_t nid; -	int type; -	struct snd_jack *jack; -}; -  #define MUX_IDX_UNDEF	((unsigned char)-1)  struct alc_customize_define { @@ -366,9 +360,6 @@ struct alc_spec {  	/* PCM information */  	struct hda_pcm pcm_rec[3];	/* used in alc_build_pcms() */ -	/* jack detection */ -	struct snd_array jacks; -  	/* dynamic controls, init_verbs and input_mux */  	struct auto_pin_cfg autocfg;  	struct alc_customize_define cdefine; @@ -394,6 +385,7 @@ struct alc_spec {  	/* other flags */  	unsigned int no_analog :1; /* digital I/O only */  	unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ +	unsigned int single_input_src:1;  	int init_amp;  	int codec_variant;	/* flag for other variants */ @@ -1032,94 +1024,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,  	alc_fix_pll(codec);  } -#ifdef CONFIG_SND_HDA_INPUT_JACK -static void alc_free_jack_priv(struct snd_jack *jack) -{ -	struct alc_jack *jacks = jack->private_data; -	jacks->nid = 0; -	jacks->jack = NULL; -} - -static int alc_add_jack(struct hda_codec *codec, -		hda_nid_t nid, int type) -{ -	struct alc_spec *spec; -	struct alc_jack *jack; -	const char *name; -	int err; - -	spec = codec->spec; -	snd_array_init(&spec->jacks, sizeof(*jack), 32); -	jack = snd_array_new(&spec->jacks); -	if (!jack) -		return -ENOMEM; - -	jack->nid = nid; -	jack->type = type; -	name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; - -	err = snd_jack_new(codec->bus->card, name, type, &jack->jack); -	if (err < 0) -		return err; -	jack->jack->private_data = jack; -	jack->jack->private_free = alc_free_jack_priv; -	return 0; -} - -static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) -{ -	struct alc_spec *spec = codec->spec; -	struct alc_jack *jacks = spec->jacks.list; - -	if (jacks) { -		int i; -		for (i = 0; i < spec->jacks.used; i++) { -			if (jacks->nid == nid) { -				unsigned int present; -				present = snd_hda_jack_detect(codec, nid); - -				present = (present) ? jacks->type : 0; - -				snd_jack_report(jacks->jack, present); -			} -			jacks++; -		} -	} -} -  static int alc_init_jacks(struct hda_codec *codec)  { +#ifdef CONFIG_SND_HDA_INPUT_JACK  	struct alc_spec *spec = codec->spec;  	int err;  	unsigned int hp_nid = spec->autocfg.hp_pins[0];  	unsigned int mic_nid = spec->ext_mic.pin;  	if (hp_nid) { -		err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); +		err = snd_hda_input_jack_add(codec, hp_nid, +					     SND_JACK_HEADPHONE, NULL);  		if (err < 0)  			return err; -		alc_report_jack(codec, hp_nid); +		snd_hda_input_jack_report(codec, hp_nid);  	}  	if (mic_nid) { -		err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); +		err = snd_hda_input_jack_add(codec, mic_nid, +					     SND_JACK_MICROPHONE, NULL);  		if (err < 0)  			return err; -		alc_report_jack(codec, mic_nid); +		snd_hda_input_jack_report(codec, mic_nid);  	} - -	return 0; -} -#else -static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) -{ -} - -static inline int alc_init_jacks(struct hda_codec *codec) -{ +#endif /* CONFIG_SND_HDA_INPUT_JACK */  	return 0;  } -#endif  static void alc_automute_speaker(struct hda_codec *codec, int pinctl)  { @@ -1133,7 +1063,7 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl)  		nid = spec->autocfg.hp_pins[i];  		if (!nid)  			break; -		alc_report_jack(codec, nid); +		snd_hda_input_jack_report(codec, nid);  		spec->jack_present |= snd_hda_jack_detect(codec, nid);  	} @@ -1240,7 +1170,7 @@ static void alc_mic_automute(struct hda_codec *codec)  					  AC_VERB_SET_CONNECT_SEL,  					  alive->mux_idx);  	} -	alc_report_jack(codec, spec->ext_mic.pin); +	snd_hda_input_jack_report(codec, spec->ext_mic.pin);  	/* FIXME: analog mixer */  } @@ -2292,13 +2222,13 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), -	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0, +	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,  		HDA_OUTPUT), -	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT), -	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), -	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), -	HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT), -	HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT), +	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), +	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), +	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), +	HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), +	HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),  	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),  	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), @@ -2309,7 +2239,6 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {  	{ } /* end */  }; -  static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -3919,6 +3848,8 @@ static struct hda_amp_list alc880_lg_loopbacks[] = {   * Common callbacks   */ +static void alc_init_special_input_src(struct hda_codec *codec); +  static int alc_init(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; @@ -3929,6 +3860,7 @@ static int alc_init(struct hda_codec *codec)  	for (i = 0; i < spec->num_init_verbs; i++)  		snd_hda_sequence_write(codec, spec->init_verbs[i]); +	alc_init_special_input_src(codec);  	if (spec->init_hook)  		spec->init_hook(codec); @@ -4284,6 +4216,7 @@ static void alc_free(struct hda_codec *codec)  		return;  	alc_shutup(codec); +	snd_hda_input_jack_free(codec);  	alc_free_kctls(codec);  	kfree(spec);  	snd_hda_detach_beep_device(codec); @@ -5151,7 +5084,9 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,  	switch (cfg->line_out_type) {  	case AUTO_PIN_SPEAKER_OUT: -		return "Speaker"; +		if (cfg->line_outs == 1) +			return "Speaker"; +		break;  	case AUTO_PIN_HP_OUT:  		return "Headphone";  	default: @@ -5205,16 +5140,19 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,  				return err;  		} else {  			const char *name = pfx; -			if (!name) +			int index = i; +			if (!name) {  				name = chname[i]; +				index = 0; +			}  			err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, -						name, i, +						name, index,  					  HDA_COMPOSE_AMP_VAL(nid, 3, 0,  							      HDA_OUTPUT));  			if (err < 0)  				return err;  			err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, -					       name, i, +					       name, index,  					  HDA_COMPOSE_AMP_VAL(nid, 3, 2,  							      HDA_INPUT));  			if (err < 0) @@ -5585,6 +5523,7 @@ static void fixup_single_adc(struct hda_codec *codec)  			spec->capsrc_nids += i;  		spec->adc_nids += i;  		spec->num_adc_nids = 1; +		spec->single_input_src = 1;  	}  } @@ -5596,6 +5535,16 @@ static void fixup_dual_adc_switch(struct hda_codec *codec)  	init_capsrc_for_pin(codec, spec->int_mic.pin);  } +/* initialize some special cases for input sources */ +static void alc_init_special_input_src(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	if (spec->dual_adc_switch) +		fixup_dual_adc_switch(codec); +	else if (spec->single_input_src) +		init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); +} +  static void set_capture_mixer(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; @@ -5611,7 +5560,7 @@ static void set_capture_mixer(struct hda_codec *codec)  		int mux = 0;  		int num_adcs = spec->num_adc_nids;  		if (spec->dual_adc_switch) -			fixup_dual_adc_switch(codec); +			num_adcs = 1;  		else if (spec->auto_mic)  			fixup_automic_adc(codec);  		else if (spec->input_mux) { @@ -5620,8 +5569,6 @@ static void set_capture_mixer(struct hda_codec *codec)  			else if (spec->input_mux->num_items == 1)  				fixup_single_adc(codec);  		} -		if (spec->dual_adc_switch) -			num_adcs = 1;  		spec->cap_mixer = caps[mux][num_adcs - 1];  	}  } @@ -10748,6 +10695,7 @@ static struct alc_config_preset alc882_presets[] = {   */  enum {  	PINFIX_ABIT_AW9D_MAX, +	PINFIX_LENOVO_Y530,  	PINFIX_PB_M5210,  	PINFIX_ACER_ASPIRE_7736,  }; @@ -10762,6 +10710,14 @@ static const struct alc_fixup alc882_fixups[] = {  			{ }  		}  	}, +	[PINFIX_LENOVO_Y530] = { +		.type = ALC_FIXUP_PINS, +		.v.pins = (const struct alc_pincfg[]) { +			{ 0x15, 0x99130112 }, /* rear int speakers */ +			{ 0x16, 0x99130111 }, /* subwoofer */ +			{ } +		} +	},  	[PINFIX_PB_M5210] = {  		.type = ALC_FIXUP_VERBS,  		.v.verbs = (const struct hda_verb[]) { @@ -10777,6 +10733,7 @@ static const struct alc_fixup alc882_fixups[] = {  static struct snd_pci_quirk alc882_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), +	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),  	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),  	SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),  	{} @@ -10829,23 +10786,28 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec)  	hda_nid_t pin, dac;  	int i; -	for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { -		pin = spec->autocfg.hp_pins[i]; -		if (!pin) -			break; -		dac = spec->multiout.hp_nid; -		if (!dac) -			dac = spec->multiout.dac_nids[0]; /* to front */ -		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); +	if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { +		for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { +			pin = spec->autocfg.hp_pins[i]; +			if (!pin) +				break; +			dac = spec->multiout.hp_nid; +			if (!dac) +				dac = spec->multiout.dac_nids[0]; /* to front */ +			alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); +		}  	} -	for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { -		pin = spec->autocfg.speaker_pins[i]; -		if (!pin) -			break; -		dac = spec->multiout.extra_out_nid[0]; -		if (!dac) -			dac = spec->multiout.dac_nids[0]; /* to front */ -		alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); + +	if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { +		for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { +			pin = spec->autocfg.speaker_pins[i]; +			if (!pin) +				break; +			dac = spec->multiout.extra_out_nid[0]; +			if (!dac) +				dac = spec->multiout.dac_nids[0]; /* to front */ +			alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); +		}  	}  } @@ -13796,6 +13758,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)  }  #define alc268_auto_init_analog_input	alc882_auto_init_analog_input +#define alc268_auto_init_input_src	alc882_auto_init_input_src  /* init callback for auto-configuration model -- overriding the default init */  static void alc268_auto_init(struct hda_codec *codec) @@ -13805,6 +13768,7 @@ static void alc268_auto_init(struct hda_codec *codec)  	alc268_auto_init_hp_out(codec);  	alc268_auto_init_mono_speaker_out(codec);  	alc268_auto_init_analog_input(codec); +	alc268_auto_init_input_src(codec);  	alc_auto_init_digital(codec);  	if (spec->unsol_event)  		alc_inithook(codec); @@ -14092,7 +14056,6 @@ static int patch_alc268(struct hda_codec *codec)  	if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {  		/* check whether NID 0x07 is valid */  		unsigned int wcap = get_wcaps(codec, 0x07); -		int i;  		spec->capsrc_nids = alc268_capsrc_nids;  		/* get type */ @@ -14112,13 +14075,6 @@ static int patch_alc268(struct hda_codec *codec)  			spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);  			add_mixer(spec, alc268_capture_mixer);  		} -		/* set default input source */ -		for (i = 0; i < spec->num_adc_nids; i++) -			snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], -				0, AC_VERB_SET_CONNECT_SEL, -				i < spec->num_mux_defs ? -				spec->input_mux[i].items[0].index : -				spec->input_mux->items[0].index);  	}  	spec->vmaster_nid = 0x02; @@ -14495,7 +14451,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)  				 HDA_AMP_MUTE, bits);  	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,  				 HDA_AMP_MUTE, bits); -	alc_report_jack(codec, nid); +	snd_hda_input_jack_report(codec, nid);  }  /* unsolicited event for HP jack sensing */ @@ -14807,11 +14763,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)  		fillup_priv_adc_nids(codec, alc269_adc_candidates,  				     sizeof(alc269_adc_candidates)); -	/* set default input source */ -	if (!spec->dual_adc_switch) -		select_or_unmute_capsrc(codec, spec->capsrc_nids[0], -					spec->input_mux->items[0].index); -  	err = alc_auto_add_mic_boost(codec);  	if (err < 0)  		return err; @@ -14825,6 +14776,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)  #define alc269_auto_init_multi_out	alc268_auto_init_multi_out  #define alc269_auto_init_hp_out		alc268_auto_init_hp_out  #define alc269_auto_init_analog_input	alc882_auto_init_analog_input +#define alc269_auto_init_input_src	alc882_auto_init_input_src  /* init callback for auto-configuration model -- overriding the default init */ @@ -14834,6 +14786,8 @@ static void alc269_auto_init(struct hda_codec *codec)  	alc269_auto_init_multi_out(codec);  	alc269_auto_init_hp_out(codec);  	alc269_auto_init_analog_input(codec); +	if (!spec->dual_adc_switch) +		alc269_auto_init_input_src(codec);  	alc_auto_init_digital(codec);  	if (spec->unsol_event)  		alc_inithook(codec);  |