ALSA: hda/realtek - Replace ALC260 model=replacer with the auto-parser
The support for Replacer 627V in the auto-parser needs the unique unsol event handling: although the machine has a single output pin 0x0f, it's used for both the headphone and the speaker, and the driver needs to toggle the output route via GPIO 1. In addition, it needs a special COEF setup with 0x3050. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
					parent
					
						
							
								15317ab216
							
						
					
				
			
			
				commit
				
					
						20f7d928fa
					
				
			
		
					 3 changed files with 44 additions and 77 deletions
				
			
		|  | @ -30,7 +30,6 @@ ALC880 | |||
| ALC260 | ||||
| ====== | ||||
|   fujitsu	Fujitsu S7020 | ||||
|   replacer	Replacer 672V | ||||
|   favorit100	Maxdata Favorit 100XS | ||||
|   basic		fixed pin assignment (old default model) | ||||
|   test		for testing/debugging purpose, almost all controls can | ||||
|  |  | |||
|  | @ -8,7 +8,6 @@ enum { | |||
| 	ALC260_AUTO, | ||||
| 	ALC260_BASIC, | ||||
| 	ALC260_FUJITSU_S702X, | ||||
| 	ALC260_REPLACER_672V, | ||||
| 	ALC260_FAVORIT100, | ||||
| #ifdef CONFIG_SND_DEBUG | ||||
| 	ALC260_TEST, | ||||
|  | @ -192,23 +191,6 @@ static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { | |||
| 	{ } /* end */ | ||||
| }; | ||||
| 
 | ||||
| /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
 | ||||
|  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | ||||
|  */ | ||||
| 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), | ||||
| 	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||||
| 	ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||||
| 	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), | ||||
| 	HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), | ||||
| 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||||
| 	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||||
| 	ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||||
| 	{ } /* end */ | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * initialization verbs | ||||
|  */ | ||||
|  | @ -441,48 +423,6 @@ static const struct hda_verb alc260_favorit100_init_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}, | ||||
| 
 | ||||
| 	{0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||||
| 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||||
| 	{0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||||
| 
 | ||||
| 	{0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
| /* toggle speaker-output according to the hp-jack state */ | ||||
| static void alc260_replacer_672v_automute(struct hda_codec *codec) | ||||
| { | ||||
|         unsigned int present; | ||||
| 
 | ||||
| 	/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | ||||
| 	present = snd_hda_jack_detect(codec, 0x0f); | ||||
| 	if (present) { | ||||
| 		snd_hda_codec_write_cache(codec, 0x01, 0, | ||||
| 					  AC_VERB_SET_GPIO_DATA, 1); | ||||
| 		snd_hda_codec_write_cache(codec, 0x0f, 0, | ||||
| 					  AC_VERB_SET_PIN_WIDGET_CONTROL, | ||||
| 					  PIN_HP); | ||||
| 	} else { | ||||
| 		snd_hda_codec_write_cache(codec, 0x01, 0, | ||||
| 					  AC_VERB_SET_GPIO_DATA, 0); | ||||
| 		snd_hda_codec_write_cache(codec, 0x0f, 0, | ||||
| 					  AC_VERB_SET_PIN_WIDGET_CONTROL, | ||||
| 					  PIN_OUT); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | ||||
|                                        unsigned int res) | ||||
| { | ||||
|         if ((res >> 26) == ALC_HP_EVENT) | ||||
|                 alc260_replacer_672v_automute(codec); | ||||
| } | ||||
| 
 | ||||
| static const struct hda_verb alc260_hp_dc7600_verbs[] = { | ||||
| 	{0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||||
| 	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||||
|  | @ -691,7 +631,6 @@ static const struct hda_verb alc260_test_init_verbs[] = { | |||
| static const char * const alc260_models[ALC260_MODEL_LAST] = { | ||||
| 	[ALC260_BASIC]		= "basic", | ||||
| 	[ALC260_FUJITSU_S702X]	= "fujitsu", | ||||
| 	[ALC260_REPLACER_672V]	= "replacer", | ||||
| 	[ALC260_FAVORIT100]	= "favorit100", | ||||
| #ifdef CONFIG_SND_DEBUG | ||||
| 	[ALC260_TEST]		= "test", | ||||
|  | @ -706,7 +645,6 @@ static const struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
| 	SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | ||||
| 	SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | ||||
| 	SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | ||||
| 	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
|  | @ -747,20 +685,6 @@ static const struct alc_config_preset alc260_presets[] = { | |||
| 		.num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), | ||||
| 		.input_mux = alc260_favorit100_capture_sources, | ||||
| 	}, | ||||
| 	[ALC260_REPLACER_672V] = { | ||||
| 		.mixers = { alc260_replacer_672v_mixer }, | ||||
| 		.init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, | ||||
| 		.num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||||
| 		.dac_nids = alc260_dac_nids, | ||||
| 		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||||
| 		.adc_nids = alc260_adc_nids, | ||||
| 		.dig_out_nid = ALC260_DIGOUT_NID, | ||||
| 		.num_channel_mode = ARRAY_SIZE(alc260_modes), | ||||
| 		.channel_mode = alc260_modes, | ||||
| 		.input_mux = &alc260_capture_source, | ||||
| 		.unsol_event = alc260_replacer_672v_unsol_event, | ||||
| 		.init_hook = alc260_replacer_672v_automute, | ||||
| 	}, | ||||
| #ifdef CONFIG_SND_DEBUG | ||||
| 	[ALC260_TEST] = { | ||||
| 		.mixers = { alc260_test_mixer }, | ||||
|  |  | |||
|  | @ -4211,8 +4211,35 @@ enum { | |||
| 	ALC260_FIXUP_HP_PIN_0F, | ||||
| 	ALC260_FIXUP_COEF, | ||||
| 	ALC260_FIXUP_GPIO1, | ||||
| 	ALC260_FIXUP_GPIO1_TOGGLE, | ||||
| 	ALC260_FIXUP_REPLACER, | ||||
| }; | ||||
| 
 | ||||
| static void alc260_gpio1_automute(struct hda_codec *codec) | ||||
| { | ||||
| 	struct alc_spec *spec = codec->spec; | ||||
| 	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||||
| 			    spec->hp_jack_present); | ||||
| } | ||||
| 
 | ||||
| static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | ||||
| 				      const struct alc_fixup *fix, int action) | ||||
| { | ||||
| 	struct alc_spec *spec = codec->spec; | ||||
| 	if (action == ALC_FIXUP_ACT_PROBE) { | ||||
| 		/* although the machine has only one output pin, we need to
 | ||||
| 		 * toggle GPIO1 according to the jack state | ||||
| 		 */ | ||||
| 		spec->automute_hook = alc260_gpio1_automute; | ||||
| 		spec->detect_hp = 1; | ||||
| 		spec->automute_speaker = 1; | ||||
| 		spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | ||||
| 		snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); | ||||
| 		spec->unsol_event = alc_sku_unsol_event; | ||||
| 		add_verb(codec->spec, alc_gpio1_init_verbs); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static const struct alc_fixup alc260_fixups[] = { | ||||
| 	[ALC260_FIXUP_HP_DC5750] = { | ||||
| 		.type = ALC_FIXUP_PINS, | ||||
|  | @ -4242,6 +4269,22 @@ static const struct alc_fixup alc260_fixups[] = { | |||
| 		.type = ALC_FIXUP_VERBS, | ||||
| 		.v.verbs = alc_gpio1_init_verbs, | ||||
| 	}, | ||||
| 	[ALC260_FIXUP_GPIO1_TOGGLE] = { | ||||
| 		.type = ALC_FIXUP_FUNC, | ||||
| 		.v.func = alc260_fixup_gpio1_toggle, | ||||
| 		.chained = true, | ||||
| 		.chain_id = ALC260_FIXUP_HP_PIN_0F, | ||||
| 	}, | ||||
| 	[ALC260_FIXUP_REPLACER] = { | ||||
| 		.type = ALC_FIXUP_VERBS, | ||||
| 		.v.verbs = (const struct hda_verb[]) { | ||||
| 			{ 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||||
| 			{ 0x20, AC_VERB_SET_PROC_COEF,  0x3050 }, | ||||
| 			{ } | ||||
| 		}, | ||||
| 		.chained = true, | ||||
| 		.chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static const struct snd_pci_quirk alc260_fixup_tbl[] = { | ||||
|  | @ -4249,6 +4292,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { | |||
| 	SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | ||||
| 	SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | ||||
| 	SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | ||||
| 	SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | ||||
| 	SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | ||||
| 	{} | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Takashi Iwai
				Takashi Iwai