Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
0004  *   AD1986A, AD1988
0005  *
0006  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
0007  */
0008 
0009 #include <linux/init.h>
0010 #include <linux/slab.h>
0011 #include <linux/module.h>
0012 
0013 #include <sound/core.h>
0014 #include <sound/hda_codec.h>
0015 #include "hda_local.h"
0016 #include "hda_auto_parser.h"
0017 #include "hda_beep.h"
0018 #include "hda_jack.h"
0019 #include "hda_generic.h"
0020 
0021 
0022 struct ad198x_spec {
0023     struct hda_gen_spec gen;
0024 
0025     /* for auto parser */
0026     int smux_paths[4];
0027     unsigned int cur_smux;
0028     hda_nid_t eapd_nid;
0029 
0030     unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
0031     int num_smux_conns;
0032 };
0033 
0034 
0035 #ifdef CONFIG_SND_HDA_INPUT_BEEP
0036 /* additional beep mixers; the actual parameters are overwritten at build */
0037 static const struct snd_kcontrol_new ad_beep_mixer[] = {
0038     HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
0039     HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
0040     { } /* end */
0041 };
0042 
0043 #define set_beep_amp(spec, nid, idx, dir) \
0044     ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
0045 #else
0046 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
0047 #endif
0048 
0049 #ifdef CONFIG_SND_HDA_INPUT_BEEP
0050 static int create_beep_ctls(struct hda_codec *codec)
0051 {
0052     struct ad198x_spec *spec = codec->spec;
0053     const struct snd_kcontrol_new *knew;
0054 
0055     if (!spec->beep_amp)
0056         return 0;
0057 
0058     for (knew = ad_beep_mixer ; knew->name; knew++) {
0059         int err;
0060         struct snd_kcontrol *kctl;
0061         kctl = snd_ctl_new1(knew, codec);
0062         if (!kctl)
0063             return -ENOMEM;
0064         kctl->private_value = spec->beep_amp;
0065         err = snd_hda_ctl_add(codec, 0, kctl);
0066         if (err < 0)
0067             return err;
0068     }
0069     return 0;
0070 }
0071 #else
0072 #define create_beep_ctls(codec)     0
0073 #endif
0074 
0075 #ifdef CONFIG_PM
0076 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
0077                 hda_nid_t hp)
0078 {
0079     if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
0080         snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
0081                 !codec->inv_eapd ? 0x00 : 0x02);
0082     if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
0083         snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
0084                 !codec->inv_eapd ? 0x00 : 0x02);
0085 }
0086 
0087 static void ad198x_power_eapd(struct hda_codec *codec)
0088 {
0089     /* We currently only handle front, HP */
0090     switch (codec->core.vendor_id) {
0091     case 0x11d41882:
0092     case 0x11d4882a:
0093     case 0x11d41884:
0094     case 0x11d41984:
0095     case 0x11d41883:
0096     case 0x11d4184a:
0097     case 0x11d4194a:
0098     case 0x11d4194b:
0099     case 0x11d41988:
0100     case 0x11d4198b:
0101     case 0x11d4989a:
0102     case 0x11d4989b:
0103         ad198x_power_eapd_write(codec, 0x12, 0x11);
0104         break;
0105     case 0x11d41981:
0106     case 0x11d41983:
0107         ad198x_power_eapd_write(codec, 0x05, 0x06);
0108         break;
0109     case 0x11d41986:
0110         ad198x_power_eapd_write(codec, 0x1b, 0x1a);
0111         break;
0112     }
0113 }
0114 
0115 static int ad198x_suspend(struct hda_codec *codec)
0116 {
0117     snd_hda_shutup_pins(codec);
0118     ad198x_power_eapd(codec);
0119     return 0;
0120 }
0121 #endif
0122 
0123 /* follow EAPD via vmaster hook */
0124 static void ad_vmaster_eapd_hook(void *private_data, int enabled)
0125 {
0126     struct hda_codec *codec = private_data;
0127     struct ad198x_spec *spec = codec->spec;
0128 
0129     if (!spec->eapd_nid)
0130         return;
0131     if (codec->inv_eapd)
0132         enabled = !enabled;
0133     snd_hda_codec_write_cache(codec, spec->eapd_nid, 0,
0134                    AC_VERB_SET_EAPD_BTLENABLE,
0135                    enabled ? 0x02 : 0x00);
0136 }
0137 
0138 /*
0139  * Automatic parse of I/O pins from the BIOS configuration
0140  */
0141 
0142 static int ad198x_auto_build_controls(struct hda_codec *codec)
0143 {
0144     int err;
0145 
0146     err = snd_hda_gen_build_controls(codec);
0147     if (err < 0)
0148         return err;
0149     err = create_beep_ctls(codec);
0150     if (err < 0)
0151         return err;
0152     return 0;
0153 }
0154 
0155 static const struct hda_codec_ops ad198x_auto_patch_ops = {
0156     .build_controls = ad198x_auto_build_controls,
0157     .build_pcms = snd_hda_gen_build_pcms,
0158     .init = snd_hda_gen_init,
0159     .free = snd_hda_gen_free,
0160     .unsol_event = snd_hda_jack_unsol_event,
0161 #ifdef CONFIG_PM
0162     .check_power_status = snd_hda_gen_check_power_status,
0163     .suspend = ad198x_suspend,
0164 #endif
0165 };
0166 
0167 
0168 static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp)
0169 {
0170     struct ad198x_spec *spec = codec->spec;
0171     struct auto_pin_cfg *cfg = &spec->gen.autocfg;
0172     int err;
0173 
0174     codec->spdif_status_reset = 1;
0175     codec->no_trigger_sense = 1;
0176     codec->no_sticky_stream = 1;
0177 
0178     spec->gen.indep_hp = indep_hp;
0179     if (!spec->gen.add_stereo_mix_input)
0180         spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
0181 
0182     err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
0183     if (err < 0)
0184         return err;
0185     err = snd_hda_gen_parse_auto_config(codec, cfg);
0186     if (err < 0)
0187         return err;
0188 
0189     return 0;
0190 }
0191 
0192 /*
0193  * AD1986A specific
0194  */
0195 
0196 static int alloc_ad_spec(struct hda_codec *codec)
0197 {
0198     struct ad198x_spec *spec;
0199 
0200     spec = kzalloc(sizeof(*spec), GFP_KERNEL);
0201     if (!spec)
0202         return -ENOMEM;
0203     codec->spec = spec;
0204     snd_hda_gen_spec_init(&spec->gen);
0205     codec->patch_ops = ad198x_auto_patch_ops;
0206     return 0;
0207 }
0208 
0209 /*
0210  * AD1986A fixup codes
0211  */
0212 
0213 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
0214 static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
0215                      const struct hda_fixup *fix, int action)
0216 {
0217     struct ad198x_spec *spec = codec->spec;
0218 
0219     if (action == HDA_FIXUP_ACT_PRE_PROBE) {
0220         codec->inv_jack_detect = 1;
0221         spec->gen.keep_eapd_on = 1;
0222         spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
0223         spec->eapd_nid = 0x1b;
0224     }
0225 }
0226 
0227 /* Toshiba Satellite L40 implements EAPD in a standard way unlike others */
0228 static void ad1986a_fixup_eapd(struct hda_codec *codec,
0229                    const struct hda_fixup *fix, int action)
0230 {
0231     struct ad198x_spec *spec = codec->spec;
0232 
0233     if (action == HDA_FIXUP_ACT_PRE_PROBE) {
0234         codec->inv_eapd = 0;
0235         spec->gen.keep_eapd_on = 1;
0236         spec->eapd_nid = 0x1b;
0237     }
0238 }
0239 
0240 /* enable stereo-mix input for avoiding regression on KDE (bko#88251) */
0241 static void ad1986a_fixup_eapd_mix_in(struct hda_codec *codec,
0242                       const struct hda_fixup *fix, int action)
0243 {
0244     struct ad198x_spec *spec = codec->spec;
0245 
0246     if (action == HDA_FIXUP_ACT_PRE_PROBE) {
0247         ad1986a_fixup_eapd(codec, fix, action);
0248         spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_ENABLE;
0249     }
0250 }
0251 
0252 enum {
0253     AD1986A_FIXUP_INV_JACK_DETECT,
0254     AD1986A_FIXUP_ULTRA,
0255     AD1986A_FIXUP_SAMSUNG,
0256     AD1986A_FIXUP_3STACK,
0257     AD1986A_FIXUP_LAPTOP,
0258     AD1986A_FIXUP_LAPTOP_IMIC,
0259     AD1986A_FIXUP_EAPD,
0260     AD1986A_FIXUP_EAPD_MIX_IN,
0261     AD1986A_FIXUP_EASYNOTE,
0262 };
0263 
0264 static const struct hda_fixup ad1986a_fixups[] = {
0265     [AD1986A_FIXUP_INV_JACK_DETECT] = {
0266         .type = HDA_FIXUP_FUNC,
0267         .v.func = ad_fixup_inv_jack_detect,
0268     },
0269     [AD1986A_FIXUP_ULTRA] = {
0270         .type = HDA_FIXUP_PINS,
0271         .v.pins = (const struct hda_pintbl[]) {
0272             { 0x1b, 0x90170110 }, /* speaker */
0273             { 0x1d, 0x90a7013e }, /* int mic */
0274             {}
0275         },
0276     },
0277     [AD1986A_FIXUP_SAMSUNG] = {
0278         .type = HDA_FIXUP_PINS,
0279         .v.pins = (const struct hda_pintbl[]) {
0280             { 0x1b, 0x90170110 }, /* speaker */
0281             { 0x1d, 0x90a7013e }, /* int mic */
0282             { 0x20, 0x411111f0 }, /* N/A */
0283             { 0x24, 0x411111f0 }, /* N/A */
0284             {}
0285         },
0286     },
0287     [AD1986A_FIXUP_3STACK] = {
0288         .type = HDA_FIXUP_PINS,
0289         .v.pins = (const struct hda_pintbl[]) {
0290             { 0x1a, 0x02214021 }, /* headphone */
0291             { 0x1b, 0x01014011 }, /* front */
0292             { 0x1c, 0x01813030 }, /* line-in */
0293             { 0x1d, 0x01a19020 }, /* rear mic */
0294             { 0x1e, 0x411111f0 }, /* N/A */
0295             { 0x1f, 0x02a190f0 }, /* mic */
0296             { 0x20, 0x411111f0 }, /* N/A */
0297             {}
0298         },
0299     },
0300     [AD1986A_FIXUP_LAPTOP] = {
0301         .type = HDA_FIXUP_PINS,
0302         .v.pins = (const struct hda_pintbl[]) {
0303             { 0x1a, 0x02214021 }, /* headphone */
0304             { 0x1b, 0x90170110 }, /* speaker */
0305             { 0x1c, 0x411111f0 }, /* N/A */
0306             { 0x1d, 0x411111f0 }, /* N/A */
0307             { 0x1e, 0x411111f0 }, /* N/A */
0308             { 0x1f, 0x02a191f0 }, /* mic */
0309             { 0x20, 0x411111f0 }, /* N/A */
0310             {}
0311         },
0312     },
0313     [AD1986A_FIXUP_LAPTOP_IMIC] = {
0314         .type = HDA_FIXUP_PINS,
0315         .v.pins = (const struct hda_pintbl[]) {
0316             { 0x1d, 0x90a7013e }, /* int mic */
0317             {}
0318         },
0319         .chained_before = 1,
0320         .chain_id = AD1986A_FIXUP_LAPTOP,
0321     },
0322     [AD1986A_FIXUP_EAPD] = {
0323         .type = HDA_FIXUP_FUNC,
0324         .v.func = ad1986a_fixup_eapd,
0325     },
0326     [AD1986A_FIXUP_EAPD_MIX_IN] = {
0327         .type = HDA_FIXUP_FUNC,
0328         .v.func = ad1986a_fixup_eapd_mix_in,
0329     },
0330     [AD1986A_FIXUP_EASYNOTE] = {
0331         .type = HDA_FIXUP_PINS,
0332         .v.pins = (const struct hda_pintbl[]) {
0333             { 0x1a, 0x0421402f }, /* headphone */
0334             { 0x1b, 0x90170110 }, /* speaker */
0335             { 0x1c, 0x411111f0 }, /* N/A */
0336             { 0x1d, 0x90a70130 }, /* int mic */
0337             { 0x1e, 0x411111f0 }, /* N/A */
0338             { 0x1f, 0x04a19040 }, /* mic */
0339             { 0x20, 0x411111f0 }, /* N/A */
0340             { 0x21, 0x411111f0 }, /* N/A */
0341             { 0x22, 0x411111f0 }, /* N/A */
0342             { 0x23, 0x411111f0 }, /* N/A */
0343             { 0x24, 0x411111f0 }, /* N/A */
0344             { 0x25, 0x411111f0 }, /* N/A */
0345             {}
0346         },
0347         .chained = true,
0348         .chain_id = AD1986A_FIXUP_EAPD_MIX_IN,
0349     },
0350 };
0351 
0352 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
0353     SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC),
0354     SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9V", AD1986A_FIXUP_LAPTOP_IMIC),
0355     SND_PCI_QUIRK(0x1043, 0x1443, "ASUS Z99He", AD1986A_FIXUP_EAPD),
0356     SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8JN", AD1986A_FIXUP_EAPD),
0357     SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK),
0358     SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK),
0359     SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK),
0360     SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD),
0361     SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP),
0362     SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
0363     SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
0364     SND_PCI_QUIRK(0x1631, 0xc022, "PackardBell EasyNote MX65", AD1986A_FIXUP_EASYNOTE),
0365     SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
0366     SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK),
0367     SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK),
0368     {}
0369 };
0370 
0371 static const struct hda_model_fixup ad1986a_fixup_models[] = {
0372     { .id = AD1986A_FIXUP_3STACK, .name = "3stack" },
0373     { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" },
0374     { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" },
0375     { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */
0376     { .id = AD1986A_FIXUP_EAPD, .name = "eapd" },
0377     {}
0378 };
0379 
0380 /*
0381  */
0382 static int patch_ad1986a(struct hda_codec *codec)
0383 {
0384     int err;
0385     struct ad198x_spec *spec;
0386     static const hda_nid_t preferred_pairs[] = {
0387         0x1a, 0x03,
0388         0x1b, 0x03,
0389         0x1c, 0x04,
0390         0x1d, 0x05,
0391         0x1e, 0x03,
0392         0
0393     };
0394 
0395     err = alloc_ad_spec(codec);
0396     if (err < 0)
0397         return err;
0398     spec = codec->spec;
0399 
0400     /* AD1986A has the inverted EAPD implementation */
0401     codec->inv_eapd = 1;
0402 
0403     spec->gen.mixer_nid = 0x07;
0404     spec->gen.beep_nid = 0x19;
0405     set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
0406 
0407     /* AD1986A has a hardware problem that it can't share a stream
0408      * with multiple output pins.  The copy of front to surrounds
0409      * causes noisy or silent outputs at a certain timing, e.g.
0410      * changing the volume.
0411      * So, let's disable the shared stream.
0412      */
0413     spec->gen.multiout.no_share_stream = 1;
0414     /* give fixed DAC/pin pairs */
0415     spec->gen.preferred_dacs = preferred_pairs;
0416 
0417     /* AD1986A can't manage the dynamic pin on/off smoothly */
0418     spec->gen.auto_mute_via_amp = 1;
0419 
0420     snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl,
0421                ad1986a_fixups);
0422     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
0423 
0424     err = ad198x_parse_auto_config(codec, false);
0425     if (err < 0) {
0426         snd_hda_gen_free(codec);
0427         return err;
0428     }
0429 
0430     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
0431 
0432     return 0;
0433 }
0434 
0435 
0436 /*
0437  * AD1983 specific
0438  */
0439 
0440 /*
0441  * SPDIF mux control for AD1983 auto-parser
0442  */
0443 static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
0444                       struct snd_ctl_elem_info *uinfo)
0445 {
0446     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0447     struct ad198x_spec *spec = codec->spec;
0448     static const char * const texts2[] = { "PCM", "ADC" };
0449     static const char * const texts3[] = { "PCM", "ADC1", "ADC2" };
0450     int num_conns = spec->num_smux_conns;
0451 
0452     if (num_conns == 2)
0453         return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2);
0454     else if (num_conns == 3)
0455         return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
0456     else
0457         return -EINVAL;
0458 }
0459 
0460 static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
0461                      struct snd_ctl_elem_value *ucontrol)
0462 {
0463     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0464     struct ad198x_spec *spec = codec->spec;
0465 
0466     ucontrol->value.enumerated.item[0] = spec->cur_smux;
0467     return 0;
0468 }
0469 
0470 static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
0471                      struct snd_ctl_elem_value *ucontrol)
0472 {
0473     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0474     struct ad198x_spec *spec = codec->spec;
0475     unsigned int val = ucontrol->value.enumerated.item[0];
0476     hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
0477     int num_conns = spec->num_smux_conns;
0478 
0479     if (val >= num_conns)
0480         return -EINVAL;
0481     if (spec->cur_smux == val)
0482         return 0;
0483     spec->cur_smux = val;
0484     snd_hda_codec_write_cache(codec, dig_out, 0,
0485                   AC_VERB_SET_CONNECT_SEL, val);
0486     return 1;
0487 }
0488 
0489 static const struct snd_kcontrol_new ad1983_auto_smux_mixer = {
0490     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0491     .name = "IEC958 Playback Source",
0492     .info = ad1983_auto_smux_enum_info,
0493     .get = ad1983_auto_smux_enum_get,
0494     .put = ad1983_auto_smux_enum_put,
0495 };
0496 
0497 static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
0498 {
0499     struct ad198x_spec *spec = codec->spec;
0500     hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
0501     int num_conns;
0502 
0503     if (!dig_out)
0504         return 0;
0505     num_conns = snd_hda_get_num_conns(codec, dig_out);
0506     if (num_conns != 2 && num_conns != 3)
0507         return 0;
0508     spec->num_smux_conns = num_conns;
0509     if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer))
0510         return -ENOMEM;
0511     return 0;
0512 }
0513 
0514 static int patch_ad1983(struct hda_codec *codec)
0515 {
0516     static const hda_nid_t conn_0c[] = { 0x08 };
0517     static const hda_nid_t conn_0d[] = { 0x09 };
0518     struct ad198x_spec *spec;
0519     int err;
0520 
0521     err = alloc_ad_spec(codec);
0522     if (err < 0)
0523         return err;
0524     spec = codec->spec;
0525 
0526     spec->gen.mixer_nid = 0x0e;
0527     spec->gen.beep_nid = 0x10;
0528     set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
0529 
0530     /* limit the loopback routes not to confuse the parser */
0531     snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c);
0532     snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d);
0533 
0534     err = ad198x_parse_auto_config(codec, false);
0535     if (err < 0)
0536         goto error;
0537     err = ad1983_add_spdif_mux_ctl(codec);
0538     if (err < 0)
0539         goto error;
0540     return 0;
0541 
0542  error:
0543     snd_hda_gen_free(codec);
0544     return err;
0545 }
0546 
0547 
0548 /*
0549  * AD1981 HD specific
0550  */
0551 
0552 static void ad1981_fixup_hp_eapd(struct hda_codec *codec,
0553                  const struct hda_fixup *fix, int action)
0554 {
0555     struct ad198x_spec *spec = codec->spec;
0556 
0557     if (action == HDA_FIXUP_ACT_PRE_PROBE) {
0558         spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
0559         spec->eapd_nid = 0x05;
0560     }
0561 }
0562 
0563 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
0564  * damage by overloading
0565  */
0566 static void ad1981_fixup_amp_override(struct hda_codec *codec,
0567                       const struct hda_fixup *fix, int action)
0568 {
0569     if (action == HDA_FIXUP_ACT_PRE_PROBE)
0570         snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
0571                       (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
0572                       (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
0573                       (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
0574                       (1 << AC_AMPCAP_MUTE_SHIFT));
0575 }
0576 
0577 enum {
0578     AD1981_FIXUP_AMP_OVERRIDE,
0579     AD1981_FIXUP_HP_EAPD,
0580 };
0581 
0582 static const struct hda_fixup ad1981_fixups[] = {
0583     [AD1981_FIXUP_AMP_OVERRIDE] = {
0584         .type = HDA_FIXUP_FUNC,
0585         .v.func = ad1981_fixup_amp_override,
0586     },
0587     [AD1981_FIXUP_HP_EAPD] = {
0588         .type = HDA_FIXUP_FUNC,
0589         .v.func = ad1981_fixup_hp_eapd,
0590         .chained = true,
0591         .chain_id = AD1981_FIXUP_AMP_OVERRIDE,
0592     },
0593 };
0594 
0595 static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
0596     SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
0597     SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD),
0598     SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
0599     /* HP nx6320 (reversed SSID, H/W bug) */
0600     SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD),
0601     {}
0602 };
0603 
0604 static int patch_ad1981(struct hda_codec *codec)
0605 {
0606     struct ad198x_spec *spec;
0607     int err;
0608 
0609     err = alloc_ad_spec(codec);
0610     if (err < 0)
0611         return -ENOMEM;
0612     spec = codec->spec;
0613 
0614     spec->gen.mixer_nid = 0x0e;
0615     spec->gen.beep_nid = 0x10;
0616     set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
0617 
0618     snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
0619     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
0620 
0621     err = ad198x_parse_auto_config(codec, false);
0622     if (err < 0)
0623         goto error;
0624     err = ad1983_add_spdif_mux_ctl(codec);
0625     if (err < 0)
0626         goto error;
0627 
0628     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
0629 
0630     return 0;
0631 
0632  error:
0633     snd_hda_gen_free(codec);
0634     return err;
0635 }
0636 
0637 
0638 /*
0639  * AD1988
0640  *
0641  * Output pins and routes
0642  *
0643  *        Pin               Mix     Sel     DAC (*)
0644  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
0645  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
0646  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
0647  * port-D 0x12 (mute/hp) <- 0x29         <- 04
0648  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
0649  * port-F 0x16 (mute)    <- 0x2a         <- 06
0650  * port-G 0x24 (mute)    <- 0x27         <- 05
0651  * port-H 0x25 (mute)    <- 0x28         <- 0a
0652  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
0653  *
0654  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
0655  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
0656  *
0657  * Input pins and routes
0658  *
0659  *        pin     boost   mix input # / adc input #
0660  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
0661  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
0662  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
0663  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
0664  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
0665  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
0666  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
0667  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
0668  *
0669  *
0670  * DAC assignment
0671  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
0672  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
0673  *
0674  * Inputs of Analog Mix (0x20)
0675  *   0:Port-B (front mic)
0676  *   1:Port-C/G/H (line-in)
0677  *   2:Port-A
0678  *   3:Port-D (line-in/2)
0679  *   4:Port-E/G/H (mic-in)
0680  *   5:Port-F (mic2-in)
0681  *   6:CD
0682  *   7:Beep
0683  *
0684  * ADC selection
0685  *   0:Port-A
0686  *   1:Port-B (front mic-in)
0687  *   2:Port-C (line-in)
0688  *   3:Port-F (mic2-in)
0689  *   4:Port-E (mic-in)
0690  *   5:CD
0691  *   6:Port-G
0692  *   7:Port-H
0693  *   8:Port-D (line-in/2)
0694  *   9:Mix
0695  *
0696  * Proposed pin assignments by the datasheet
0697  *
0698  * 6-stack
0699  * Port-A front headphone
0700  *      B front mic-in
0701  *      C rear line-in
0702  *      D rear front-out
0703  *      E rear mic-in
0704  *      F rear surround
0705  *      G rear CLFE
0706  *      H rear side
0707  *
0708  * 3-stack
0709  * Port-A front headphone
0710  *      B front mic
0711  *      C rear line-in/surround
0712  *      D rear front-out
0713  *      E rear mic-in/CLFE
0714  *
0715  * laptop
0716  * Port-A headphone
0717  *      B mic-in
0718  *      C docking station
0719  *      D internal speaker (with EAPD)
0720  *      E/F quad mic array
0721  */
0722 
0723 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
0724                       struct snd_ctl_elem_info *uinfo)
0725 {
0726     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0727     struct ad198x_spec *spec = codec->spec;
0728     static const char * const texts[] = {
0729         "PCM", "ADC1", "ADC2", "ADC3",
0730     };
0731     int num_conns = spec->num_smux_conns;
0732 
0733     if (num_conns > 4)
0734         num_conns = 4;
0735     return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts);
0736 }
0737 
0738 static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
0739                      struct snd_ctl_elem_value *ucontrol)
0740 {
0741     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0742     struct ad198x_spec *spec = codec->spec;
0743 
0744     ucontrol->value.enumerated.item[0] = spec->cur_smux;
0745     return 0;
0746 }
0747 
0748 static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
0749                      struct snd_ctl_elem_value *ucontrol)
0750 {
0751     struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
0752     struct ad198x_spec *spec = codec->spec;
0753     unsigned int val = ucontrol->value.enumerated.item[0];
0754     struct nid_path *path;
0755     int num_conns = spec->num_smux_conns;
0756 
0757     if (val >= num_conns)
0758         return -EINVAL;
0759     if (spec->cur_smux == val)
0760         return 0;
0761 
0762     mutex_lock(&codec->control_mutex);
0763     path = snd_hda_get_path_from_idx(codec,
0764                      spec->smux_paths[spec->cur_smux]);
0765     if (path)
0766         snd_hda_activate_path(codec, path, false, true);
0767     path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]);
0768     if (path)
0769         snd_hda_activate_path(codec, path, true, true);
0770     spec->cur_smux = val;
0771     mutex_unlock(&codec->control_mutex);
0772     return 1;
0773 }
0774 
0775 static const struct snd_kcontrol_new ad1988_auto_smux_mixer = {
0776     .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
0777     .name = "IEC958 Playback Source",
0778     .info = ad1988_auto_smux_enum_info,
0779     .get = ad1988_auto_smux_enum_get,
0780     .put = ad1988_auto_smux_enum_put,
0781 };
0782 
0783 static int ad1988_auto_init(struct hda_codec *codec)
0784 {
0785     struct ad198x_spec *spec = codec->spec;
0786     int i, err;
0787 
0788     err = snd_hda_gen_init(codec);
0789     if (err < 0)
0790         return err;
0791     if (!spec->gen.autocfg.dig_outs)
0792         return 0;
0793 
0794     for (i = 0; i < 4; i++) {
0795         struct nid_path *path;
0796         path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]);
0797         if (path)
0798             snd_hda_activate_path(codec, path, path->active, false);
0799     }
0800 
0801     return 0;
0802 }
0803 
0804 static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
0805 {
0806     struct ad198x_spec *spec = codec->spec;
0807     int i, num_conns;
0808     /* we create four static faked paths, since AD codecs have odd
0809      * widget connections regarding the SPDIF out source
0810      */
0811     static const struct nid_path fake_paths[4] = {
0812         {
0813             .depth = 3,
0814             .path = { 0x02, 0x1d, 0x1b },
0815             .idx = { 0, 0, 0 },
0816             .multi = { 0, 0, 0 },
0817         },
0818         {
0819             .depth = 4,
0820             .path = { 0x08, 0x0b, 0x1d, 0x1b },
0821             .idx = { 0, 0, 1, 0 },
0822             .multi = { 0, 1, 0, 0 },
0823         },
0824         {
0825             .depth = 4,
0826             .path = { 0x09, 0x0b, 0x1d, 0x1b },
0827             .idx = { 0, 1, 1, 0 },
0828             .multi = { 0, 1, 0, 0 },
0829         },
0830         {
0831             .depth = 4,
0832             .path = { 0x0f, 0x0b, 0x1d, 0x1b },
0833             .idx = { 0, 2, 1, 0 },
0834             .multi = { 0, 1, 0, 0 },
0835         },
0836     };
0837 
0838     /* SPDIF source mux appears to be present only on AD1988A */
0839     if (!spec->gen.autocfg.dig_outs ||
0840         get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX)
0841         return 0;
0842 
0843     num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
0844     if (num_conns != 3 && num_conns != 4)
0845         return 0;
0846     spec->num_smux_conns = num_conns;
0847 
0848     for (i = 0; i < num_conns; i++) {
0849         struct nid_path *path = snd_array_new(&spec->gen.paths);
0850         if (!path)
0851             return -ENOMEM;
0852         *path = fake_paths[i];
0853         if (!i)
0854             path->active = 1;
0855         spec->smux_paths[i] = snd_hda_get_path_idx(codec, path);
0856     }
0857 
0858     if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer))
0859         return -ENOMEM;
0860 
0861     codec->patch_ops.init = ad1988_auto_init;
0862 
0863     return 0;
0864 }
0865 
0866 /*
0867  */
0868 
0869 enum {
0870     AD1988_FIXUP_6STACK_DIG,
0871 };
0872 
0873 static const struct hda_fixup ad1988_fixups[] = {
0874     [AD1988_FIXUP_6STACK_DIG] = {
0875         .type = HDA_FIXUP_PINS,
0876         .v.pins = (const struct hda_pintbl[]) {
0877             { 0x11, 0x02214130 }, /* front-hp */
0878             { 0x12, 0x01014010 }, /* line-out */
0879             { 0x14, 0x02a19122 }, /* front-mic */
0880             { 0x15, 0x01813021 }, /* line-in */
0881             { 0x16, 0x01011012 }, /* line-out */
0882             { 0x17, 0x01a19020 }, /* mic */
0883             { 0x1b, 0x0145f1f0 }, /* SPDIF */
0884             { 0x24, 0x01016011 }, /* line-out */
0885             { 0x25, 0x01012013 }, /* line-out */
0886             { }
0887         }
0888     },
0889 };
0890 
0891 static const struct hda_model_fixup ad1988_fixup_models[] = {
0892     { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" },
0893     {}
0894 };
0895 
0896 static int patch_ad1988(struct hda_codec *codec)
0897 {
0898     struct ad198x_spec *spec;
0899     int err;
0900 
0901     err = alloc_ad_spec(codec);
0902     if (err < 0)
0903         return err;
0904     spec = codec->spec;
0905 
0906     spec->gen.mixer_nid = 0x20;
0907     spec->gen.mixer_merge_nid = 0x21;
0908     spec->gen.beep_nid = 0x10;
0909     set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
0910 
0911     snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
0912     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
0913 
0914     err = ad198x_parse_auto_config(codec, true);
0915     if (err < 0)
0916         goto error;
0917     err = ad1988_add_spdif_mux_ctl(codec);
0918     if (err < 0)
0919         goto error;
0920 
0921     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
0922 
0923     return 0;
0924 
0925  error:
0926     snd_hda_gen_free(codec);
0927     return err;
0928 }
0929 
0930 
0931 /*
0932  * AD1884 / AD1984
0933  *
0934  * port-B - front line/mic-in
0935  * port-E - aux in/out
0936  * port-F - aux in/out
0937  * port-C - rear line/mic-in
0938  * port-D - rear line/hp-out
0939  * port-A - front line/hp-out
0940  *
0941  * AD1984 = AD1884 + two digital mic-ins
0942  *
0943  * AD1883 / AD1884A / AD1984A / AD1984B
0944  *
0945  * port-B (0x14) - front mic-in
0946  * port-E (0x1c) - rear mic-in
0947  * port-F (0x16) - CD / ext out
0948  * port-C (0x15) - rear line-in
0949  * port-D (0x12) - rear line-out
0950  * port-A (0x11) - front hp-out
0951  *
0952  * AD1984A = AD1884A + digital-mic
0953  * AD1883 = equivalent with AD1984A
0954  * AD1984B = AD1984A + extra SPDIF-out
0955  */
0956 
0957 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
0958  * damage by overloading
0959  */
0960 static void ad1884_fixup_amp_override(struct hda_codec *codec,
0961                       const struct hda_fixup *fix, int action)
0962 {
0963     if (action == HDA_FIXUP_ACT_PRE_PROBE)
0964         snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
0965                       (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
0966                       (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
0967                       (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
0968                       (1 << AC_AMPCAP_MUTE_SHIFT));
0969 }
0970 
0971 /* toggle GPIO1 according to the mute state */
0972 static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
0973 {
0974     struct hda_codec *codec = private_data;
0975     struct ad198x_spec *spec = codec->spec;
0976 
0977     if (spec->eapd_nid)
0978         ad_vmaster_eapd_hook(private_data, enabled);
0979     snd_hda_codec_write_cache(codec, 0x01, 0,
0980                    AC_VERB_SET_GPIO_DATA,
0981                    enabled ? 0x00 : 0x02);
0982 }
0983 
0984 static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
0985                  const struct hda_fixup *fix, int action)
0986 {
0987     struct ad198x_spec *spec = codec->spec;
0988 
0989     switch (action) {
0990     case HDA_FIXUP_ACT_PRE_PROBE:
0991         spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
0992         spec->gen.own_eapd_ctl = 1;
0993         snd_hda_codec_write_cache(codec, 0x01, 0,
0994                       AC_VERB_SET_GPIO_MASK, 0x02);
0995         snd_hda_codec_write_cache(codec, 0x01, 0,
0996                       AC_VERB_SET_GPIO_DIRECTION, 0x02);
0997         snd_hda_codec_write_cache(codec, 0x01, 0,
0998                       AC_VERB_SET_GPIO_DATA, 0x02);
0999         break;
1000     case HDA_FIXUP_ACT_PROBE:
1001         if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1002             spec->eapd_nid = spec->gen.autocfg.line_out_pins[0];
1003         else
1004             spec->eapd_nid = spec->gen.autocfg.speaker_pins[0];
1005         break;
1006     }
1007 }
1008 
1009 static void ad1884_fixup_thinkpad(struct hda_codec *codec,
1010                   const struct hda_fixup *fix, int action)
1011 {
1012     struct ad198x_spec *spec = codec->spec;
1013 
1014     if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1015         spec->gen.keep_eapd_on = 1;
1016         spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
1017         spec->eapd_nid = 0x12;
1018         /* Analog PC Beeper - allow firmware/ACPI beeps */
1019         spec->beep_amp = HDA_COMPOSE_AMP_VAL(0x20, 3, 3, HDA_INPUT);
1020         spec->gen.beep_nid = 0; /* no digital beep */
1021     }
1022 }
1023 
1024 /* set magic COEFs for dmic */
1025 static const struct hda_verb ad1884_dmic_init_verbs[] = {
1026     {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
1027     {0x01, AC_VERB_SET_PROC_COEF, 0x08},
1028     {}
1029 };
1030 
1031 enum {
1032     AD1884_FIXUP_AMP_OVERRIDE,
1033     AD1884_FIXUP_HP_EAPD,
1034     AD1884_FIXUP_DMIC_COEF,
1035     AD1884_FIXUP_THINKPAD,
1036     AD1884_FIXUP_HP_TOUCHSMART,
1037 };
1038 
1039 static const struct hda_fixup ad1884_fixups[] = {
1040     [AD1884_FIXUP_AMP_OVERRIDE] = {
1041         .type = HDA_FIXUP_FUNC,
1042         .v.func = ad1884_fixup_amp_override,
1043     },
1044     [AD1884_FIXUP_HP_EAPD] = {
1045         .type = HDA_FIXUP_FUNC,
1046         .v.func = ad1884_fixup_hp_eapd,
1047         .chained = true,
1048         .chain_id = AD1884_FIXUP_AMP_OVERRIDE,
1049     },
1050     [AD1884_FIXUP_DMIC_COEF] = {
1051         .type = HDA_FIXUP_VERBS,
1052         .v.verbs = ad1884_dmic_init_verbs,
1053     },
1054     [AD1884_FIXUP_THINKPAD] = {
1055         .type = HDA_FIXUP_FUNC,
1056         .v.func = ad1884_fixup_thinkpad,
1057         .chained = true,
1058         .chain_id = AD1884_FIXUP_DMIC_COEF,
1059     },
1060     [AD1884_FIXUP_HP_TOUCHSMART] = {
1061         .type = HDA_FIXUP_VERBS,
1062         .v.verbs = ad1884_dmic_init_verbs,
1063         .chained = true,
1064         .chain_id = AD1884_FIXUP_HP_EAPD,
1065     },
1066 };
1067 
1068 static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
1069     SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART),
1070     SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
1071     SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_THINKPAD),
1072     {}
1073 };
1074 
1075 
1076 static int patch_ad1884(struct hda_codec *codec)
1077 {
1078     struct ad198x_spec *spec;
1079     int err;
1080 
1081     err = alloc_ad_spec(codec);
1082     if (err < 0)
1083         return err;
1084     spec = codec->spec;
1085 
1086     spec->gen.mixer_nid = 0x20;
1087     spec->gen.mixer_merge_nid = 0x21;
1088     spec->gen.beep_nid = 0x10;
1089     set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1090 
1091     snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
1092     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1093 
1094     err = ad198x_parse_auto_config(codec, true);
1095     if (err < 0)
1096         goto error;
1097     err = ad1983_add_spdif_mux_ctl(codec);
1098     if (err < 0)
1099         goto error;
1100 
1101     snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1102 
1103     return 0;
1104 
1105  error:
1106     snd_hda_gen_free(codec);
1107     return err;
1108 }
1109 
1110 /*
1111  * AD1882 / AD1882A
1112  *
1113  * port-A - front hp-out
1114  * port-B - front mic-in
1115  * port-C - rear line-in, shared surr-out (3stack)
1116  * port-D - rear line-out
1117  * port-E - rear mic-in, shared clfe-out (3stack)
1118  * port-F - rear surr-out (6stack)
1119  * port-G - rear clfe-out (6stack)
1120  */
1121 
1122 static int patch_ad1882(struct hda_codec *codec)
1123 {
1124     struct ad198x_spec *spec;
1125     int err;
1126 
1127     err = alloc_ad_spec(codec);
1128     if (err < 0)
1129         return err;
1130     spec = codec->spec;
1131 
1132     spec->gen.mixer_nid = 0x20;
1133     spec->gen.mixer_merge_nid = 0x21;
1134     spec->gen.beep_nid = 0x10;
1135     set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1136     err = ad198x_parse_auto_config(codec, true);
1137     if (err < 0)
1138         goto error;
1139     err = ad1988_add_spdif_mux_ctl(codec);
1140     if (err < 0)
1141         goto error;
1142     return 0;
1143 
1144  error:
1145     snd_hda_gen_free(codec);
1146     return err;
1147 }
1148 
1149 
1150 /*
1151  * patch entries
1152  */
1153 static const struct hda_device_id snd_hda_id_analog[] = {
1154     HDA_CODEC_ENTRY(0x11d4184a, "AD1884A", patch_ad1884),
1155     HDA_CODEC_ENTRY(0x11d41882, "AD1882", patch_ad1882),
1156     HDA_CODEC_ENTRY(0x11d41883, "AD1883", patch_ad1884),
1157     HDA_CODEC_ENTRY(0x11d41884, "AD1884", patch_ad1884),
1158     HDA_CODEC_ENTRY(0x11d4194a, "AD1984A", patch_ad1884),
1159     HDA_CODEC_ENTRY(0x11d4194b, "AD1984B", patch_ad1884),
1160     HDA_CODEC_ENTRY(0x11d41981, "AD1981", patch_ad1981),
1161     HDA_CODEC_ENTRY(0x11d41983, "AD1983", patch_ad1983),
1162     HDA_CODEC_ENTRY(0x11d41984, "AD1984", patch_ad1884),
1163     HDA_CODEC_ENTRY(0x11d41986, "AD1986A", patch_ad1986a),
1164     HDA_CODEC_ENTRY(0x11d41988, "AD1988", patch_ad1988),
1165     HDA_CODEC_ENTRY(0x11d4198b, "AD1988B", patch_ad1988),
1166     HDA_CODEC_ENTRY(0x11d4882a, "AD1882A", patch_ad1882),
1167     HDA_CODEC_ENTRY(0x11d4989a, "AD1989A", patch_ad1988),
1168     HDA_CODEC_ENTRY(0x11d4989b, "AD1989B", patch_ad1988),
1169     {} /* terminator */
1170 };
1171 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_analog);
1172 
1173 MODULE_LICENSE("GPL");
1174 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
1175 
1176 static struct hda_codec_driver analog_driver = {
1177     .id = snd_hda_id_analog,
1178 };
1179 
1180 module_hda_codec_driver(analog_driver);