aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-02-16 06:35:16 -0500
committerTakashi Iwai <tiwai@suse.de>2012-02-16 06:39:35 -0500
commit20f7d928fa6e51ca81648946ead6244c58a0b4c0 (patch)
tree48627846fbe1977d87e9d58b7ffd8b05f845deaa
parent15317ab21686044f1af96dd329ba809a08f04b89 (diff)
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>
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt1
-rw-r--r--sound/pci/hda/alc260_quirks.c76
-rw-r--r--sound/pci/hda/patch_realtek.c44
3 files changed, 44 insertions, 77 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 5cc76090f5d6..870cb1a22473 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -30,7 +30,6 @@ ALC880
30ALC260 30ALC260
31====== 31======
32 fujitsu Fujitsu S7020 32 fujitsu Fujitsu S7020
33 replacer Replacer 672V
34 favorit100 Maxdata Favorit 100XS 33 favorit100 Maxdata Favorit 100XS
35 basic fixed pin assignment (old default model) 34 basic fixed pin assignment (old default model)
36 test for testing/debugging purpose, almost all controls can 35 test for testing/debugging purpose, almost all controls can
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
index 2f1594b3d4bd..55da43dddf38 100644
--- a/sound/pci/hda/alc260_quirks.c
+++ b/sound/pci/hda/alc260_quirks.c
@@ -8,7 +8,6 @@ enum {
8 ALC260_AUTO, 8 ALC260_AUTO,
9 ALC260_BASIC, 9 ALC260_BASIC,
10 ALC260_FUJITSU_S702X, 10 ALC260_FUJITSU_S702X,
11 ALC260_REPLACER_672V,
12 ALC260_FAVORIT100, 11 ALC260_FAVORIT100,
13#ifdef CONFIG_SND_DEBUG 12#ifdef CONFIG_SND_DEBUG
14 ALC260_TEST, 13 ALC260_TEST,
@@ -192,23 +191,6 @@ static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
192 { } /* end */ 191 { } /* end */
193}; 192};
194 193
195/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
196 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
197 */
198static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
199 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
200 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
201 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
202 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
203 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
204 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
205 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
206 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
207 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
208 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
209 { } /* end */
210};
211
212/* 194/*
213 * initialization verbs 195 * initialization verbs
214 */ 196 */
@@ -441,48 +423,6 @@ static const struct hda_verb alc260_favorit100_init_verbs[] = {
441 { } 423 { }
442}; 424};
443 425
444static const struct hda_verb alc260_replacer_672v_verbs[] = {
445 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
446 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
447 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
448
449 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
450 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
451 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
452
453 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
454 {}
455};
456
457/* toggle speaker-output according to the hp-jack state */
458static void alc260_replacer_672v_automute(struct hda_codec *codec)
459{
460 unsigned int present;
461
462 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
463 present = snd_hda_jack_detect(codec, 0x0f);
464 if (present) {
465 snd_hda_codec_write_cache(codec, 0x01, 0,
466 AC_VERB_SET_GPIO_DATA, 1);
467 snd_hda_codec_write_cache(codec, 0x0f, 0,
468 AC_VERB_SET_PIN_WIDGET_CONTROL,
469 PIN_HP);
470 } else {
471 snd_hda_codec_write_cache(codec, 0x01, 0,
472 AC_VERB_SET_GPIO_DATA, 0);
473 snd_hda_codec_write_cache(codec, 0x0f, 0,
474 AC_VERB_SET_PIN_WIDGET_CONTROL,
475 PIN_OUT);
476 }
477}
478
479static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
480 unsigned int res)
481{
482 if ((res >> 26) == ALC_HP_EVENT)
483 alc260_replacer_672v_automute(codec);
484}
485
486static const struct hda_verb alc260_hp_dc7600_verbs[] = { 426static const struct hda_verb alc260_hp_dc7600_verbs[] = {
487 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 427 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
488 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -691,7 +631,6 @@ static const struct hda_verb alc260_test_init_verbs[] = {
691static const char * const alc260_models[ALC260_MODEL_LAST] = { 631static const char * const alc260_models[ALC260_MODEL_LAST] = {
692 [ALC260_BASIC] = "basic", 632 [ALC260_BASIC] = "basic",
693 [ALC260_FUJITSU_S702X] = "fujitsu", 633 [ALC260_FUJITSU_S702X] = "fujitsu",
694 [ALC260_REPLACER_672V] = "replacer",
695 [ALC260_FAVORIT100] = "favorit100", 634 [ALC260_FAVORIT100] = "favorit100",
696#ifdef CONFIG_SND_DEBUG 635#ifdef CONFIG_SND_DEBUG
697 [ALC260_TEST] = "test", 636 [ALC260_TEST] = "test",
@@ -706,7 +645,6 @@ static const struct snd_pci_quirk alc260_cfg_tbl[] = {
706 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), 645 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
707 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), 646 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
708 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), 647 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
709 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
710 {} 648 {}
711}; 649};
712 650
@@ -747,20 +685,6 @@ static const struct alc_config_preset alc260_presets[] = {
747 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), 685 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
748 .input_mux = alc260_favorit100_capture_sources, 686 .input_mux = alc260_favorit100_capture_sources,
749 }, 687 },
750 [ALC260_REPLACER_672V] = {
751 .mixers = { alc260_replacer_672v_mixer },
752 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
753 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
754 .dac_nids = alc260_dac_nids,
755 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
756 .adc_nids = alc260_adc_nids,
757 .dig_out_nid = ALC260_DIGOUT_NID,
758 .num_channel_mode = ARRAY_SIZE(alc260_modes),
759 .channel_mode = alc260_modes,
760 .input_mux = &alc260_capture_source,
761 .unsol_event = alc260_replacer_672v_unsol_event,
762 .init_hook = alc260_replacer_672v_automute,
763 },
764#ifdef CONFIG_SND_DEBUG 688#ifdef CONFIG_SND_DEBUG
765 [ALC260_TEST] = { 689 [ALC260_TEST] = {
766 .mixers = { alc260_test_mixer }, 690 .mixers = { alc260_test_mixer },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 95ef722e4075..cfa6ad758343 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4211,8 +4211,35 @@ enum {
4211 ALC260_FIXUP_HP_PIN_0F, 4211 ALC260_FIXUP_HP_PIN_0F,
4212 ALC260_FIXUP_COEF, 4212 ALC260_FIXUP_COEF,
4213 ALC260_FIXUP_GPIO1, 4213 ALC260_FIXUP_GPIO1,
4214 ALC260_FIXUP_GPIO1_TOGGLE,
4215 ALC260_FIXUP_REPLACER,
4214}; 4216};
4215 4217
4218static void alc260_gpio1_automute(struct hda_codec *codec)
4219{
4220 struct alc_spec *spec = codec->spec;
4221 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4222 spec->hp_jack_present);
4223}
4224
4225static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4226 const struct alc_fixup *fix, int action)
4227{
4228 struct alc_spec *spec = codec->spec;
4229 if (action == ALC_FIXUP_ACT_PROBE) {
4230 /* although the machine has only one output pin, we need to
4231 * toggle GPIO1 according to the jack state
4232 */
4233 spec->automute_hook = alc260_gpio1_automute;
4234 spec->detect_hp = 1;
4235 spec->automute_speaker = 1;
4236 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4237 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4238 spec->unsol_event = alc_sku_unsol_event;
4239 add_verb(codec->spec, alc_gpio1_init_verbs);
4240 }
4241}
4242
4216static const struct alc_fixup alc260_fixups[] = { 4243static const struct alc_fixup alc260_fixups[] = {
4217 [ALC260_FIXUP_HP_DC5750] = { 4244 [ALC260_FIXUP_HP_DC5750] = {
4218 .type = ALC_FIXUP_PINS, 4245 .type = ALC_FIXUP_PINS,
@@ -4242,6 +4269,22 @@ static const struct alc_fixup alc260_fixups[] = {
4242 .type = ALC_FIXUP_VERBS, 4269 .type = ALC_FIXUP_VERBS,
4243 .v.verbs = alc_gpio1_init_verbs, 4270 .v.verbs = alc_gpio1_init_verbs,
4244 }, 4271 },
4272 [ALC260_FIXUP_GPIO1_TOGGLE] = {
4273 .type = ALC_FIXUP_FUNC,
4274 .v.func = alc260_fixup_gpio1_toggle,
4275 .chained = true,
4276 .chain_id = ALC260_FIXUP_HP_PIN_0F,
4277 },
4278 [ALC260_FIXUP_REPLACER] = {
4279 .type = ALC_FIXUP_VERBS,
4280 .v.verbs = (const struct hda_verb[]) {
4281 { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
4282 { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
4283 { }
4284 },
4285 .chained = true,
4286 .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
4287 },
4245}; 4288};
4246 4289
4247static const struct snd_pci_quirk alc260_fixup_tbl[] = { 4290static const struct snd_pci_quirk alc260_fixup_tbl[] = {
@@ -4249,6 +4292,7 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
4249 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), 4292 SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
4250 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), 4293 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
4251 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), 4294 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
4295 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
4252 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), 4296 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
4253 {} 4297 {}
4254}; 4298};