diff options
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 677 |
1 files changed, 381 insertions, 296 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 51c08edd756..52928d9a72d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -282,12 +282,6 @@ struct alc_mic_route { unsigned char amix_idx; }; -struct alc_jack { - hda_nid_t nid; - int type; - struct snd_jack *jack; -}; - #define MUX_IDX_UNDEF ((unsigned char)-1) struct alc_customize_define { @@ -303,6 +297,8 @@ struct alc_customize_define { unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ }; +struct alc_fixup; + struct alc_spec { /* codec parameterization */ struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ @@ -364,9 +360,6 @@ struct alc_spec { /* PCM information */ struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ - /* jack detection */ - struct snd_array jacks; - /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct alc_customize_define cdefine; @@ -392,6 +385,7 @@ struct alc_spec { /* 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; int init_amp; int codec_variant; /* flag for other variants */ @@ -404,6 +398,11 @@ struct alc_spec { /* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; + + /* fix-up list */ + int fixup_id; + const struct alc_fixup *fixup_list; + const char *fixup_name; }; /* @@ -550,7 +549,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, /* * Control the mode of pin widget settings via the mixer. "pc" is used - * instead of "%" to avoid consequences of accidently treating the % as + * instead of "%" to avoid consequences of accidentally treating the % as * being part of a format specifier. Maximum allowed length of a value is * 63 characters plus NULL terminator. * @@ -1025,94 +1024,32 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, alc_fix_pll(codec); } -#ifdef CONFIG_SND_HDA_INPUT_JACK -static void alc_free_jack_priv(struct snd_jack *jack) -{ - struct alc_jack *jacks = jack->private_data; - jacks->nid = 0; - jacks->jack = NULL; -} - -static int alc_add_jack(struct hda_codec *codec, - hda_nid_t nid, int type) -{ - struct alc_spec *spec; - struct alc_jack *jack; - const char *name; - int err; - - spec = codec->spec; - snd_array_init(&spec->jacks, sizeof(*jack), 32); - jack = snd_array_new(&spec->jacks); - if (!jack) - return -ENOMEM; - - jack->nid = nid; - jack->type = type; - name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ; - - err = snd_jack_new(codec->bus->card, name, type, &jack->jack); - if (err < 0) - return err; - jack->jack->private_data = jack; - jack->jack->private_free = alc_free_jack_priv; - return 0; -} - -static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) -{ - struct alc_spec *spec = codec->spec; - struct alc_jack *jacks = spec->jacks.list; - - if (jacks) { - int i; - for (i = 0; i < spec->jacks.used; i++) { - if (jacks->nid == nid) { - unsigned int present; - present = snd_hda_jack_detect(codec, nid); - - present = (present) ? jacks->type : 0; - - snd_jack_report(jacks->jack, present); - } - jacks++; - } - } -} - static int alc_init_jacks(struct hda_codec *codec) { +#ifdef CONFIG_SND_HDA_INPUT_JACK struct alc_spec *spec = codec->spec; int err; unsigned int hp_nid = spec->autocfg.hp_pins[0]; unsigned int mic_nid = spec->ext_mic.pin; if (hp_nid) { - err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE); + err = snd_hda_input_jack_add(codec, hp_nid, + SND_JACK_HEADPHONE, NULL); if (err < 0) return err; - alc_report_jack(codec, hp_nid); + snd_hda_input_jack_report(codec, hp_nid); } if (mic_nid) { - err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE); + err = snd_hda_input_jack_add(codec, mic_nid, + SND_JACK_MICROPHONE, NULL); if (err < 0) return err; - alc_report_jack(codec, mic_nid); + snd_hda_input_jack_report(codec, mic_nid); } - +#endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } -#else -static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid) -{ -} - -static inline int alc_init_jacks(struct hda_codec *codec) -{ - return 0; -} -#endif static void alc_automute_speaker(struct hda_codec *codec, int pinctl) { @@ -1126,11 +1063,8 @@ static void alc_automute_speaker(struct hda_codec *codec, int pinctl) nid = spec->autocfg.hp_pins[i]; if (!nid) break; - if (snd_hda_jack_detect(codec, nid)) { - spec->jack_present = 1; - break; - } - alc_report_jack(codec, spec->autocfg.hp_pins[i]); + snd_hda_input_jack_report(codec, nid); + spec->jack_present |= snd_hda_jack_detect(codec, nid); } mute = spec->jack_present ? HDA_AMP_MUTE : 0; @@ -1236,7 +1170,7 @@ static void alc_mic_automute(struct hda_codec *codec) AC_VERB_SET_CONNECT_SEL, alive->mux_idx); } - alc_report_jack(codec, spec->ext_mic.pin); + snd_hda_input_jack_report(codec, spec->ext_mic.pin); /* FIXME: analog mixer */ } @@ -1331,6 +1265,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0660: case 0x10ec0662: case 0x10ec0663: + case 0x10ec0665: case 0x10ec0862: case 0x10ec0889: set_eapd(codec, 0x14, 1); @@ -1355,7 +1290,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case 0x10ec0883: case 0x10ec0885: case 0x10ec0887: - case 0x10ec0889: + /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ alc889_coef_init(codec); break; case 0x10ec0888: @@ -1683,88 +1618,133 @@ struct alc_model_fixup { }; struct alc_fixup { - unsigned int sku; - const struct alc_pincfg *pins; - const struct hda_verb *verbs; - void (*func)(struct hda_codec *codec, const struct alc_fixup *fix, - int pre_init); + int type; + bool chained; + int chain_id; + union { + unsigned int sku; + const struct alc_pincfg *pins; + const struct hda_verb *verbs; + void (*func)(struct hda_codec *codec, + const struct alc_fixup *fix, + int action); + } v; }; -static void __alc_pick_fixup(struct hda_codec *codec, - const struct alc_fixup *fix, - const char *modelname, - int pre_init) -{ - const struct alc_pincfg *cfg; - struct alc_spec *spec; +enum { + ALC_FIXUP_INVALID, + ALC_FIXUP_SKU, + ALC_FIXUP_PINS, + ALC_FIXUP_VERBS, + ALC_FIXUP_FUNC, +}; - cfg = fix->pins; - if (pre_init && fix->sku) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", - codec->chip_name, modelname); -#endif - spec = codec->spec; - spec->cdefine.sku_cfg = fix->sku; - spec->cdefine.fixup = 1; - } - if (pre_init && cfg) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", - codec->chip_name, modelname); -#endif - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); - } - if (!pre_init && fix->verbs) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", - codec->chip_name, modelname); -#endif - add_verb(codec->spec, fix->verbs); - } - if (fix->func) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", - codec->chip_name, modelname); -#endif - fix->func(codec, fix, pre_init); - } -} +enum { + ALC_FIXUP_ACT_PRE_PROBE, + ALC_FIXUP_ACT_PROBE, + ALC_FIXUP_ACT_INIT, +}; -static void alc_pick_fixup(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix, - int pre_init) +static void alc_apply_fixup(struct hda_codec *codec, int action) { - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (quirk) { - fix += quirk->value; + struct alc_spec *spec = codec->spec; + int id = spec->fixup_id; #ifdef CONFIG_SND_DEBUG_VERBOSE - __alc_pick_fixup(codec, fix, quirk->name, pre_init); -#else - __alc_pick_fixup(codec, fix, NULL, pre_init); + const char *modelname = spec->fixup_name; #endif + int depth = 0; + + if (!spec->fixup_list) + return; + + while (id >= 0) { + const struct alc_fixup *fix = spec->fixup_list + id; + const struct alc_pincfg *cfg; + + switch (fix->type) { + case ALC_FIXUP_SKU: + if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) + break;; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply sku override for %s\n", + codec->chip_name, modelname); + spec->cdefine.sku_cfg = fix->v.sku; + spec->cdefine.fixup = 1; + break; + case ALC_FIXUP_PINS: + cfg = fix->v.pins; + if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply pincfg for %s\n", + codec->chip_name, modelname); + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, + cfg->val); + break; + case ALC_FIXUP_VERBS: + if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply fix-verbs for %s\n", + codec->chip_name, modelname); + add_verb(codec->spec, fix->v.verbs); + break; + case ALC_FIXUP_FUNC: + if (!fix->v.func) + break; + snd_printdd(KERN_INFO "hda_codec: %s: " + "Apply fix-func for %s\n", + codec->chip_name, modelname); + fix->v.func(codec, fix, action); + break; + default: + snd_printk(KERN_ERR "hda_codec: %s: " + "Invalid fixup type %d\n", + codec->chip_name, fix->type); + break; + } + if (!fix[id].chained) + break; + if (++depth > 10) + break; + id = fix[id].chain_id; } } -static void alc_pick_fixup_model(struct hda_codec *codec, - const struct alc_model_fixup *models, - const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix, - int pre_init) +static void alc_pick_fixup(struct hda_codec *codec, + const struct alc_model_fixup *models, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fixlist) { + struct alc_spec *spec = codec->spec; + int id = -1; + const char *name = NULL; + if (codec->modelname && models) { while (models->name) { if (!strcmp(codec->modelname, models->name)) { - fix += models->id; + id = models->id; + name = models->name; break; } models++; } - __alc_pick_fixup(codec, fix, codec->modelname, pre_init); - } else { - alc_pick_fixup(codec, quirk, fix, pre_init); + } + if (id < 0) { + quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (quirk) { + id = quirk->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + name = quirk->name; +#endif + } + } + + spec->fixup_id = id; + if (id >= 0) { + spec->fixup_list = fixlist; + spec->fixup_name = name; } } @@ -2238,6 +2218,28 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { { } /* end */ }; +static 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), + HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, + HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + static 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), @@ -2866,7 +2868,7 @@ static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { /* * slave controls for virtual master */ -static const char *alc_slave_vols[] = { +static const char * const alc_slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", "Center Playback Volume", @@ -2880,7 +2882,7 @@ static const char *alc_slave_vols[] = { NULL, }; -static const char *alc_slave_sws[] = { +static const char * const alc_slave_sws[] = { "Front Playback Switch", "Surround Playback Switch", "Center Playback Switch", @@ -3847,6 +3849,8 @@ static struct hda_amp_list alc880_lg_loopbacks[] = { * Common callbacks */ +static void alc_init_special_input_src(struct hda_codec *codec); + static int alc_init(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -3857,10 +3861,13 @@ static int alc_init(struct hda_codec *codec) for (i = 0; i < spec->num_init_verbs; i++) snd_hda_sequence_write(codec, spec->init_verbs[i]); + alc_init_special_input_src(codec); if (spec->init_hook) spec->init_hook(codec); + alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); + hda_call_check_power_status(codec, 0x01); return 0; } @@ -4210,6 +4217,7 @@ static void alc_free(struct hda_codec *codec) return; alc_shutup(codec); + snd_hda_input_jack_free(codec); alc_free_kctls(codec); kfree(spec); snd_hda_detach_beep_device(codec); @@ -4233,6 +4241,7 @@ static void alc_power_eapd(struct hda_codec *codec) case 0x10ec0660: case 0x10ec0662: case 0x10ec0663: + case 0x10ec0665: case 0x10ec0862: case 0x10ec0889: set_eapd(codec, 0x14, 0); @@ -4559,7 +4568,7 @@ static struct hda_verb alc880_test_init_verbs[] = { /* */ -static const char *alc880_models[ALC880_MODEL_LAST] = { +static const char * const alc880_models[ALC880_MODEL_LAST] = { [ALC880_3ST] = "3stack", [ALC880_TCL_S700] = "tcl", [ALC880_3ST_DIG] = "3stack-digout", @@ -4628,7 +4637,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), - SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734), + SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734), SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), @@ -5077,7 +5086,9 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, switch (cfg->line_out_type) { case AUTO_PIN_SPEAKER_OUT: - return "Speaker"; + if (cfg->line_outs == 1) + return "Speaker"; + break; case AUTO_PIN_HP_OUT: return "Headphone"; default: @@ -5092,7 +5103,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, false); @@ -5131,16 +5142,19 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; + index = 0; + } err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); if (err < 0) return err; err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); if (err < 0) @@ -5511,6 +5525,7 @@ static void fixup_single_adc(struct hda_codec *codec) spec->capsrc_nids += i; spec->adc_nids += i; spec->num_adc_nids = 1; + spec->single_input_src = 1; } } @@ -5522,6 +5537,16 @@ static void fixup_dual_adc_switch(struct hda_codec *codec) init_capsrc_for_pin(codec, spec->int_mic.pin); } +/* initialize some special cases for input sources */ +static void alc_init_special_input_src(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + if (spec->dual_adc_switch) + fixup_dual_adc_switch(codec); + else if (spec->single_input_src) + init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); +} + static void set_capture_mixer(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -5537,7 +5562,7 @@ static void set_capture_mixer(struct hda_codec *codec) int mux = 0; int num_adcs = spec->num_adc_nids; if (spec->dual_adc_switch) - fixup_dual_adc_switch(codec); + num_adcs = 1; else if (spec->auto_mic) fixup_automic_adc(codec); else if (spec->input_mux) { @@ -5546,8 +5571,6 @@ static void set_capture_mixer(struct hda_codec *codec) else if (spec->input_mux->num_items == 1) fixup_single_adc(codec); } - if (spec->dual_adc_switch) - num_adcs = 1; spec->cap_mixer = caps[mux][num_adcs - 1]; } } @@ -7090,7 +7113,8 @@ enum { static const struct alc_fixup alc260_fixups[] = { [PINFIX_HP_DC5750] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x11, 0x90130110 }, /* speaker */ { } } @@ -7105,7 +7129,7 @@ static struct snd_pci_quirk alc260_fixup_tbl[] = { /* * ALC260 configurations */ -static const char *alc260_models[ALC260_MODEL_LAST] = { +static const char * const alc260_models[ALC260_MODEL_LAST] = { [ALC260_BASIC] = "basic", [ALC260_HP] = "hp", [ALC260_HP_3013] = "hp-3013", @@ -7301,8 +7325,10 @@ static int patch_alc260(struct hda_codec *codec) board_config = ALC260_AUTO; } - if (board_config == ALC260_AUTO) - alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); + if (board_config == ALC260_AUTO) { + alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC260_AUTO) { /* automatic parse from the BIOS config */ @@ -7350,8 +7376,7 @@ static int patch_alc260(struct hda_codec *codec) set_capture_mixer(codec); set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); - if (board_config == ALC260_AUTO) - alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x08; @@ -9727,7 +9752,7 @@ static hda_nid_t alc1200_slave_dig_outs[] = { /* * configuration and preset */ -static const char *alc882_models[ALC882_MODEL_LAST] = { +static const char * const alc882_models[ALC882_MODEL_LAST] = { [ALC882_3ST_DIG] = "3stack-dig", [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", @@ -9811,7 +9836,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), - SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), @@ -9838,7 +9863,6 @@ 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), @@ -10303,7 +10327,7 @@ static struct alc_config_preset alc882_presets[] = { .init_hook = alc_automute_amp, }, [ALC888_ACER_ASPIRE_4930G] = { - .mixers = { alc888_base_mixer, + .mixers = { alc888_acer_aspire_4930g_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, alc888_acer_aspire_4930g_verbs }, @@ -10672,34 +10696,56 @@ static struct alc_config_preset alc882_presets[] = { */ enum { PINFIX_ABIT_AW9D_MAX, + PINFIX_LENOVO_Y530, PINFIX_PB_M5210, PINFIX_ACER_ASPIRE_7736, + PINFIX_GIGABYTE_880GM, }; static const struct alc_fixup alc882_fixups[] = { [PINFIX_ABIT_AW9D_MAX] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x01080104 }, /* side */ { 0x16, 0x01011012 }, /* rear */ { 0x17, 0x01016011 }, /* clfe */ { } } }, + [PINFIX_LENOVO_Y530] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x15, 0x99130112 }, /* rear int speakers */ + { 0x16, 0x99130111 }, /* subwoofer */ + { } + } + }, [PINFIX_PB_M5210] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, {} } }, [PINFIX_ACER_ASPIRE_7736] = { - .sku = ALC_FIXUP_SKU_IGNORE, + .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[] = { 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), {} }; @@ -10750,23 +10796,28 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) hda_nid_t pin, dac; int i; - for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { - pin = spec->autocfg.hp_pins[i]; - if (!pin) - break; - dac = spec->multiout.hp_nid; - if (!dac) - dac = spec->multiout.dac_nids[0]; /* to front */ - alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); + if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { + for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { + pin = spec->autocfg.hp_pins[i]; + if (!pin) + break; + dac = spec->multiout.hp_nid; + if (!dac) + dac = spec->multiout.dac_nids[0]; /* to front */ + alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); + } } - for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { - pin = spec->autocfg.speaker_pins[i]; - if (!pin) - break; - dac = spec->multiout.extra_out_nid[0]; - if (!dac) - dac = spec->multiout.dac_nids[0]; /* to front */ - alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); + + if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { + for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { + pin = spec->autocfg.speaker_pins[i]; + if (!pin) + break; + dac = spec->multiout.extra_out_nid[0]; + if (!dac) + dac = spec->multiout.dac_nids[0]; /* to front */ + alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); + } } } @@ -10873,9 +10924,6 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) return 0; } -static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, - const struct auto_pin_cfg *cfg); - /* almost identical with ALC880 parser... */ static int alc882_parse_auto_config(struct hda_codec *codec) { @@ -10893,10 +10941,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); if (err < 0) return err; - if (codec->vendor_id == 0x10ec0887) - err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); - else - err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); if (err < 0) return err; err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], @@ -10984,8 +11029,10 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC882_AUTO; } - if (board_config == ALC882_AUTO) - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); + if (board_config == ALC882_AUTO) { + alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } alc_auto_parse_customize_define(codec); @@ -11061,8 +11108,7 @@ static int patch_alc882(struct hda_codec *codec) if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); - if (board_config == ALC882_AUTO) - alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x0c; @@ -12452,19 +12498,14 @@ enum { static const struct alc_fixup alc262_fixups[] = { [PINFIX_FSC_H270] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ { 0x15, 0x0221142f }, /* front HP */ { 0x1b, 0x0121141f }, /* rear HP */ { } } }, - [PINFIX_PB_M5210] = { - .verbs = (const struct hda_verb[]) { - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, - {} - } - }, }; static struct snd_pci_quirk alc262_fixup_tbl[] = { @@ -12554,7 +12595,7 @@ static void alc262_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc262_models[ALC262_MODEL_LAST] = { +static const char * const alc262_models[ALC262_MODEL_LAST] = { [ALC262_BASIC] = "basic", [ALC262_HIPPO] = "hippo", [ALC262_HIPPO_1] = "hippo_1", @@ -12582,6 +12623,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", ALC262_HP_BPC), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", + ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), @@ -12895,8 +12938,10 @@ static int patch_alc262(struct hda_codec *codec) board_config = ALC262_AUTO; } - if (board_config == ALC262_AUTO) - alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1); + if (board_config == ALC262_AUTO) { + alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC262_AUTO) { /* automatic parse from the BIOS config */ @@ -12966,8 +13011,7 @@ static int patch_alc262(struct hda_codec *codec) if (!spec->no_analog && has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); - if (board_config == ALC262_AUTO) - alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x0c; @@ -13724,6 +13768,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) } #define alc268_auto_init_analog_input alc882_auto_init_analog_input +#define alc268_auto_init_input_src alc882_auto_init_input_src /* init callback for auto-configuration model -- overriding the default init */ static void alc268_auto_init(struct hda_codec *codec) @@ -13733,6 +13778,7 @@ static void alc268_auto_init(struct hda_codec *codec) alc268_auto_init_hp_out(codec); alc268_auto_init_mono_speaker_out(codec); alc268_auto_init_analog_input(codec); + alc268_auto_init_input_src(codec); alc_auto_init_digital(codec); if (spec->unsol_event) alc_inithook(codec); @@ -13741,7 +13787,7 @@ static void alc268_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc268_models[ALC268_MODEL_LAST] = { +static const char * const alc268_models[ALC268_MODEL_LAST] = { [ALC267_QUANTA_IL1] = "quanta-il1", [ALC268_3ST] = "3stack", [ALC268_TOSHIBA] = "toshiba", @@ -14020,7 +14066,6 @@ static int patch_alc268(struct hda_codec *codec) if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - int i; spec->capsrc_nids = alc268_capsrc_nids; /* get type */ @@ -14040,13 +14085,6 @@ static int patch_alc268(struct hda_codec *codec) spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); add_mixer(spec, alc268_capture_mixer); } - /* set default input source */ - for (i = 0; i < spec->num_adc_nids; i++) - snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], - 0, AC_VERB_SET_CONNECT_SEL, - i < spec->num_mux_defs ? - spec->input_mux[i].items[0].index : - spec->input_mux->items[0].index); } spec->vmaster_nid = 0x02; @@ -14086,7 +14124,7 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { }; static hda_nid_t alc269_adc_candidates[] = { - 0x08, 0x09, 0x07, + 0x08, 0x09, 0x07, 0x11, }; #define alc269_modes alc260_modes @@ -14423,7 +14461,7 @@ static void alc269_speaker_automute(struct hda_codec *codec) HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, HDA_AMP_MUTE, bits); - alc_report_jack(codec, nid); + snd_hda_input_jack_report(codec, nid); } /* unsolicited event for HP jack sensing */ @@ -14735,11 +14773,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) fillup_priv_adc_nids(codec, alc269_adc_candidates, sizeof(alc269_adc_candidates)); - /* set default input source */ - if (!spec->dual_adc_switch) - select_or_unmute_capsrc(codec, spec->capsrc_nids[0], - spec->input_mux->items[0].index); - err = alc_auto_add_mic_boost(codec); if (err < 0) return err; @@ -14753,6 +14786,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) #define alc269_auto_init_multi_out alc268_auto_init_multi_out #define alc269_auto_init_hp_out alc268_auto_init_hp_out #define alc269_auto_init_analog_input alc882_auto_init_analog_input +#define alc269_auto_init_input_src alc882_auto_init_input_src /* init callback for auto-configuration model -- overriding the default init */ @@ -14762,6 +14796,8 @@ static void alc269_auto_init(struct hda_codec *codec) alc269_auto_init_multi_out(codec); alc269_auto_init_hp_out(codec); alc269_auto_init_analog_input(codec); + if (!spec->dual_adc_switch) + alc269_auto_init_input_src(codec); alc_auto_init_digital(codec); if (spec->unsol_event) alc_inithook(codec); @@ -14822,17 +14858,19 @@ static int alc269_resume(struct hda_codec *codec) #endif /* SND_HDA_NEEDS_RESUME */ static void alc269_fixup_hweq(struct hda_codec *codec, - const struct alc_fixup *fix, int pre_init) + const struct alc_fixup *fix, int action) { int coef; + if (action != ALC_FIXUP_ACT_INIT) + return; coef = alc_read_coef_idx(codec, 0x1e); alc_write_coef_idx(codec, 0x1e, coef | 0x80); } enum { ALC269_FIXUP_SONY_VAIO, - ALC275_FIX_SONY_VAIO_GPIO2, + ALC275_FIXUP_SONY_VAIO_GPIO2, ALC269_FIXUP_DELL_M101Z, ALC269_FIXUP_SKU_IGNORE, ALC269_FIXUP_ASUS_G73JW, @@ -14842,22 +14880,26 @@ enum { static const struct alc_fixup alc269_fixups[] = { [ALC269_FIXUP_SONY_VAIO] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, {} } }, - [ALC275_FIX_SONY_VAIO_GPIO2] = { - .verbs = (const struct hda_verb[]) { + [ALC275_FIXUP_SONY_VAIO_GPIO2] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, { } - } + }, + .chained = true, + .chain_id = ALC269_FIXUP_SONY_VAIO }, [ALC269_FIXUP_DELL_M101Z] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { /* Enables internal speaker */ {0x20, AC_VERB_SET_COEF_INDEX, 13}, {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, @@ -14865,40 +14907,42 @@ static const struct alc_fixup alc269_fixups[] = { } }, [ALC269_FIXUP_SKU_IGNORE] = { - .sku = ALC_FIXUP_SKU_IGNORE, + .type = ALC_FIXUP_SKU, + .v.sku = ALC_FIXUP_SKU_IGNORE, }, [ALC269_FIXUP_ASUS_G73JW] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x99130111 }, /* subwoofer */ { } } }, [ALC269_FIXUP_LENOVO_EAPD] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, {} } }, [ALC275_FIXUP_SONY_HWEQ] = { - .func = alc269_fixup_hweq, - .verbs = (const struct hda_verb[]) { - {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, - { } - } + .type = ALC_FIXUP_FUNC, + .v.func = alc269_fixup_hweq, + .chained = true, + .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 } }; static struct snd_pci_quirk alc269_fixup_tbl[] = { - SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), + 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(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 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), + SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), {} @@ -14908,7 +14952,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { /* * configuration and preset */ -static const char *alc269_models[ALC269_MODEL_LAST] = { +static const char * const alc269_models[ALC269_MODEL_LAST] = { [ALC269_BASIC] = "basic", [ALC269_QUANTA_FL1] = "quanta", [ALC269_AMIC] = "laptop-amic", @@ -14932,7 +14976,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), - SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC), + SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), @@ -15184,8 +15228,10 @@ static int patch_alc269(struct hda_codec *codec) board_config = ALC269_AUTO; } - if (board_config == ALC269_AUTO) - alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); + if (board_config == ALC269_AUTO) { + alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC269_AUTO) { /* automatic parse from the BIOS config */ @@ -15246,8 +15292,7 @@ static int patch_alc269(struct hda_codec *codec) if (has_cdefine_beep(codec)) set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); - if (board_config == ALC269_AUTO) - alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); spec->vmaster_nid = 0x02; @@ -15950,7 +15995,7 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct alc_spec *spec = codec->spec; - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, true); @@ -15971,9 +16016,12 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; - err = __alc861_create_out_sw(codec, name, nid, i, 3); + index = 0; + } + err = __alc861_create_out_sw(codec, name, nid, index, 3); if (err < 0) return err; } @@ -16156,7 +16204,7 @@ static struct hda_amp_list alc861_loopbacks[] = { /* * configuration and preset */ -static const char *alc861_models[ALC861_MODEL_LAST] = { +static const char * const alc861_models[ALC861_MODEL_LAST] = { [ALC861_3ST] = "3stack", [ALC660_3ST] = "3stack-660", [ALC861_3ST_DIG] = "3stack-dig", @@ -16306,7 +16354,8 @@ enum { static const struct alc_fixup alc861_fixups[] = { [PINFIX_FSC_AMILO_PI1505] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x0b, 0x0221101f }, /* HP */ { 0x0f, 0x90170310 }, /* speaker */ { } @@ -16341,8 +16390,10 @@ static int patch_alc861(struct hda_codec *codec) board_config = ALC861_AUTO; } - if (board_config == ALC861_AUTO) - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); + if (board_config == ALC861_AUTO) { + alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC861_AUTO) { /* automatic parse from the BIOS config */ @@ -16379,8 +16430,7 @@ static int patch_alc861(struct hda_codec *codec) spec->vmaster_nid = 0x03; - if (board_config == ALC861_AUTO) - alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; if (board_config == ALC861_AUTO) { @@ -16857,7 +16907,7 @@ static void alc861vd_dallas_setup(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { +static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", [ALC660VD_3ST_DIG] = "3stack-660-digout", [ALC660VD_ASUS_V1S] = "asus-v1s", @@ -17072,12 +17122,14 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) /* add playback controls from the parsed DAC table */ -/* Based on ALC880 version. But ALC861VD and ALC887 have separate, +/* Based on ALC880 version. But ALC861VD has separate, * different NIDs for mute/unmute switch and volume control */ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { - static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; + static const char * const chname[4] = { + "Front", "Surround", "CLFE", "Side" + }; const char *pfx = alc_get_line_out_pfx(cfg, true); hda_nid_t nid_v, nid_s; int i, err; @@ -17120,16 +17172,19 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; + index = 0; + } err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); if (err < 0) return err; err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, - name, i, + name, index, HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); if (err < 0) @@ -17262,7 +17317,8 @@ enum { /* reset GPIO1 */ static const struct alc_fixup alc861vd_fixups[] = { [ALC660VD_FIX_ASUS_GPIO1] = { - .verbs = (const struct hda_verb[]) { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, @@ -17297,8 +17353,10 @@ static int patch_alc861vd(struct hda_codec *codec) board_config = ALC861VD_AUTO; } - if (board_config == ALC861VD_AUTO) - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); + if (board_config == ALC861VD_AUTO) { + alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } if (board_config == ALC861VD_AUTO) { /* automatic parse from the BIOS config */ @@ -17346,8 +17404,7 @@ static int patch_alc861vd(struct hda_codec *codec) spec->vmaster_nid = 0x02; - if (board_config == ALC861VD_AUTO) - alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -18630,7 +18687,7 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { /* * configuration and preset */ -static const char *alc662_models[ALC662_MODEL_LAST] = { +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", @@ -18725,8 +18782,6 @@ 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), @@ -18735,6 +18790,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", ALC663_ASUS_H13), + SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E), {} }; @@ -19145,7 +19201,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct alc_spec *spec = codec->spec; - static const char *chname[4] = { + static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; const char *pfx = alc_get_line_out_pfx(cfg, true); @@ -19175,12 +19231,15 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, return err; } else { const char *name = pfx; - if (!name) + int index = i; + if (!name) { name = chname[i]; - err = __alc662_add_vol_ctl(spec, name, nid, i, 3); + index = 0; + } + err = __alc662_add_vol_ctl(spec, name, nid, index, 3); if (err < 0) return err; - err = __alc662_add_sw_ctl(spec, name, mix, i, 3); + err = __alc662_add_sw_ctl(spec, name, mix, index, 3); if (err < 0) return err; } @@ -19378,7 +19437,10 @@ static void alc662_auto_init(struct hda_codec *codec) } static void alc272_fixup_mario(struct hda_codec *codec, - const struct alc_fixup *fix, int pre_init) { + const struct alc_fixup *fix, int action) +{ + if (action != ALC_FIXUP_ACT_PROBE) + return; if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, (0x3b << AC_AMPCAP_OFFSET_SHIFT) | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | @@ -19392,31 +19454,53 @@ enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, + ALC662_FIXUP_CZC_P10T, + ALC662_FIXUP_GIGABYTE, }; static const struct alc_fixup alc662_fixups[] = { [ALC662_FIXUP_ASPIRE] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x99130112 }, /* subwoofer */ { } } }, [ALC662_FIXUP_IDEAPAD] = { - .pins = (const struct alc_pincfg[]) { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { { 0x17, 0x99130112 }, /* subwoofer */ { } } }, [ALC272_FIXUP_MARIO] = { - .func = alc272_fixup_mario, - } + .type = ALC_FIXUP_FUNC, + .v.func = alc272_fixup_mario, + }, + [ALC662_FIXUP_CZC_P10T] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, + {} + } + }, + [ALC662_FIXUP_GIGABYTE] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1114410 }, /* set as speaker */ + { } + } + }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 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), {} }; @@ -19462,7 +19546,9 @@ static int patch_alc662(struct hda_codec *codec) } if (board_config == ALC662_AUTO) { - alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1); + alc_pick_fixup(codec, alc662_fixup_models, + alc662_fixup_tbl, alc662_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); /* automatic parse from the BIOS config */ err = alc662_parse_auto_config(codec); if (err < 0) { @@ -19520,12 +19606,11 @@ static int patch_alc662(struct hda_codec *codec) } spec->vmaster_nid = 0x02; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + codec->patch_ops = alc_patch_ops; - if (board_config == ALC662_AUTO) { + if (board_config == ALC662_AUTO) spec->init_hook = alc662_auto_init; - alc_pick_fixup_model(codec, alc662_fixup_models, - alc662_fixup_tbl, alc662_fixups, 0); - } alc_init_jacks(codec); @@ -19913,7 +19998,7 @@ static void alc680_auto_init(struct hda_codec *codec) /* * configuration and preset */ -static const char *alc680_models[ALC680_MODEL_LAST] = { +static const char * const alc680_models[ALC680_MODEL_LAST] = { [ALC680_BASE] = "base", [ALC680_AUTO] = "auto", }; |