From 20f7d928fa6e51ca81648946ead6244c58a0b4c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Feb 2012 12:35:16 +0100 Subject: [PATCH] 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 --- Documentation/sound/alsa/HD-Audio-Models.txt | 1 - sound/pci/hda/alc260_quirks.c | 76 -------------------- 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 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 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 { 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 }, 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 { 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), {} }; -- 2.30.2