diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-02-16 06:35:16 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-02-16 06:39:35 -0500 |
commit | 20f7d928fa6e51ca81648946ead6244c58a0b4c0 (patch) | |
tree | 48627846fbe1977d87e9d58b7ffd8b05f845deaa | |
parent | 15317ab21686044f1af96dd329ba809a08f04b89 (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.txt | 1 | ||||
-rw-r--r-- | sound/pci/hda/alc260_quirks.c | 76 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 44 |
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 | |||
30 | ALC260 | 30 | ALC260 |
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 | */ | ||
198 | static 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 | ||
444 | static 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 */ | ||
458 | static 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 | |||
479 | static 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 | |||
486 | static const struct hda_verb alc260_hp_dc7600_verbs[] = { | 426 | static 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[] = { | |||
691 | static const char * const alc260_models[ALC260_MODEL_LAST] = { | 631 | static 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 | ||
4218 | static 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 | |||
4225 | static 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 | |||
4216 | static const struct alc_fixup alc260_fixups[] = { | 4243 | static 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 | ||
4247 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 4290 | static 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 | }; |