diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
| -rw-r--r-- | sound/pci/hda/patch_realtek.c | 3732 | 
1 files changed, 1861 insertions, 1871 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 52928d9a72d..7a4e10002f5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -299,11 +299,23 @@ struct alc_customize_define {  struct alc_fixup; +struct alc_multi_io { +	hda_nid_t pin;		/* multi-io widget pin NID */ +	hda_nid_t dac;		/* DAC to be connected */ +	unsigned int ctl_in;	/* cached input-pin control value */ +}; + +enum { +	ALC_AUTOMUTE_PIN,	/* change the pin control */ +	ALC_AUTOMUTE_AMP,	/* mute/unmute the pin AMP */ +	ALC_AUTOMUTE_MIXER,	/* mute/unmute mixer widget AMP */ +}; +  struct alc_spec {  	/* codec parameterization */ -	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */ +	const struct snd_kcontrol_new *mixers[5];	/* mixer arrays */  	unsigned int num_mixers; -	struct snd_kcontrol_new *cap_mixer;	/* capture mixer */ +	const struct snd_kcontrol_new *cap_mixer;	/* capture mixer */  	unsigned int beep_amp;	/* beep amp value, set via set_beep_amp() */  	const struct hda_verb *init_verbs[10];	/* initialization verbs @@ -313,14 +325,14 @@ struct alc_spec {  	unsigned int num_init_verbs;  	char stream_name_analog[32];	/* analog PCM stream */ -	struct hda_pcm_stream *stream_analog_playback; -	struct hda_pcm_stream *stream_analog_capture; -	struct hda_pcm_stream *stream_analog_alt_playback; -	struct hda_pcm_stream *stream_analog_alt_capture; +	const struct hda_pcm_stream *stream_analog_playback; +	const struct hda_pcm_stream *stream_analog_capture; +	const struct hda_pcm_stream *stream_analog_alt_playback; +	const struct hda_pcm_stream *stream_analog_alt_capture;  	char stream_name_digital[32];	/* digital PCM stream */ -	struct hda_pcm_stream *stream_digital_playback; -	struct hda_pcm_stream *stream_digital_capture; +	const struct hda_pcm_stream *stream_digital_playback; +	const struct hda_pcm_stream *stream_digital_capture;  	/* playback */  	struct hda_multi_out multiout;	/* playback set-up @@ -333,8 +345,8 @@ struct alc_spec {  	/* capture */  	unsigned int num_adc_nids; -	hda_nid_t *adc_nids; -	hda_nid_t *capsrc_nids; +	const hda_nid_t *adc_nids; +	const hda_nid_t *capsrc_nids;  	hda_nid_t dig_in_nid;		/* digital-in NID; optional */  	/* capture setup for dynamic dual-adc switch */ @@ -348,6 +360,7 @@ struct alc_spec {  	const struct hda_input_mux *input_mux;  	unsigned int cur_mux[3];  	struct alc_mic_route ext_mic; +	struct alc_mic_route dock_mic;  	struct alc_mic_route int_mic;  	/* channel model */ @@ -375,17 +388,27 @@ struct alc_spec {  #ifdef CONFIG_SND_HDA_POWER_SAVE  	void (*power_hook)(struct hda_codec *codec);  #endif +	void (*shutup)(struct hda_codec *codec);  	/* for pin sensing */ -	unsigned int sense_updated: 1;  	unsigned int jack_present: 1; -	unsigned int master_sw: 1; +	unsigned int line_jack_present:1; +	unsigned int master_mute:1;  	unsigned int auto_mic:1; +	unsigned int automute:1;	/* HP automute enabled */ +	unsigned int detect_line:1;	/* Line-out detection enabled */ +	unsigned int automute_lines:1;	/* automute line-out as well */ +	unsigned int automute_hp_lo:1;	/* both HP and LO available */  	/* 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; + +	/* auto-mute control */ +	int automute_mode; +	hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; +  	int init_amp;  	int codec_variant;	/* flag for other variants */ @@ -403,25 +426,29 @@ struct alc_spec {  	int fixup_id;  	const struct alc_fixup *fixup_list;  	const char *fixup_name; + +	/* multi-io */ +	int multi_ios; +	struct alc_multi_io multi_io[4];  };  /*   * configuration template - to be copied to the spec instance   */  struct alc_config_preset { -	struct snd_kcontrol_new *mixers[5]; /* should be identical size +	const struct snd_kcontrol_new *mixers[5]; /* should be identical size  					     * with spec  					     */ -	struct snd_kcontrol_new *cap_mixer; /* capture mixer */ +	const struct snd_kcontrol_new *cap_mixer; /* capture mixer */  	const struct hda_verb *init_verbs[5];  	unsigned int num_dacs; -	hda_nid_t *dac_nids; +	const hda_nid_t *dac_nids;  	hda_nid_t dig_out_nid;		/* optional */  	hda_nid_t hp_nid;		/* optional */ -	hda_nid_t *slave_dig_outs; +	const hda_nid_t *slave_dig_outs;  	unsigned int num_adc_nids; -	hda_nid_t *adc_nids; -	hda_nid_t *capsrc_nids; +	const hda_nid_t *adc_nids; +	const hda_nid_t *capsrc_nids;  	hda_nid_t dig_in_nid;  	unsigned int num_channel_mode;  	const struct hda_channel_mode *channel_mode; @@ -433,7 +460,7 @@ struct alc_config_preset {  	void (*setup)(struct hda_codec *);  	void (*init_hook)(struct hda_codec *);  #ifdef CONFIG_SND_HDA_POWER_SAVE -	struct hda_amp_list *loopbacks; +	const struct hda_amp_list *loopbacks;  	void (*power_hook)(struct hda_codec *codec);  #endif  }; @@ -560,11 +587,11 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,   * NIDs 0x0f and 0x10 have been observed to have this behaviour as of   * March 2006.   */ -static char *alc_pin_mode_names[] = { +static const char * const alc_pin_mode_names[] = {  	"Mic 50pc bias", "Mic 80pc bias",  	"Line in", "Line out", "Headphone out",  }; -static unsigned char alc_pin_mode_values[] = { +static const unsigned char alc_pin_mode_values[] = {  	PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,  };  /* The control can present all 5 options, or it can limit the options based @@ -583,7 +610,7 @@ static unsigned char alc_pin_mode_values[] = {  /* Info about the pin modes supported by the different pin direction modes.   * For each direction the minimum and maximum values are given.   */ -static signed char alc_pin_mode_dir_info[5][2] = { +static const signed char alc_pin_mode_dir_info[5][2] = {  	{ 0, 2 },    /* ALC_PIN_DIR_IN */  	{ 3, 4 },    /* ALC_PIN_DIR_OUT */  	{ 0, 4 },    /* ALC_PIN_DIR_INOUT */ @@ -900,7 +927,7 @@ static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)  /*   */ -static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) +static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)  {  	if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))  		return; @@ -971,21 +998,21 @@ static void setup_preset(struct hda_codec *codec,  }  /* Enable GPIO mask and set output */ -static struct hda_verb alc_gpio1_init_verbs[] = { +static const struct hda_verb alc_gpio1_init_verbs[] = {  	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},  	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},  	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},  	{ }  }; -static struct hda_verb alc_gpio2_init_verbs[] = { +static const struct hda_verb alc_gpio2_init_verbs[] = {  	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},  	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},  	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},  	{ }  }; -static struct hda_verb alc_gpio3_init_verbs[] = { +static const struct hda_verb alc_gpio3_init_verbs[] = {  	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},  	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},  	{0x01, AC_VERB_SET_GPIO_DATA, 0x03}, @@ -1031,6 +1058,7 @@ static int alc_init_jacks(struct hda_codec *codec)  	int err;  	unsigned int hp_nid = spec->autocfg.hp_pins[0];  	unsigned int mic_nid = spec->ext_mic.pin; +	unsigned int dock_nid = spec->dock_mic.pin;  	if (hp_nid) {  		err = snd_hda_input_jack_add(codec, hp_nid, @@ -1047,46 +1075,116 @@ static int alc_init_jacks(struct hda_codec *codec)  			return err;  		snd_hda_input_jack_report(codec, mic_nid);  	} +	if (dock_nid) { +		err = snd_hda_input_jack_add(codec, dock_nid, +					     SND_JACK_MICROPHONE, NULL); +		if (err < 0) +			return err; +		snd_hda_input_jack_report(codec, dock_nid); +	}  #endif /* CONFIG_SND_HDA_INPUT_JACK */  	return 0;  } -static void alc_automute_speaker(struct hda_codec *codec, int pinctl) +static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)  { -	struct alc_spec *spec = codec->spec; -	unsigned int mute; -	hda_nid_t nid; -	int i; +	int i, present = 0; -	spec->jack_present = 0; -	for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { -		nid = spec->autocfg.hp_pins[i]; +	for (i = 0; i < num_pins; i++) { +		hda_nid_t nid = pins[i];  		if (!nid)  			break;  		snd_hda_input_jack_report(codec, nid); -		spec->jack_present |= snd_hda_jack_detect(codec, nid); +		present |= snd_hda_jack_detect(codec, nid);  	} +	return present; +} -	mute = spec->jack_present ? HDA_AMP_MUTE : 0; -	/* Toggle internal speakers muting */ -	for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { -		nid = spec->autocfg.speaker_pins[i]; +static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, +			bool mute, bool hp_out) +{ +	struct alc_spec *spec = codec->spec; +	unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; +	unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); +	int i; + +	for (i = 0; i < num_pins; i++) { +		hda_nid_t nid = pins[i];  		if (!nid)  			break; -		if (pinctl) { +		switch (spec->automute_mode) { +		case ALC_AUTOMUTE_PIN:  			snd_hda_codec_write(codec, nid, 0, -				    AC_VERB_SET_PIN_WIDGET_CONTROL, -				    spec->jack_present ? 0 : PIN_OUT); -		} else { +					    AC_VERB_SET_PIN_WIDGET_CONTROL, +					    pin_bits); +			break; +		case ALC_AUTOMUTE_AMP:  			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, mute); +						 HDA_AMP_MUTE, mute_bits); +			break; +		case ALC_AUTOMUTE_MIXER: +			nid = spec->automute_mixer_nid[i]; +			if (!nid) +				break; +			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, +						 HDA_AMP_MUTE, mute_bits); +			snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, +						 HDA_AMP_MUTE, mute_bits); +			break;  		}  	}  } -static void alc_automute_pin(struct hda_codec *codec) +/* Toggle internal speakers muting */ +static void update_speakers(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	int on; + +	if (!spec->automute) +		on = 0; +	else +		on = spec->jack_present | spec->line_jack_present; +	on |= spec->master_mute; +	do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), +		    spec->autocfg.speaker_pins, on, false); + +	/* toggle line-out mutes if needed, too */ +	/* if LO is a copy of either HP or Speaker, don't need to handle it */ +	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || +	    spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) +		return; +	if (!spec->automute_lines || !spec->automute) +		on = 0; +	else +		on = spec->jack_present; +	on |= spec->master_mute; +	do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), +		    spec->autocfg.line_out_pins, on, false); +} + +static void alc_hp_automute(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; + +	if (!spec->automute) +		return; +	spec->jack_present = +		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), +			     spec->autocfg.hp_pins); +	update_speakers(codec); +} + +static void alc_line_automute(struct hda_codec *codec)  { -	alc_automute_speaker(codec, 1); +	struct alc_spec *spec = codec->spec; + +	if (!spec->automute || !spec->detect_line) +		return; +	spec->line_jack_present = +		detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), +			     spec->autocfg.line_out_pins); +	update_speakers(codec);  }  static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, @@ -1128,7 +1226,7 @@ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)  static void alc_mic_automute(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	struct alc_mic_route *dead, *alive; +	struct alc_mic_route *dead1, *dead2, *alive;  	unsigned int present, type;  	hda_nid_t cap_nid; @@ -1146,13 +1244,24 @@ static void alc_mic_automute(struct hda_codec *codec)  	cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; +	alive = &spec->int_mic; +	dead1 = &spec->ext_mic; +	dead2 = &spec->dock_mic; +  	present = snd_hda_jack_detect(codec, spec->ext_mic.pin);  	if (present) {  		alive = &spec->ext_mic; -		dead = &spec->int_mic; -	} else { -		alive = &spec->int_mic; -		dead = &spec->ext_mic; +		dead1 = &spec->int_mic; +		dead2 = &spec->dock_mic; +	} +	if (!present && spec->dock_mic.pin > 0) { +		present = snd_hda_jack_detect(codec, spec->dock_mic.pin); +		if (present) { +			alive = &spec->dock_mic; +			dead1 = &spec->int_mic; +			dead2 = &spec->ext_mic; +		} +		snd_hda_input_jack_report(codec, spec->dock_mic.pin);  	}  	type = get_wcaps_type(get_wcaps(codec, cap_nid)); @@ -1161,9 +1270,14 @@ static void alc_mic_automute(struct hda_codec *codec)  		snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,  					 alive->mux_idx,  					 HDA_AMP_MUTE, 0); -		snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, -					 dead->mux_idx, -					 HDA_AMP_MUTE, HDA_AMP_MUTE); +		if (dead1->pin > 0) +			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, +						 dead1->mux_idx, +						 HDA_AMP_MUTE, HDA_AMP_MUTE); +		if (dead2->pin > 0) +			snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, +						 dead2->mux_idx, +						 HDA_AMP_MUTE, HDA_AMP_MUTE);  	} else {  		/* MUX style (e.g. ALC880) */  		snd_hda_codec_write_cache(codec, cap_nid, 0, @@ -1184,7 +1298,10 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)  		res >>= 26;  	switch (res) {  	case ALC880_HP_EVENT: -		alc_automute_pin(codec); +		alc_hp_automute(codec); +		break; +	case ALC880_FRONT_EVENT: +		alc_line_automute(codec);  		break;  	case ALC880_MIC_EVENT:  		alc_mic_automute(codec); @@ -1194,7 +1311,8 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)  static void alc_inithook(struct hda_codec *codec)  { -	alc_automute_pin(codec); +	alc_hp_automute(codec); +	alc_line_automute(codec);  	alc_mic_automute(codec);  } @@ -1236,6 +1354,43 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)  				    on ? 2 : 0);  } +/* turn on/off EAPD controls of the codec */ +static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) +{ +	/* We currently only handle front, HP */ +	switch (codec->vendor_id) { +	case 0x10ec0260: +		set_eapd(codec, 0x0f, on); +		set_eapd(codec, 0x10, on); +		break; +	case 0x10ec0262: +	case 0x10ec0267: +	case 0x10ec0268: +	case 0x10ec0269: +	case 0x10ec0270: +	case 0x10ec0272: +	case 0x10ec0660: +	case 0x10ec0662: +	case 0x10ec0663: +	case 0x10ec0665: +	case 0x10ec0862: +	case 0x10ec0889: +	case 0x10ec0892: +		set_eapd(codec, 0x14, on); +		set_eapd(codec, 0x15, on); +		break; +	} +} + +/* generic shutup callback; + * just turning off EPAD and a little pause for avoiding pop-noise + */ +static void alc_eapd_shutup(struct hda_codec *codec) +{ +	alc_auto_setup_eapd(codec, false); +	msleep(200); +} +  static void alc_auto_init_amp(struct hda_codec *codec, int type)  {  	unsigned int tmp; @@ -1251,27 +1406,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)  		snd_hda_sequence_write(codec, alc_gpio3_init_verbs);  		break;  	case ALC_INIT_DEFAULT: -		switch (codec->vendor_id) { -		case 0x10ec0260: -			set_eapd(codec, 0x0f, 1); -			set_eapd(codec, 0x10, 1); -			break; -		case 0x10ec0262: -		case 0x10ec0267: -		case 0x10ec0268: -		case 0x10ec0269: -		case 0x10ec0270: -		case 0x10ec0272: -		case 0x10ec0660: -		case 0x10ec0662: -		case 0x10ec0663: -		case 0x10ec0665: -		case 0x10ec0862: -		case 0x10ec0889: -			set_eapd(codec, 0x14, 1); -			set_eapd(codec, 0x15, 1); -			break; -		} +		alc_auto_setup_eapd(codec, true);  		switch (codec->vendor_id) {  		case 0x10ec0260:  			snd_hda_codec_write(codec, 0x1a, 0, @@ -1315,20 +1450,128 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)  	}  } +static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, +				  struct snd_ctl_elem_info *uinfo) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; +	static const char * const texts2[] = { +		"Disabled", "Enabled" +	}; +	static const char * const texts3[] = { +		"Disabled", "Speaker Only", "Line-Out+Speaker" +	}; +	const char * const *texts; + +	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; +	uinfo->count = 1; +	if (spec->automute_hp_lo) { +		uinfo->value.enumerated.items = 3; +		texts = texts3; +	} else { +		uinfo->value.enumerated.items = 2; +		texts = texts2; +	} +	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) +		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; +	strcpy(uinfo->value.enumerated.name, +	       texts[uinfo->value.enumerated.item]); +	return 0; +} + +static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, +				 struct snd_ctl_elem_value *ucontrol) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; +	unsigned int val; +	if (!spec->automute) +		val = 0; +	else if (!spec->automute_lines) +		val = 1; +	else +		val = 2; +	ucontrol->value.enumerated.item[0] = val; +	return 0; +} + +static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, +				 struct snd_ctl_elem_value *ucontrol) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; + +	switch (ucontrol->value.enumerated.item[0]) { +	case 0: +		if (!spec->automute) +			return 0; +		spec->automute = 0; +		break; +	case 1: +		if (spec->automute && !spec->automute_lines) +			return 0; +		spec->automute = 1; +		spec->automute_lines = 0; +		break; +	case 2: +		if (!spec->automute_hp_lo) +			return -EINVAL; +		if (spec->automute && spec->automute_lines) +			return 0; +		spec->automute = 1; +		spec->automute_lines = 1; +		break; +	default: +		return -EINVAL; +	} +	update_speakers(codec); +	return 1; +} + +static const struct snd_kcontrol_new alc_automute_mode_enum = { +	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, +	.name = "Auto-Mute Mode", +	.info = alc_automute_mode_info, +	.get = alc_automute_mode_get, +	.put = alc_automute_mode_put, +}; + +static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); + +static int alc_add_automute_mode_enum(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	struct snd_kcontrol_new *knew; + +	knew = alc_kcontrol_new(spec); +	if (!knew) +		return -ENOMEM; +	*knew = alc_automute_mode_enum; +	knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL); +	if (!knew->name) +		return -ENOMEM; +	return 0; +} +  static void alc_init_auto_hp(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	struct auto_pin_cfg *cfg = &spec->autocfg; +	int present = 0;  	int i; -	if (!cfg->hp_pins[0]) { -		if (cfg->line_out_type != AUTO_PIN_HP_OUT) -			return; -	} +	if (cfg->hp_pins[0]) +		present++; +	if (cfg->line_out_pins[0]) +		present++; +	if (cfg->speaker_pins[0]) +		present++; +	if (present < 2) /* need two different output types */ +		return; +	if (present == 3) +		spec->automute_hp_lo = 1; /* both HP and LO automute */  	if (!cfg->speaker_pins[0]) { -		if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) -			return;  		memcpy(cfg->speaker_pins, cfg->line_out_pins,  		       sizeof(cfg->speaker_pins));  		cfg->speaker_outs = cfg->line_outs; @@ -1341,28 +1584,49 @@ static void alc_init_auto_hp(struct hda_codec *codec)  	}  	for (i = 0; i < cfg->hp_outs; i++) { +		hda_nid_t nid = cfg->hp_pins[i]; +		if (!is_jack_detectable(codec, nid)) +			continue;  		snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", -			    cfg->hp_pins[i]); -		snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, +			    nid); +		snd_hda_codec_write_cache(codec, nid, 0,  				  AC_VERB_SET_UNSOLICITED_ENABLE,  				  AC_USRSP_EN | ALC880_HP_EVENT); +		spec->automute = 1; +		spec->automute_mode = ALC_AUTOMUTE_PIN; +	} +	if (spec->automute && cfg->line_out_pins[0] && +	    cfg->line_out_pins[0] != cfg->hp_pins[0] && +	    cfg->line_out_pins[0] != cfg->speaker_pins[0]) { +		for (i = 0; i < cfg->line_outs; i++) { +			hda_nid_t nid = cfg->line_out_pins[i]; +			if (!is_jack_detectable(codec, nid)) +				continue; +			snd_printdd("realtek: Enable Line-Out auto-muting " +				    "on NID 0x%x\n", nid); +			snd_hda_codec_write_cache(codec, nid, 0, +					AC_VERB_SET_UNSOLICITED_ENABLE, +					AC_USRSP_EN | ALC880_FRONT_EVENT); +			spec->detect_line = 1; +		} +		spec->automute_lines = spec->detect_line; +	} + +	if (spec->automute) { +		/* create a control for automute mode */ +		alc_add_automute_mode_enum(codec); +		spec->unsol_event = alc_sku_unsol_event;  	} -	spec->unsol_event = alc_sku_unsol_event;  }  static void alc_init_auto_mic(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	struct auto_pin_cfg *cfg = &spec->autocfg; -	hda_nid_t fixed, ext; +	hda_nid_t fixed, ext, dock;  	int i; -	/* there must be only two mic inputs exclusively */ -	for (i = 0; i < cfg->num_inputs; i++) -		if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) -			return; - -	fixed = ext = 0; +	fixed = ext = dock = 0;  	for (i = 0; i < cfg->num_inputs; i++) {  		hda_nid_t nid = cfg->inputs[i].pin;  		unsigned int defcfg; @@ -1371,26 +1635,45 @@ static void alc_init_auto_mic(struct hda_codec *codec)  		case INPUT_PIN_ATTR_INT:  			if (fixed)  				return; /* already occupied */ +			if (cfg->inputs[i].type != AUTO_PIN_MIC) +				return; /* invalid type */  			fixed = nid;  			break;  		case INPUT_PIN_ATTR_UNUSED:  			return; /* invalid entry */ +		case INPUT_PIN_ATTR_DOCK: +			if (dock) +				return; /* already occupied */ +			if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) +				return; /* invalid type */ +			dock = nid; +			break;  		default:  			if (ext)  				return; /* already occupied */ +			if (cfg->inputs[i].type != AUTO_PIN_MIC) +				return; /* invalid type */  			ext = nid;  			break;  		}  	} +	if (!ext && dock) { +		ext = dock; +		dock = 0; +	}  	if (!ext || !fixed)  		return; -	if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) +	if (!is_jack_detectable(codec, ext))  		return; /* no unsol support */ -	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", -		    ext, fixed); +	if (dock && !is_jack_detectable(codec, dock)) +		return; /* no unsol support */ +	snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", +		    ext, fixed, dock);  	spec->ext_mic.pin = ext; +	spec->dock_mic.pin = dock;  	spec->int_mic.pin = fixed;  	spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ +	spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */  	spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */  	spec->auto_mic = 1;  	snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, @@ -1583,9 +1866,6 @@ do_sku:  				return 1;  		spec->autocfg.hp_pins[0] = nid;  	} - -	alc_init_auto_hp(codec); -	alc_init_auto_mic(codec);  	return 1;  } @@ -1598,9 +1878,10 @@ static void alc_ssid_check(struct hda_codec *codec,  		snd_printd("realtek: "  			   "Enable default setup for auto mode as fallback\n");  		spec->init_amp = ALC_INIT_DEFAULT; -		alc_init_auto_hp(codec); -		alc_init_auto_mic(codec);  	} + +	alc_init_auto_hp(codec); +	alc_init_auto_mic(codec);  }  /* @@ -1704,11 +1985,11 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)  				   codec->chip_name, fix->type);  			break;  		} -		if (!fix[id].chained) +		if (!fix->chained)  			break;  		if (++depth > 10)  			break; -		id = fix[id].chain_id; +		id = fix->chain_id;  	}  } @@ -1842,7 +2123,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec)  /*   * 2ch mode   */ -static struct hda_verb alc888_4ST_ch2_intel_init[] = { +static const struct hda_verb alc888_4ST_ch2_intel_init[] = {  /* Mic-in jack as mic in */  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -1857,7 +2138,7 @@ static struct hda_verb alc888_4ST_ch2_intel_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc888_4ST_ch4_intel_init[] = { +static const struct hda_verb alc888_4ST_ch4_intel_init[] = {  /* Mic-in jack as mic in */  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -1872,7 +2153,7 @@ static struct hda_verb alc888_4ST_ch4_intel_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc888_4ST_ch6_intel_init[] = { +static const struct hda_verb alc888_4ST_ch6_intel_init[] = {  /* Mic-in jack as CLFE */  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -1887,7 +2168,7 @@ static struct hda_verb alc888_4ST_ch6_intel_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc888_4ST_ch8_intel_init[] = { +static const struct hda_verb alc888_4ST_ch8_intel_init[] = {  /* Mic-in jack as CLFE */  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -1899,7 +2180,7 @@ static struct hda_verb alc888_4ST_ch8_intel_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { +static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {  	{ 2, alc888_4ST_ch2_intel_init },  	{ 4, alc888_4ST_ch4_intel_init },  	{ 6, alc888_4ST_ch6_intel_init }, @@ -1910,7 +2191,7 @@ static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {   * ALC888 Fujitsu Siemens Amillo xa3530   */ -static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { +static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {  /* Front Mic: set to PIN_IN (empty by default) */  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Connect Internal HP to Front */ @@ -1943,22 +2224,6 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {  	{}  }; -static void alc_automute_amp(struct hda_codec *codec) -{ -	alc_automute_speaker(codec, 0); -} - -static void alc_automute_amp_unsol_event(struct hda_codec *codec, -					 unsigned int res) -{ -	if (codec->vendor_id == 0x10ec0880) -		res >>= 28; -	else -		res >>= 26; -	if (res == ALC880_HP_EVENT) -		alc_automute_amp(codec); -} -  static void alc889_automute_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; @@ -1969,12 +2234,14 @@ static void alc889_automute_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[2] = 0x17;  	spec->autocfg.speaker_pins[3] = 0x19;  	spec->autocfg.speaker_pins[4] = 0x1a; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc889_intel_init_hook(struct hda_codec *codec)  {  	alc889_coef_init(codec); -	alc_automute_amp(codec); +	alc_hp_automute(codec);  }  static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) @@ -1985,13 +2252,15 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[1] = 0x1b; /* hp */  	spec->autocfg.speaker_pins[0] = 0x14; /* speaker */  	spec->autocfg.speaker_pins[1] = 0x15; /* bass */ +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /*   * ALC888 Acer Aspire 4930G model   */ -static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { +static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {  /* Front Mic: set to PIN_IN (empty by default) */  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Unselect Front Mic by default in input mixer 3 */ @@ -2014,7 +2283,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {   * ALC888 Acer Aspire 6530G model   */ -static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { +static const 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)}, @@ -2044,7 +2313,7 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {   *ALC888 Acer Aspire 7730G model   */ -static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { +static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {  /* 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) */ @@ -2074,7 +2343,7 @@ static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {   * ALC889 Acer Aspire 8930G model   */ -static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { +static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {  /* Front Mic: set to PIN_IN (empty by default) */  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Unselect Front Mic by default in input mixer 3 */ @@ -2120,7 +2389,7 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {  	{ }  }; -static struct hda_input_mux alc888_2_capture_sources[2] = { +static const struct hda_input_mux alc888_2_capture_sources[2] = {  	/* Front mic only available on one ADC */  	{  		.num_items = 4, @@ -2141,7 +2410,7 @@ static struct hda_input_mux alc888_2_capture_sources[2] = {  	}  }; -static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { +static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {  	/* Interal mic only available on one ADC */  	{  		.num_items = 5, @@ -2164,7 +2433,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {  	}  }; -static struct hda_input_mux alc889_capture_sources[3] = { +static const struct hda_input_mux alc889_capture_sources[3] = {  	/* Digital mic only available on first "ADC" */  	{  		.num_items = 5, @@ -2196,7 +2465,7 @@ static struct hda_input_mux alc889_capture_sources[3] = {  	}  }; -static struct snd_kcontrol_new alc888_base_mixer[] = { +static const struct snd_kcontrol_new alc888_base_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2218,7 +2487,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { +static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2240,7 +2509,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { +static const 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),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2267,6 +2536,8 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x16;  	spec->autocfg.speaker_pins[2] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) @@ -2277,6 +2548,8 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x16;  	spec->autocfg.speaker_pins[2] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) @@ -2287,6 +2560,8 @@ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x16;  	spec->autocfg.speaker_pins[2] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) @@ -2297,6 +2572,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x16;  	spec->autocfg.speaker_pins[2] = 0x1b; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* @@ -2307,12 +2584,12 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)   *                 F-Mic = 0x1b, HP = 0x19   */ -static hda_nid_t alc880_dac_nids[4] = { +static const hda_nid_t alc880_dac_nids[4] = {  	/* front, rear, clfe, rear_surr */  	0x02, 0x05, 0x04, 0x03  }; -static hda_nid_t alc880_adc_nids[3] = { +static const hda_nid_t alc880_adc_nids[3] = {  	/* ADC0-2 */  	0x07, 0x08, 0x09,  }; @@ -2321,7 +2598,7 @@ static hda_nid_t alc880_adc_nids[3] = {   * but it shows zero connection in the real implementation on some devices.   * Note: this is a 915GAV bug, fixed on 915GLV   */ -static hda_nid_t alc880_adc_nids_alt[2] = { +static const hda_nid_t alc880_adc_nids_alt[2] = {  	/* ADC1-2 */  	0x08, 0x09,  }; @@ -2329,7 +2606,7 @@ static hda_nid_t alc880_adc_nids_alt[2] = {  #define ALC880_DIGOUT_NID	0x06  #define ALC880_DIGIN_NID	0x0a -static struct hda_input_mux alc880_capture_source = { +static const struct hda_input_mux alc880_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -2341,7 +2618,7 @@ static struct hda_input_mux alc880_capture_source = {  /* channel source setting (2/6 channel selection for 3-stack) */  /* 2ch mode */ -static struct hda_verb alc880_threestack_ch2_init[] = { +static const struct hda_verb alc880_threestack_ch2_init[] = {  	/* set line-in to input, mute it */  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },  	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -2352,7 +2629,7 @@ static struct hda_verb alc880_threestack_ch2_init[] = {  };  /* 6ch mode */ -static struct hda_verb alc880_threestack_ch6_init[] = { +static const struct hda_verb alc880_threestack_ch6_init[] = {  	/* set line-in to output, unmute it */  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -2362,12 +2639,12 @@ static struct hda_verb alc880_threestack_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc880_threestack_modes[2] = { +static const struct hda_channel_mode alc880_threestack_modes[2] = {  	{ 2, alc880_threestack_ch2_init },  	{ 6, alc880_threestack_ch6_init },  }; -static struct snd_kcontrol_new alc880_three_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), @@ -2512,14 +2789,14 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,  	}  #define DEFINE_CAPMIX(num) \ -static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ +static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \  	_DEFINE_CAPMIX(num),				      \  	_DEFINE_CAPSRC(num),				      \  	{ } /* end */					      \  }  #define DEFINE_CAPMIX_NOSRC(num) \ -static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ +static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \  	_DEFINE_CAPMIX(num),					    \  	{ } /* end */						    \  } @@ -2542,7 +2819,7 @@ DEFINE_CAPMIX_NOSRC(3);   */  /* additional mixers to alc880_three_stack_mixer */ -static struct snd_kcontrol_new alc880_five_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {  	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),  	{ } /* end */ @@ -2550,7 +2827,7 @@ static struct snd_kcontrol_new alc880_five_stack_mixer[] = {  /* channel source setting (6/8 channel selection for 5-stack) */  /* 6ch mode */ -static struct hda_verb alc880_fivestack_ch6_init[] = { +static const struct hda_verb alc880_fivestack_ch6_init[] = {  	/* set line-in to input, mute it */  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },  	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -2558,14 +2835,14 @@ static struct hda_verb alc880_fivestack_ch6_init[] = {  };  /* 8ch mode */ -static struct hda_verb alc880_fivestack_ch8_init[] = { +static const struct hda_verb alc880_fivestack_ch8_init[] = {  	/* set line-in to output, unmute it */  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ } /* end */  }; -static struct hda_channel_mode alc880_fivestack_modes[2] = { +static const struct hda_channel_mode alc880_fivestack_modes[2] = {  	{ 6, alc880_fivestack_ch6_init },  	{ 8, alc880_fivestack_ch8_init },  }; @@ -2580,12 +2857,12 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = {   *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b   */ -static hda_nid_t alc880_6st_dac_nids[4] = { +static const hda_nid_t alc880_6st_dac_nids[4] = {  	/* front, rear, clfe, rear_surr */  	0x02, 0x03, 0x04, 0x05  }; -static struct hda_input_mux alc880_6stack_capture_source = { +static const struct hda_input_mux alc880_6stack_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -2596,11 +2873,11 @@ static struct hda_input_mux alc880_6stack_capture_source = {  };  /* fixed 8-channels */ -static struct hda_channel_mode alc880_sixstack_modes[1] = { +static const struct hda_channel_mode alc880_sixstack_modes[1] = {  	{ 8, NULL },  }; -static struct snd_kcontrol_new alc880_six_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2655,18 +2932,18 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = {   * haven't setup any initialization verbs for these yet...   */ -static hda_nid_t alc880_w810_dac_nids[3] = { +static const hda_nid_t alc880_w810_dac_nids[3] = {  	/* front, rear/surround, clfe */  	0x02, 0x03, 0x04  };  /* fixed 6 channels */ -static struct hda_channel_mode alc880_w810_modes[1] = { +static const struct hda_channel_mode alc880_w810_modes[1] = {  	{ 6, NULL }  };  /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ -static struct snd_kcontrol_new alc880_w810_base_mixer[] = { +static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2688,17 +2965,17 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = {   *                 Line = 0x1a   */ -static hda_nid_t alc880_z71v_dac_nids[1] = { +static const hda_nid_t alc880_z71v_dac_nids[1] = {  	0x02  };  #define ALC880_Z71V_HP_DAC	0x03  /* fixed 2 channels */ -static struct hda_channel_mode alc880_2_jack_modes[1] = { +static const struct hda_channel_mode alc880_2_jack_modes[1] = {  	{ 2, NULL }  }; -static struct snd_kcontrol_new alc880_z71v_mixer[] = { +static const struct snd_kcontrol_new alc880_z71v_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2718,12 +2995,12 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = {   * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18   */ -static hda_nid_t alc880_f1734_dac_nids[1] = { +static const hda_nid_t alc880_f1734_dac_nids[1] = {  	0x03  };  #define ALC880_F1734_HP_DAC	0x02 -static struct snd_kcontrol_new alc880_f1734_mixer[] = { +static const struct snd_kcontrol_new alc880_f1734_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2735,7 +3012,7 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = {  	{ } /* end */  }; -static struct hda_input_mux alc880_f1734_capture_source = { +static const struct hda_input_mux alc880_f1734_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x1 }, @@ -2755,7 +3032,7 @@ static struct hda_input_mux alc880_f1734_capture_source = {  #define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */  #define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */ -static struct snd_kcontrol_new alc880_asus_mixer[] = { +static const struct snd_kcontrol_new alc880_asus_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2789,14 +3066,14 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = {   */  /* additional mixers to alc880_asus_mixer */ -static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { +static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {  	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),  	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),  	{ } /* end */  };  /* TCL S700 */ -static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { +static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -2810,7 +3087,7 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {  };  /* Uniwill */ -static struct snd_kcontrol_new alc880_uniwill_mixer[] = { +static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2837,7 +3114,7 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2851,7 +3128,7 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { +static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2878,7 +3155,6 @@ static const char * const alc_slave_vols[] = {  	"Speaker Playback Volume",  	"Mono Playback Volume",  	"Line-Out Playback Volume", -	"PCM Playback Volume",  	NULL,  }; @@ -2893,7 +3169,6 @@ static const char * const alc_slave_sws[] = {  	"Mono Playback Switch",  	"IEC958 Playback Switch",  	"Line-Out Playback Switch", -	"PCM Playback Switch",  	NULL,  }; @@ -2914,7 +3189,7 @@ static void alc_free_kctls(struct hda_codec *codec);  #ifdef CONFIG_SND_HDA_INPUT_BEEP  /* additional beep mixers; the actual parameters are overwritten at build */ -static struct snd_kcontrol_new alc_beep_mixer[] = { +static const struct snd_kcontrol_new alc_beep_mixer[] = {  	HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),  	HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),  	{ } /* end */ @@ -2925,7 +3200,7 @@ static int alc_build_controls(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	struct snd_kcontrol *kctl = NULL; -	struct snd_kcontrol_new *knew; +	const struct snd_kcontrol_new *knew;  	int i, j, err;  	unsigned int u;  	hda_nid_t nid; @@ -2962,7 +3237,7 @@ static int alc_build_controls(struct hda_codec *codec)  #ifdef CONFIG_SND_HDA_INPUT_BEEP  	/* create beep controls if needed */  	if (spec->beep_amp) { -		struct snd_kcontrol_new *knew; +		const struct snd_kcontrol_new *knew;  		for (knew = alc_beep_mixer; knew->name; knew++) {  			struct snd_kcontrol *kctl;  			kctl = snd_ctl_new1(knew, codec); @@ -3001,7 +3276,7 @@ static int alc_build_controls(struct hda_codec *codec)  		if (!kctl)  			kctl = snd_hda_find_mixer_ctl(codec, "Input Source");  		for (i = 0; kctl && i < kctl->count; i++) { -			hda_nid_t *nids = spec->capsrc_nids; +			const hda_nid_t *nids = spec->capsrc_nids;  			if (!nids)  				nids = spec->adc_nids;  			err = snd_hda_add_nid(codec, kctl, i, nids[i]); @@ -3079,7 +3354,7 @@ static int alc_build_controls(struct hda_codec *codec)  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc880_volume_init_verbs[] = { +static const struct hda_verb alc880_volume_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -3130,7 +3405,7 @@ static struct hda_verb alc880_volume_init_verbs[] = {   * 3-stack pin configuration:   * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b   */ -static struct hda_verb alc880_pin_3stack_init_verbs[] = { +static const struct hda_verb alc880_pin_3stack_init_verbs[] = {  	/*  	 * preset connection lists of input pins  	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround @@ -3168,7 +3443,7 @@ static struct hda_verb alc880_pin_3stack_init_verbs[] = {   * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,   * line-in/side = 0x1a, f-mic = 0x1b   */ -static struct hda_verb alc880_pin_5stack_init_verbs[] = { +static const struct hda_verb alc880_pin_5stack_init_verbs[] = {  	/*  	 * preset connection lists of input pins  	 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround @@ -3212,7 +3487,7 @@ static struct hda_verb alc880_pin_5stack_init_verbs[] = {   * W810 pin configuration:   * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b   */ -static struct hda_verb alc880_pin_w810_init_verbs[] = { +static const struct hda_verb alc880_pin_w810_init_verbs[] = {  	/* hphone/speaker input selector: front DAC */  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, @@ -3233,7 +3508,7 @@ static struct hda_verb alc880_pin_w810_init_verbs[] = {   * Z71V pin configuration:   * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)   */ -static struct hda_verb alc880_pin_z71v_init_verbs[] = { +static const struct hda_verb alc880_pin_z71v_init_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3252,7 +3527,7 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = {   * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,   * f-mic = 0x19, line = 0x1a, HP = 0x1b   */ -static struct hda_verb alc880_pin_6stack_init_verbs[] = { +static const struct hda_verb alc880_pin_6stack_init_verbs[] = {  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -3282,7 +3557,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {   * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,   * line = 0x1a   */ -static struct hda_verb alc880_uniwill_init_verbs[] = { +static const struct hda_verb alc880_uniwill_init_verbs[] = {  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3320,7 +3595,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = {  * Uniwill P53  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,   */ -static struct hda_verb alc880_uniwill_p53_init_verbs[] = { +static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3349,7 +3624,7 @@ static struct hda_verb alc880_uniwill_p53_init_verbs[] = {  	{ }  }; -static struct hda_verb alc880_beep_init_verbs[] = { +static const struct hda_verb alc880_beep_init_verbs[] = {  	{ 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },  	{ }  }; @@ -3372,11 +3647,13 @@ static void alc880_uniwill_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x16; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc880_uniwill_init_hook(struct hda_codec *codec)  { -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	alc88x_simple_mic_automute(codec);  } @@ -3391,7 +3668,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,  		alc88x_simple_mic_automute(codec);  		break;  	default: -		alc_automute_amp_unsol_event(codec, res); +		alc_sku_unsol_event(codec, res);  		break;  	}  } @@ -3402,6 +3679,8 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) @@ -3426,14 +3705,14 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,  	if ((res >> 28) == ALC880_DCVOL_EVENT)  		alc880_uniwill_p53_dcvol_automute(codec);  	else -		alc_automute_amp_unsol_event(codec, res); +		alc_sku_unsol_event(codec, res);  }  /*   * F1734 pin configuration:   * HP = 0x14, speaker-out = 0x15, mic = 0x18   */ -static struct hda_verb alc880_pin_f1734_init_verbs[] = { +static const struct hda_verb alc880_pin_f1734_init_verbs[] = {  	{0x07, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},  	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -3465,7 +3744,7 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = {   * ASUS pin configuration:   * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a   */ -static struct hda_verb alc880_pin_asus_init_verbs[] = { +static const struct hda_verb alc880_pin_asus_init_verbs[] = {  	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02},  	{0x11, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, @@ -3499,7 +3778,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = {  #define alc880_gpio3_init_verbs	alc_gpio3_init_verbs  /* Clevo m520g init */ -static struct hda_verb alc880_pin_clevo_init_verbs[] = { +static const struct hda_verb alc880_pin_clevo_init_verbs[] = {  	/* headphone output */  	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},  	/* line-out */ @@ -3527,7 +3806,7 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = {  	{ }  }; -static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { +static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {  	/* change to EAPD mode */  	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},  	{0x20, AC_VERB_SET_PROC_COEF,  0x3060}, @@ -3565,12 +3844,12 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {   */  /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ -static hda_nid_t alc880_lg_dac_nids[3] = { +static const hda_nid_t alc880_lg_dac_nids[3] = {  	0x05, 0x02, 0x03  };  /* seems analog CD is not working */ -static struct hda_input_mux alc880_lg_capture_source = { +static const struct hda_input_mux alc880_lg_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x1 }, @@ -3580,34 +3859,34 @@ static struct hda_input_mux alc880_lg_capture_source = {  };  /* 2,4,6 channel modes */ -static struct hda_verb alc880_lg_ch2_init[] = { +static const struct hda_verb alc880_lg_ch2_init[] = {  	/* set line-in and mic-in to input */  	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ }  }; -static struct hda_verb alc880_lg_ch4_init[] = { +static const struct hda_verb alc880_lg_ch4_init[] = {  	/* set line-in to out and mic-in to input */  	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ }  }; -static struct hda_verb alc880_lg_ch6_init[] = { +static const struct hda_verb alc880_lg_ch6_init[] = {  	/* set line-in and mic-in to output */  	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },  	{ }  }; -static struct hda_channel_mode alc880_lg_ch_modes[3] = { +static const struct hda_channel_mode alc880_lg_ch_modes[3] = {  	{ 2, alc880_lg_ch2_init },  	{ 4, alc880_lg_ch4_init },  	{ 6, alc880_lg_ch6_init },  }; -static struct snd_kcontrol_new alc880_lg_mixer[] = { +static const struct snd_kcontrol_new alc880_lg_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -3632,7 +3911,7 @@ static struct snd_kcontrol_new alc880_lg_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc880_lg_init_verbs[] = { +static const struct hda_verb alc880_lg_init_verbs[] = {  	/* set capture source to mic-in */  	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -3670,6 +3949,8 @@ static void alc880_lg_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* @@ -3684,7 +3965,7 @@ static void alc880_lg_setup(struct hda_codec *codec)   *   SPDIF-Out: 0x1e   */ -static struct hda_input_mux alc880_lg_lw_capture_source = { +static const struct hda_input_mux alc880_lg_lw_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -3695,7 +3976,7 @@ static struct hda_input_mux alc880_lg_lw_capture_source = {  #define alc880_lg_lw_modes alc880_threestack_modes -static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { +static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), @@ -3720,7 +4001,7 @@ static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc880_lg_lw_init_verbs[] = { +static const struct hda_verb alc880_lg_lw_init_verbs[] = {  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */  	{0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */  	{0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ @@ -3754,9 +4035,11 @@ static void alc880_lg_lw_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { +static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -3766,7 +4049,7 @@ static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {  	{ } /* end */  }; -static struct hda_input_mux alc880_medion_rim_capture_source = { +static const struct hda_input_mux alc880_medion_rim_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x0 }, @@ -3774,7 +4057,7 @@ static struct hda_input_mux alc880_medion_rim_capture_source = {  	},  }; -static struct hda_verb alc880_medion_rim_init_verbs[] = { +static const struct hda_verb alc880_medion_rim_init_verbs[] = {  	{0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3801,7 +4084,7 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = {  static void alc880_medion_rim_automute(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	/* toggle EAPD */  	if (spec->jack_present)  		snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); @@ -3825,10 +4108,12 @@ static void alc880_medion_rim_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x1b; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc880_loopbacks[] = { +static const struct hda_amp_list alc880_loopbacks[] = {  	{ 0x0b, HDA_INPUT, 0 },  	{ 0x0b, HDA_INPUT, 1 },  	{ 0x0b, HDA_INPUT, 2 }, @@ -3837,7 +4122,7 @@ static struct hda_amp_list alc880_loopbacks[] = {  	{ } /* end */  }; -static struct hda_amp_list alc880_lg_loopbacks[] = { +static const struct hda_amp_list alc880_lg_loopbacks[] = {  	{ 0x0b, HDA_INPUT, 1 },  	{ 0x0b, HDA_INPUT, 6 },  	{ 0x0b, HDA_INPUT, 7 }, @@ -4009,7 +4294,7 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,  	return 0;  } -static struct hda_pcm_stream dualmic_pcm_analog_capture = { +static const struct hda_pcm_stream dualmic_pcm_analog_capture = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2, @@ -4022,7 +4307,7 @@ static struct hda_pcm_stream dualmic_pcm_analog_capture = {  /*   */ -static struct hda_pcm_stream alc880_pcm_analog_playback = { +static const struct hda_pcm_stream alc880_pcm_analog_playback = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 8, @@ -4034,21 +4319,21 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = {  	},  }; -static struct hda_pcm_stream alc880_pcm_analog_capture = { +static const struct hda_pcm_stream alc880_pcm_analog_capture = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2,  	/* NID is set in alc_build_pcms */  }; -static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { +static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2,  	/* NID is set in alc_build_pcms */  }; -static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { +static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {  	.substreams = 2, /* can be overridden */  	.channels_min = 2,  	.channels_max = 2, @@ -4059,7 +4344,7 @@ static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {  	},  }; -static struct hda_pcm_stream alc880_pcm_digital_playback = { +static const struct hda_pcm_stream alc880_pcm_digital_playback = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2, @@ -4072,7 +4357,7 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = {  	},  }; -static struct hda_pcm_stream alc880_pcm_digital_capture = { +static const struct hda_pcm_stream alc880_pcm_digital_capture = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2, @@ -4080,7 +4365,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = {  };  /* Used by alc_build_pcms to flag that a PCM has no playback stream */ -static struct hda_pcm_stream alc_pcm_null_stream = { +static const struct hda_pcm_stream alc_pcm_null_stream = {  	.substreams = 0,  	.channels_min = 0,  	.channels_max = 0, @@ -4174,7 +4459,7 @@ static int alc_build_pcms(struct hda_codec *codec)  				alc_pcm_null_stream;  			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;  		} -		if (spec->num_adc_nids > 1) { +		if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {  			info->stream[SNDRV_PCM_STREAM_CAPTURE] =  				*spec->stream_analog_alt_capture;  			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = @@ -4193,6 +4478,10 @@ static int alc_build_pcms(struct hda_codec *codec)  static inline void alc_shutup(struct hda_codec *codec)  { +	struct alc_spec *spec = codec->spec; + +	if (spec && spec->shutup) +		spec->shutup(codec);  	snd_hda_shutup_pins(codec);  } @@ -4226,28 +4515,7 @@ static void alc_free(struct hda_codec *codec)  #ifdef CONFIG_SND_HDA_POWER_SAVE  static void alc_power_eapd(struct hda_codec *codec)  { -	/* We currently only handle front, HP */ -	switch (codec->vendor_id) { -	case 0x10ec0260: -		set_eapd(codec, 0x0f, 0); -		set_eapd(codec, 0x10, 0); -		break; -	case 0x10ec0262: -	case 0x10ec0267: -	case 0x10ec0268: -	case 0x10ec0269: -	case 0x10ec0270: -	case 0x10ec0272: -	case 0x10ec0660: -	case 0x10ec0662: -	case 0x10ec0663: -	case 0x10ec0665: -	case 0x10ec0862: -	case 0x10ec0889: -		set_eapd(codec, 0x14, 0); -		set_eapd(codec, 0x15, 0); -		break; -	} +	alc_auto_setup_eapd(codec, false);  }  static int alc_suspend(struct hda_codec *codec, pm_message_t state) @@ -4263,6 +4531,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)  #ifdef SND_HDA_NEEDS_RESUME  static int alc_resume(struct hda_codec *codec)  { +	msleep(150); /* to avoid pop noise */  	codec->patch_ops.init(codec);  	snd_hda_codec_resume_amp(codec);  	snd_hda_codec_resume_cache(codec); @@ -4273,7 +4542,7 @@ static int alc_resume(struct hda_codec *codec)  /*   */ -static struct hda_codec_ops alc_patch_ops = { +static const struct hda_codec_ops alc_patch_ops = {  	.build_controls = alc_build_controls,  	.build_pcms = alc_build_pcms,  	.init = alc_init, @@ -4308,11 +4577,11 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)   * enum controls.   */  #ifdef CONFIG_SND_DEBUG -static hda_nid_t alc880_test_dac_nids[4] = { +static const hda_nid_t alc880_test_dac_nids[4] = {  	0x02, 0x03, 0x04, 0x05  }; -static struct hda_input_mux alc880_test_capture_source = { +static const struct hda_input_mux alc880_test_capture_source = {  	.num_items = 7,  	.items = {  		{ "In-1", 0x0 }, @@ -4325,7 +4594,7 @@ static struct hda_input_mux alc880_test_capture_source = {  	},  }; -static struct hda_channel_mode alc880_test_modes[4] = { +static const struct hda_channel_mode alc880_test_modes[4] = {  	{ 2, NULL },  	{ 4, NULL },  	{ 6, NULL }, @@ -4335,7 +4604,7 @@ static struct hda_channel_mode alc880_test_modes[4] = {  static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,  				 struct snd_ctl_elem_info *uinfo)  { -	static char *texts[] = { +	static const char * const texts[] = {  		"N/A", "Line Out", "HP Out",  		"In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"  	}; @@ -4380,7 +4649,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,  {  	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);  	hda_nid_t nid = (hda_nid_t)kcontrol->private_value; -	static unsigned int ctls[] = { +	static const unsigned int ctls[] = {  		0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,  		AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,  		AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, @@ -4410,7 +4679,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,  static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,  				 struct snd_ctl_elem_info *uinfo)  { -	static char *texts[] = { +	static const char * const texts[] = {  		"Front", "Surround", "CLFE", "Side"  	};  	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -4471,7 +4740,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,  			.private_value = nid	       \  			} -static struct snd_kcontrol_new alc880_test_mixer[] = { +static const struct snd_kcontrol_new alc880_test_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -4512,7 +4781,7 @@ static struct snd_kcontrol_new alc880_test_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc880_test_init_verbs[] = { +static const struct hda_verb alc880_test_init_verbs[] = {  	/* Unmute inputs of 0x0c - 0x0f */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -4596,7 +4865,7 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = {  	[ALC880_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc880_cfg_tbl[] = { +static const struct snd_pci_quirk alc880_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),  	SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),  	SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), @@ -4676,7 +4945,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {  /*   * ALC880 codec presets   */ -static struct alc_config_preset alc880_presets[] = { +static const struct alc_config_preset alc880_presets[] = {  	[ALC880_3ST] = {  		.mixers = { alc880_three_stack_mixer },  		.init_verbs = { alc880_volume_init_verbs, @@ -4794,7 +5063,7 @@ static struct alc_config_preset alc880_presets[] = {  		.input_mux = &alc880_f1734_capture_source,  		.unsol_event = alc880_uniwill_p53_unsol_event,  		.setup = alc880_uniwill_p53_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC880_ASUS] = {  		.mixers = { alc880_asus_mixer }, @@ -4885,7 +5154,7 @@ static struct alc_config_preset alc880_presets[] = {  		.input_mux = &alc880_capture_source,  		.unsol_event = alc880_uniwill_p53_unsol_event,  		.setup = alc880_uniwill_p53_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC880_FUJITSU] = {  		.mixers = { alc880_fujitsu_mixer }, @@ -4900,7 +5169,7 @@ static struct alc_config_preset alc880_presets[] = {  		.input_mux = &alc880_capture_source,  		.unsol_event = alc880_uniwill_p53_unsol_event,  		.setup = alc880_uniwill_p53_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC880_CLEVO] = {  		.mixers = { alc880_three_stack_mixer }, @@ -4925,9 +5194,9 @@ static struct alc_config_preset alc880_presets[] = {  		.channel_mode = alc880_lg_ch_modes,  		.need_dac_fix = 1,  		.input_mux = &alc880_lg_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc880_lg_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  #ifdef CONFIG_SND_HDA_POWER_SAVE  		.loopbacks = alc880_lg_loopbacks,  #endif @@ -4942,9 +5211,9 @@ static struct alc_config_preset alc880_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),  		.channel_mode = alc880_lg_lw_modes,  		.input_mux = &alc880_lg_lw_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc880_lg_lw_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC880_MEDION_RIM] = {  		.mixers = { alc880_medion_rim_mixer }, @@ -4984,20 +5253,25 @@ enum {  	ALC_CTL_WIDGET_MUTE,  	ALC_CTL_BIND_MUTE,  }; -static struct snd_kcontrol_new alc880_control_templates[] = { +static const struct snd_kcontrol_new alc880_control_templates[] = {  	HDA_CODEC_VOLUME(NULL, 0, 0, 0),  	HDA_CODEC_MUTE(NULL, 0, 0, 0),  	HDA_BIND_MUTE(NULL, 0, 0, 0),  }; +static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec) +{ +	snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); +	return snd_array_new(&spec->kctls); +} +  /* add dynamic controls */  static int add_control(struct alc_spec *spec, int type, const char *name,  		       int cidx, unsigned long val)  {  	struct snd_kcontrol_new *knew; -	snd_array_init(&spec->kctls, sizeof(*knew), 32); -	knew = snd_array_new(&spec->kctls); +	knew = alc_kcontrol_new(spec);  	if (!knew)  		return -ENOMEM;  	*knew = alc880_control_templates[type]; @@ -5055,7 +5329,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,  		nid = cfg->line_out_pins[i];  		if (alc880_is_fixed_pin(nid)) {  			int idx = alc880_fixed_pin_idx(nid); -			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); +			spec->private_dac_nids[i] = alc880_idx_to_dac(idx);  			assigned[idx] = 1;  		}  	} @@ -5067,7 +5341,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,  		/* search for an empty channel */  		for (j = 0; j < cfg->line_outs; j++) {  			if (!assigned[j]) { -				spec->multiout.dac_nids[i] = +				spec->private_dac_nids[i] =  					alc880_idx_to_dac(j);  				assigned[j] = 1;  				break; @@ -5078,10 +5352,13 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,  	return 0;  } -static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, +static const char *alc_get_line_out_pfx(struct alc_spec *spec,  					bool can_be_master)  { -	if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) +	struct auto_pin_cfg *cfg = &spec->autocfg; + +	if (cfg->line_outs == 1 && !spec->multi_ios && +	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)  		return "Master";  	switch (cfg->line_out_type) { @@ -5092,7 +5369,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,  	case AUTO_PIN_HP_OUT:  		return "Headphone";  	default: -		if (cfg->line_outs == 1) +		if (cfg->line_outs == 1 && !spec->multi_ios)  			return "PCM";  		break;  	} @@ -5106,11 +5383,15 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,  	static const char * const chname[4] = {  		"Front", "Surround", NULL /*CLFE*/, "Side"  	}; -	const char *pfx = alc_get_line_out_pfx(cfg, false); +	const char *pfx = alc_get_line_out_pfx(spec, false);  	hda_nid_t nid; -	int i, err; +	int i, err, noutputs; -	for (i = 0; i < cfg->line_outs; i++) { +	noutputs = cfg->line_outs; +	if (spec->multi_ios > 0) +		noutputs += spec->multi_ios; + +	for (i = 0; i < noutputs; i++) {  		if (!spec->multiout.dac_nids[i])  			continue;  		nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); @@ -5376,6 +5657,8 @@ static void alc880_auto_init_input_src(struct hda_codec *codec)  	}  } +static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); +  /* 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 @@ -5384,7 +5667,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc880_ignore); @@ -5396,6 +5679,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec)  	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);  	if (err < 0)  		return err; +	err = alc_auto_add_multi_channel_mode(codec); +	if (err < 0) +		return err;  	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);  	if (err < 0)  		return err; @@ -5467,6 +5753,12 @@ static void fixup_automic_adc(struct hda_codec *codec)  			spec->capsrc_nids += i;  		spec->adc_nids += i;  		spec->num_adc_nids = 1; +		/* optional dock-mic */ +		eidx = get_connection_index(codec, cap, spec->dock_mic.pin); +		if (eidx < 0) +			spec->dock_mic.pin = 0; +		else +			spec->dock_mic.mux_idx = eidx;  		return;  	}  	snd_printd(KERN_INFO "hda_codec: %s: " @@ -5494,6 +5786,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)  	struct alc_spec *spec = codec->spec;  	int i; +	if (!pin) +		return 0;  	for (i = 0; i < spec->num_adc_nids; i++) {  		hda_nid_t cap = spec->capsrc_nids ?  			spec->capsrc_nids[i] : spec->adc_nids[i]; @@ -5534,6 +5828,7 @@ static void fixup_dual_adc_switch(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	init_capsrc_for_pin(codec, spec->ext_mic.pin); +	init_capsrc_for_pin(codec, spec->dock_mic.pin);  	init_capsrc_for_pin(codec, spec->int_mic.pin);  } @@ -5550,7 +5845,7 @@ static void alc_init_special_input_src(struct hda_codec *codec)  static void set_capture_mixer(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	static struct snd_kcontrol_new *caps[2][3] = { +	static const struct snd_kcontrol_new *caps[2][3] = {  		{ alc_capture_mixer_nosrc1,  		  alc_capture_mixer_nosrc2,  		  alc_capture_mixer_nosrc3 }, @@ -5576,7 +5871,7 @@ 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, +static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,  				 int num_nids)  {  	struct alc_spec *spec = codec->spec; @@ -5642,9 +5937,11 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,  #define set_beep_amp(spec, nid, idx, dir) \  	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) -static struct snd_pci_quirk beep_white_list[] = { +static const struct snd_pci_quirk beep_white_list[] = {  	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),  	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), +	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), +	SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),  	SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),  	{}  }; @@ -5752,17 +6049,17 @@ static int patch_alc880(struct hda_codec *codec)   * ALC260 support   */ -static hda_nid_t alc260_dac_nids[1] = { +static const hda_nid_t alc260_dac_nids[1] = {  	/* front */  	0x02,  }; -static hda_nid_t alc260_adc_nids[1] = { +static const hda_nid_t alc260_adc_nids[1] = {  	/* ADC0 */  	0x04,  }; -static hda_nid_t alc260_adc_nids_alt[1] = { +static const hda_nid_t alc260_adc_nids_alt[1] = {  	/* ADC1 */  	0x05,  }; @@ -5770,7 +6067,7 @@ static hda_nid_t alc260_adc_nids_alt[1] = {  /* NIDs used when simultaneous access to both ADCs makes sense.  Note that   * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.   */ -static hda_nid_t alc260_dual_adc_nids[2] = { +static const hda_nid_t alc260_dual_adc_nids[2] = {  	/* ADC0, ADC1 */  	0x04, 0x05  }; @@ -5778,7 +6075,7 @@ static hda_nid_t alc260_dual_adc_nids[2] = {  #define ALC260_DIGOUT_NID	0x03  #define ALC260_DIGIN_NID	0x06 -static struct hda_input_mux alc260_capture_source = { +static const struct hda_input_mux alc260_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -5794,7 +6091,7 @@ static struct hda_input_mux alc260_capture_source = {   * recording the mixer output on the second ADC (ADC0 doesn't have a   * connection to the mixer output).   */ -static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { +static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {  	{  		.num_items = 3,  		.items = { @@ -5818,7 +6115,7 @@ static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {  /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to   * the Fujitsu S702x, but jacks are marked differently.   */ -static struct hda_input_mux alc260_acer_capture_sources[2] = { +static const struct hda_input_mux alc260_acer_capture_sources[2] = {  	{  		.num_items = 4,  		.items = { @@ -5841,7 +6138,7 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = {  };  /* Maxdata Favorit 100XS */ -static struct hda_input_mux alc260_favorit100_capture_sources[2] = { +static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {  	{  		.num_items = 2,  		.items = { @@ -5865,7 +6162,7 @@ static struct hda_input_mux alc260_favorit100_capture_sources[2] = {   * element which allows changing the channel mode, so the verb list is   * never used.   */ -static struct hda_channel_mode alc260_modes[1] = { +static const struct hda_channel_mode alc260_modes[1] = {  	{ 2, NULL },  }; @@ -5879,7 +6176,7 @@ static struct hda_channel_mode alc260_modes[1] = {   * acer: acer + capture   */ -static struct snd_kcontrol_new alc260_base_output_mixer[] = { +static const struct snd_kcontrol_new alc260_base_output_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), @@ -5889,7 +6186,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc260_input_mixer[] = { +static const struct snd_kcontrol_new alc260_input_mixer[] = {  	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),  	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),  	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), @@ -5902,21 +6199,14 @@ static struct snd_kcontrol_new alc260_input_mixer[] = {  };  /* update HP, line and mono out pins according to the master switch */ -static void alc260_hp_master_update(struct hda_codec *codec, -				    hda_nid_t hp, hda_nid_t line, -				    hda_nid_t mono) +static void alc260_hp_master_update(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	unsigned int val = spec->master_sw ? PIN_HP : 0; -	/* change HP and line-out pins */ -	snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    val); -	snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    val); -	/* mono (speaker) depending on the HP jack sense */ -	val = (val && !spec->jack_present) ? PIN_OUT : 0; -	snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    val); + +	/* change HP pins */ +	do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), +		    spec->autocfg.hp_pins, spec->master_mute, true); +	update_speakers(codec);  }  static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, @@ -5924,7 +6214,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,  {  	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);  	struct alc_spec *spec = codec->spec; -	*ucontrol->value.integer.value = spec->master_sw; +	*ucontrol->value.integer.value = !spec->master_mute;  	return 0;  } @@ -5933,20 +6223,16 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,  {  	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);  	struct alc_spec *spec = codec->spec; -	int val = !!*ucontrol->value.integer.value; -	hda_nid_t hp, line, mono; +	int val = !*ucontrol->value.integer.value; -	if (val == spec->master_sw) +	if (val == spec->master_mute)  		return 0; -	spec->master_sw = val; -	hp = (kcontrol->private_value >> 16) & 0xff; -	line = (kcontrol->private_value >> 8) & 0xff; -	mono = kcontrol->private_value & 0xff; -	alc260_hp_master_update(codec, hp, line, mono); +	spec->master_mute = val; +	alc260_hp_master_update(codec);  	return 1;  } -static struct snd_kcontrol_new alc260_hp_output_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -5954,7 +6240,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {  		.info = snd_ctl_boolean_mono_info,  		.get = alc260_hp_master_sw_get,  		.put = alc260_hp_master_sw_put, -		.private_value = (0x0f << 16) | (0x10 << 8) | 0x11  	},  	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), @@ -5966,26 +6251,23 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc260_hp_unsol_verbs[] = { +static const struct hda_verb alc260_hp_unsol_verbs[] = {  	{0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{},  }; -static void alc260_hp_automute(struct hda_codec *codec) +static void alc260_hp_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	spec->jack_present = snd_hda_jack_detect(codec, 0x10); -	alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); -} - -static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc260_hp_automute(codec); +	spec->autocfg.hp_pins[0] = 0x0f; +	spec->autocfg.speaker_pins[0] = 0x10; +	spec->autocfg.speaker_pins[1] = 0x11; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  } -static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", @@ -5993,7 +6275,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {  		.info = snd_ctl_boolean_mono_info,  		.get = alc260_hp_master_sw_get,  		.put = alc260_hp_master_sw_put, -		.private_value = (0x15 << 16) | (0x10 << 8) | 0x11  	},  	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), @@ -6006,7 +6287,18 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { +static void alc260_hp_3013_setup(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; + +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x10; +	spec->autocfg.speaker_pins[1] = 0x11; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN; +} + +static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), @@ -6016,7 +6308,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {  	},  }; -static struct hda_bind_ctls alc260_dc7600_bind_switch = { +static const struct hda_bind_ctls alc260_dc7600_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), @@ -6025,7 +6317,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),  	HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), @@ -6033,49 +6325,27 @@ static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc260_hp_3013_unsol_verbs[] = { +static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{},  }; -static void alc260_hp_3013_automute(struct hda_codec *codec) +static void alc260_hp_3012_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	spec->jack_present = snd_hda_jack_detect(codec, 0x15); -	alc260_hp_master_update(codec, 0x15, 0x10, 0x11); -} - -static void alc260_hp_3013_unsol_event(struct hda_codec *codec, -				       unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc260_hp_3013_automute(codec); -} - -static void alc260_hp_3012_automute(struct hda_codec *codec) -{ -	unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; - -	snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    bits); -	snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    bits); -	snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -			    bits); -} - -static void alc260_hp_3012_unsol_event(struct hda_codec *codec, -				       unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc260_hp_3012_automute(codec); +	spec->autocfg.hp_pins[0] = 0x10; +	spec->autocfg.speaker_pins[0] = 0x0f; +	spec->autocfg.speaker_pins[1] = 0x11; +	spec->autocfg.speaker_pins[2] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  }  /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,   * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.   */ -static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),  	ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), @@ -6112,7 +6382,7 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {   * controls for such models.  On models without a "mono speaker" the control   * won't do anything.   */ -static struct snd_kcontrol_new alc260_acer_mixer[] = { +static const struct snd_kcontrol_new alc260_acer_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),  	ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), @@ -6133,7 +6403,7 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = {  /* Maxdata Favorit 100XS: one output and one input (0x12) jack   */ -static struct snd_kcontrol_new alc260_favorit100_mixer[] = { +static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),  	ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), @@ -6146,7 +6416,7 @@ static struct snd_kcontrol_new alc260_favorit100_mixer[] = {  /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,   * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.   */ -static struct snd_kcontrol_new alc260_will_mixer[] = { +static const struct snd_kcontrol_new alc260_will_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), @@ -6163,7 +6433,7 @@ static struct snd_kcontrol_new alc260_will_mixer[] = {  /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,   * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.   */ -static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { +static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), @@ -6180,7 +6450,7 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {  /*   * initialization verbs   */ -static struct hda_verb alc260_init_verbs[] = { +static const struct hda_verb alc260_init_verbs[] = {  	/* Line In pin widget for input */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	/* CD pin widget for input */ @@ -6244,7 +6514,7 @@ static struct hda_verb alc260_init_verbs[] = {  };  #if 0 /* should be identical with alc260_init_verbs? */ -static struct hda_verb alc260_hp_init_verbs[] = { +static const struct hda_verb alc260_hp_init_verbs[] = {  	/* Headphone and output */  	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},  	/* mono output */ @@ -6294,7 +6564,7 @@ static struct hda_verb alc260_hp_init_verbs[] = {  };  #endif -static struct hda_verb alc260_hp_3013_init_verbs[] = { +static const struct hda_verb alc260_hp_3013_init_verbs[] = {  	/* Line out and output */  	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},  	/* mono output */ @@ -6347,7 +6617,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = {   * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD   * audio = 0x16, internal speaker = 0x10.   */ -static struct hda_verb alc260_fujitsu_init_verbs[] = { +static const struct hda_verb alc260_fujitsu_init_verbs[] = {  	/* Disable all GPIOs */  	{0x01, AC_VERB_SET_GPIO_MASK, 0},  	/* Internal speaker is connected to headphone pin */ @@ -6429,7 +6699,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = {  /* Initialisation sequence for ALC260 as configured in Acer TravelMate and   * similar laptops (adapted from Fujitsu init verbs).   */ -static struct hda_verb alc260_acer_init_verbs[] = { +static const struct hda_verb alc260_acer_init_verbs[] = {  	/* On TravelMate laptops, GPIO 0 enables the internal speaker and  	 * the headphone jack.  Turn this on and rely on the standard mute  	 * methods whenever the user wants to turn these outputs off. @@ -6517,7 +6787,7 @@ static struct hda_verb alc260_acer_init_verbs[] = {  /* Initialisation sequence for Maxdata Favorit 100XS   * (adapted from Acer init verbs).   */ -static struct hda_verb alc260_favorit100_init_verbs[] = { +static const struct hda_verb alc260_favorit100_init_verbs[] = {  	/* GPIO 0 enables the output jack.  	 * Turn this on and rely on the standard mute  	 * methods whenever the user wants to turn these outputs off. @@ -6597,7 +6867,7 @@ static struct hda_verb alc260_favorit100_init_verbs[] = {  	{ }  }; -static struct hda_verb alc260_will_verbs[] = { +static const struct hda_verb alc260_will_verbs[] = {  	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -6607,7 +6877,7 @@ static struct hda_verb alc260_will_verbs[] = {  	{}  }; -static struct hda_verb alc260_replacer_672v_verbs[] = { +static const struct hda_verb alc260_replacer_672v_verbs[] = {  	{0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},  	{0x1a, AC_VERB_SET_COEF_INDEX, 0x07},  	{0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, @@ -6649,7 +6919,7 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,                  alc260_replacer_672v_automute(codec);  } -static struct hda_verb alc260_hp_dc7600_verbs[] = { +static const struct hda_verb alc260_hp_dc7600_verbs[] = {  	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -6667,17 +6937,17 @@ static struct hda_verb alc260_hp_dc7600_verbs[] = {   * configuration.   */  #ifdef CONFIG_SND_DEBUG -static hda_nid_t alc260_test_dac_nids[1] = { +static const hda_nid_t alc260_test_dac_nids[1] = {  	0x02,  }; -static hda_nid_t alc260_test_adc_nids[2] = { +static const hda_nid_t alc260_test_adc_nids[2] = {  	0x04, 0x05,  };  /* For testing the ALC260, each input MUX needs its own definition since   * the signal assignments are different.  This assumes that the first ADC   * is NID 0x04.   */ -static struct hda_input_mux alc260_test_capture_sources[2] = { +static const struct hda_input_mux alc260_test_capture_sources[2] = {  	{  		.num_items = 7,  		.items = { @@ -6704,7 +6974,7 @@ static struct hda_input_mux alc260_test_capture_sources[2] = {  		},          },  }; -static struct snd_kcontrol_new alc260_test_mixer[] = { +static const struct snd_kcontrol_new alc260_test_mixer[] = {  	/* Output driver widgets */  	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), @@ -6768,7 +7038,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc260_test_init_verbs[] = { +static const struct hda_verb alc260_test_init_verbs[] = {  	/* Enable all GPIOs as outputs with an initial value of 0 */  	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},  	{0x01, AC_VERB_SET_GPIO_DATA, 0x00}, @@ -6906,7 +7176,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,  	spec->multiout.num_dacs = 1;  	spec->multiout.dac_nids = spec->private_dac_nids; -	spec->multiout.dac_nids[0] = 0x02; +	spec->private_dac_nids[0] = 0x02;  	nid = cfg->line_out_pins[0];  	if (nid) { @@ -7004,7 +7274,7 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec)  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc260_volume_init_verbs[] = { +static const struct hda_verb alc260_volume_init_verbs[] = {  	/*  	 * Unmute ADC0-1 and set the default input to mic-in  	 */ @@ -7049,7 +7319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc260_ignore[] = { 0x17, 0 }; +	static const hda_nid_t alc260_ignore[] = { 0x17, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc260_ignore); @@ -7094,7 +7364,7 @@ static void alc260_auto_init(struct hda_codec *codec)  }  #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc260_loopbacks[] = { +static const struct hda_amp_list alc260_loopbacks[] = {  	{ 0x07, HDA_INPUT, 0 },  	{ 0x07, HDA_INPUT, 1 },  	{ 0x07, HDA_INPUT, 2 }, @@ -7121,7 +7391,7 @@ static const struct alc_fixup alc260_fixups[] = {  	},  }; -static struct snd_pci_quirk alc260_fixup_tbl[] = { +static const struct snd_pci_quirk alc260_fixup_tbl[] = {  	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),  	{}  }; @@ -7145,7 +7415,7 @@ static const char * const alc260_models[ALC260_MODEL_LAST] = {  	[ALC260_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc260_cfg_tbl[] = { +static const struct snd_pci_quirk alc260_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),  	SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),  	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), @@ -7169,7 +7439,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc260_presets[] = { +static const struct alc_config_preset alc260_presets[] = {  	[ALC260_BASIC] = {  		.mixers = { alc260_base_output_mixer,  			    alc260_input_mixer }, @@ -7194,8 +7464,9 @@ static struct alc_config_preset alc260_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc260_modes),  		.channel_mode = alc260_modes,  		.input_mux = &alc260_capture_source, -		.unsol_event = alc260_hp_unsol_event, -		.init_hook = alc260_hp_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc260_hp_setup, +		.init_hook = alc_inithook,  	},  	[ALC260_HP_DC7600] = {  		.mixers = { alc260_hp_dc7600_mixer, @@ -7209,8 +7480,9 @@ static struct alc_config_preset alc260_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc260_modes),  		.channel_mode = alc260_modes,  		.input_mux = &alc260_capture_source, -		.unsol_event = alc260_hp_3012_unsol_event, -		.init_hook = alc260_hp_3012_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc260_hp_3012_setup, +		.init_hook = alc_inithook,  	},  	[ALC260_HP_3013] = {  		.mixers = { alc260_hp_3013_mixer, @@ -7224,8 +7496,9 @@ static struct alc_config_preset alc260_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc260_modes),  		.channel_mode = alc260_modes,  		.input_mux = &alc260_capture_source, -		.unsol_event = alc260_hp_3013_unsol_event, -		.init_hook = alc260_hp_3013_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc260_hp_3013_setup, +		.init_hook = alc_inithook,  	},  	[ALC260_FUJITSU_S702X] = {  		.mixers = { alc260_fujitsu_mixer }, @@ -7383,6 +7656,7 @@ static int patch_alc260(struct hda_codec *codec)  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC260_AUTO)  		spec->init_hook = alc260_auto_init; +	spec->shutup = alc_eapd_shutup;  #ifdef CONFIG_SND_HDA_POWER_SAVE  	if (!spec->loopback.amplist)  		spec->loopback.amplist = alc260_loopbacks; @@ -7410,12 +7684,12 @@ static int patch_alc260(struct hda_codec *codec)  #define ALC1200_DIGOUT_NID	0x10 -static struct hda_channel_mode alc882_ch_modes[1] = { +static const struct hda_channel_mode alc882_ch_modes[1] = {  	{ 8, NULL }  };  /* DACs */ -static hda_nid_t alc882_dac_nids[4] = { +static const hda_nid_t alc882_dac_nids[4] = {  	/* front, rear, clfe, rear_surr */  	0x02, 0x03, 0x04, 0x05  }; @@ -7425,20 +7699,20 @@ static hda_nid_t alc882_dac_nids[4] = {  #define alc882_adc_nids		alc880_adc_nids  #define alc882_adc_nids_alt	alc880_adc_nids_alt  #define alc883_adc_nids		alc882_adc_nids_alt -static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; -static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; +static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; +static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };  #define alc889_adc_nids		alc880_adc_nids -static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; -static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; +static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; +static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };  #define alc883_capsrc_nids	alc882_capsrc_nids_alt -static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; +static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };  #define alc889_capsrc_nids	alc882_capsrc_nids  /* input MUX */  /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc882_capture_source = { +static const struct hda_input_mux alc882_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -7450,7 +7724,7 @@ static struct hda_input_mux alc882_capture_source = {  #define alc883_capture_source	alc882_capture_source -static struct hda_input_mux alc889_capture_source = { +static const struct hda_input_mux alc889_capture_source = {  	.num_items = 3,  	.items = {  		{ "Front Mic", 0x0 }, @@ -7459,7 +7733,7 @@ static struct hda_input_mux alc889_capture_source = {  	},  }; -static struct hda_input_mux mb5_capture_source = { +static const struct hda_input_mux mb5_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x1 }, @@ -7468,7 +7742,7 @@ static struct hda_input_mux mb5_capture_source = {  	},  }; -static struct hda_input_mux macmini3_capture_source = { +static const struct hda_input_mux macmini3_capture_source = {  	.num_items = 2,  	.items = {  		{ "Line", 0x2 }, @@ -7476,7 +7750,7 @@ static struct hda_input_mux macmini3_capture_source = {  	},  }; -static struct hda_input_mux alc883_3stack_6ch_intel = { +static const struct hda_input_mux alc883_3stack_6ch_intel = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x1 }, @@ -7486,7 +7760,7 @@ static struct hda_input_mux alc883_3stack_6ch_intel = {  	},  }; -static struct hda_input_mux alc883_lenovo_101e_capture_source = { +static const struct hda_input_mux alc883_lenovo_101e_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x1 }, @@ -7494,7 +7768,7 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {  	},  }; -static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { +static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -7504,7 +7778,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {  	},  }; -static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { +static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x0 }, @@ -7512,7 +7786,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {  	},  }; -static struct hda_input_mux alc883_lenovo_sky_capture_source = { +static const struct hda_input_mux alc883_lenovo_sky_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -7521,7 +7795,7 @@ static struct hda_input_mux alc883_lenovo_sky_capture_source = {  	},  }; -static struct hda_input_mux alc883_asus_eee1601_capture_source = { +static const struct hda_input_mux alc883_asus_eee1601_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x0 }, @@ -7529,7 +7803,7 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {  	},  }; -static struct hda_input_mux alc889A_mb31_capture_source = { +static const struct hda_input_mux alc889A_mb31_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x0 }, @@ -7540,7 +7814,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = {  	},  }; -static struct hda_input_mux alc889A_imac91_capture_source = { +static const struct hda_input_mux alc889A_imac91_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x01 }, @@ -7551,14 +7825,14 @@ static struct hda_input_mux alc889A_imac91_capture_source = {  /*   * 2ch mode   */ -static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { +static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {  	{ 2, NULL }  };  /*   * 2ch mode   */ -static struct hda_verb alc882_3ST_ch2_init[] = { +static const struct hda_verb alc882_3ST_ch2_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -7569,7 +7843,7 @@ static struct hda_verb alc882_3ST_ch2_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc882_3ST_ch4_init[] = { +static const struct hda_verb alc882_3ST_ch4_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7581,7 +7855,7 @@ static struct hda_verb alc882_3ST_ch4_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc882_3ST_ch6_init[] = { +static const struct hda_verb alc882_3ST_ch6_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7591,7 +7865,7 @@ static struct hda_verb alc882_3ST_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { +static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {  	{ 2, alc882_3ST_ch2_init },  	{ 4, alc882_3ST_ch4_init },  	{ 6, alc882_3ST_ch6_init }, @@ -7602,7 +7876,7 @@ static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {  /*   * 2ch mode   */ -static struct hda_verb alc883_3ST_ch2_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -7614,7 +7888,7 @@ static struct hda_verb alc883_3ST_ch2_clevo_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc883_3ST_ch4_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -7627,7 +7901,7 @@ static struct hda_verb alc883_3ST_ch4_clevo_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc883_3ST_ch6_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -7638,7 +7912,7 @@ static struct hda_verb alc883_3ST_ch6_clevo_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { +static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {  	{ 2, alc883_3ST_ch2_clevo_init },  	{ 4, alc883_3ST_ch4_clevo_init },  	{ 6, alc883_3ST_ch6_clevo_init }, @@ -7648,7 +7922,7 @@ static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {  /*   * 6ch mode   */ -static struct hda_verb alc882_sixstack_ch6_init[] = { +static const struct hda_verb alc882_sixstack_ch6_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7659,7 +7933,7 @@ static struct hda_verb alc882_sixstack_ch6_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc882_sixstack_ch8_init[] = { +static const struct hda_verb alc882_sixstack_ch8_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7667,7 +7941,7 @@ static struct hda_verb alc882_sixstack_ch8_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc882_sixstack_modes[2] = { +static const struct hda_channel_mode alc882_sixstack_modes[2] = {  	{ 6, alc882_sixstack_ch6_init },  	{ 8, alc882_sixstack_ch8_init },  }; @@ -7675,7 +7949,7 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {  /* Macbook Air 2,1 */ -static struct hda_channel_mode alc885_mba21_ch_modes[1] = { +static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {        { 2, NULL },  }; @@ -7686,7 +7960,7 @@ static struct hda_channel_mode alc885_mba21_ch_modes[1] = {  /*   * 2ch mode   */ -static struct hda_verb alc885_mbp_ch2_init[] = { +static const struct hda_verb alc885_mbp_ch2_init[] = {  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },  	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{ 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -7696,7 +7970,7 @@ static struct hda_verb alc885_mbp_ch2_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc885_mbp_ch4_init[] = { +static const struct hda_verb alc885_mbp_ch4_init[] = {  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -7705,7 +7979,7 @@ static struct hda_verb alc885_mbp_ch4_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { +static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {  	{ 2, alc885_mbp_ch2_init },  	{ 4, alc885_mbp_ch4_init },  }; @@ -7715,7 +7989,7 @@ static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {   * Speakers/Woofer/HP = Front   * LineIn = Input   */ -static struct hda_verb alc885_mb5_ch2_init[] = { +static const struct hda_verb alc885_mb5_ch2_init[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},  	{ } /* end */ @@ -7727,14 +8001,14 @@ static struct hda_verb alc885_mb5_ch2_init[] = {   * Woofer = LFE   * LineIn = Surround   */ -static struct hda_verb alc885_mb5_ch6_init[] = { +static const struct hda_verb alc885_mb5_ch6_init[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{ } /* end */  }; -static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { +static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {  	{ 2, alc885_mb5_ch2_init },  	{ 6, alc885_mb5_ch6_init },  }; @@ -7744,7 +8018,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {  /*   * 2ch mode   */ -static struct hda_verb alc883_4ST_ch2_init[] = { +static const struct hda_verb alc883_4ST_ch2_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, @@ -7757,7 +8031,7 @@ static struct hda_verb alc883_4ST_ch2_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc883_4ST_ch4_init[] = { +static const struct hda_verb alc883_4ST_ch4_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, @@ -7771,7 +8045,7 @@ static struct hda_verb alc883_4ST_ch4_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc883_4ST_ch6_init[] = { +static const struct hda_verb alc883_4ST_ch6_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7786,7 +8060,7 @@ static struct hda_verb alc883_4ST_ch6_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc883_4ST_ch8_init[] = { +static const struct hda_verb alc883_4ST_ch8_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, @@ -7799,7 +8073,7 @@ static struct hda_verb alc883_4ST_ch8_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { +static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {  	{ 2, alc883_4ST_ch2_init },  	{ 4, alc883_4ST_ch4_init },  	{ 6, alc883_4ST_ch6_init }, @@ -7810,7 +8084,7 @@ static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {  /*   * 2ch mode   */ -static struct hda_verb alc883_3ST_ch2_intel_init[] = { +static const struct hda_verb alc883_3ST_ch2_intel_init[] = {  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -7821,7 +8095,7 @@ static struct hda_verb alc883_3ST_ch2_intel_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc883_3ST_ch4_intel_init[] = { +static const struct hda_verb alc883_3ST_ch4_intel_init[] = {  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7833,7 +8107,7 @@ static struct hda_verb alc883_3ST_ch4_intel_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc883_3ST_ch6_intel_init[] = { +static const struct hda_verb alc883_3ST_ch6_intel_init[] = {  	{ 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7843,7 +8117,7 @@ static struct hda_verb alc883_3ST_ch6_intel_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { +static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {  	{ 2, alc883_3ST_ch2_intel_init },  	{ 4, alc883_3ST_ch4_intel_init },  	{ 6, alc883_3ST_ch6_intel_init }, @@ -7852,7 +8126,7 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {  /*   * 2ch mode   */ -static struct hda_verb alc889_ch2_intel_init[] = { +static const struct hda_verb alc889_ch2_intel_init[] = {  	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },  	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },  	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, @@ -7865,7 +8139,7 @@ static struct hda_verb alc889_ch2_intel_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc889_ch6_intel_init[] = { +static const struct hda_verb alc889_ch6_intel_init[] = {  	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },  	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },  	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7878,7 +8152,7 @@ static struct hda_verb alc889_ch6_intel_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc889_ch8_intel_init[] = { +static const struct hda_verb alc889_ch8_intel_init[] = {  	{ 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },  	{ 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },  	{ 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7889,7 +8163,7 @@ static struct hda_verb alc889_ch8_intel_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc889_8ch_intel_modes[3] = { +static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {  	{ 2, alc889_ch2_intel_init },  	{ 6, alc889_ch6_intel_init },  	{ 8, alc889_ch8_intel_init }, @@ -7898,7 +8172,7 @@ static struct hda_channel_mode alc889_8ch_intel_modes[3] = {  /*   * 6ch mode   */ -static struct hda_verb alc883_sixstack_ch6_init[] = { +static const struct hda_verb alc883_sixstack_ch6_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7909,7 +8183,7 @@ static struct hda_verb alc883_sixstack_ch6_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc883_sixstack_ch8_init[] = { +static const struct hda_verb alc883_sixstack_ch8_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7917,7 +8191,7 @@ static struct hda_verb alc883_sixstack_ch8_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc883_sixstack_modes[2] = { +static const struct hda_channel_mode alc883_sixstack_modes[2] = {  	{ 6, alc883_sixstack_ch6_init },  	{ 8, alc883_sixstack_ch8_init },  }; @@ -7926,7 +8200,7 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {  /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17   *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b   */ -static struct snd_kcontrol_new alc882_base_mixer[] = { +static const struct snd_kcontrol_new alc882_base_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -7953,14 +8227,14 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {  /* Macbook Air 2,1 same control for HP and internal Speaker */ -static struct snd_kcontrol_new alc885_mba21_mixer[] = { +static const struct snd_kcontrol_new alc885_mba21_mixer[] = {        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),       { }  }; -static struct snd_kcontrol_new alc885_mbp3_mixer[] = { +static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), @@ -7975,7 +8249,7 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc885_mb5_mixer[] = { +static const struct snd_kcontrol_new alc885_mb5_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), @@ -7993,7 +8267,7 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc885_macmini3_mixer[] = { +static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), @@ -8008,14 +8282,14 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc885_imac91_mixer[] = { +static const struct snd_kcontrol_new alc885_imac91_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),  	{ } /* end */  }; -static struct snd_kcontrol_new alc882_w2jc_mixer[] = { +static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -8028,7 +8302,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc882_targa_mixer[] = { +static const struct snd_kcontrol_new alc882_targa_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -8048,7 +8322,7 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {  /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???   *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c   */ -static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { +static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -8065,7 +8339,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { +static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -8079,7 +8353,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc882_chmode_mixer[] = { +static const struct snd_kcontrol_new alc882_chmode_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Channel Mode", @@ -8090,7 +8364,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc882_base_init_verbs[] = { +static const struct hda_verb alc882_base_init_verbs[] = {  	/* Front mixer: unmute input/output amp left and right (volume = 0) */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -8152,7 +8426,7 @@ static struct hda_verb alc882_base_init_verbs[] = {  	{ }  }; -static struct hda_verb alc882_adc1_init_verbs[] = { +static const struct hda_verb alc882_adc1_init_verbs[] = {  	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, @@ -8164,26 +8438,26 @@ static struct hda_verb alc882_adc1_init_verbs[] = {  	{ }  }; -static struct hda_verb alc882_eapd_verbs[] = { +static const struct hda_verb alc882_eapd_verbs[] = {  	/* change to EAPD mode */  	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},  	{0x20, AC_VERB_SET_PROC_COEF, 0x3060},  	{ }  }; -static struct hda_verb alc889_eapd_verbs[] = { +static const struct hda_verb alc889_eapd_verbs[] = {  	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; -static struct hda_verb alc_hp15_unsol_verbs[] = { +static const struct hda_verb alc_hp15_unsol_verbs[] = {  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{}  }; -static struct hda_verb alc885_init_verbs[] = { +static const struct hda_verb alc885_init_verbs[] = {  	/* Front mixer: unmute input/output amp left and right (volume = 0) */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8242,7 +8516,7 @@ static struct hda_verb alc885_init_verbs[] = {  	{ }  }; -static struct hda_verb alc885_init_input_verbs[] = { +static const struct hda_verb alc885_init_input_verbs[] = {  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, @@ -8251,7 +8525,7 @@ static struct hda_verb alc885_init_input_verbs[] = {  /* Unmute Selector 24h and set the default input to front mic */ -static struct hda_verb alc889_init_input_verbs[] = { +static const struct hda_verb alc889_init_input_verbs[] = {  	{0x24, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{ } @@ -8261,7 +8535,7 @@ static struct hda_verb alc889_init_input_verbs[] = {  #define alc883_init_verbs	alc882_base_init_verbs  /* Mac Pro test */ -static struct snd_kcontrol_new alc882_macpro_mixer[] = { +static const struct snd_kcontrol_new alc882_macpro_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), @@ -8274,7 +8548,7 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc882_macpro_init_verbs[] = { +static const struct hda_verb alc882_macpro_init_verbs[] = {  	/* Front mixer: unmute input/output amp left and right (volume = 0) */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -8326,7 +8600,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = {  };  /* Macbook 5,1 */ -static struct hda_verb alc885_mb5_init_verbs[] = { +static const struct hda_verb alc885_mb5_init_verbs[] = {  	/* DACs */  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8375,7 +8649,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = {  };  /* Macmini 3,1 */ -static struct hda_verb alc885_macmini3_init_verbs[] = { +static const struct hda_verb alc885_macmini3_init_verbs[] = {  	/* DACs */  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8422,7 +8696,7 @@ static struct hda_verb alc885_macmini3_init_verbs[] = {  }; -static struct hda_verb alc885_mba21_init_verbs[] = { +static const struct hda_verb alc885_mba21_init_verbs[] = {  	/*Internal and HP Speaker Mixer*/  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -8445,7 +8719,7 @@ static struct hda_verb alc885_mba21_init_verbs[] = {  /* Macbook Pro rev3 */ -static struct hda_verb alc885_mbp3_init_verbs[] = { +static const struct hda_verb alc885_mbp3_init_verbs[] = {  	/* Front mixer: unmute input/output amp left and right (volume = 0) */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -8509,7 +8783,7 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {  };  /* iMac 9,1 */ -static struct hda_verb alc885_imac91_init_verbs[] = { +static const struct hda_verb alc885_imac91_init_verbs[] = {  	/* Internal Speaker Pin (0x0c) */  	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },  	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8564,14 +8838,14 @@ static struct hda_verb alc885_imac91_init_verbs[] = {  };  /* iMac 24 mixer. */ -static struct snd_kcontrol_new alc885_imac24_mixer[] = { +static const struct snd_kcontrol_new alc885_imac24_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),  	{ } /* end */  };  /* iMac 24 init verbs. */ -static struct hda_verb alc885_imac24_init_verbs[] = { +static const struct hda_verb alc885_imac24_init_verbs[] = {  	/* Internal speakers: output 0 (0x0c) */  	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8599,6 +8873,8 @@ static void alc885_imac24_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x18;  	spec->autocfg.speaker_pins[1] = 0x1a; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  #define alc885_mb5_setup	alc885_imac24_setup @@ -8611,6 +8887,8 @@ static void alc885_mba21_setup(struct hda_codec *codec)         spec->autocfg.hp_pins[0] = 0x14;         spec->autocfg.speaker_pins[0] = 0x18; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } @@ -8621,6 +8899,8 @@ static void alc885_mbp3_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc885_imac91_setup(struct hda_codec *codec) @@ -8630,9 +8910,11 @@ static void alc885_imac91_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x18;  	spec->autocfg.speaker_pins[1] = 0x1a; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc882_targa_verbs[] = { +static const struct hda_verb alc882_targa_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8651,7 +8933,7 @@ static struct hda_verb alc882_targa_verbs[] = {  static void alc882_targa_automute(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,  				  spec->jack_present ? 1 : 3);  } @@ -8662,6 +8944,8 @@ static void alc882_targa_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x1b; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) @@ -8670,7 +8954,7 @@ static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)  		alc882_targa_automute(codec);  } -static struct hda_verb alc882_asus_a7j_verbs[] = { +static const struct hda_verb alc882_asus_a7j_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8688,7 +8972,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc882_asus_a7m_verbs[] = { +static const struct hda_verb alc882_asus_a7m_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8749,13 +9033,13 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)  static void alc885_imac24_init_hook(struct hda_codec *codec)  {  	alc885_macpro_init_hook(codec); -	alc_automute_amp(codec); +	alc_hp_automute(codec);  }  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc883_auto_init_verbs[] = { +static const struct hda_verb alc883_auto_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -8795,7 +9079,7 @@ static struct hda_verb alc883_auto_init_verbs[] = {  };  /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ -static struct hda_verb alc889A_mb31_ch2_init[] = { +static const struct hda_verb alc889A_mb31_ch2_init[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */  	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */ @@ -8804,7 +9088,7 @@ static struct hda_verb alc889A_mb31_ch2_init[] = {  };  /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ -static struct hda_verb alc889A_mb31_ch4_init[] = { +static const struct hda_verb alc889A_mb31_ch4_init[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */  	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */ @@ -8813,7 +9097,7 @@ static struct hda_verb alc889A_mb31_ch4_init[] = {  };  /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ -static struct hda_verb alc889A_mb31_ch5_init[] = { +static const struct hda_verb alc889A_mb31_ch5_init[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */  	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */ @@ -8822,7 +9106,7 @@ static struct hda_verb alc889A_mb31_ch5_init[] = {  };  /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ -static struct hda_verb alc889A_mb31_ch6_init[] = { +static const struct hda_verb alc889A_mb31_ch6_init[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */  	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */ @@ -8830,14 +9114,14 @@ static struct hda_verb alc889A_mb31_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { +static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {  	{ 2, alc889A_mb31_ch2_init },  	{ 4, alc889A_mb31_ch4_init },  	{ 5, alc889A_mb31_ch5_init },  	{ 6, alc889A_mb31_ch6_init },  }; -static struct hda_verb alc883_medion_eapd_verbs[] = { +static const struct hda_verb alc883_medion_eapd_verbs[] = {          /* eanable EAPD on medion laptop */  	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},  	{0x20, AC_VERB_SET_PROC_COEF, 0x3070}, @@ -8846,7 +9130,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {  #define alc883_base_mixer	alc882_base_mixer -static struct snd_kcontrol_new alc883_mitac_mixer[] = { +static const struct snd_kcontrol_new alc883_mitac_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), @@ -8863,7 +9147,7 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { +static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8877,7 +9161,7 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { +static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8891,7 +9175,7 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -8908,7 +9192,7 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8931,7 +9215,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8955,7 +9239,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { +static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8979,7 +9263,7 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_fivestack_mixer[] = { +static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -9002,7 +9286,7 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_targa_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9023,7 +9307,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9039,7 +9323,7 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {  	HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), @@ -9048,7 +9332,7 @@ static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -9060,7 +9344,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { +static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9073,7 +9357,7 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { +static const 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), @@ -9083,7 +9367,7 @@ static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc883_medion_wim2160_verbs[] = { +static const 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)}, @@ -9107,9 +9391,11 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1a;  	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { +static const 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),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9121,7 +9407,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { +static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), @@ -9134,7 +9420,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { +static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -9159,7 +9445,7 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc889A_mb31_mixer[] = { +static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {  	/* Output mixers */  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), @@ -9185,7 +9471,7 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_vaiott_mixer[] = { +static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -9195,7 +9481,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc883_bind_cap_vol = { +static const struct hda_bind_ctls alc883_bind_cap_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), @@ -9204,7 +9490,7 @@ static struct hda_bind_ctls alc883_bind_cap_vol = {  	},  }; -static struct hda_bind_ctls alc883_bind_cap_switch = { +static const struct hda_bind_ctls alc883_bind_cap_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), @@ -9213,7 +9499,7 @@ static struct hda_bind_ctls alc883_bind_cap_switch = {  	},  }; -static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { +static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9225,7 +9511,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { +static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {  	HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),  	HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),  	{ @@ -9240,7 +9526,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc883_chmode_mixer[] = { +static const struct snd_kcontrol_new alc883_chmode_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Channel Mode", @@ -9259,9 +9545,11 @@ static void alc883_mitac_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc883_mitac_verbs[] = { +static const struct hda_verb alc883_mitac_verbs[] = {  	/* HP */  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9276,7 +9564,7 @@ static struct hda_verb alc883_mitac_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_clevo_m540r_verbs[] = { +static const struct hda_verb alc883_clevo_m540r_verbs[] = {  	/* HP */  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9292,7 +9580,7 @@ static struct hda_verb alc883_clevo_m540r_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_clevo_m720_verbs[] = { +static const struct hda_verb alc883_clevo_m720_verbs[] = {  	/* HP */  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9307,7 +9595,7 @@ static struct hda_verb alc883_clevo_m720_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { +static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {  	/* HP */  	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9321,7 +9609,7 @@ static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_targa_verbs[] = { +static const struct hda_verb alc883_targa_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9350,14 +9638,14 @@ static struct hda_verb alc883_targa_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_lenovo_101e_verbs[] = { +static const struct hda_verb alc883_lenovo_101e_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},          {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},  	{ } /* end */  }; -static struct hda_verb alc883_lenovo_nb0763_verbs[] = { +static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {          {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},          {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -9365,7 +9653,7 @@ static struct hda_verb alc883_lenovo_nb0763_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc888_lenovo_ms7195_verbs[] = { +static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -9374,7 +9662,7 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc883_haier_w66_verbs[] = { +static const struct hda_verb alc883_haier_w66_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9387,7 +9675,7 @@ static struct hda_verb alc883_haier_w66_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc888_lenovo_sky_verbs[] = { +static const struct hda_verb alc888_lenovo_sky_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -9399,12 +9687,12 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = {  	{ } /* end */  }; -static struct hda_verb alc888_6st_dell_verbs[] = { +static const struct hda_verb alc888_6st_dell_verbs[] = {  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},  	{ }  }; -static struct hda_verb alc883_vaiott_verbs[] = { +static const struct hda_verb alc883_vaiott_verbs[] = {  	/* HP */  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9423,9 +9711,11 @@ static void alc888_3st_hp_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x16;  	spec->autocfg.speaker_pins[2] = 0x18; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc888_3st_hp_verbs[] = { +static const struct hda_verb alc888_3st_hp_verbs[] = {  	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Front: output 0 (0x0c) */  	{0x16, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Rear : output 1 (0x0d) */  	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02},	/* CLFE : output 2 (0x0e) */ @@ -9436,7 +9726,7 @@ static struct hda_verb alc888_3st_hp_verbs[] = {  /*   * 2ch mode   */ -static struct hda_verb alc888_3st_hp_2ch_init[] = { +static const struct hda_verb alc888_3st_hp_2ch_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -9447,7 +9737,7 @@ static struct hda_verb alc888_3st_hp_2ch_init[] = {  /*   * 4ch mode   */ -static struct hda_verb alc888_3st_hp_4ch_init[] = { +static const struct hda_verb alc888_3st_hp_4ch_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -9459,7 +9749,7 @@ static struct hda_verb alc888_3st_hp_4ch_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc888_3st_hp_6ch_init[] = { +static const struct hda_verb alc888_3st_hp_6ch_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -9469,39 +9759,21 @@ static struct hda_verb alc888_3st_hp_6ch_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc888_3st_hp_modes[3] = { +static const struct hda_channel_mode alc888_3st_hp_modes[3] = {  	{ 2, alc888_3st_hp_2ch_init },  	{ 4, alc888_3st_hp_4ch_init },  	{ 6, alc888_3st_hp_6ch_init },  }; -/* toggle front-jack and RCA according to the hp-jack state */ -static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) +static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)  { - 	unsigned int present = snd_hda_jack_detect(codec, 0x1b); - -	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - -/* toggle RCA according to the front-jack state */ -static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) -{ - 	unsigned int present = snd_hda_jack_detect(codec, 0x14); - -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} +	struct alc_spec *spec = codec->spec; -static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, -					     unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc888_lenovo_ms7195_front_automute(codec); -	if ((res >> 26) == ALC880_FRONT_EVENT) -		alc888_lenovo_ms7195_rca_automute(codec); +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.line_out_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* toggle speaker-output according to the hp-jack state */ @@ -9511,6 +9783,8 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* toggle speaker-output according to the hp-jack state */ @@ -9523,11 +9797,13 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc883_clevo_m720_init_hook(struct hda_codec *codec)  { -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	alc88x_simple_mic_automute(codec);  } @@ -9539,7 +9815,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,  		alc88x_simple_mic_automute(codec);  		break;  	default: -		alc_automute_amp_unsol_event(codec, res); +		alc_sku_unsol_event(codec, res);  		break;  	}  } @@ -9551,6 +9827,8 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc883_haier_w66_setup(struct hda_codec *codec) @@ -9559,33 +9837,21 @@ static void alc883_haier_w66_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) -{ -	int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; - -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} - -static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) +static void alc883_lenovo_101e_setup(struct hda_codec *codec)  { -	int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; - -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} +	struct alc_spec *spec = codec->spec; -static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc883_lenovo_101e_all_automute(codec); -	if ((res >> 26) == ALC880_FRONT_EVENT) -		alc883_lenovo_101e_ispeaker_automute(codec); +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.line_out_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->detect_line = 1; +	spec->automute_lines = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* toggle speaker-output according to the hp-jack state */ @@ -9596,9 +9862,11 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x15;  	spec->autocfg.speaker_pins[1] = 0x16; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc883_acer_eapd_verbs[] = { +static const struct hda_verb alc883_acer_eapd_verbs[] = {  	/* HP Pin: output 0 (0x0c) */  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -9625,6 +9893,8 @@ static void alc888_6st_dell_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[1] = 0x15;  	spec->autocfg.speaker_pins[2] = 0x16;  	spec->autocfg.speaker_pins[3] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc888_lenovo_sky_setup(struct hda_codec *codec) @@ -9637,6 +9907,8 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec)  	spec->autocfg.speaker_pins[2] = 0x16;  	spec->autocfg.speaker_pins[3] = 0x17;  	spec->autocfg.speaker_pins[4] = 0x1a; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc883_vaiott_setup(struct hda_codec *codec) @@ -9646,9 +9918,11 @@ static void alc883_vaiott_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14;  	spec->autocfg.speaker_pins[1] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc888_asus_m90v_verbs[] = { +static const struct hda_verb alc888_asus_m90v_verbs[] = {  	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9671,9 +9945,11 @@ static void alc883_mode2_setup(struct hda_codec *codec)  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.mux_idx = 1;  	spec->auto_mic = 1; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct hda_verb alc888_asus_eee1601_verbs[] = { +static const struct hda_verb alc888_asus_eee1601_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -9692,10 +9968,10 @@ static void alc883_eee1601_inithook(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x1b; -	alc_automute_pin(codec); +	alc_hp_automute(codec);  } -static struct hda_verb alc889A_mb31_verbs[] = { +static const struct hda_verb alc889A_mb31_verbs[] = {  	/* Init rear pin (used as headphone output) */  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */ @@ -9741,11 +10017,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)  #define alc882_pcm_digital_playback	alc880_pcm_digital_playback  #define alc882_pcm_digital_capture	alc880_pcm_digital_capture -static hda_nid_t alc883_slave_dig_outs[] = { +static const hda_nid_t alc883_slave_dig_outs[] = {  	ALC1200_DIGOUT_NID, 0,  }; -static hda_nid_t alc1200_slave_dig_outs[] = { +static const hda_nid_t alc1200_slave_dig_outs[] = {  	ALC883_DIGOUT_NID, 0,  }; @@ -9804,7 +10080,7 @@ static const char * const alc882_models[ALC882_MODEL_LAST] = {  	[ALC882_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc882_cfg_tbl[] = { +static const struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),  	SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), @@ -9863,6 +10139,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),  	SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),  	SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), +	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),  	SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),  	SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), @@ -9930,7 +10207,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {  };  /* codec SSID table for Intel Mac */ -static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { +static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {  	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),  	SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),  	SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), @@ -9957,7 +10234,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {  	{} /* terminator */  }; -static struct alc_config_preset alc882_presets[] = { +static const struct alc_config_preset alc882_presets[] = {  	[ALC882_3ST_DIG] = {  		.mixers = { alc882_base_mixer },  		.init_verbs = { alc882_base_init_verbs, @@ -10013,9 +10290,9 @@ static struct alc_config_preset alc882_presets[] = {  			.channel_mode = alc885_mba21_ch_modes,  			.num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),  			.input_mux = &alc882_capture_source, -			.unsol_event = alc_automute_amp_unsol_event, +			.unsol_event = alc_sku_unsol_event,  			.setup = alc885_mba21_setup, -			.init_hook = alc_automute_amp, +			.init_hook = alc_hp_automute,         },  	[ALC885_MBP3] = {  		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, @@ -10029,9 +10306,9 @@ static struct alc_config_preset alc882_presets[] = {  		.input_mux = &alc882_capture_source,  		.dig_out_nid = ALC882_DIGOUT_NID,  		.dig_in_nid = ALC882_DIGIN_NID, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc885_mbp3_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC885_MB5] = {  		.mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, @@ -10044,9 +10321,9 @@ static struct alc_config_preset alc882_presets[] = {  		.input_mux = &mb5_capture_source,  		.dig_out_nid = ALC882_DIGOUT_NID,  		.dig_in_nid = ALC882_DIGIN_NID, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc885_mb5_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC885_MACMINI3] = {  		.mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, @@ -10059,9 +10336,9 @@ static struct alc_config_preset alc882_presets[] = {  		.input_mux = &macmini3_capture_source,  		.dig_out_nid = ALC882_DIGOUT_NID,  		.dig_in_nid = ALC882_DIGIN_NID, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc885_macmini3_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC885_MACPRO] = {  		.mixers = { alc882_macpro_mixer }, @@ -10085,7 +10362,7 @@ static struct alc_config_preset alc882_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),  		.channel_mode = alc882_ch_modes,  		.input_mux = &alc882_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc885_imac24_setup,  		.init_hook = alc885_imac24_init_hook,  	}, @@ -10100,9 +10377,9 @@ static struct alc_config_preset alc882_presets[] = {  		.input_mux = &alc889A_imac91_capture_source,  		.dig_out_nid = ALC882_DIGOUT_NID,  		.dig_in_nid = ALC882_DIGIN_NID, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc885_imac91_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC882_TARGA] = {  		.mixers = { alc882_targa_mixer, alc882_chmode_mixer }, @@ -10118,7 +10395,7 @@ static struct alc_config_preset alc882_presets[] = {  		.channel_mode = alc882_3ST_6ch_modes,  		.need_dac_fix = 1,  		.input_mux = &alc882_capture_source, -		.unsol_event = alc882_targa_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc882_targa_setup,  		.init_hook = alc882_targa_automute,  	}, @@ -10212,8 +10489,8 @@ static struct alc_config_preset alc882_presets[] = {  		.capsrc_nids = alc889_capsrc_nids,  		.input_mux = &alc889_capture_source,  		.setup = alc889_automute_setup, -		.init_hook = alc_automute_amp, -		.unsol_event = alc_automute_amp_unsol_event, +		.init_hook = alc_hp_automute, +		.unsol_event = alc_sku_unsol_event,  		.need_dac_fix = 1,  	},  	[ALC889_INTEL] = { @@ -10233,7 +10510,7 @@ static struct alc_config_preset alc882_presets[] = {  		.input_mux = &alc889_capture_source,  		.setup = alc889_automute_setup,  		.init_hook = alc889_intel_init_hook, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.need_dac_fix = 1,  	},  	[ALC883_6ST_DIG] = { @@ -10322,9 +10599,9 @@ static struct alc_config_preset alc882_presets[] = {  		.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, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_acer_aspire_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_ACER_ASPIRE_4930G] = {  		.mixers = { alc888_acer_aspire_4930g_mixer, @@ -10344,9 +10621,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_mux_defs =  			ARRAY_SIZE(alc888_2_capture_sources),  		.input_mux = alc888_2_capture_sources, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_acer_aspire_4930g_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_ACER_ASPIRE_6530G] = {  		.mixers = { alc888_acer_aspire_6530_mixer }, @@ -10363,9 +10640,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_mux_defs =  			ARRAY_SIZE(alc888_2_capture_sources),  		.input_mux = alc888_acer_aspire_6530_sources, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_acer_aspire_6530g_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_ACER_ASPIRE_8930G] = {  		.mixers = { alc889_acer_aspire_8930g_mixer, @@ -10386,9 +10663,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_mux_defs =  			ARRAY_SIZE(alc889_capture_sources),  		.input_mux = alc889_capture_sources, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc889_acer_aspire_8930g_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  #ifdef CONFIG_SND_HDA_POWER_SAVE  		.power_hook = alc_power_eapd,  #endif @@ -10409,9 +10686,9 @@ static struct alc_config_preset alc882_presets[] = {  		.need_dac_fix = 1,  		.const_channel_count = 6,  		.input_mux = &alc883_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_acer_aspire_7730g_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC883_MEDION] = {  		.mixers = { alc883_fivestack_mixer, @@ -10438,9 +10715,9 @@ static struct alc_config_preset alc882_presets[] = {  		.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, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_medion_wim2160_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC883_LAPTOP_EAPD] = {  		.mixers = { alc883_base_mixer }, @@ -10490,8 +10767,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),  		.channel_mode = alc883_3ST_2ch_modes,  		.input_mux = &alc883_lenovo_101e_capture_source, -		.unsol_event = alc883_lenovo_101e_unsol_event, -		.init_hook = alc883_lenovo_101e_all_automute, +		.setup = alc883_lenovo_101e_setup, +		.unsol_event = alc_sku_unsol_event, +		.init_hook = alc_inithook,  	},  	[ALC883_LENOVO_NB0763] = {  		.mixers = { alc883_lenovo_nb0763_mixer }, @@ -10502,9 +10780,9 @@ static struct alc_config_preset alc882_presets[] = {  		.channel_mode = alc883_3ST_2ch_modes,  		.need_dac_fix = 1,  		.input_mux = &alc883_lenovo_nb0763_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_lenovo_nb0763_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_LENOVO_MS7195_DIG] = {  		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10516,8 +10794,9 @@ static struct alc_config_preset alc882_presets[] = {  		.channel_mode = alc883_3ST_6ch_modes,  		.need_dac_fix = 1,  		.input_mux = &alc883_capture_source, -		.unsol_event = alc883_lenovo_ms7195_unsol_event, -		.init_hook = alc888_lenovo_ms7195_front_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc888_lenovo_ms7195_setup, +		.init_hook = alc_inithook,  	},  	[ALC883_HAIER_W66] = {  		.mixers = { alc883_targa_2ch_mixer}, @@ -10528,9 +10807,9 @@ static struct alc_config_preset alc882_presets[] = {  		.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, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_haier_w66_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_3ST_HP] = {  		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10541,9 +10820,9 @@ static struct alc_config_preset alc882_presets[] = {  		.channel_mode = alc888_3st_hp_modes,  		.need_dac_fix = 1,  		.input_mux = &alc883_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_3st_hp_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_6ST_DELL] = {  		.mixers = { alc883_base_mixer, alc883_chmode_mixer }, @@ -10555,9 +10834,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),  		.channel_mode = alc883_sixstack_modes,  		.input_mux = &alc883_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_6st_dell_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC883_MITAC] = {  		.mixers = { alc883_mitac_mixer }, @@ -10567,9 +10846,9 @@ static struct alc_config_preset alc882_presets[] = {  		.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, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_mitac_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC883_FUJITSU_PI2515] = {  		.mixers = { alc883_2ch_fujitsu_pi2515_mixer }, @@ -10581,9 +10860,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),  		.channel_mode = alc883_3ST_2ch_modes,  		.input_mux = &alc883_fujitsu_pi2515_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_2ch_fujitsu_pi2515_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_FUJITSU_XA3530] = {  		.mixers = { alc888_base_mixer, alc883_chmode_mixer }, @@ -10600,9 +10879,9 @@ static struct alc_config_preset alc882_presets[] = {  		.num_mux_defs =  			ARRAY_SIZE(alc888_2_capture_sources),  		.input_mux = alc888_2_capture_sources, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_fujitsu_xa3530_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_LENOVO_SKY] = {  		.mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, @@ -10614,9 +10893,9 @@ static struct alc_config_preset alc882_presets[] = {  		.channel_mode = alc883_sixstack_modes,  		.need_dac_fix = 1,  		.input_mux = &alc883_lenovo_sky_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc888_lenovo_sky_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC888_ASUS_M90V] = {  		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10684,9 +10963,9 @@ static struct alc_config_preset alc882_presets[] = {  		.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, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc883_vaiott_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  }; @@ -10699,7 +10978,6 @@ enum {  	PINFIX_LENOVO_Y530,  	PINFIX_PB_M5210,  	PINFIX_ACER_ASPIRE_7736, -	PINFIX_GIGABYTE_880GM,  };  static const struct alc_fixup alc882_fixups[] = { @@ -10731,21 +11009,13 @@ static const struct alc_fixup alc882_fixups[] = {  		.type = ALC_FIXUP_SKU,  		.v.sku = ALC_FIXUP_SKU_IGNORE,  	}, -	[PINFIX_GIGABYTE_880GM] = { -		.type = ALC_FIXUP_PINS, -		.v.pins = (const struct alc_pincfg[]) { -			{ 0x14, 0x1114410 }, /* set as speaker */ -			{ } -		} -	},  }; -static struct snd_pci_quirk alc882_fixup_tbl[] = { +static const 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), -	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM),  	{}  }; @@ -10849,6 +11119,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec)  		const struct hda_input_mux *imux;  		int conns, mute, idx, item; +		/* mute ADC */ +		snd_hda_codec_write(codec, spec->adc_nids[c], 0, +				    AC_VERB_SET_AMP_GAIN_MUTE, +				    AMP_IN_MUTE(0)); +  		conns = snd_hda_get_connections(codec, nid, conn_list,  						ARRAY_SIZE(conn_list));  		if (conns < 0) @@ -10928,7 +11203,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)  static int alc882_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };  	int err;  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, @@ -10941,6 +11216,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec)  	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);  	if (err < 0)  		return err; +	err = alc_auto_add_multi_channel_mode(codec); +	if (err < 0) +		return err;  	err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);  	if (err < 0)  		return err; @@ -11142,14 +11420,14 @@ static int patch_alc882(struct hda_codec *codec)  #define alc262_modes		alc260_modes  #define alc262_capture_source	alc882_capture_source -static hda_nid_t alc262_dmic_adc_nids[1] = { +static const hda_nid_t alc262_dmic_adc_nids[1] = {  	/* ADC0 */  	0x09  }; -static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; +static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; -static struct snd_kcontrol_new alc262_base_mixer[] = { +static const struct snd_kcontrol_new alc262_base_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11170,71 +11448,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {  };  /* update HP, line and mono-out pins according to the master switch */ -static void alc262_hp_master_update(struct hda_codec *codec) -{ -	struct alc_spec *spec = codec->spec; -	int val = spec->master_sw; - -	/* HP & line-out */ -	snd_hda_codec_write_cache(codec, 0x1b, 0, -				  AC_VERB_SET_PIN_WIDGET_CONTROL, -				  val ? PIN_HP : 0); -	snd_hda_codec_write_cache(codec, 0x15, 0, -				  AC_VERB_SET_PIN_WIDGET_CONTROL, -				  val ? PIN_HP : 0); -	/* mono (speaker) depending on the HP jack sense */ -	val = val && !spec->jack_present; -	snd_hda_codec_write_cache(codec, 0x16, 0, -				  AC_VERB_SET_PIN_WIDGET_CONTROL, -				  val ? PIN_OUT : 0); -} +#define alc262_hp_master_update		alc260_hp_master_update -static void alc262_hp_bpc_automute(struct hda_codec *codec) +static void alc262_hp_bpc_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	spec->jack_present = snd_hda_jack_detect(codec, 0x1b); -	alc262_hp_master_update(codec); -} - -static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) -{ -	if ((res >> 26) != ALC880_HP_EVENT) -		return; -	alc262_hp_bpc_automute(codec); +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.speaker_pins[0] = 0x16; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  } -static void alc262_hp_wildwest_automute(struct hda_codec *codec) +static void alc262_hp_wildwest_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	spec->jack_present = snd_hda_jack_detect(codec, 0x15); -	alc262_hp_master_update(codec); -} - -static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	if ((res >> 26) != ALC880_HP_EVENT) -		return; -	alc262_hp_wildwest_automute(codec); +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x16; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  }  #define alc262_hp_master_sw_get		alc260_hp_master_sw_get - -static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, -				   struct snd_ctl_elem_value *ucontrol) -{ -	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); -	struct alc_spec *spec = codec->spec; -	int val = !!*ucontrol->value.integer.value; - -	if (val == spec->master_sw) -		return 0; -	spec->master_sw = val; -	alc262_hp_master_update(codec); -	return 1; -} +#define alc262_hp_master_sw_put		alc260_hp_master_sw_put  #define ALC262_HP_MASTER_SWITCH					\  	{							\ @@ -11251,7 +11488,7 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,  	} -static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {  	ALC262_HP_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11275,7 +11512,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {  	ALC262_HP_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -11295,7 +11532,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {  	HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -11309,9 +11546,11 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  } -static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { +static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -11322,7 +11561,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_hp_t5735_verbs[] = { +static const struct hda_verb alc262_hp_t5735_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11330,7 +11569,7 @@ static struct hda_verb alc262_hp_t5735_verbs[] = {  	{ }  }; -static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { +static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -11340,7 +11579,7 @@ static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_hp_rp5700_verbs[] = { +static const struct hda_verb alc262_hp_rp5700_verbs[] = {  	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -11354,7 +11593,7 @@ static struct hda_verb alc262_hp_rp5700_verbs[] = {  	{}  }; -static struct hda_input_mux alc262_hp_rp5700_capture_source = { +static const struct hda_input_mux alc262_hp_rp5700_capture_source = {  	.num_items = 1,  	.items = {  		{ "Line", 0x1 }, @@ -11362,44 +11601,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = {  };  /* bind hp and internal speaker mute (with plug check) as master switch */ -static void alc262_hippo_master_update(struct hda_codec *codec) -{ -	struct alc_spec *spec = codec->spec; -	hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; -	hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; -	hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; -	unsigned int mute; - -	/* HP */ -	mute = spec->master_sw ? 0 : HDA_AMP_MUTE; -	snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, mute); -	/* mute internal speaker per jack sense */ -	if (spec->jack_present) -		mute = HDA_AMP_MUTE; -	if (line_nid) -		snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, mute); -	if (speaker_nid && speaker_nid != line_nid) -		snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, mute); -} - +#define alc262_hippo_master_update	alc262_hp_master_update  #define alc262_hippo_master_sw_get	alc262_hp_master_sw_get - -static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, -				      struct snd_ctl_elem_value *ucontrol) -{ -	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); -	struct alc_spec *spec = codec->spec; -	int val = !!*ucontrol->value.integer.value; - -	if (val == spec->master_sw) -		return 0; -	spec->master_sw = val; -	alc262_hippo_master_update(codec); -	return 1; -} +#define alc262_hippo_master_sw_put	alc262_hp_master_sw_put  #define ALC262_HIPPO_MASTER_SWITCH				\  	{							\ @@ -11416,7 +11620,7 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,  			     (SUBDEV_SPEAKER(0) << 16), \  	} -static struct snd_kcontrol_new alc262_hippo_mixer[] = { +static const struct snd_kcontrol_new alc262_hippo_mixer[] = {  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11433,7 +11637,7 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_hippo1_mixer[] = { +static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11450,28 +11654,14 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {  };  /* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_hippo_automute(struct hda_codec *codec) -{ -	struct alc_spec *spec = codec->spec; -	hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - -	spec->jack_present = snd_hda_jack_detect(codec, hp_nid); -	alc262_hippo_master_update(codec); -} - -static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) -{ -	if ((res >> 26) != ALC880_HP_EVENT) -		return; -	alc262_hippo_automute(codec); -} -  static void alc262_hippo_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc262_hippo1_setup(struct hda_codec *codec) @@ -11480,10 +11670,12 @@ static void alc262_hippo1_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct snd_kcontrol_new alc262_sony_mixer[] = { +static const struct snd_kcontrol_new alc262_sony_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -11493,7 +11685,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { +static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11504,7 +11696,7 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_tyan_mixer[] = { +static const struct snd_kcontrol_new alc262_tyan_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), @@ -11520,7 +11712,7 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_tyan_verbs[] = { +static const struct hda_verb alc262_tyan_verbs[] = {  	/* Headphone automute */  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11542,6 +11734,8 @@ static void alc262_tyan_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } @@ -11551,7 +11745,7 @@ static void alc262_tyan_setup(struct hda_codec *codec)  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc262_init_verbs[] = { +static const struct hda_verb alc262_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -11627,13 +11821,13 @@ static struct hda_verb alc262_init_verbs[] = {  	{ }  }; -static struct hda_verb alc262_eapd_verbs[] = { +static const struct hda_verb alc262_eapd_verbs[] = {  	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; -static struct hda_verb alc262_hippo1_unsol_verbs[] = { +static const struct hda_verb alc262_hippo1_unsol_verbs[] = {  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},  	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, @@ -11643,7 +11837,7 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {  	{}  }; -static struct hda_verb alc262_sony_unsol_verbs[] = { +static const struct hda_verb alc262_sony_unsol_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic @@ -11653,7 +11847,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {  	{}  }; -static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { +static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11662,7 +11856,7 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_toshiba_s06_verbs[] = { +static const struct hda_verb alc262_toshiba_s06_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11685,6 +11879,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)  	spec->int_mic.pin = 0x12;  	spec->int_mic.mux_idx = 9;  	spec->auto_mic = 1; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  }  /* @@ -11694,7 +11890,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec)   *  0x18 = external mic   */ -static struct snd_kcontrol_new alc262_nec_mixer[] = { +static const struct snd_kcontrol_new alc262_nec_mixer[] = {  	HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), @@ -11707,7 +11903,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_nec_verbs[] = { +static const struct hda_verb alc262_nec_verbs[] = {  	/* Unmute Speaker */  	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -11730,7 +11926,7 @@ static struct hda_verb alc262_nec_verbs[] = {  #define ALC_HP_EVENT	0x37 -static struct hda_verb alc262_fujitsu_unsol_verbs[] = { +static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {  	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, @@ -11738,20 +11934,20 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = {  	{}  }; -static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { +static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{}  }; -static struct hda_verb alc262_lenovo_3000_init_verbs[] = { +static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {  	/* Front Mic pin: input vref at 50% */  	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},  	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},  	{}  }; -static struct hda_input_mux alc262_fujitsu_capture_source = { +static const struct hda_input_mux alc262_fujitsu_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -11760,7 +11956,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = {  	},  }; -static struct hda_input_mux alc262_HP_capture_source = { +static const struct hda_input_mux alc262_HP_capture_source = {  	.num_items = 5,  	.items = {  		{ "Mic", 0x0 }, @@ -11771,7 +11967,7 @@ static struct hda_input_mux alc262_HP_capture_source = {  	},  }; -static struct hda_input_mux alc262_HP_D7000_capture_source = { +static const struct hda_input_mux alc262_HP_D7000_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -11781,44 +11977,19 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = {  	},  }; -/* mute/unmute internal speaker according to the hp jacks and mute state */ -static void alc262_fujitsu_automute(struct hda_codec *codec, int force) +static void alc262_fujitsu_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	unsigned int mute; -	if (force || !spec->sense_updated) { -		spec->jack_present = snd_hda_jack_detect(codec, 0x14) || -				     snd_hda_jack_detect(codec, 0x1b); -		spec->sense_updated = 1; -	} -	/* unmute internal speaker only if both HPs are unplugged and -	 * master switch is on -	 */ -	if (spec->jack_present) -		mute = HDA_AMP_MUTE; -	else -		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, mute); -} - -/* unsolicited event for HP jack sensing */ -static void alc262_fujitsu_unsol_event(struct hda_codec *codec, -				       unsigned int res) -{ -	if ((res >> 26) != ALC_HP_EVENT) -		return; -	alc262_fujitsu_automute(codec, 1); -} - -static void alc262_fujitsu_init_hook(struct hda_codec *codec) -{ -	alc262_fujitsu_automute(codec, 1); +	spec->autocfg.hp_pins[0] = 0x14; +	spec->autocfg.hp_pins[1] = 0x1b; +	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  /* bind volumes of both NID 0x0c and 0x0d */ -static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { +static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), @@ -11827,78 +11998,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {  	},  }; -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) -{ -	struct alc_spec *spec = codec->spec; -	unsigned int mute; - -	if (force || !spec->sense_updated) { -		spec->jack_present = snd_hda_jack_detect(codec, 0x1b); -		spec->sense_updated = 1; -	} -	if (spec->jack_present) { -		/* mute internal speaker */ -		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, HDA_AMP_MUTE); -		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, HDA_AMP_MUTE); -	} else { -		/* unmute internal speaker if necessary */ -		mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); -		snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, mute); -		snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, -					 HDA_AMP_MUTE, mute); -	} -} - -/* unsolicited event for HP jack sensing */ -static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, -				       unsigned int res) -{ -	if ((res >> 26) != ALC_HP_EVENT) -		return; -	alc262_lenovo_3000_automute(codec, 1); -} - -static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, -				  int dir, int idx, long *valp) -{ -	int i, change = 0; - -	for (i = 0; i < 2; i++, valp++) -		change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, -						   HDA_AMP_MUTE, -						   *valp ? 0 : HDA_AMP_MUTE); -	return change; -} - -/* bind hp and internal speaker mute (with plug check) */ -static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, -					 struct snd_ctl_elem_value *ucontrol) -{ -	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); -	long *valp = ucontrol->value.integer.value; -	int change; - -	change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); -	change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); -	if (change) -		alc262_fujitsu_automute(codec, 0); -	return change; -} - -static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", -		.subdevice = HDA_SUBDEV_AMP_FLAG, -		.info = snd_hda_mixer_amp_switch_info, -		.get = snd_hda_mixer_amp_switch_get, -		.put = alc262_fujitsu_master_sw_put, -		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), +		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14, +		.info = snd_ctl_boolean_mono_info, +		.get = alc262_hp_master_sw_get, +		.put = alc262_hp_master_sw_put,  	},  	{  		.iface = NID_MAPPING, @@ -11916,30 +12024,26 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {  	{ } /* end */  }; -/* bind hp and internal speaker mute (with plug check) */ -static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, -					 struct snd_ctl_elem_value *ucontrol) +static void alc262_lenovo_3000_setup(struct hda_codec *codec)  { -	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); -	long *valp = ucontrol->value.integer.value; -	int change; +	struct alc_spec *spec = codec->spec; -	change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); -	if (change) -		alc262_lenovo_3000_automute(codec, 0); -	return change; +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->autocfg.speaker_pins[1] = 0x16; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } -static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { +static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", -		.subdevice = HDA_SUBDEV_AMP_FLAG, -		.info = snd_hda_mixer_amp_switch_info, -		.get = snd_hda_mixer_amp_switch_get, -		.put = alc262_lenovo_3000_master_sw_put, -		.private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), +		.subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, +		.info = snd_ctl_boolean_mono_info, +		.get = alc262_hp_master_sw_get, +		.put = alc262_hp_master_sw_put,  	},  	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),  	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -11952,7 +12056,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { +static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -11965,13 +12069,13 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {  };  /* additional init verbs for Benq laptops */ -static struct hda_verb alc262_EAPD_verbs[] = { +static const struct hda_verb alc262_EAPD_verbs[] = {  	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},  	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},  	{}  }; -static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { +static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},  	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, @@ -11981,7 +12085,7 @@ static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {  };  /* Samsung Q1 Ultra Vista model setup */ -static struct snd_kcontrol_new alc262_ultra_mixer[] = { +static const struct snd_kcontrol_new alc262_ultra_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), @@ -11991,7 +12095,7 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc262_ultra_verbs[] = { +static const struct hda_verb alc262_ultra_verbs[] = {  	/* output mixer */  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -12054,7 +12158,7 @@ static void alc262_ultra_unsol_event(struct hda_codec *codec,  	alc262_ultra_automute(codec);  } -static struct hda_input_mux alc262_ultra_capture_source = { +static const struct hda_input_mux alc262_ultra_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x1 }, @@ -12080,7 +12184,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,  	return ret;  } -static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { +static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),  	{ @@ -12155,9 +12259,9 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,  	spec->multiout.num_dacs = 1;	/* only use one dac */  	spec->multiout.dac_nids = spec->private_dac_nids; -	spec->multiout.dac_nids[0] = 2; +	spec->private_dac_nids[0] = 2; -	pfx = alc_get_line_out_pfx(cfg, true); +	pfx = alc_get_line_out_pfx(spec, true);  	if (!pfx)  		pfx = "Front";  	for (i = 0; i < 2; i++) { @@ -12211,7 +12315,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc262_volume_init_verbs[] = { +static const struct hda_verb alc262_volume_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -12272,7 +12376,7 @@ static struct hda_verb alc262_volume_init_verbs[] = {  	{ }  }; -static struct hda_verb alc262_HP_BPC_init_verbs[] = { +static const struct hda_verb alc262_HP_BPC_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -12376,7 +12480,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {  	{ }  }; -static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { +static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {  	/*  	 * Unmute ADC0-2 and set the default input to mic-in  	 */ @@ -12472,7 +12576,7 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {  	{ }  }; -static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { +static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },	/* Front Speaker */  	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -12508,7 +12612,7 @@ static const struct alc_fixup alc262_fixups[] = {  	},  }; -static struct snd_pci_quirk alc262_fixup_tbl[] = { +static const struct snd_pci_quirk alc262_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),  	{}  }; @@ -12531,7 +12635,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc262_ignore); @@ -12616,7 +12720,7 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = {  	[ALC262_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc262_cfg_tbl[] = { +static const struct snd_pci_quirk alc262_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),  	SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),  	SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", @@ -12668,7 +12772,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc262_presets[] = { +static const struct alc_config_preset alc262_presets[] = {  	[ALC262_BASIC] = {  		.mixers = { alc262_base_mixer },  		.init_verbs = { alc262_init_verbs }, @@ -12689,9 +12793,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc262_hippo_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_hippo_setup, -		.init_hook = alc262_hippo_automute, +		.init_hook = alc_inithook,  	},  	[ALC262_HIPPO_1] = {  		.mixers = { alc262_hippo1_mixer }, @@ -12703,9 +12807,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc262_hippo_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_hippo1_setup, -		.init_hook = alc262_hippo_automute, +		.init_hook = alc_inithook,  	},  	[ALC262_FUJITSU] = {  		.mixers = { alc262_fujitsu_mixer }, @@ -12718,8 +12822,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_fujitsu_capture_source, -		.unsol_event = alc262_fujitsu_unsol_event, -		.init_hook = alc262_fujitsu_init_hook, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc262_fujitsu_setup, +		.init_hook = alc_inithook,  	},  	[ALC262_HP_BPC] = {  		.mixers = { alc262_HP_BPC_mixer }, @@ -12730,8 +12835,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_HP_capture_source, -		.unsol_event = alc262_hp_bpc_unsol_event, -		.init_hook = alc262_hp_bpc_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc262_hp_bpc_setup, +		.init_hook = alc_inithook,  	},  	[ALC262_HP_BPC_D7000_WF] = {  		.mixers = { alc262_HP_BPC_WildWest_mixer }, @@ -12742,8 +12848,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_HP_D7000_capture_source, -		.unsol_event = alc262_hp_wildwest_unsol_event, -		.init_hook = alc262_hp_wildwest_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc262_hp_wildwest_setup, +		.init_hook = alc_inithook,  	},  	[ALC262_HP_BPC_D7000_WL] = {  		.mixers = { alc262_HP_BPC_WildWest_mixer, @@ -12755,8 +12862,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_HP_D7000_capture_source, -		.unsol_event = alc262_hp_wildwest_unsol_event, -		.init_hook = alc262_hp_wildwest_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc262_hp_wildwest_setup, +		.init_hook = alc_inithook,  	},  	[ALC262_HP_TC_T5735] = {  		.mixers = { alc262_hp_t5735_mixer }, @@ -12799,9 +12907,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc262_hippo_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_hippo_setup, -		.init_hook = alc262_hippo_automute, +		.init_hook = alc_inithook,  	},  	[ALC262_BENQ_T31] = {  		.mixers = { alc262_benq_t31_mixer }, @@ -12813,9 +12921,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc262_hippo_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_hippo_setup, -		.init_hook = alc262_hippo_automute, +		.init_hook = alc_inithook,  	},  	[ALC262_ULTRA] = {  		.mixers = { alc262_ultra_mixer }, @@ -12844,7 +12952,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_fujitsu_capture_source, -		.unsol_event = alc262_lenovo_3000_unsol_event, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc262_lenovo_3000_setup, +		.init_hook = alc_inithook,  	},  	[ALC262_NEC] = {  		.mixers = { alc262_nec_mixer }, @@ -12881,9 +12991,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc262_hippo_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_hippo_setup, -		.init_hook = alc262_hippo_automute, +		.init_hook = alc_inithook,  	},  	[ALC262_TYAN] = {  		.mixers = { alc262_tyan_mixer }, @@ -12895,9 +13005,9 @@ static struct alc_config_preset alc262_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc262_modes),  		.channel_mode = alc262_modes,  		.input_mux = &alc262_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc262_tyan_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  }; @@ -13018,6 +13128,7 @@ static int patch_alc262(struct hda_codec *codec)  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC262_AUTO)  		spec->init_hook = alc262_auto_init; +	spec->shutup = alc_eapd_shutup;  	alc_init_jacks(codec);  #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -13034,24 +13145,24 @@ static int patch_alc262(struct hda_codec *codec)  #define ALC268_DIGOUT_NID	ALC880_DIGOUT_NID  #define alc268_modes		alc260_modes -static hda_nid_t alc268_dac_nids[2] = { +static const hda_nid_t alc268_dac_nids[2] = {  	/* front, hp */  	0x02, 0x03  }; -static hda_nid_t alc268_adc_nids[2] = { +static const hda_nid_t alc268_adc_nids[2] = {  	/* ADC0-1 */  	0x08, 0x07  }; -static hda_nid_t alc268_adc_nids_alt[1] = { +static const hda_nid_t alc268_adc_nids_alt[1] = {  	/* ADC0 */  	0x08  }; -static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; +static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; -static struct snd_kcontrol_new alc268_base_mixer[] = { +static const struct snd_kcontrol_new alc268_base_mixer[] = {  	/* output mixer control */  	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -13063,7 +13174,7 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {  	{ }  }; -static struct snd_kcontrol_new alc268_toshiba_mixer[] = { +static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {  	/* output mixer control */  	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), @@ -13075,7 +13186,7 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = {  };  /* bind Beep switches of both NID 0x0f and 0x10 */ -static struct hda_bind_ctls alc268_bind_beep_sw = { +static const struct hda_bind_ctls alc268_bind_beep_sw = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), @@ -13084,27 +13195,27 @@ static struct hda_bind_ctls alc268_bind_beep_sw = {  	},  }; -static struct snd_kcontrol_new alc268_beep_mixer[] = { +static const struct snd_kcontrol_new alc268_beep_mixer[] = {  	HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),  	HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),  	{ }  }; -static struct hda_verb alc268_eapd_verbs[] = { +static const struct hda_verb alc268_eapd_verbs[] = {  	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  };  /* Toshiba specific */ -static struct hda_verb alc268_toshiba_verbs[] = { +static const struct hda_verb alc268_toshiba_verbs[] = {  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},  	{ } /* end */  };  /* Acer specific */  /* bind volumes of both NID 0x02 and 0x03 */ -static struct hda_bind_ctls alc268_acer_bind_master_vol = { +static const struct hda_bind_ctls alc268_acer_bind_master_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -13113,66 +13224,44 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = {  	},  }; -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc268_acer_automute(struct hda_codec *codec, int force) +static void alc268_acer_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; -	unsigned int mute; -	if (force || !spec->sense_updated) { -		spec->jack_present = snd_hda_jack_detect(codec, 0x14); -		spec->sense_updated = 1; -	} -	if (spec->jack_present) -		mute = HDA_AMP_MUTE; /* mute internal speaker */ -	else /* unmute internal speaker if necessary */ -		mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, mute); +	spec->autocfg.hp_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  } +#define alc268_acer_master_sw_get	alc262_hp_master_sw_get +#define alc268_acer_master_sw_put	alc262_hp_master_sw_put -/* bind hp and internal speaker mute (with plug check) */ -static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, -				     struct snd_ctl_elem_value *ucontrol) -{ -	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); -	long *valp = ucontrol->value.integer.value; -	int change; - -	change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); -	if (change) -		alc268_acer_automute(codec, 0); -	return change; -} - -static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {  	/* output mixer control */  	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", -		.subdevice = HDA_SUBDEV_AMP_FLAG, -		.info = snd_hda_mixer_amp_switch_info, -		.get = snd_hda_mixer_amp_switch_get, +		.subdevice = HDA_SUBDEV_NID_FLAG | 0x15, +		.info = snd_ctl_boolean_mono_info, +		.get = alc268_acer_master_sw_get,  		.put = alc268_acer_master_sw_put, -		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),  	},  	HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),  	{ }  }; -static struct snd_kcontrol_new alc268_acer_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_mixer[] = {  	/* output mixer control */  	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", -		.subdevice = HDA_SUBDEV_AMP_FLAG, -		.info = snd_hda_mixer_amp_switch_info, -		.get = snd_hda_mixer_amp_switch_get, +		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14, +		.info = snd_ctl_boolean_mono_info, +		.get = alc268_acer_master_sw_get,  		.put = alc268_acer_master_sw_put, -		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),  	},  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),  	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), @@ -13180,24 +13269,23 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {  	{ }  }; -static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {  	/* output mixer control */  	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Master Playback Switch", -		.subdevice = HDA_SUBDEV_AMP_FLAG, -		.info = snd_hda_mixer_amp_switch_info, -		.get = snd_hda_mixer_amp_switch_get, +		.subdevice = HDA_SUBDEV_NID_FLAG | 0x14, +		.info = snd_ctl_boolean_mono_info, +		.get = alc268_acer_master_sw_get,  		.put = alc268_acer_master_sw_put, -		.private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),  	},  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),  	HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),  	{ }  }; -static struct hda_verb alc268_acer_aspire_one_verbs[] = { +static const struct hda_verb alc268_acer_aspire_one_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -13207,7 +13295,7 @@ static struct hda_verb alc268_acer_aspire_one_verbs[] = {  	{ }  }; -static struct hda_verb alc268_acer_verbs[] = { +static const struct hda_verb alc268_acer_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */  	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -13219,53 +13307,16 @@ static struct hda_verb alc268_acer_verbs[] = {  };  /* unsolicited event for HP jack sensing */ -#define alc268_toshiba_unsol_event	alc262_hippo_unsol_event  #define alc268_toshiba_setup		alc262_hippo_setup -#define alc268_toshiba_automute		alc262_hippo_automute - -static void alc268_acer_unsol_event(struct hda_codec *codec, -				       unsigned int res) -{ -	if ((res >> 26) != ALC880_HP_EVENT) -		return; -	alc268_acer_automute(codec, 1); -} - -static void alc268_acer_init_hook(struct hda_codec *codec) -{ -	alc268_acer_automute(codec, 1); -} - -/* toggle speaker-output according to the hp-jack state */ -static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -} - -static void alc268_acer_lc_unsol_event(struct hda_codec *codec, -				    unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc268_aspire_one_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -}  static void alc268_acer_lc_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0f; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x12; @@ -13273,13 +13324,7 @@ static void alc268_acer_lc_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } -static void alc268_acer_lc_init_hook(struct hda_codec *codec) -{ -	alc268_aspire_one_speaker_automute(codec); -	alc_mic_automute(codec); -} - -static struct snd_kcontrol_new alc268_dell_mixer[] = { +static const struct snd_kcontrol_new alc268_dell_mixer[] = {  	/* output mixer control */  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -13290,7 +13335,7 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = {  	{ }  }; -static struct hda_verb alc268_dell_verbs[] = { +static const struct hda_verb alc268_dell_verbs[] = {  	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -13310,9 +13355,11 @@ static void alc268_dell_setup(struct hda_codec *codec)  	spec->int_mic.pin = 0x19;  	spec->int_mic.mux_idx = 1;  	spec->auto_mic = 1; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  } -static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { +static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), @@ -13324,7 +13371,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {  	{ }  }; -static struct hda_verb alc267_quanta_il1_verbs[] = { +static const struct hda_verb alc267_quanta_il1_verbs[] = {  	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},  	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},  	{ } @@ -13340,12 +13387,14 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec)  	spec->int_mic.pin = 0x19;  	spec->int_mic.mux_idx = 1;  	spec->auto_mic = 1; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN;  }  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc268_base_init_verbs[] = { +static const struct hda_verb alc268_base_init_verbs[] = {  	/* Unmute DAC0-1 and set vol = 0 */  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -13393,7 +13442,7 @@ static struct hda_verb alc268_base_init_verbs[] = {  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc268_volume_init_verbs[] = { +static const struct hda_verb alc268_volume_init_verbs[] = {  	/* set output DAC */  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -13419,20 +13468,20 @@ static struct hda_verb alc268_volume_init_verbs[] = {  	{ }  }; -static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),  	{ } /* end */  }; -static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),  	_DEFINE_CAPSRC(1),  	{ } /* end */  }; -static struct snd_kcontrol_new alc268_capture_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), @@ -13441,7 +13490,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {  	{ } /* end */  }; -static struct hda_input_mux alc268_capture_source = { +static const struct hda_input_mux alc268_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -13451,7 +13500,7 @@ static struct hda_input_mux alc268_capture_source = {  	},  }; -static struct hda_input_mux alc268_acer_capture_source = { +static const struct hda_input_mux alc268_acer_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -13460,7 +13509,7 @@ static struct hda_input_mux alc268_acer_capture_source = {  	},  }; -static struct hda_input_mux alc268_acer_dmic_capture_source = { +static const struct hda_input_mux alc268_acer_dmic_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -13470,7 +13519,7 @@ static struct hda_input_mux alc268_acer_dmic_capture_source = {  };  #ifdef CONFIG_SND_DEBUG -static struct snd_kcontrol_new alc268_test_mixer[] = { +static const struct snd_kcontrol_new alc268_test_mixer[] = {  	/* Volume widgets */  	HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -13549,7 +13598,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,  						      HDA_OUTPUT));  		if (err < 0)  			return err; -		spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; +		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;  	}  	if (nid != 0x16) @@ -13722,7 +13771,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc268_ignore[] = { 0 }; +	static const hda_nid_t alc268_ignore[] = { 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc268_ignore); @@ -13802,7 +13851,7 @@ static const char * const alc268_models[ALC268_MODEL_LAST] = {  	[ALC268_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc268_cfg_tbl[] = { +static const struct snd_pci_quirk alc268_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),  	SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),  	SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), @@ -13827,7 +13876,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {  };  /* Toshiba laptops have no unique PCI SSID but only codec SSID */ -static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { +static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),  	SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),  	SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", @@ -13835,7 +13884,7 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc268_presets[] = { +static const struct alc_config_preset alc268_presets[] = {  	[ALC267_QUANTA_IL1] = {  		.mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,  			    alc268_capture_nosrc_mixer }, @@ -13881,9 +13930,9 @@ static struct alc_config_preset alc268_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc268_modes),  		.channel_mode = alc268_modes,  		.input_mux = &alc268_capture_source, -		.unsol_event = alc268_toshiba_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc268_toshiba_setup, -		.init_hook = alc268_toshiba_automute, +		.init_hook = alc_inithook,  	},  	[ALC268_ACER] = {  		.mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, @@ -13899,8 +13948,9 @@ static struct alc_config_preset alc268_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc268_modes),  		.channel_mode = alc268_modes,  		.input_mux = &alc268_acer_capture_source, -		.unsol_event = alc268_acer_unsol_event, -		.init_hook = alc268_acer_init_hook, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc268_acer_setup, +		.init_hook = alc_inithook,  	},  	[ALC268_ACER_DMIC] = {  		.mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, @@ -13916,8 +13966,9 @@ static struct alc_config_preset alc268_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc268_modes),  		.channel_mode = alc268_modes,  		.input_mux = &alc268_acer_dmic_capture_source, -		.unsol_event = alc268_acer_unsol_event, -		.init_hook = alc268_acer_init_hook, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc268_acer_setup, +		.init_hook = alc_inithook,  	},  	[ALC268_ACER_ASPIRE_ONE] = {  		.mixers = { alc268_acer_aspire_one_mixer, @@ -13933,9 +13984,9 @@ static struct alc_config_preset alc268_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc268_modes),  		.channel_mode = alc268_modes, -		.unsol_event = alc268_acer_lc_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc268_acer_lc_setup, -		.init_hook = alc268_acer_lc_init_hook, +		.init_hook = alc_inithook,  	},  	[ALC268_DELL] = {  		.mixers = { alc268_dell_mixer, alc268_beep_mixer, @@ -13969,8 +14020,9 @@ static struct alc_config_preset alc268_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc268_modes),  		.channel_mode = alc268_modes,  		.input_mux = &alc268_capture_source, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc268_toshiba_setup, -		.init_hook = alc268_toshiba_automute, +		.init_hook = alc_inithook,  	},  #ifdef CONFIG_SND_DEBUG  	[ALC268_TEST] = { @@ -14092,6 +14144,7 @@ static int patch_alc268(struct hda_codec *codec)  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC268_AUTO)  		spec->init_hook = alc268_auto_init; +	spec->shutup = alc_eapd_shutup;  	alc_init_jacks(codec); @@ -14105,32 +14158,32 @@ static int patch_alc268(struct hda_codec *codec)  #define alc269_dac_nids		alc260_dac_nids -static hda_nid_t alc269_adc_nids[1] = { +static const hda_nid_t alc269_adc_nids[1] = {  	/* ADC1 */  	0x08,  }; -static hda_nid_t alc269_capsrc_nids[1] = { +static const hda_nid_t alc269_capsrc_nids[1] = {  	0x23,  }; -static hda_nid_t alc269vb_adc_nids[1] = { +static const hda_nid_t alc269vb_adc_nids[1] = {  	/* ADC1 */  	0x09,  }; -static hda_nid_t alc269vb_capsrc_nids[1] = { +static const hda_nid_t alc269vb_capsrc_nids[1] = {  	0x22,  }; -static hda_nid_t alc269_adc_candidates[] = { +static const hda_nid_t alc269_adc_candidates[] = {  	0x08, 0x09, 0x07, 0x11,  };  #define alc269_modes		alc260_modes  #define alc269_capture_source	alc880_lg_lw_capture_source -static struct snd_kcontrol_new alc269_base_mixer[] = { +static const struct snd_kcontrol_new alc269_base_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), @@ -14146,7 +14199,7 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { +static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {  	/* output mixer control */  	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),  	{ @@ -14167,7 +14220,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {  	{ }  }; -static struct snd_kcontrol_new alc269_lifebook_mixer[] = { +static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {  	/* output mixer control */  	HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),  	{ @@ -14191,7 +14244,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {  	{ }  }; -static struct snd_kcontrol_new alc269_laptop_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_mixer[] = {  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -14199,7 +14252,7 @@ static struct snd_kcontrol_new alc269_laptop_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), @@ -14207,14 +14260,14 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc269_asus_mixer[] = { +static const struct snd_kcontrol_new alc269_asus_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),  	{ } /* end */  };  /* capture mixer elements */ -static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14222,14 +14275,14 @@ static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),  	{ } /* end */  }; -static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14237,7 +14290,7 @@ static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14247,7 +14300,7 @@ static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {  /* FSC amilo */  #define alc269_fujitsu_mixer	alc269_laptop_mixer -static struct hda_verb alc269_quanta_fl1_verbs[] = { +static const struct hda_verb alc269_quanta_fl1_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -14257,7 +14310,7 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = {  	{ }  }; -static struct hda_verb alc269_lifebook_verbs[] = { +static const struct hda_verb alc269_lifebook_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -14274,15 +14327,7 @@ static struct hda_verb alc269_lifebook_verbs[] = {  /* toggle speaker-output according to the hp-jack state */  static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)  { -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); +	alc_hp_automute(codec);  	snd_hda_codec_write(codec, 0x20, 0,  			AC_VERB_SET_COEF_INDEX, 0x0c); @@ -14295,34 +14340,8 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)  			AC_VERB_SET_PROC_COEF, 0x480);  } -/* toggle speaker-output according to the hp-jacks state */ -static void alc269_lifebook_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	/* Check laptop headphone socket */ -	present = snd_hda_jack_detect(codec, 0x15); - -	/* Check port replicator headphone socket */ -	present |= snd_hda_jack_detect(codec, 0x1a); - -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); - -	snd_hda_codec_write(codec, 0x20, 0, -			AC_VERB_SET_COEF_INDEX, 0x0c); -	snd_hda_codec_write(codec, 0x20, 0, -			AC_VERB_SET_PROC_COEF, 0x680); - -	snd_hda_codec_write(codec, 0x20, 0, -			AC_VERB_SET_COEF_INDEX, 0x0c); -	snd_hda_codec_write(codec, 0x20, 0, -			AC_VERB_SET_PROC_COEF, 0x480); -} +#define alc269_lifebook_speaker_automute \ +	alc269_quanta_fl1_speaker_automute  static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)  { @@ -14371,6 +14390,9 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x19; @@ -14384,13 +14406,24 @@ static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)  	alc_mic_automute(codec);  } +static void alc269_lifebook_setup(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.hp_pins[1] = 0x1a; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER; +} +  static void alc269_lifebook_init_hook(struct hda_codec *codec)  {  	alc269_lifebook_speaker_automute(codec);  	alc269_lifebook_mic_autoswitch(codec);  } -static struct hda_verb alc269_laptop_dmic_init_verbs[] = { +static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x23, AC_VERB_SET_CONNECT_SEL, 0x05},  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14401,7 +14434,7 @@ static struct hda_verb alc269_laptop_dmic_init_verbs[] = {  	{}  }; -static struct hda_verb alc269_laptop_amic_init_verbs[] = { +static const struct hda_verb alc269_laptop_amic_init_verbs[] = {  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x23, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14411,7 +14444,7 @@ static struct hda_verb alc269_laptop_amic_init_verbs[] = {  	{}  }; -static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { +static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {  	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x22, AC_VERB_SET_CONNECT_SEL, 0x06},  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14422,7 +14455,7 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {  	{}  }; -static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { +static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {  	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x22, AC_VERB_SET_CONNECT_SEL, 0x01},  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14433,7 +14466,7 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {  	{}  }; -static struct hda_verb alc271_acer_dmic_verbs[] = { +static const struct hda_verb alc271_acer_dmic_verbs[] = {  	{0x20, AC_VERB_SET_COEF_INDEX, 0x0d},  	{0x20, AC_VERB_SET_PROC_COEF, 0x4000},  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -14447,42 +14480,14 @@ static struct hda_verb alc271_acer_dmic_verbs[] = {  	{ }  }; -/* toggle speaker-output according to the hp-jack state */ -static void alc269_speaker_automute(struct hda_codec *codec) -{ -	struct alc_spec *spec = codec->spec; -	unsigned int nid = spec->autocfg.hp_pins[0]; -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, nid); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -	snd_hda_input_jack_report(codec, nid); -} - -/* unsolicited event for HP jack sensing */ -static void alc269_laptop_unsol_event(struct hda_codec *codec, -				     unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc269_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -} -  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->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x19; @@ -14495,6 +14500,9 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x12; @@ -14507,6 +14515,9 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x21;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x19; @@ -14519,6 +14530,9 @@ 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->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x12; @@ -14526,16 +14540,10 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } -static void alc269_laptop_inithook(struct hda_codec *codec) -{ -	alc269_speaker_automute(codec); -	alc_mic_automute(codec); -} -  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc269_init_verbs[] = { +static const struct hda_verb alc269_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -14578,7 +14586,7 @@ static struct hda_verb alc269_init_verbs[] = {  	{ }  }; -static struct hda_verb alc269vb_init_verbs[] = { +static const struct hda_verb alc269vb_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -14636,7 +14644,7 @@ static struct hda_verb alc269vb_init_verbs[] = {  #define alc269_pcm_digital_playback	alc880_pcm_digital_playback  #define alc269_pcm_digital_capture	alc880_pcm_digital_capture -static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { +static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 8, @@ -14649,7 +14657,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {  	},  }; -static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { +static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {  	.substreams = 1,  	.channels_min = 2,  	.channels_max = 2, @@ -14733,7 +14741,7 @@ 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 }; +	static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc269_ignore); @@ -14803,7 +14811,6 @@ static void alc269_auto_init(struct hda_codec *codec)  		alc_inithook(codec);  } -#ifdef SND_HDA_NEEDS_RESUME  static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)  {  	int val = alc_read_coef_idx(codec, 0x04); @@ -14814,25 +14821,17 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)  	alc_write_coef_idx(codec, 0x04, val);  } -#ifdef CONFIG_SND_HDA_POWER_SAVE -static int alc269_suspend(struct hda_codec *codec, pm_message_t state) +static void alc269_shutup(struct hda_codec *codec)  { -	struct alc_spec *spec = codec->spec; -  	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)  		alc269_toggle_power_output(codec, 0);  	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {  		alc269_toggle_power_output(codec, 0);  		msleep(150);  	} - -	alc_shutup(codec); -	if (spec && spec->power_hook) -		spec->power_hook(codec); -	return 0;  } -#endif /* CONFIG_SND_HDA_POWER_SAVE */ +#ifdef SND_HDA_NEEDS_RESUME  static int alc269_resume(struct hda_codec *codec)  {  	if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { @@ -14868,6 +14867,23 @@ static void alc269_fixup_hweq(struct hda_codec *codec,  	alc_write_coef_idx(codec, 0x1e, coef | 0x80);  } +static void alc271_fixup_dmic(struct hda_codec *codec, +			      const struct alc_fixup *fix, int action) +{ +	static const struct hda_verb verbs[] = { +		{0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, +		{0x20, AC_VERB_SET_PROC_COEF, 0x4000}, +		{} +	}; +	unsigned int cfg; + +	if (strcmp(codec->chip_name, "ALC271X")) +		return; +	cfg = snd_hda_codec_get_pincfg(codec, 0x12); +	if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) +		snd_hda_sequence_write(codec, verbs); +} +  enum {  	ALC269_FIXUP_SONY_VAIO,  	ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -14876,6 +14892,7 @@ enum {  	ALC269_FIXUP_ASUS_G73JW,  	ALC269_FIXUP_LENOVO_EAPD,  	ALC275_FIXUP_SONY_HWEQ, +	ALC271_FIXUP_DMIC,  };  static const struct alc_fixup alc269_fixups[] = { @@ -14929,15 +14946,20 @@ static const struct alc_fixup alc269_fixups[] = {  		.v.func = alc269_fixup_hweq,  		.chained = true,  		.chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 -	} +	}, +	[ALC271_FIXUP_DMIC] = { +		.type = ALC_FIXUP_FUNC, +		.v.func = alc271_fixup_dmic, +	},  }; -static struct snd_pci_quirk alc269_fixup_tbl[] = { +static const struct snd_pci_quirk alc269_fixup_tbl[] = {  	SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),  	SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),  	SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),  	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),  	SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), +	SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),  	SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),  	SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),  	SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), @@ -14962,7 +14984,7 @@ static const char * const alc269_models[ALC269_MODEL_LAST] = {  	[ALC269_AUTO]			= "auto",  }; -static struct snd_pci_quirk alc269_cfg_tbl[] = { +static const struct snd_pci_quirk alc269_cfg_tbl[] = {  	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),  	SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),  	SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", @@ -15020,7 +15042,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc269_presets[] = { +static const struct alc_config_preset alc269_presets[] = {  	[ALC269_BASIC] = {  		.mixers = { alc269_base_mixer },  		.init_verbs = { alc269_init_verbs }, @@ -15054,9 +15076,9 @@ static struct alc_config_preset alc269_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes, -		.unsol_event = alc269_laptop_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc269_laptop_amic_setup, -		.init_hook = alc269_laptop_inithook, +		.init_hook = alc_inithook,  	},  	[ALC269_DMIC] = {  		.mixers = { alc269_laptop_mixer }, @@ -15068,9 +15090,9 @@ static struct alc_config_preset alc269_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes, -		.unsol_event = alc269_laptop_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc269_laptop_dmic_setup, -		.init_hook = alc269_laptop_inithook, +		.init_hook = alc_inithook,  	},  	[ALC269VB_AMIC] = {  		.mixers = { alc269vb_laptop_mixer }, @@ -15082,9 +15104,9 @@ static struct alc_config_preset alc269_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes, -		.unsol_event = alc269_laptop_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc269vb_laptop_amic_setup, -		.init_hook = alc269_laptop_inithook, +		.init_hook = alc_inithook,  	},  	[ALC269VB_DMIC] = {  		.mixers = { alc269vb_laptop_mixer }, @@ -15096,9 +15118,9 @@ static struct alc_config_preset alc269_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes, -		.unsol_event = alc269_laptop_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc269vb_laptop_dmic_setup, -		.init_hook = alc269_laptop_inithook, +		.init_hook = alc_inithook,  	},  	[ALC269_FUJITSU] = {  		.mixers = { alc269_fujitsu_mixer }, @@ -15110,9 +15132,9 @@ static struct alc_config_preset alc269_presets[] = {  		.hp_nid = 0x03,  		.num_channel_mode = ARRAY_SIZE(alc269_modes),  		.channel_mode = alc269_modes, -		.unsol_event = alc269_laptop_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc269_laptop_dmic_setup, -		.init_hook = alc269_laptop_inithook, +		.init_hook = alc_inithook,  	},  	[ALC269_LIFEBOOK] = {  		.mixers = { alc269_lifebook_mixer }, @@ -15124,6 +15146,7 @@ static struct alc_config_preset alc269_presets[] = {  		.channel_mode = alc269_modes,  		.input_mux = &alc269_capture_source,  		.unsol_event = alc269_lifebook_unsol_event, +		.setup = alc269_lifebook_setup,  		.init_hook = alc269_lifebook_init_hook,  	},  	[ALC271_ACER] = { @@ -15169,14 +15192,21 @@ static int alc269_fill_coef(struct hda_codec *codec)  		val = alc_read_coef_idx(codec, 0xd);  		if ((val & 0x0c00) >> 10 != 0x1) {  			/* Capless ramp up clock control */ -			alc_write_coef_idx(codec, 0xd, val | 1<<10); +			alc_write_coef_idx(codec, 0xd, val | (1<<10));  		}  		val = alc_read_coef_idx(codec, 0x17);  		if ((val & 0x01c0) >> 6 != 0x4) {  			/* Class D power on reset */ -			alc_write_coef_idx(codec, 0x17, val | 1<<7); +			alc_write_coef_idx(codec, 0x17, val | (1<<7));  		}  	} + +	val = alc_read_coef_idx(codec, 0xd); /* Class D */ +	alc_write_coef_idx(codec, 0xd, val | (1<<14)); + +	val = alc_read_coef_idx(codec, 0x4); /* HP */ +	alc_write_coef_idx(codec, 0x4, val | (1<<11)); +  	return 0;  } @@ -15297,14 +15327,12 @@ static int patch_alc269(struct hda_codec *codec)  	spec->vmaster_nid = 0x02;  	codec->patch_ops = alc_patch_ops; -#ifdef CONFIG_SND_HDA_POWER_SAVE -	codec->patch_ops.suspend = alc269_suspend; -#endif  #ifdef SND_HDA_NEEDS_RESUME  	codec->patch_ops.resume = alc269_resume;  #endif  	if (board_config == ALC269_AUTO)  		spec->init_hook = alc269_auto_init; +	spec->shutup = alc269_shutup;  	alc_init_jacks(codec);  #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -15325,7 +15353,7 @@ static int patch_alc269(struct hda_codec *codec)   * set the path ways for 2 channel output   * need to set the codec line out and mic 1 pin widgets to inputs   */ -static struct hda_verb alc861_threestack_ch2_init[] = { +static const struct hda_verb alc861_threestack_ch2_init[] = {  	/* set pin widget 1Ah (line in) for input */  	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },  	/* set pin widget 18h (mic1/2) for input, for mic also enable @@ -15344,7 +15372,7 @@ static struct hda_verb alc861_threestack_ch2_init[] = {   * 6ch mode   * need to set the codec line out and mic 1 pin widgets to outputs   */ -static struct hda_verb alc861_threestack_ch6_init[] = { +static const struct hda_verb alc861_threestack_ch6_init[] = {  	/* set pin widget 1Ah (line in) for output (Back Surround)*/  	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },  	/* set pin widget 18h (mic1) for output (CLFE)*/ @@ -15361,30 +15389,30 @@ static struct hda_verb alc861_threestack_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc861_threestack_modes[2] = { +static const struct hda_channel_mode alc861_threestack_modes[2] = {  	{ 2, alc861_threestack_ch2_init },  	{ 6, alc861_threestack_ch6_init },  };  /* Set mic1 as input and unmute the mixer */ -static struct hda_verb alc861_uniwill_m31_ch2_init[] = { +static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {  	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },  	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/  	{ } /* end */  };  /* Set mic1 as output and mute mixer */ -static struct hda_verb alc861_uniwill_m31_ch4_init[] = { +static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {  	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },  	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/  	{ } /* end */  }; -static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { +static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {  	{ 2, alc861_uniwill_m31_ch2_init },  	{ 4, alc861_uniwill_m31_ch4_init },  };  /* Set mic1 and line-in as input and unmute the mixer */ -static struct hda_verb alc861_asus_ch2_init[] = { +static const struct hda_verb alc861_asus_ch2_init[] = {  	/* set pin widget 1Ah (line in) for input */  	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },  	/* set pin widget 18h (mic1/2) for input, for mic also enable @@ -15400,7 +15428,7 @@ static struct hda_verb alc861_asus_ch2_init[] = {  	{ } /* end */  };  /* Set mic1 nad line-in as output and mute mixer */ -static struct hda_verb alc861_asus_ch6_init[] = { +static const struct hda_verb alc861_asus_ch6_init[] = {  	/* set pin widget 1Ah (line in) for output (Back Surround)*/  	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },  	/* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ @@ -15418,14 +15446,14 @@ static struct hda_verb alc861_asus_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc861_asus_modes[2] = { +static const struct hda_channel_mode alc861_asus_modes[2] = {  	{ 2, alc861_asus_ch2_init },  	{ 6, alc861_asus_ch6_init },  };  /* patch-ALC861 */ -static struct snd_kcontrol_new alc861_base_mixer[] = { +static const struct snd_kcontrol_new alc861_base_mixer[] = {          /* output mixer control */  	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15448,7 +15476,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861_3ST_mixer[] = { +static const struct snd_kcontrol_new alc861_3ST_mixer[] = {          /* output mixer control */  	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15479,7 +15507,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861_toshiba_mixer[] = { +static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {          /* output mixer control */  	HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), @@ -15488,7 +15516,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { +static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {          /* output mixer control */  	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15519,7 +15547,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861_asus_mixer[] = { +static const struct snd_kcontrol_new alc861_asus_mixer[] = {          /* output mixer control */  	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15551,7 +15579,7 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {  };  /* additional mixer */ -static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { +static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {  	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),  	{ } @@ -15560,7 +15588,7 @@ static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc861_base_init_verbs[] = { +static const struct hda_verb alc861_base_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -15626,7 +15654,7 @@ static struct hda_verb alc861_base_init_verbs[] = {  	{ }  }; -static struct hda_verb alc861_threestack_init_verbs[] = { +static const struct hda_verb alc861_threestack_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -15687,7 +15715,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {  	{ }  }; -static struct hda_verb alc861_uniwill_m31_init_verbs[] = { +static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -15749,7 +15777,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {  	{ }  }; -static struct hda_verb alc861_asus_init_verbs[] = { +static const struct hda_verb alc861_asus_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -15815,7 +15843,7 @@ static struct hda_verb alc861_asus_init_verbs[] = {  };  /* additional init verbs for ASUS laptops */ -static struct hda_verb alc861_asus_laptop_init_verbs[] = { +static const struct hda_verb alc861_asus_laptop_init_verbs[] = {  	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */  	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */  	{ } @@ -15824,7 +15852,7 @@ static struct hda_verb alc861_asus_laptop_init_verbs[] = {  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc861_auto_init_verbs[] = { +static const struct hda_verb alc861_auto_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -15873,7 +15901,7 @@ static struct hda_verb alc861_auto_init_verbs[] = {  	{ }  }; -static struct hda_verb alc861_toshiba_init_verbs[] = { +static const struct hda_verb alc861_toshiba_init_verbs[] = {  	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{ } @@ -15906,26 +15934,26 @@ static void alc861_toshiba_unsol_event(struct hda_codec *codec,  #define ALC861_DIGOUT_NID	0x07 -static struct hda_channel_mode alc861_8ch_modes[1] = { +static const struct hda_channel_mode alc861_8ch_modes[1] = {  	{ 8, NULL }  }; -static hda_nid_t alc861_dac_nids[4] = { +static const hda_nid_t alc861_dac_nids[4] = {  	/* front, surround, clfe, side */  	0x03, 0x06, 0x05, 0x04  }; -static hda_nid_t alc660_dac_nids[3] = { +static const hda_nid_t alc660_dac_nids[3] = {  	/* front, clfe, surround */  	0x03, 0x05, 0x06  }; -static hda_nid_t alc861_adc_nids[1] = { +static const hda_nid_t alc861_adc_nids[1] = {  	/* ADC0-2 */  	0x08,  }; -static struct hda_input_mux alc861_capture_source = { +static const struct hda_input_mux alc861_capture_source = {  	.num_items = 5,  	.items = {  		{ "Mic", 0x0 }, @@ -15975,7 +16003,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,  		dac = alc861_look_for_dac(codec, nid);  		if (!dac)  			continue; -		spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; +		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;  	}  	return 0;  } @@ -15998,11 +16026,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,  	static const char * const chname[4] = {  		"Front", "Surround", NULL /*CLFE*/, "Side"  	}; -	const char *pfx = alc_get_line_out_pfx(cfg, true); +	const char *pfx = alc_get_line_out_pfx(spec, true);  	hda_nid_t nid; -	int i, err; +	int i, err, noutputs; -	for (i = 0; i < cfg->line_outs; i++) { +	noutputs = cfg->line_outs; +	if (spec->multi_ios > 0) +		noutputs += spec->multi_ios; + +	for (i = 0; i < noutputs; i++) {  		nid = spec->multiout.dac_nids[i];  		if (!nid)  			continue; @@ -16135,7 +16167,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc861_ignore); @@ -16147,6 +16179,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec)  	err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);  	if (err < 0)  		return err; +	err = alc_auto_add_multi_channel_mode(codec); +	if (err < 0) +		return err;  	err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);  	if (err < 0)  		return err; @@ -16191,7 +16226,7 @@ static void alc861_auto_init(struct hda_codec *codec)  }  #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc861_loopbacks[] = { +static const struct hda_amp_list alc861_loopbacks[] = {  	{ 0x15, HDA_INPUT, 0 },  	{ 0x15, HDA_INPUT, 1 },  	{ 0x15, HDA_INPUT, 2 }, @@ -16216,7 +16251,7 @@ static const char * const alc861_models[ALC861_MODEL_LAST] = {  	[ALC861_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc861_cfg_tbl[] = { +static const struct snd_pci_quirk alc861_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),  	SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),  	SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), @@ -16240,7 +16275,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc861_presets[] = { +static const struct alc_config_preset alc861_presets[] = {  	[ALC861_3ST] = {  		.mixers = { alc861_3ST_mixer },  		.init_verbs = { alc861_threestack_init_verbs }, @@ -16363,7 +16398,7 @@ static const struct alc_fixup alc861_fixups[] = {  	},  }; -static struct snd_pci_quirk alc861_fixup_tbl[] = { +static const struct snd_pci_quirk alc861_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),  	{}  }; @@ -16456,7 +16491,7 @@ static int patch_alc861(struct hda_codec *codec)   */  #define ALC861VD_DIGOUT_NID	0x06 -static hda_nid_t alc861vd_dac_nids[4] = { +static const hda_nid_t alc861vd_dac_nids[4] = {  	/* front, surr, clfe, side surr */  	0x02, 0x03, 0x04, 0x05  }; @@ -16468,21 +16503,21 @@ static hda_nid_t alc861vd_dac_nids[4] = {   * - and it is the same as in 861vd.   * adc_nids in ALC660vd are (is) the same as in 861vd   */ -static hda_nid_t alc660vd_dac_nids[3] = { +static const hda_nid_t alc660vd_dac_nids[3] = {  	/* front, rear, clfe, rear_surr */  	0x02, 0x04, 0x03  }; -static hda_nid_t alc861vd_adc_nids[1] = { +static const hda_nid_t alc861vd_adc_nids[1] = {  	/* ADC0 */  	0x09,  }; -static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; +static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };  /* input MUX */  /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc861vd_capture_source = { +static const struct hda_input_mux alc861vd_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -16492,7 +16527,7 @@ static struct hda_input_mux alc861vd_capture_source = {  	},  }; -static struct hda_input_mux alc861vd_dallas_capture_source = { +static const struct hda_input_mux alc861vd_dallas_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x0 }, @@ -16500,7 +16535,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = {  	},  }; -static struct hda_input_mux alc861vd_hp_capture_source = { +static const struct hda_input_mux alc861vd_hp_capture_source = {  	.num_items = 2,  	.items = {  		{ "Front Mic", 0x0 }, @@ -16511,14 +16546,14 @@ static struct hda_input_mux alc861vd_hp_capture_source = {  /*   * 2ch mode   */ -static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { +static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {  	{ 2, NULL }  };  /*   * 6ch mode   */ -static struct hda_verb alc861vd_6stack_ch6_init[] = { +static const struct hda_verb alc861vd_6stack_ch6_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -16529,7 +16564,7 @@ static struct hda_verb alc861vd_6stack_ch6_init[] = {  /*   * 8ch mode   */ -static struct hda_verb alc861vd_6stack_ch8_init[] = { +static const struct hda_verb alc861vd_6stack_ch8_init[] = {  	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -16537,12 +16572,12 @@ static struct hda_verb alc861vd_6stack_ch8_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc861vd_6stack_modes[2] = { +static const struct hda_channel_mode alc861vd_6stack_modes[2] = {  	{ 6, alc861vd_6stack_ch6_init },  	{ 8, alc861vd_6stack_ch8_init },  }; -static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { +static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Channel Mode", @@ -16556,7 +16591,7 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {  /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17   *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b   */ -static struct snd_kcontrol_new alc861vd_6st_mixer[] = { +static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -16592,7 +16627,7 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861vd_3st_mixer[] = { +static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -16615,7 +16650,7 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { +static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	/*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -16639,7 +16674,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {  /* Pin assignment: Speaker=0x14, HP = 0x15,   *                 Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d   */ -static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { +static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -16656,7 +16691,7 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {  /* Pin assignment: Speaker=0x14, Line-out = 0x15,   *                 Front Mic=0x18, ATAPI Mic = 0x19,   */ -static struct snd_kcontrol_new alc861vd_hp_mixer[] = { +static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -16672,7 +16707,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = {  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc861vd_volume_init_verbs[] = { +static const struct hda_verb alc861vd_volume_init_verbs[] = {  	/*  	 * Unmute ADC0 and set the default input to mic-in  	 */ @@ -16722,7 +16757,7 @@ static struct hda_verb alc861vd_volume_init_verbs[] = {   * 3-stack pin configuration:   * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b   */ -static struct hda_verb alc861vd_3stack_init_verbs[] = { +static const struct hda_verb alc861vd_3stack_init_verbs[] = {  	/*  	 * Set pin mode and muting  	 */ @@ -16753,7 +16788,7 @@ static struct hda_verb alc861vd_3stack_init_verbs[] = {  /*   * 6-stack pin configuration:   */ -static struct hda_verb alc861vd_6stack_init_verbs[] = { +static const struct hda_verb alc861vd_6stack_init_verbs[] = {  	/*  	 * Set pin mode and muting  	 */ @@ -16794,18 +16829,18 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = {  	{ }  }; -static struct hda_verb alc861vd_eapd_verbs[] = { +static const struct hda_verb alc861vd_eapd_verbs[] = {  	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; -static struct hda_verb alc660vd_eapd_verbs[] = { +static const struct hda_verb alc660vd_eapd_verbs[] = {  	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; -static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { +static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, @@ -16819,11 +16854,13 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec)  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x1b;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc861vd_lenovo_init_hook(struct hda_codec *codec)  { -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	alc88x_simple_mic_automute(codec);  } @@ -16835,12 +16872,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,  		alc88x_simple_mic_automute(codec);  		break;  	default: -		alc_automute_amp_unsol_event(codec, res); +		alc_sku_unsol_event(codec, res);  		break;  	}  } -static struct hda_verb alc861vd_dallas_verbs[] = { +static const struct hda_verb alc861vd_dallas_verbs[] = {  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},  	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -16892,6 +16929,8 @@ static void alc861vd_dallas_setup(struct hda_codec *codec)  	spec->autocfg.hp_pins[0] = 0x15;  	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -16920,7 +16959,7 @@ static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {  	[ALC861VD_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc861vd_cfg_tbl[] = { +static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),  	SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),  	SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), @@ -16939,7 +16978,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc861vd_presets[] = { +static const struct alc_config_preset alc861vd_presets[] = {  	[ALC660VD_3ST] = {  		.mixers = { alc861vd_3st_mixer },  		.init_verbs = { alc861vd_volume_init_verbs, @@ -17016,9 +17055,9 @@ static struct alc_config_preset alc861vd_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),  		.channel_mode = alc861vd_3stack_2ch_modes,  		.input_mux = &alc861vd_dallas_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc861vd_dallas_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC861VD_HP] = {  		.mixers = { alc861vd_hp_mixer }, @@ -17029,9 +17068,9 @@ static struct alc_config_preset alc861vd_presets[] = {  		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),  		.channel_mode = alc861vd_3stack_2ch_modes,  		.input_mux = &alc861vd_hp_capture_source, -		.unsol_event = alc_automute_amp_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc861vd_dallas_setup, -		.init_hook = alc_automute_amp, +		.init_hook = alc_hp_automute,  	},  	[ALC660VD_ASUS_V1S] = {  		.mixers = { alc861vd_lenovo_mixer }, @@ -17130,11 +17169,15 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,  	static const char * const chname[4] = {  		"Front", "Surround", "CLFE", "Side"  	}; -	const char *pfx = alc_get_line_out_pfx(cfg, true); +	const char *pfx = alc_get_line_out_pfx(spec, true);  	hda_nid_t nid_v, nid_s; -	int i, err; +	int i, err, noutputs; -	for (i = 0; i < cfg->line_outs; i++) { +	noutputs = cfg->line_outs; +	if (spec->multi_ios > 0) +		noutputs += spec->multi_ios; + +	for (i = 0; i < noutputs; i++) {  		if (!spec->multiout.dac_nids[i])  			continue;  		nid_v = alc861vd_idx_to_mixer_vol( @@ -17247,7 +17290,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc861vd_ignore); @@ -17259,6 +17302,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)  	err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);  	if (err < 0)  		return err; +	err = alc_auto_add_multi_channel_mode(codec); +	if (err < 0) +		return err;  	err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);  	if (err < 0)  		return err; @@ -17327,7 +17373,7 @@ static const struct alc_fixup alc861vd_fixups[] = {  	},  }; -static struct snd_pci_quirk alc861vd_fixup_tbl[] = { +static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),  	{}  }; @@ -17410,6 +17456,7 @@ static int patch_alc861vd(struct hda_codec *codec)  	if (board_config == ALC861VD_AUTO)  		spec->init_hook = alc861vd_auto_init; +	spec->shutup = alc_eapd_shutup;  #ifdef CONFIG_SND_HDA_POWER_SAVE  	if (!spec->loopback.amplist)  		spec->loopback.amplist = alc861vd_loopbacks; @@ -17432,32 +17479,32 @@ static int patch_alc861vd(struct hda_codec *codec)  #define ALC662_DIGOUT_NID	0x06  #define ALC662_DIGIN_NID	0x0a -static hda_nid_t alc662_dac_nids[4] = { -	/* front, rear, clfe, rear_surr */ +static const hda_nid_t alc662_dac_nids[3] = { +	/* front, rear, clfe */  	0x02, 0x03, 0x04  }; -static hda_nid_t alc272_dac_nids[2] = { +static const hda_nid_t alc272_dac_nids[2] = {  	0x02, 0x03  }; -static hda_nid_t alc662_adc_nids[2] = { +static const hda_nid_t alc662_adc_nids[2] = {  	/* ADC1-2 */  	0x09, 0x08  }; -static hda_nid_t alc272_adc_nids[1] = { +static const hda_nid_t alc272_adc_nids[1] = {  	/* ADC1-2 */  	0x08,  }; -static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; -static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; +static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; +static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };  /* input MUX */  /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc662_capture_source = { +static const struct hda_input_mux alc662_capture_source = {  	.num_items = 4,  	.items = {  		{ "Mic", 0x0 }, @@ -17467,7 +17514,7 @@ static struct hda_input_mux alc662_capture_source = {  	},  }; -static struct hda_input_mux alc662_lenovo_101e_capture_source = { +static const struct hda_input_mux alc662_lenovo_101e_capture_source = {  	.num_items = 2,  	.items = {  		{ "Mic", 0x1 }, @@ -17475,7 +17522,7 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = {  	},  }; -static struct hda_input_mux alc663_capture_source = { +static const struct hda_input_mux alc663_capture_source = {  	.num_items = 3,  	.items = {  		{ "Mic", 0x0 }, @@ -17485,7 +17532,7 @@ static struct hda_input_mux alc663_capture_source = {  };  #if 0 /* set to 1 for testing other input sources below */ -static struct hda_input_mux alc272_nc10_capture_source = { +static const struct hda_input_mux alc272_nc10_capture_source = {  	.num_items = 16,  	.items = {  		{ "Autoselect Mic", 0x0 }, @@ -17511,14 +17558,14 @@ static struct hda_input_mux alc272_nc10_capture_source = {  /*   * 2ch mode   */ -static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { +static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {  	{ 2, NULL }  };  /*   * 2ch mode   */ -static struct hda_verb alc662_3ST_ch2_init[] = { +static const struct hda_verb alc662_3ST_ch2_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },  	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -17529,7 +17576,7 @@ static struct hda_verb alc662_3ST_ch2_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc662_3ST_ch6_init[] = { +static const struct hda_verb alc662_3ST_ch6_init[] = {  	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },  	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -17539,7 +17586,7 @@ static struct hda_verb alc662_3ST_ch6_init[] = {  	{ } /* end */  }; -static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { +static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {  	{ 2, alc662_3ST_ch2_init },  	{ 6, alc662_3ST_ch6_init },  }; @@ -17547,7 +17594,7 @@ static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {  /*   * 2ch mode   */ -static struct hda_verb alc662_sixstack_ch6_init[] = { +static const struct hda_verb alc662_sixstack_ch6_init[] = {  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },  	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -17557,14 +17604,14 @@ static struct hda_verb alc662_sixstack_ch6_init[] = {  /*   * 6ch mode   */ -static struct hda_verb alc662_sixstack_ch8_init[] = { +static const struct hda_verb alc662_sixstack_ch8_init[] = {  	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },  	{ } /* end */  }; -static struct hda_channel_mode alc662_5stack_modes[2] = { +static const struct hda_channel_mode alc662_5stack_modes[2] = {  	{ 2, alc662_sixstack_ch6_init },  	{ 6, alc662_sixstack_ch8_init },  }; @@ -17573,7 +17620,7 @@ static struct hda_channel_mode alc662_5stack_modes[2] = {   *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b   */ -static struct snd_kcontrol_new alc662_base_mixer[] = { +static const struct snd_kcontrol_new alc662_base_mixer[] = {  	/* output mixer control */  	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), @@ -17597,7 +17644,7 @@ static struct snd_kcontrol_new alc662_base_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { +static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -17612,7 +17659,7 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { +static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17633,7 +17680,7 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { +static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17646,7 +17693,7 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { +static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	ALC262_HIPPO_MASTER_SWITCH, @@ -17660,7 +17707,7 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { +static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {  	ALC262_HIPPO_MASTER_SWITCH,  	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17674,7 +17721,7 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc663_asus_bind_master_vol = { +static const struct hda_bind_ctls alc663_asus_bind_master_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -17683,7 +17730,7 @@ static struct hda_bind_ctls alc663_asus_bind_master_vol = {  	},  }; -static struct hda_bind_ctls alc663_asus_one_bind_switch = { +static const struct hda_bind_ctls alc663_asus_one_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17692,7 +17739,7 @@ static struct hda_bind_ctls alc663_asus_one_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc663_m51va_mixer[] = { +static const struct snd_kcontrol_new alc663_m51va_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17700,7 +17747,7 @@ static struct snd_kcontrol_new alc663_m51va_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc663_asus_tree_bind_switch = { +static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17710,7 +17757,7 @@ static struct hda_bind_ctls alc663_asus_tree_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { +static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17721,7 +17768,7 @@ static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc663_asus_four_bind_switch = { +static const struct hda_bind_ctls alc663_asus_four_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17731,7 +17778,7 @@ static struct hda_bind_ctls alc663_asus_four_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { +static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),  	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17741,7 +17788,7 @@ static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc662_1bjd_mixer[] = { +static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -17752,7 +17799,7 @@ static struct snd_kcontrol_new alc662_1bjd_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { +static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -17761,7 +17808,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {  	},  }; -static struct hda_bind_ctls alc663_asus_two_bind_switch = { +static const struct hda_bind_ctls alc663_asus_two_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17770,7 +17817,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { +static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume",  				&alc663_asus_two_bind_master_vol),  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), @@ -17781,7 +17828,7 @@ static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { +static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {  	HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),  	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17791,7 +17838,7 @@ static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc663_g71v_mixer[] = { +static const struct snd_kcontrol_new alc663_g71v_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17805,7 +17852,7 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc663_g50v_mixer[] = { +static const struct snd_kcontrol_new alc663_g50v_mixer[] = {  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), @@ -17819,7 +17866,7 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {  	{ } /* end */  }; -static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { +static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17831,7 +17878,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {  	},  }; -static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { +static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17840,7 +17887,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {  	},  }; -static struct snd_kcontrol_new alc663_mode7_mixer[] = { +static const struct snd_kcontrol_new alc663_mode7_mixer[] = {  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),  	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), @@ -17853,7 +17900,7 @@ static struct snd_kcontrol_new alc663_mode7_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc663_mode8_mixer[] = { +static const struct snd_kcontrol_new alc663_mode8_mixer[] = {  	HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),  	HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),  	HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), @@ -17865,7 +17912,7 @@ static struct snd_kcontrol_new alc663_mode8_mixer[] = {  }; -static struct snd_kcontrol_new alc662_chmode_mixer[] = { +static const struct snd_kcontrol_new alc662_chmode_mixer[] = {  	{  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,  		.name = "Channel Mode", @@ -17876,7 +17923,7 @@ static struct snd_kcontrol_new alc662_chmode_mixer[] = {  	{ } /* end */  }; -static struct hda_verb alc662_init_verbs[] = { +static const struct hda_verb alc662_init_verbs[] = {  	/* ADC: mute amp left and right */  	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -17922,55 +17969,36 @@ static struct hda_verb alc662_init_verbs[] = {  	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},  	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -	/* always trun on EAPD */ -	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, -	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - -	{ } -}; - -static struct hda_verb alc663_init_verbs[] = { -	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},  	{ }  }; -static struct hda_verb alc272_init_verbs[] = { -	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, -	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, +static const struct hda_verb alc662_eapd_init_verbs[] = { +	/* always trun on EAPD */ +	{0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, +	{0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},  	{ }  }; -static struct hda_verb alc662_sue_init_verbs[] = { +static const struct hda_verb alc662_sue_init_verbs[] = {  	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},  	{}  }; -static struct hda_verb alc662_eeepc_sue_init_verbs[] = { +static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {  	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},  	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{}  };  /* Set Unsolicited Event*/ -static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { +static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},  	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},  	{}  }; -static struct hda_verb alc663_m51va_init_verbs[] = { +static const struct hda_verb alc663_m51va_init_verbs[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -17983,7 +18011,7 @@ static struct hda_verb alc663_m51va_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_21jd_amic_init_verbs[] = { +static const struct hda_verb alc663_21jd_amic_init_verbs[] = {  	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x21, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */ @@ -17994,7 +18022,7 @@ static struct hda_verb alc663_21jd_amic_init_verbs[] = {  	{}  }; -static struct hda_verb alc662_1bjd_amic_init_verbs[] = { +static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18006,7 +18034,7 @@ static struct hda_verb alc662_1bjd_amic_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_15jd_amic_init_verbs[] = { +static const struct hda_verb alc663_15jd_amic_init_verbs[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},	/* Headphone */ @@ -18017,7 +18045,7 @@ static struct hda_verb alc663_15jd_amic_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { +static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18033,7 +18061,7 @@ static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { +static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18049,7 +18077,7 @@ static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_g71v_init_verbs[] = { +static const struct hda_verb alc663_g71v_init_verbs[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	/* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */  	/* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ @@ -18064,7 +18092,7 @@ static struct hda_verb alc663_g71v_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_g50v_init_verbs[] = { +static const struct hda_verb alc663_g50v_init_verbs[] = {  	{0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x21, AC_VERB_SET_CONNECT_SEL, 0x00},	/* Headphone */ @@ -18074,7 +18102,7 @@ static struct hda_verb alc663_g50v_init_verbs[] = {  	{}  }; -static struct hda_verb alc662_ecs_init_verbs[] = { +static const struct hda_verb alc662_ecs_init_verbs[] = {  	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},  	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},  	{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, @@ -18082,7 +18110,7 @@ static struct hda_verb alc662_ecs_init_verbs[] = {  	{}  }; -static struct hda_verb alc272_dell_zm1_init_verbs[] = { +static const struct hda_verb alc272_dell_zm1_init_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -18097,7 +18125,7 @@ static struct hda_verb alc272_dell_zm1_init_verbs[] = {  	{}  }; -static struct hda_verb alc272_dell_init_verbs[] = { +static const struct hda_verb alc272_dell_init_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -18112,7 +18140,7 @@ static struct hda_verb alc272_dell_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_mode7_init_verbs[] = { +static const struct hda_verb alc663_mode7_init_verbs[] = {  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -18131,7 +18159,7 @@ static struct hda_verb alc663_mode7_init_verbs[] = {  	{}  }; -static struct hda_verb alc663_mode8_init_verbs[] = { +static const struct hda_verb alc663_mode8_init_verbs[] = {  	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},  	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18151,61 +18179,29 @@ static struct hda_verb alc663_mode8_init_verbs[] = {  	{}  }; -static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { +static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),  	{ } /* end */  }; -static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { +static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {  	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),  	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),  	{ } /* end */  }; -static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +static void alc662_lenovo_101e_setup(struct hda_codec *codec)  { -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x14); -	bits = present ? HDA_AMP_MUTE : 0; - -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} - -static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - - 	present = snd_hda_jack_detect(codec, 0x1b); -	bits = present ? HDA_AMP_MUTE : 0; - -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} - -static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	if ((res >> 26) == ALC880_HP_EVENT) -		alc662_lenovo_101e_all_automute(codec); -	if ((res >> 26) == ALC880_FRONT_EVENT) -		alc662_lenovo_101e_ispeaker_automute(codec); -} +	struct alc_spec *spec = codec->spec; -/* unsolicited event for HP jack sensing */ -static void alc662_eeepc_unsol_event(struct hda_codec *codec, -				     unsigned int res) -{ -	if ((res >> 26) == ALC880_MIC_EVENT) -		alc_mic_automute(codec); -	else -		alc262_hippo_unsol_event(codec, res); +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.line_out_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x15; +	spec->automute = 1; +	spec->detect_line = 1; +	spec->automute_lines = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc662_eeepc_setup(struct hda_codec *codec) @@ -18220,180 +18216,24 @@ static void alc662_eeepc_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } -static void alc662_eeepc_inithook(struct hda_codec *codec) -{ -	alc262_hippo_automute(codec); -	alc_mic_automute(codec); -} -  static void alc662_eeepc_ep20_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	spec->autocfg.hp_pins[0] = 0x14;  	spec->autocfg.speaker_pins[0] = 0x1b; -} - -#define alc662_eeepc_ep20_inithook	alc262_hippo_master_update - -static void alc663_m51va_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x21); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -} - -static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x21); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -} - -static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, -				 HDA_AMP_MUTE, bits); -} - -static void alc662_f5z_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x1b); -	bits = present ? 0 : PIN_OUT; -	snd_hda_codec_write(codec, 0x14, 0, -			 AC_VERB_SET_PIN_WIDGET_CONTROL, bits); -} - -static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present1, present2; - -	present1 = snd_hda_jack_detect(codec, 0x21); -	present2 = snd_hda_jack_detect(codec, 0x15); - -	if (present1 || present2) { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, 0); -	} else { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); -	} -} - -static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present1, present2; - -	present1 = snd_hda_jack_detect(codec, 0x1b); -	present2 = snd_hda_jack_detect(codec, 0x15); - -	if (present1 || present2) { -		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -					 HDA_AMP_MUTE, HDA_AMP_MUTE); -		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -					 HDA_AMP_MUTE, HDA_AMP_MUTE); -	} else { -		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, -					 HDA_AMP_MUTE, 0); -		snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, -					 HDA_AMP_MUTE, 0); -	} -} - -static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present1, present2; - -	present1 = snd_hda_codec_read(codec, 0x1b, 0, -			AC_VERB_GET_PIN_SENSE, 0) -			& AC_PINSENSE_PRESENCE; -	present2 = snd_hda_codec_read(codec, 0x21, 0, -			AC_VERB_GET_PIN_SENSE, 0) -			& AC_PINSENSE_PRESENCE; - -	if (present1 || present2) { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, 0); -		snd_hda_codec_write_cache(codec, 0x17, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, 0); -	} else { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); -		snd_hda_codec_write_cache(codec, 0x17, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); -	} -} - -static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) -{ -	unsigned int present1, present2; - -	present1 = snd_hda_codec_read(codec, 0x21, 0, -			AC_VERB_GET_PIN_SENSE, 0) -			& AC_PINSENSE_PRESENCE; -	present2 = snd_hda_codec_read(codec, 0x15, 0, -			AC_VERB_GET_PIN_SENSE, 0) -			& AC_PINSENSE_PRESENCE; - -	if (present1 || present2) { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, 0); -		snd_hda_codec_write_cache(codec, 0x17, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, 0); -	} else { -		snd_hda_codec_write_cache(codec, 0x14, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); -		snd_hda_codec_write_cache(codec, 0x17, 0, -			AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); -	} -} - -static void alc663_m51va_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_m51va_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc663_m51va_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x12; @@ -18401,18 +18241,15 @@ static void alc663_m51va_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } -static void alc663_m51va_inithook(struct hda_codec *codec) -{ -	alc663_m51va_speaker_automute(codec); -	alc_mic_automute(codec); -} -  /* ***************** Mode1 ******************************/ -#define alc663_mode1_unsol_event	alc663_m51va_unsol_event -  static void alc663_mode1_setup(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER;  	spec->ext_mic.pin = 0x18;  	spec->ext_mic.mux_idx = 0;  	spec->int_mic.pin = 0x19; @@ -18420,229 +18257,144 @@ static void alc663_mode1_setup(struct hda_codec *codec)  	spec->auto_mic = 1;  } -#define alc663_mode1_inithook		alc663_m51va_inithook -  /* ***************** Mode2 ******************************/ -static void alc662_mode2_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc662_mode2_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc662_f5z_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  } -#define alc662_mode2_setup	alc663_mode1_setup - -static void alc662_mode2_inithook(struct hda_codec *codec) -{ -	alc662_f5z_speaker_automute(codec); -	alc_mic_automute(codec); -}  /* ***************** Mode3 ******************************/ -static void alc663_mode3_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc663_mode3_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_two_hp_m1_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  } -#define alc663_mode3_setup	alc663_mode1_setup - -static void alc663_mode3_inithook(struct hda_codec *codec) -{ -	alc663_two_hp_m1_speaker_automute(codec); -	alc_mic_automute(codec); -}  /* ***************** Mode4 ******************************/ -static void alc663_mode4_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc663_mode4_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_21jd_two_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->autocfg.speaker_pins[1] = 0x16; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute_mixer_nid[1] = 0x0e; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  } -#define alc663_mode4_setup	alc663_mode1_setup - -static void alc663_mode4_inithook(struct hda_codec *codec) -{ -	alc663_21jd_two_speaker_automute(codec); -	alc_mic_automute(codec); -}  /* ***************** Mode5 ******************************/ -static void alc663_mode5_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc663_mode5_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_15jd_two_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->autocfg.speaker_pins[1] = 0x16; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute_mixer_nid[1] = 0x0e; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  } -#define alc663_mode5_setup	alc663_mode1_setup - -static void alc663_mode5_inithook(struct hda_codec *codec) -{ -	alc663_15jd_two_speaker_automute(codec); -	alc_mic_automute(codec); -}  /* ***************** Mode6 ******************************/ -static void alc663_mode6_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_two_hp_m2_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -} - -#define alc663_mode6_setup	alc663_mode1_setup - -static void alc663_mode6_inithook(struct hda_codec *codec) +static void alc663_mode6_setup(struct hda_codec *codec)  { -	alc663_two_hp_m2_speaker_automute(codec); -	alc_mic_automute(codec); +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.hp_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute_mixer_nid[0] = 0x0c; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_MIXER; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  }  /* ***************** Mode7 ******************************/ -static void alc663_mode7_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc663_mode7_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_two_hp_m7_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -} - -#define alc663_mode7_setup	alc663_mode1_setup - -static void alc663_mode7_inithook(struct hda_codec *codec) -{ -	alc663_two_hp_m7_speaker_automute(codec); -	alc_mic_automute(codec); +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x1b; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x19; +	spec->int_mic.mux_idx = 1; +	spec->auto_mic = 1;  }  /* ***************** Mode8 ******************************/ -static void alc663_mode8_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_two_hp_m8_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -} - -#define alc663_mode8_setup	alc663_m51va_setup - -static void alc663_mode8_inithook(struct hda_codec *codec) -{ -	alc663_two_hp_m8_speaker_automute(codec); -	alc_mic_automute(codec); -} - -static void alc663_g71v_hp_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x21); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} - -static void alc663_g71v_front_automute(struct hda_codec *codec) -{ -	unsigned int present; -	unsigned char bits; - -	present = snd_hda_jack_detect(codec, 0x15); -	bits = present ? HDA_AMP_MUTE : 0; -	snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, -				 HDA_AMP_MUTE, bits); -} - -static void alc663_g71v_unsol_event(struct hda_codec *codec, -					   unsigned int res) -{ -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_g71v_hp_automute(codec); -		break; -	case ALC880_FRONT_EVENT: -		alc663_g71v_front_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} -} - -#define alc663_g71v_setup	alc663_m51va_setup - -static void alc663_g71v_inithook(struct hda_codec *codec) +static void alc663_mode8_setup(struct hda_codec *codec)  { -	alc663_g71v_front_automute(codec); -	alc663_g71v_hp_automute(codec); -	alc_mic_automute(codec); +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.hp_pins[1] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->autocfg.speaker_pins[0] = 0x17; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_PIN; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x12; +	spec->int_mic.mux_idx = 9; +	spec->auto_mic = 1;  } -static void alc663_g50v_unsol_event(struct hda_codec *codec, -					   unsigned int res) +static void alc663_g71v_setup(struct hda_codec *codec)  { -	switch (res >> 26) { -	case ALC880_HP_EVENT: -		alc663_m51va_speaker_automute(codec); -		break; -	case ALC880_MIC_EVENT: -		alc_mic_automute(codec); -		break; -	} +	struct alc_spec *spec = codec->spec; +	spec->autocfg.hp_pins[0] = 0x21; +	spec->autocfg.line_out_pins[0] = 0x15; +	spec->autocfg.speaker_pins[0] = 0x14; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP; +	spec->detect_line = 1; +	spec->automute_lines = 1; +	spec->ext_mic.pin = 0x18; +	spec->ext_mic.mux_idx = 0; +	spec->int_mic.pin = 0x12; +	spec->int_mic.mux_idx = 9; +	spec->auto_mic = 1;  }  #define alc663_g50v_setup	alc663_m51va_setup -static void alc663_g50v_inithook(struct hda_codec *codec) -{ -	alc663_m51va_speaker_automute(codec); -	alc_mic_automute(codec); -} - -static struct snd_kcontrol_new alc662_ecs_mixer[] = { +static const struct snd_kcontrol_new alc662_ecs_mixer[] = {  	HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	ALC262_HIPPO_MASTER_SWITCH, @@ -18656,7 +18408,7 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {  	{ } /* end */  }; -static struct snd_kcontrol_new alc272_nc10_mixer[] = { +static const struct snd_kcontrol_new alc272_nc10_mixer[] = {  	/* Master Playback automatically created from Speaker and Headphone */  	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -18691,7 +18443,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = {  	[ALC662_3ST_2ch_DIG]	= "3stack-dig",  	[ALC662_3ST_6ch_DIG]	= "3stack-6ch-dig",  	[ALC662_3ST_6ch]	= "3stack-6ch", -	[ALC662_5ST_DIG]	= "6stack-dig", +	[ALC662_5ST_DIG]	= "5stack-dig",  	[ALC662_LENOVO_101E]	= "lenovo-101e",  	[ALC662_ASUS_EEEPC_P701] = "eeepc-p701",  	[ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", @@ -18714,7 +18466,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = {  	[ALC662_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc662_cfg_tbl[] = { +static const struct snd_pci_quirk alc662_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),  	SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),  	SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), @@ -18782,6 +18534,8 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {  		      ALC662_3ST_6ch_DIG),  	SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),  	SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), +	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", +		      ALC662_3ST_6ch_DIG),  	SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),  	SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),  	SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), @@ -18794,10 +18548,10 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {  	{}  }; -static struct alc_config_preset alc662_presets[] = { +static const struct alc_config_preset alc662_presets[] = {  	[ALC662_3ST_2ch_DIG] = {  		.mixers = { alc662_3ST_2ch_mixer }, -		.init_verbs = { alc662_init_verbs }, +		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID, @@ -18808,7 +18562,7 @@ static struct alc_config_preset alc662_presets[] = {  	},  	[ALC662_3ST_6ch_DIG] = {  		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, -		.init_verbs = { alc662_init_verbs }, +		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID, @@ -18820,7 +18574,7 @@ static struct alc_config_preset alc662_presets[] = {  	},  	[ALC662_3ST_6ch] = {  		.mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, -		.init_verbs = { alc662_init_verbs }, +		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), @@ -18830,7 +18584,7 @@ static struct alc_config_preset alc662_presets[] = {  	},  	[ALC662_5ST_DIG] = {  		.mixers = { alc662_base_mixer, alc662_chmode_mixer }, -		.init_verbs = { alc662_init_verbs }, +		.init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID, @@ -18841,104 +18595,120 @@ static struct alc_config_preset alc662_presets[] = {  	},  	[ALC662_LENOVO_101E] = {  		.mixers = { alc662_lenovo_101e_mixer }, -		.init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc662_sue_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes,  		.input_mux = &alc662_lenovo_101e_capture_source, -		.unsol_event = alc662_lenovo_101e_unsol_event, -		.init_hook = alc662_lenovo_101e_all_automute, +		.unsol_event = alc_sku_unsol_event, +		.setup = alc662_lenovo_101e_setup, +		.init_hook = alc_inithook,  	},  	[ALC662_ASUS_EEEPC_P701] = {  		.mixers = { alc662_eeepc_p701_mixer },  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc662_eeepc_sue_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc662_eeepc_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc662_eeepc_setup, -		.init_hook = alc662_eeepc_inithook, +		.init_hook = alc_inithook,  	},  	[ALC662_ASUS_EEEPC_EP20] = {  		.mixers = { alc662_eeepc_ep20_mixer,  			    alc662_chmode_mixer },  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc662_eeepc_ep20_sue_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),  		.channel_mode = alc662_3ST_6ch_modes,  		.input_mux = &alc662_lenovo_101e_capture_source, -		.unsol_event = alc662_eeepc_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc662_eeepc_ep20_setup, -		.init_hook = alc662_eeepc_ep20_inithook, +		.init_hook = alc_inithook,  	},  	[ALC662_ECS] = {  		.mixers = { alc662_ecs_mixer },  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc662_ecs_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc662_eeepc_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc662_eeepc_setup, -		.init_hook = alc662_eeepc_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_M51VA] = {  		.mixers = { alc663_m51va_mixer }, -		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc663_m51va_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_m51va_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_m51va_setup, -		.init_hook = alc663_m51va_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_G71V] = {  		.mixers = { alc663_g71v_mixer }, -		.init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc663_g71v_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_g71v_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_g71v_setup, -		.init_hook = alc663_g71v_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_H13] = {  		.mixers = { alc663_m51va_mixer }, -		.init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc663_m51va_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_m51va_unsol_event, -		.init_hook = alc663_m51va_inithook, +		.setup = alc663_m51va_setup, +		.unsol_event = alc_sku_unsol_event, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_G50V] = {  		.mixers = { alc663_g50v_mixer }, -		.init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc663_g50v_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),  		.channel_mode = alc662_3ST_6ch_modes,  		.input_mux = &alc663_capture_source, -		.unsol_event = alc663_g50v_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_g50v_setup, -		.init_hook = alc663_g50v_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE1] = {  		.mixers = { alc663_m51va_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_21jd_amic_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -18946,28 +18716,30 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode1_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode1_setup, -		.init_hook = alc663_mode1_inithook, +		.init_hook = alc_inithook,  	},  	[ALC662_ASUS_MODE2] = {  		.mixers = { alc662_1bjd_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc662_1bjd_amic_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.dac_nids = alc662_dac_nids,  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc662_mode2_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc662_mode2_setup, -		.init_hook = alc662_mode2_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE3] = {  		.mixers = { alc663_two_hp_m1_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_two_hp_amic_m1_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -18975,14 +18747,15 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode3_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode3_setup, -		.init_hook = alc663_mode3_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE4] = {  		.mixers = { alc663_asus_21jd_clfe_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_21jd_amic_init_verbs},  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -18990,14 +18763,15 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode4_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode4_setup, -		.init_hook = alc663_mode4_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE5] = {  		.mixers = { alc663_asus_15jd_clfe_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_15jd_amic_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -19005,14 +18779,15 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode5_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode5_setup, -		.init_hook = alc663_mode5_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE6] = {  		.mixers = { alc663_two_hp_m2_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_two_hp_amic_m2_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -19020,14 +18795,15 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode6_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode6_setup, -		.init_hook = alc663_mode6_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE7] = {  		.mixers = { alc663_mode7_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_mode7_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -19035,14 +18811,15 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode7_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode7_setup, -		.init_hook = alc663_mode7_inithook, +		.init_hook = alc_inithook,  	},  	[ALC663_ASUS_MODE8] = {  		.mixers = { alc663_mode8_mixer },  		.cap_mixer = alc662_auto_capture_mixer,  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_mode8_init_verbs },  		.num_dacs = ARRAY_SIZE(alc662_dac_nids),  		.hp_nid = 0x03, @@ -19050,52 +18827,57 @@ static struct alc_config_preset alc662_presets[] = {  		.dig_out_nid = ALC662_DIGOUT_NID,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_mode8_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode8_setup, -		.init_hook = alc663_mode8_inithook, +		.init_hook = alc_inithook,  	},  	[ALC272_DELL] = {  		.mixers = { alc663_m51va_mixer },  		.cap_mixer = alc272_auto_capture_mixer, -		.init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc272_dell_init_verbs },  		.num_dacs = ARRAY_SIZE(alc272_dac_nids), -		.dac_nids = alc662_dac_nids, +		.dac_nids = alc272_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.adc_nids = alc272_adc_nids,  		.num_adc_nids = ARRAY_SIZE(alc272_adc_nids),  		.capsrc_nids = alc272_capsrc_nids,  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_m51va_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_m51va_setup, -		.init_hook = alc663_m51va_inithook, +		.init_hook = alc_inithook,  	},  	[ALC272_DELL_ZM1] = {  		.mixers = { alc663_m51va_mixer },  		.cap_mixer = alc662_auto_capture_mixer, -		.init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, +		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs, +				alc272_dell_zm1_init_verbs },  		.num_dacs = ARRAY_SIZE(alc272_dac_nids), -		.dac_nids = alc662_dac_nids, +		.dac_nids = alc272_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.adc_nids = alc662_adc_nids,  		.num_adc_nids = 1,  		.capsrc_nids = alc662_capsrc_nids,  		.channel_mode = alc662_3ST_2ch_modes, -		.unsol_event = alc663_m51va_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_m51va_setup, -		.init_hook = alc663_m51va_inithook, +		.init_hook = alc_inithook,  	},  	[ALC272_SAMSUNG_NC10] = {  		.mixers = { alc272_nc10_mixer },  		.init_verbs = { alc662_init_verbs, +				alc662_eapd_init_verbs,  				alc663_21jd_amic_init_verbs },  		.num_dacs = ARRAY_SIZE(alc272_dac_nids),  		.dac_nids = alc272_dac_nids,  		.num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),  		.channel_mode = alc662_3ST_2ch_modes,  		/*.input_mux = &alc272_nc10_capture_source,*/ -		.unsol_event = alc663_mode4_unsol_event, +		.unsol_event = alc_sku_unsol_event,  		.setup = alc663_mode4_setup, -		.init_hook = alc663_mode4_inithook, +		.init_hook = alc_inithook,  	},  }; @@ -19105,45 +18887,79 @@ static struct alc_config_preset alc662_presets[] = {   */  /* convert from MIX nid to DAC */ -static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) +static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)  { -	if (nid == 0x0f) -		return 0x02; -	else if (nid >= 0x0c && nid <= 0x0e) -		return nid - 0x0c + 0x02; -	else if (nid == 0x26) /* ALC887-VD has this DAC too */ -		return 0x25; -	else -		return 0; +	hda_nid_t list[5]; +	int i, num; + +	num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); +	for (i = 0; i < num; i++) { +		if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) +			return list[i]; +	} +	return 0; +} + +/* go down to the selector widget before the mixer */ +static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) +{ +	hda_nid_t srcs[5]; +	int num = snd_hda_get_connections(codec, pin, srcs, +					  ARRAY_SIZE(srcs)); +	if (num != 1 || +	    get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) +		return pin; +	return srcs[0];  }  /* get MIX nid connected to the given pin targeted to DAC */ -static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, +static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,  				   hda_nid_t dac)  {  	hda_nid_t mix[5];  	int i, num; +	pin = alc_go_down_to_selector(codec, pin);  	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));  	for (i = 0; i < num; i++) { -		if (alc662_mix_to_dac(mix[i]) == dac) +		if (alc_auto_mix_to_dac(codec, mix[i]) == dac)  			return mix[i];  	}  	return 0;  } +/* select the connection from pin to DAC if needed */ +static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, +			       hda_nid_t dac) +{ +	hda_nid_t mix[5]; +	int i, num; + +	pin = alc_go_down_to_selector(codec, pin); +	num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); +	if (num < 2) +		return 0; +	for (i = 0; i < num; i++) { +		if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { +			snd_hda_codec_update_cache(codec, pin, 0, +						   AC_VERB_SET_CONNECT_SEL, i); +			return 0; +		} +	} +	return 0; +} +  /* look for an empty DAC slot */ -static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) +static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)  {  	struct alc_spec *spec = codec->spec;  	hda_nid_t srcs[5];  	int i, j, num; +	pin = alc_go_down_to_selector(codec, pin);  	num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); -	if (num < 0) -		return 0;  	for (i = 0; i < num; i++) { -		hda_nid_t nid = alc662_mix_to_dac(srcs[i]); +		hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);  		if (!nid)  			continue;  		for (j = 0; j < spec->multiout.num_dacs; j++) @@ -19165,10 +18981,10 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,  	spec->multiout.dac_nids = spec->private_dac_nids;  	for (i = 0; i < cfg->line_outs; i++) { -		dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); +		dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);  		if (!dac)  			continue; -		spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; +		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;  	}  	return 0;  } @@ -19204,15 +19020,23 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,  	static const char * const chname[4] = {  		"Front", "Surround", NULL /*CLFE*/, "Side"  	}; -	const char *pfx = alc_get_line_out_pfx(cfg, true); -	hda_nid_t nid, mix; -	int i, err; +	const char *pfx = alc_get_line_out_pfx(spec, true); +	hda_nid_t nid, mix, pin; +	int i, err, noutputs; -	for (i = 0; i < cfg->line_outs; i++) { +	noutputs = cfg->line_outs; +	if (spec->multi_ios > 0) +		noutputs += spec->multi_ios; + +	for (i = 0; i < noutputs; i++) {  		nid = spec->multiout.dac_nids[i];  		if (!nid)  			continue; -		mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); +		if (i >= cfg->line_outs) +			pin = spec->multi_io[i - 1].pin; +		else +			pin = cfg->line_out_pins[i]; +		mix = alc_auto_dac_to_mix(codec, pin, nid);  		if (!mix)  			continue;  		if (!pfx && i == 2) { @@ -19258,7 +19082,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,  	if (!pin)  		return 0; -	nid = alc662_look_for_dac(codec, pin); +	nid = alc_auto_look_for_dac(codec, pin);  	if (!nid) {  		/* the corresponding DAC is already occupied */  		if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) @@ -19268,7 +19092,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,  				   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));  	} -	mix = alc662_dac_to_mix(codec, pin, nid); +	mix = alc_auto_dac_to_mix(codec, pin, nid);  	if (!mix)  		return 0;  	err = alc662_add_vol_ctl(spec, pfx, nid, 3); @@ -19292,14 +19116,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,  	hda_nid_t srcs[HDA_MAX_CONNECTIONS];  	alc_set_pin_output(codec, nid, pin_type); -	/* need the manual connection? */  	num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); -	if (num <= 1) -		return;  	for (i = 0; i < num; i++) { -		if (alc662_mix_to_dac(srcs[i]) != dac) +		if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)  			continue; -		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); +		/* need the manual connection? */ +		if (num > 1) +			snd_hda_codec_write(codec, nid, 0, +					    AC_VERB_SET_CONNECT_SEL, i); +		/* unmute mixer widget inputs */ +		snd_hda_codec_write(codec, srcs[i], 0, +				    AC_VERB_SET_AMP_GAIN_MUTE, +				    AMP_IN_UNMUTE(0)); +		snd_hda_codec_write(codec, srcs[i], 0, +				    AC_VERB_SET_AMP_GAIN_MUTE, +				    AMP_IN_UNMUTE(1));  		return;  	}  } @@ -19356,11 +19187,164 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)  #define alc662_auto_init_input_src	alc882_auto_init_input_src +/* + * multi-io helper + */ +static int alc_auto_fill_multi_ios(struct hda_codec *codec, +				   unsigned int location) +{ +	struct alc_spec *spec = codec->spec; +	struct auto_pin_cfg *cfg = &spec->autocfg; +	int type, i, num_pins = 0; + +	for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { +		for (i = 0; i < cfg->num_inputs; i++) { +			hda_nid_t nid = cfg->inputs[i].pin; +			hda_nid_t dac; +			unsigned int defcfg, caps; +			if (cfg->inputs[i].type != type) +				continue; +			defcfg = snd_hda_codec_get_pincfg(codec, nid); +			if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) +				continue; +			if (location && get_defcfg_location(defcfg) != location) +				continue; +			caps = snd_hda_query_pin_caps(codec, nid); +			if (!(caps & AC_PINCAP_OUT)) +				continue; +			dac = alc_auto_look_for_dac(codec, nid); +			if (!dac) +				continue; +			spec->multi_io[num_pins].pin = nid; +			spec->multi_io[num_pins].dac = dac; +			num_pins++; +			spec->private_dac_nids[spec->multiout.num_dacs++] = dac; +		} +	} +	spec->multiout.num_dacs = 1; +	if (num_pins < 2) +		return 0; +	return num_pins; +} + +static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, +				 struct snd_ctl_elem_info *uinfo) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; + +	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; +	uinfo->count = 1; +	uinfo->value.enumerated.items = spec->multi_ios + 1; +	if (uinfo->value.enumerated.item > spec->multi_ios) +		uinfo->value.enumerated.item = spec->multi_ios; +	sprintf(uinfo->value.enumerated.name, "%dch", +		(uinfo->value.enumerated.item + 1) * 2); +	return 0; +} + +static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, +				struct snd_ctl_elem_value *ucontrol) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; +	ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; +	return 0; +} + +static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) +{ +	struct alc_spec *spec = codec->spec; +	hda_nid_t nid = spec->multi_io[idx].pin; + +	if (!spec->multi_io[idx].ctl_in) +		spec->multi_io[idx].ctl_in = +			snd_hda_codec_read(codec, nid, 0, +					   AC_VERB_GET_PIN_WIDGET_CONTROL, 0); +	if (output) { +		snd_hda_codec_update_cache(codec, nid, 0, +					   AC_VERB_SET_PIN_WIDGET_CONTROL, +					   PIN_OUT); +		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) +			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, +						 HDA_AMP_MUTE, 0); +		alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); +	} else { +		if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) +			snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, +						 HDA_AMP_MUTE, HDA_AMP_MUTE); +		snd_hda_codec_update_cache(codec, nid, 0, +					   AC_VERB_SET_PIN_WIDGET_CONTROL, +					   spec->multi_io[idx].ctl_in); +	} +	return 0; +} + +static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, +				struct snd_ctl_elem_value *ucontrol) +{ +	struct hda_codec *codec = snd_kcontrol_chip(kcontrol); +	struct alc_spec *spec = codec->spec; +	int i, ch; + +	ch = ucontrol->value.enumerated.item[0]; +	if (ch < 0 || ch > spec->multi_ios) +		return -EINVAL; +	if (ch == (spec->ext_channel_count - 1) / 2) +		return 0; +	spec->ext_channel_count = (ch + 1) * 2; +	for (i = 0; i < spec->multi_ios; i++) +		alc_set_multi_io(codec, i, i < ch); +	spec->multiout.max_channels = spec->ext_channel_count; +	return 1; +} + +static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { +	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, +	.name = "Channel Mode", +	.info = alc_auto_ch_mode_info, +	.get = alc_auto_ch_mode_get, +	.put = alc_auto_ch_mode_put, +}; + +static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) +{ +	struct alc_spec *spec = codec->spec; +	struct auto_pin_cfg *cfg = &spec->autocfg; +	unsigned int location, defcfg; +	int num_pins; + +	if (cfg->line_outs != 1 || +	    cfg->line_out_type != AUTO_PIN_LINE_OUT) +		return 0; + +	defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); +	location = get_defcfg_location(defcfg); + +	num_pins = alc_auto_fill_multi_ios(codec, location); +	if (num_pins > 0) { +		struct snd_kcontrol_new *knew; + +		knew = alc_kcontrol_new(spec); +		if (!knew) +			return -ENOMEM; +		*knew = alc_auto_channel_mode_enum; +		knew->name = kstrdup("Channel Mode", GFP_KERNEL); +		if (!knew->name) +			return -ENOMEM; + +		spec->multi_ios = num_pins; +		spec->ext_channel_count = 2; +		spec->multiout.num_dacs = num_pins + 1; +	} +	return 0; +} +  static int alc662_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; +	static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc662_ignore); @@ -19372,6 +19356,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec)  	err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);  	if (err < 0)  		return err; +	err = alc_auto_add_multi_channel_mode(codec); +	if (err < 0) +		return err;  	err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);  	if (err < 0)  		return err; @@ -19402,14 +19389,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec)  	spec->num_mux_defs = 1;  	spec->input_mux = &spec->private_imux[0]; -	add_verb(spec, alc662_init_verbs); -	if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || -	    codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) -		add_verb(spec, alc663_init_verbs); - -	if (codec->vendor_id == 0x10ec0272) -		add_verb(spec, alc272_init_verbs); -  	err = alc_auto_add_mic_boost(codec);  	if (err < 0)  		return err; @@ -19455,7 +19434,7 @@ enum {  	ALC662_FIXUP_IDEAPAD,  	ALC272_FIXUP_MARIO,  	ALC662_FIXUP_CZC_P10T, -	ALC662_FIXUP_GIGABYTE, +	ALC662_FIXUP_SKU_IGNORE,  };  static const struct alc_fixup alc662_fixups[] = { @@ -19484,20 +19463,17 @@ static const struct alc_fixup alc662_fixups[] = {  			{}  		}  	}, -	[ALC662_FIXUP_GIGABYTE] = { -		.type = ALC_FIXUP_PINS, -		.v.pins = (const struct alc_pincfg[]) { -			{ 0x14, 0x1114410 }, /* set as speaker */ -			{ } -		} +	[ALC662_FIXUP_SKU_IGNORE] = { +		.type = ALC_FIXUP_SKU, +		.v.sku = ALC_FIXUP_SKU_IGNORE,  	},  }; -static struct snd_pci_quirk alc662_fixup_tbl[] = { +static const struct snd_pci_quirk alc662_fixup_tbl[] = {  	SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), +	SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),  	SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),  	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), -	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE),  	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),  	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),  	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), @@ -19611,6 +19587,7 @@ static int patch_alc662(struct hda_codec *codec)  	codec->patch_ops = alc_patch_ops;  	if (board_config == ALC662_AUTO)  		spec->init_hook = alc662_auto_init; +	spec->shutup = alc_eapd_shutup;  	alc_init_jacks(codec); @@ -19639,6 +19616,15 @@ static int patch_alc888(struct hda_codec *codec)  	return patch_alc882(codec);  } +static int patch_alc899(struct hda_codec *codec) +{ +	if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) { +		kfree(codec->chip_name); +		codec->chip_name = kstrdup("ALC898", GFP_KERNEL); +	} +	return patch_alc882(codec); +} +  /*   * ALC680 support   */ @@ -19646,12 +19632,12 @@ static int patch_alc888(struct hda_codec *codec)  #define ALC680_DIGOUT_NID	ALC880_DIGOUT_NID  #define alc680_modes		alc260_modes -static hda_nid_t alc680_dac_nids[3] = { +static const hda_nid_t alc680_dac_nids[3] = {  	/* Lout1, Lout2, hp */  	0x02, 0x03, 0x04  }; -static hda_nid_t alc680_adc_nids[3] = { +static const hda_nid_t alc680_adc_nids[3] = {  	/* ADC0-2 */  	/* DMIC, MIC, Line-in*/  	0x07, 0x08, 0x09 @@ -19671,8 +19657,7 @@ static void alc680_rec_autoswitch(struct hda_codec *codec)  	for (i = 0; i < cfg->num_inputs; i++) {  		nid = cfg->inputs[i].pin; -		if (!(snd_hda_query_pin_caps(codec, nid) & -		      AC_PINCAP_PRES_DETECT)) +		if (!is_jack_detectable(codec, nid))  			continue;  		if (snd_hda_jack_detect(codec, nid)) {  			if (cfg->inputs[i].type < type_found) { @@ -19719,7 +19704,7 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,  	return 0;  } -static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { +static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {  	.substreams = 1, /* can be overridden */  	.channels_min = 2,  	.channels_max = 2, @@ -19730,7 +19715,7 @@ static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {  	},  }; -static struct snd_kcontrol_new alc680_base_mixer[] = { +static const struct snd_kcontrol_new alc680_base_mixer[] = {  	/* output mixer control */  	HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),  	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -19742,7 +19727,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = {  	{ }  }; -static struct hda_bind_ctls alc680_bind_cap_vol = { +static const struct hda_bind_ctls alc680_bind_cap_vol = {  	.ops = &snd_hda_bind_vol,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), @@ -19752,7 +19737,7 @@ static struct hda_bind_ctls alc680_bind_cap_vol = {  	},  }; -static struct hda_bind_ctls alc680_bind_cap_switch = { +static const struct hda_bind_ctls alc680_bind_cap_switch = {  	.ops = &snd_hda_bind_sw,  	.values = {  		HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), @@ -19762,7 +19747,7 @@ static struct hda_bind_ctls alc680_bind_cap_switch = {  	},  }; -static struct snd_kcontrol_new alc680_master_capture_mixer[] = { +static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {  	HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),  	HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),  	{ } /* end */ @@ -19771,7 +19756,7 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = {  /*   * generic initialization of ADC, input mixers and output mixers   */ -static struct hda_verb alc680_init_verbs[] = { +static const struct hda_verb alc680_init_verbs[] = {  	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},  	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -19809,20 +19794,22 @@ static void alc680_base_setup(struct hda_codec *codec)  	spec->autocfg.inputs[0].type = AUTO_PIN_MIC;  	spec->autocfg.inputs[1].pin = 0x19;  	spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; +	spec->automute = 1; +	spec->automute_mode = ALC_AUTOMUTE_AMP;  }  static void alc680_unsol_event(struct hda_codec *codec,  					   unsigned int res)  {  	if ((res >> 26) == ALC880_HP_EVENT) -		alc_automute_amp(codec); +		alc_hp_automute(codec);  	if ((res >> 26) == ALC880_MIC_EVENT)  		alc680_rec_autoswitch(codec);  }  static void alc680_inithook(struct hda_codec *codec)  { -	alc_automute_amp(codec); +	alc_hp_automute(codec);  	alc680_rec_autoswitch(codec);  } @@ -19859,7 +19846,7 @@ static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,  		if (err < 0)  			return err; -		spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; +		spec->private_dac_nids[spec->multiout.num_dacs++] = dac;  	}  	return 0; @@ -19945,7 +19932,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec)  {  	struct alc_spec *spec = codec->spec;  	int err; -	static hda_nid_t alc680_ignore[] = { 0 }; +	static const hda_nid_t alc680_ignore[] = { 0 };  	err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,  					   alc680_ignore); @@ -20003,12 +19990,12 @@ static const char * const alc680_models[ALC680_MODEL_LAST] = {  	[ALC680_AUTO]		= "auto",  }; -static struct snd_pci_quirk alc680_cfg_tbl[] = { +static const struct snd_pci_quirk alc680_cfg_tbl[] = {  	SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),  	{}  }; -static struct alc_config_preset alc680_presets[] = { +static const struct alc_config_preset alc680_presets[] = {  	[ALC680_BASE] = {  		.mixers = { alc680_base_mixer },  		.cap_mixer =  alc680_master_capture_mixer, @@ -20089,7 +20076,8 @@ static int patch_alc680(struct hda_codec *codec)  /*   * patch entries   */ -static struct hda_codec_preset snd_hda_preset_realtek[] = { +static const struct hda_codec_preset snd_hda_preset_realtek[] = { +	{ .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },  	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },  	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },  	{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, @@ -20098,6 +20086,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {  	{ .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },  	{ .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },  	{ .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, +	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },  	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",  	  .patch = patch_alc861 },  	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, @@ -20125,6 +20114,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {  	{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },  	{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },  	{ .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, +	{ .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },  	{} /* terminator */  };  |