linux/sound/pci/hda/patch_realtek.c
<<
>>
Prefs
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * HD audio interface patch for Realtek ALC codecs
   5 *
   6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
   7 *                    PeiSen Hou <pshou@realtek.com.tw>
   8 *                    Takashi Iwai <tiwai@suse.de>
   9 *                    Jonathan Woithe <jwoithe@just42.net>
  10 *
  11 *  This driver is free software; you can redistribute it and/or modify
  12 *  it under the terms of the GNU General Public License as published by
  13 *  the Free Software Foundation; either version 2 of the License, or
  14 *  (at your option) any later version.
  15 *
  16 *  This driver is distributed in the hope that it will be useful,
  17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 *  GNU General Public License for more details.
  20 *
  21 *  You should have received a copy of the GNU General Public License
  22 *  along with this program; if not, write to the Free Software
  23 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  24 */
  25
  26#include <linux/init.h>
  27#include <linux/delay.h>
  28#include <linux/slab.h>
  29#include <linux/pci.h>
  30#include <linux/dmi.h>
  31#include <linux/module.h>
  32#include <linux/input.h>
  33#include <sound/core.h>
  34#include <sound/jack.h>
  35#include "hda_codec.h"
  36#include "hda_local.h"
  37#include "hda_auto_parser.h"
  38#include "hda_jack.h"
  39#include "hda_generic.h"
  40
  41/* keep halting ALC5505 DSP, for power saving */
  42#define HALT_REALTEK_ALC5505
  43
  44/* for GPIO Poll */
  45#define GPIO_MASK       0x03
  46
  47/* extra amp-initialization sequence types */
  48enum {
  49        ALC_INIT_NONE,
  50        ALC_INIT_DEFAULT,
  51        ALC_INIT_GPIO1,
  52        ALC_INIT_GPIO2,
  53        ALC_INIT_GPIO3,
  54};
  55
  56enum {
  57        ALC_HEADSET_MODE_UNKNOWN,
  58        ALC_HEADSET_MODE_UNPLUGGED,
  59        ALC_HEADSET_MODE_HEADSET,
  60        ALC_HEADSET_MODE_MIC,
  61        ALC_HEADSET_MODE_HEADPHONE,
  62};
  63
  64enum {
  65        ALC_HEADSET_TYPE_UNKNOWN,
  66        ALC_HEADSET_TYPE_CTIA,
  67        ALC_HEADSET_TYPE_OMTP,
  68};
  69
  70struct alc_customize_define {
  71        unsigned int  sku_cfg;
  72        unsigned char port_connectivity;
  73        unsigned char check_sum;
  74        unsigned char customization;
  75        unsigned char external_amp;
  76        unsigned int  enable_pcbeep:1;
  77        unsigned int  platform_type:1;
  78        unsigned int  swap:1;
  79        unsigned int  override:1;
  80        unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
  81};
  82
  83struct alc_spec {
  84        struct hda_gen_spec gen; /* must be at head */
  85
  86        /* codec parameterization */
  87        const struct snd_kcontrol_new *mixers[5];       /* mixer arrays */
  88        unsigned int num_mixers;
  89        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
  90
  91        struct alc_customize_define cdefine;
  92        unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
  93
  94        /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */
  95        int mute_led_polarity;
  96        hda_nid_t mute_led_nid;
  97        hda_nid_t cap_mute_led_nid;
  98
  99        unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */
 100        unsigned int gpio_mute_led_mask;
 101        unsigned int gpio_mic_led_mask;
 102
 103        hda_nid_t headset_mic_pin;
 104        hda_nid_t headphone_mic_pin;
 105        int current_headset_mode;
 106        int current_headset_type;
 107
 108        /* hooks */
 109        void (*init_hook)(struct hda_codec *codec);
 110#ifdef CONFIG_PM
 111        void (*power_hook)(struct hda_codec *codec);
 112#endif
 113        void (*shutup)(struct hda_codec *codec);
 114
 115        int init_amp;
 116        int codec_variant;      /* flag for other variants */
 117        unsigned int has_alc5505_dsp:1;
 118        unsigned int no_depop_delay:1;
 119
 120        /* for PLL fix */
 121        hda_nid_t pll_nid;
 122        unsigned int pll_coef_idx, pll_coef_bit;
 123        unsigned int coef0;
 124        struct input_dev *kb_dev;
 125};
 126
 127/*
 128 * COEF access helper functions
 129 */
 130
 131static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
 132                               unsigned int coef_idx)
 133{
 134        unsigned int val;
 135
 136        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
 137        val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
 138        return val;
 139}
 140
 141#define alc_read_coef_idx(codec, coef_idx) \
 142        alc_read_coefex_idx(codec, 0x20, coef_idx)
 143
 144static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
 145                                 unsigned int coef_idx, unsigned int coef_val)
 146{
 147        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx);
 148        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val);
 149}
 150
 151#define alc_write_coef_idx(codec, coef_idx, coef_val) \
 152        alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val)
 153
 154static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid,
 155                                  unsigned int coef_idx, unsigned int mask,
 156                                  unsigned int bits_set)
 157{
 158        unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx);
 159
 160        if (val != -1)
 161                alc_write_coefex_idx(codec, nid, coef_idx,
 162                                     (val & ~mask) | bits_set);
 163}
 164
 165#define alc_update_coef_idx(codec, coef_idx, mask, bits_set)    \
 166        alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set)
 167
 168/* a special bypass for COEF 0; read the cached value at the second time */
 169static unsigned int alc_get_coef0(struct hda_codec *codec)
 170{
 171        struct alc_spec *spec = codec->spec;
 172
 173        if (!spec->coef0)
 174                spec->coef0 = alc_read_coef_idx(codec, 0);
 175        return spec->coef0;
 176}
 177
 178/* coef writes/updates batch */
 179struct coef_fw {
 180        unsigned char nid;
 181        unsigned char idx;
 182        unsigned short mask;
 183        unsigned short val;
 184};
 185
 186#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \
 187        { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) }
 188#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val)
 189#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val)
 190#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val)
 191
 192static void alc_process_coef_fw(struct hda_codec *codec,
 193                                const struct coef_fw *fw)
 194{
 195        for (; fw->nid; fw++) {
 196                if (fw->mask == (unsigned short)-1)
 197                        alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val);
 198                else
 199                        alc_update_coefex_idx(codec, fw->nid, fw->idx,
 200                                              fw->mask, fw->val);
 201        }
 202}
 203
 204/*
 205 * Append the given mixer and verb elements for the later use
 206 * The mixer array is referred in build_controls(), and init_verbs are
 207 * called in init().
 208 */
 209static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
 210{
 211        if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
 212                return;
 213        spec->mixers[spec->num_mixers++] = mix;
 214}
 215
 216/*
 217 * GPIO setup tables, used in initialization
 218 */
 219/* Enable GPIO mask and set output */
 220static const struct hda_verb alc_gpio1_init_verbs[] = {
 221        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 222        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 223        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 224        { }
 225};
 226
 227static const struct hda_verb alc_gpio2_init_verbs[] = {
 228        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 229        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 230        {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
 231        { }
 232};
 233
 234static const struct hda_verb alc_gpio3_init_verbs[] = {
 235        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 236        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 237        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 238        { }
 239};
 240
 241/*
 242 * Fix hardware PLL issue
 243 * On some codecs, the analog PLL gating control must be off while
 244 * the default value is 1.
 245 */
 246static void alc_fix_pll(struct hda_codec *codec)
 247{
 248        struct alc_spec *spec = codec->spec;
 249
 250        if (spec->pll_nid)
 251                alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx,
 252                                      1 << spec->pll_coef_bit, 0);
 253}
 254
 255static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
 256                             unsigned int coef_idx, unsigned int coef_bit)
 257{
 258        struct alc_spec *spec = codec->spec;
 259        spec->pll_nid = nid;
 260        spec->pll_coef_idx = coef_idx;
 261        spec->pll_coef_bit = coef_bit;
 262        alc_fix_pll(codec);
 263}
 264
 265/* update the master volume per volume-knob's unsol event */
 266static void alc_update_knob_master(struct hda_codec *codec,
 267                                   struct hda_jack_callback *jack)
 268{
 269        unsigned int val;
 270        struct snd_kcontrol *kctl;
 271        struct snd_ctl_elem_value *uctl;
 272
 273        kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume");
 274        if (!kctl)
 275                return;
 276        uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 277        if (!uctl)
 278                return;
 279        val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
 280                                 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 281        val &= HDA_AMP_VOLMASK;
 282        uctl->value.integer.value[0] = val;
 283        uctl->value.integer.value[1] = val;
 284        kctl->put(kctl, uctl);
 285        kfree(uctl);
 286}
 287
 288static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
 289{
 290        /* For some reason, the res given from ALC880 is broken.
 291           Here we adjust it properly. */
 292        snd_hda_jack_unsol_event(codec, res >> 2);
 293}
 294
 295/* Change EAPD to verb control */
 296static void alc_fill_eapd_coef(struct hda_codec *codec)
 297{
 298        int coef;
 299
 300        coef = alc_get_coef0(codec);
 301
 302        switch (codec->core.vendor_id) {
 303        case 0x10ec0262:
 304                alc_update_coef_idx(codec, 0x7, 0, 1<<5);
 305                break;
 306        case 0x10ec0267:
 307        case 0x10ec0268:
 308                alc_update_coef_idx(codec, 0x7, 0, 1<<13);
 309                break;
 310        case 0x10ec0269:
 311                if ((coef & 0x00f0) == 0x0010)
 312                        alc_update_coef_idx(codec, 0xd, 0, 1<<14);
 313                if ((coef & 0x00f0) == 0x0020)
 314                        alc_update_coef_idx(codec, 0x4, 1<<15, 0);
 315                if ((coef & 0x00f0) == 0x0030)
 316                        alc_update_coef_idx(codec, 0x10, 1<<9, 0);
 317                break;
 318        case 0x10ec0280:
 319        case 0x10ec0284:
 320        case 0x10ec0290:
 321        case 0x10ec0292:
 322                alc_update_coef_idx(codec, 0x4, 1<<15, 0);
 323                break;
 324        case 0x10ec0233:
 325        case 0x10ec0255:
 326        case 0x10ec0256:
 327        case 0x10ec0282:
 328        case 0x10ec0283:
 329        case 0x10ec0286:
 330        case 0x10ec0288:
 331        case 0x10ec0298:
 332                alc_update_coef_idx(codec, 0x10, 1<<9, 0);
 333                break;
 334        case 0x10ec0285:
 335        case 0x10ec0293:
 336                alc_update_coef_idx(codec, 0xa, 1<<13, 0);
 337                break;
 338        case 0x10ec0662:
 339                if ((coef & 0x00f0) == 0x0030)
 340                        alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
 341                break;
 342        case 0x10ec0272:
 343        case 0x10ec0273:
 344        case 0x10ec0663:
 345        case 0x10ec0665:
 346        case 0x10ec0670:
 347        case 0x10ec0671:
 348        case 0x10ec0672:
 349                alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */
 350                break;
 351        case 0x10ec0668:
 352                alc_update_coef_idx(codec, 0x7, 3<<13, 0);
 353                break;
 354        case 0x10ec0867:
 355                alc_update_coef_idx(codec, 0x4, 1<<10, 0);
 356                break;
 357        case 0x10ec0888:
 358                if ((coef & 0x00f0) == 0x0020 || (coef & 0x00f0) == 0x0030)
 359                        alc_update_coef_idx(codec, 0x7, 1<<5, 0);
 360                break;
 361        case 0x10ec0892:
 362                alc_update_coef_idx(codec, 0x7, 1<<5, 0);
 363                break;
 364        case 0x10ec0899:
 365        case 0x10ec0900:
 366                alc_update_coef_idx(codec, 0x7, 1<<1, 0);
 367                break;
 368        }
 369}
 370
 371/* additional initialization for ALC888 variants */
 372static void alc888_coef_init(struct hda_codec *codec)
 373{
 374        switch (alc_get_coef0(codec) & 0x00f0) {
 375        /* alc888-VA */
 376        case 0x00:
 377        /* alc888-VB */
 378        case 0x10:
 379                alc_update_coef_idx(codec, 7, 0, 0x2030); /* Turn EAPD to High */
 380                break;
 381        }
 382}
 383
 384/* turn on/off EAPD control (only if available) */
 385static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
 386{
 387        if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
 388                return;
 389        if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
 390                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
 391                                    on ? 2 : 0);
 392}
 393
 394/* turn on/off EAPD controls of the codec */
 395static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
 396{
 397        /* We currently only handle front, HP */
 398        static hda_nid_t pins[] = {
 399                0x0f, 0x10, 0x14, 0x15, 0x17, 0
 400        };
 401        hda_nid_t *p;
 402        for (p = pins; *p; p++)
 403                set_eapd(codec, *p, on);
 404}
 405
 406/* generic shutup callback;
 407 * just turning off EPAD and a little pause for avoiding pop-noise
 408 */
 409static void alc_eapd_shutup(struct hda_codec *codec)
 410{
 411        struct alc_spec *spec = codec->spec;
 412
 413        alc_auto_setup_eapd(codec, false);
 414        if (!spec->no_depop_delay)
 415                msleep(200);
 416        snd_hda_shutup_pins(codec);
 417}
 418
 419/* generic EAPD initialization */
 420static void alc_auto_init_amp(struct hda_codec *codec, int type)
 421{
 422        alc_fill_eapd_coef(codec);
 423        alc_auto_setup_eapd(codec, true);
 424        switch (type) {
 425        case ALC_INIT_GPIO1:
 426                snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
 427                break;
 428        case ALC_INIT_GPIO2:
 429                snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
 430                break;
 431        case ALC_INIT_GPIO3:
 432                snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
 433                break;
 434        case ALC_INIT_DEFAULT:
 435                switch (codec->core.vendor_id) {
 436                case 0x10ec0260:
 437                        alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010);
 438                        break;
 439                case 0x10ec0880:
 440                case 0x10ec0882:
 441                case 0x10ec0883:
 442                case 0x10ec0885:
 443                        alc_update_coef_idx(codec, 7, 0, 0x2030);
 444                        break;
 445                case 0x10ec0888:
 446                        alc888_coef_init(codec);
 447                        break;
 448                }
 449                break;
 450        }
 451}
 452
 453
 454/*
 455 * Realtek SSID verification
 456 */
 457
 458/* Could be any non-zero and even value. When used as fixup, tells
 459 * the driver to ignore any present sku defines.
 460 */
 461#define ALC_FIXUP_SKU_IGNORE (2)
 462
 463static void alc_fixup_sku_ignore(struct hda_codec *codec,
 464                                 const struct hda_fixup *fix, int action)
 465{
 466        struct alc_spec *spec = codec->spec;
 467        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
 468                spec->cdefine.fixup = 1;
 469                spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
 470        }
 471}
 472
 473static void alc_fixup_no_depop_delay(struct hda_codec *codec,
 474                                    const struct hda_fixup *fix, int action)
 475{
 476        struct alc_spec *spec = codec->spec;
 477
 478        if (action == HDA_FIXUP_ACT_PROBE) {
 479                spec->no_depop_delay = 1;
 480                codec->depop_delay = 0;
 481        }
 482}
 483
 484static int alc_auto_parse_customize_define(struct hda_codec *codec)
 485{
 486        unsigned int ass, tmp, i;
 487        unsigned nid = 0;
 488        struct alc_spec *spec = codec->spec;
 489
 490        spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
 491
 492        if (spec->cdefine.fixup) {
 493                ass = spec->cdefine.sku_cfg;
 494                if (ass == ALC_FIXUP_SKU_IGNORE)
 495                        return -1;
 496                goto do_sku;
 497        }
 498
 499        if (!codec->bus->pci)
 500                return -1;
 501        ass = codec->core.subsystem_id & 0xffff;
 502        if (ass != codec->bus->pci->subsystem_device && (ass & 1))
 503                goto do_sku;
 504
 505        nid = 0x1d;
 506        if (codec->core.vendor_id == 0x10ec0260)
 507                nid = 0x17;
 508        ass = snd_hda_codec_get_pincfg(codec, nid);
 509
 510        if (!(ass & 1)) {
 511                codec_info(codec, "%s: SKU not ready 0x%08x\n",
 512                           codec->core.chip_name, ass);
 513                return -1;
 514        }
 515
 516        /* check sum */
 517        tmp = 0;
 518        for (i = 1; i < 16; i++) {
 519                if ((ass >> i) & 1)
 520                        tmp++;
 521        }
 522        if (((ass >> 16) & 0xf) != tmp)
 523                return -1;
 524
 525        spec->cdefine.port_connectivity = ass >> 30;
 526        spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
 527        spec->cdefine.check_sum = (ass >> 16) & 0xf;
 528        spec->cdefine.customization = ass >> 8;
 529do_sku:
 530        spec->cdefine.sku_cfg = ass;
 531        spec->cdefine.external_amp = (ass & 0x38) >> 3;
 532        spec->cdefine.platform_type = (ass & 0x4) >> 2;
 533        spec->cdefine.swap = (ass & 0x2) >> 1;
 534        spec->cdefine.override = ass & 0x1;
 535
 536        codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n",
 537                   nid, spec->cdefine.sku_cfg);
 538        codec_dbg(codec, "SKU: port_connectivity=0x%x\n",
 539                   spec->cdefine.port_connectivity);
 540        codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
 541        codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
 542        codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization);
 543        codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
 544        codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
 545        codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap);
 546        codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override);
 547
 548        return 0;
 549}
 550
 551/* return the position of NID in the list, or -1 if not found */
 552static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
 553{
 554        int i;
 555        for (i = 0; i < nums; i++)
 556                if (list[i] == nid)
 557                        return i;
 558        return -1;
 559}
 560/* return true if the given NID is found in the list */
 561static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
 562{
 563        return find_idx_in_nid_list(nid, list, nums) >= 0;
 564}
 565
 566/* check subsystem ID and set up device-specific initialization;
 567 * return 1 if initialized, 0 if invalid SSID
 568 */
 569/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
 570 *      31 ~ 16 :       Manufacture ID
 571 *      15 ~ 8  :       SKU ID
 572 *      7  ~ 0  :       Assembly ID
 573 *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
 574 */
 575static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports)
 576{
 577        unsigned int ass, tmp, i;
 578        unsigned nid;
 579        struct alc_spec *spec = codec->spec;
 580
 581        if (spec->cdefine.fixup) {
 582                ass = spec->cdefine.sku_cfg;
 583                if (ass == ALC_FIXUP_SKU_IGNORE)
 584                        return 0;
 585                goto do_sku;
 586        }
 587
 588        ass = codec->core.subsystem_id & 0xffff;
 589        if (codec->bus->pci &&
 590            ass != codec->bus->pci->subsystem_device && (ass & 1))
 591                goto do_sku;
 592
 593        /* invalid SSID, check the special NID pin defcfg instead */
 594        /*
 595         * 31~30        : port connectivity
 596         * 29~21        : reserve
 597         * 20           : PCBEEP input
 598         * 19~16        : Check sum (15:1)
 599         * 15~1         : Custom
 600         * 0            : override
 601        */
 602        nid = 0x1d;
 603        if (codec->core.vendor_id == 0x10ec0260)
 604                nid = 0x17;
 605        ass = snd_hda_codec_get_pincfg(codec, nid);
 606        codec_dbg(codec,
 607                  "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n",
 608                   ass, nid);
 609        if (!(ass & 1))
 610                return 0;
 611        if ((ass >> 30) != 1)   /* no physical connection */
 612                return 0;
 613
 614        /* check sum */
 615        tmp = 0;
 616        for (i = 1; i < 16; i++) {
 617                if ((ass >> i) & 1)
 618                        tmp++;
 619        }
 620        if (((ass >> 16) & 0xf) != tmp)
 621                return 0;
 622do_sku:
 623        codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
 624                   ass & 0xffff, codec->core.vendor_id);
 625        /*
 626         * 0 : override
 627         * 1 :  Swap Jack
 628         * 2 : 0 --> Desktop, 1 --> Laptop
 629         * 3~5 : External Amplifier control
 630         * 7~6 : Reserved
 631        */
 632        tmp = (ass & 0x38) >> 3;        /* external Amp control */
 633        switch (tmp) {
 634        case 1:
 635                spec->init_amp = ALC_INIT_GPIO1;
 636                break;
 637        case 3:
 638                spec->init_amp = ALC_INIT_GPIO2;
 639                break;
 640        case 7:
 641                spec->init_amp = ALC_INIT_GPIO3;
 642                break;
 643        case 5:
 644        default:
 645                spec->init_amp = ALC_INIT_DEFAULT;
 646                break;
 647        }
 648
 649        /* is laptop or Desktop and enable the function "Mute internal speaker
 650         * when the external headphone out jack is plugged"
 651         */
 652        if (!(ass & 0x8000))
 653                return 1;
 654        /*
 655         * 10~8 : Jack location
 656         * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
 657         * 14~13: Resvered
 658         * 15   : 1 --> enable the function "Mute internal speaker
 659         *              when the external headphone out jack is plugged"
 660         */
 661        if (!spec->gen.autocfg.hp_pins[0] &&
 662            !(spec->gen.autocfg.line_out_pins[0] &&
 663              spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
 664                hda_nid_t nid;
 665                tmp = (ass >> 11) & 0x3;        /* HP to chassis */
 666                nid = ports[tmp];
 667                if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins,
 668                                      spec->gen.autocfg.line_outs))
 669                        return 1;
 670                spec->gen.autocfg.hp_pins[0] = nid;
 671        }
 672        return 1;
 673}
 674
 675/* Check the validity of ALC subsystem-id
 676 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
 677static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
 678{
 679        if (!alc_subsystem_id(codec, ports)) {
 680                struct alc_spec *spec = codec->spec;
 681                codec_dbg(codec,
 682                          "realtek: Enable default setup for auto mode as fallback\n");
 683                spec->init_amp = ALC_INIT_DEFAULT;
 684        }
 685}
 686
 687/*
 688 */
 689
 690static void alc_fixup_inv_dmic(struct hda_codec *codec,
 691                               const struct hda_fixup *fix, int action)
 692{
 693        struct alc_spec *spec = codec->spec;
 694
 695        spec->gen.inv_dmic_split = 1;
 696}
 697
 698
 699#ifdef CONFIG_SND_HDA_INPUT_BEEP
 700/* additional beep mixers; the actual parameters are overwritten at build */
 701static const struct snd_kcontrol_new alc_beep_mixer[] = {
 702        HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
 703        HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
 704        { } /* end */
 705};
 706#endif
 707
 708static int alc_build_controls(struct hda_codec *codec)
 709{
 710        struct alc_spec *spec = codec->spec;
 711        int i, err;
 712
 713        err = snd_hda_gen_build_controls(codec);
 714        if (err < 0)
 715                return err;
 716
 717        for (i = 0; i < spec->num_mixers; i++) {
 718                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
 719                if (err < 0)
 720                        return err;
 721        }
 722
 723#ifdef CONFIG_SND_HDA_INPUT_BEEP
 724        /* create beep controls if needed */
 725        if (spec->beep_amp) {
 726                const struct snd_kcontrol_new *knew;
 727                for (knew = alc_beep_mixer; knew->name; knew++) {
 728                        struct snd_kcontrol *kctl;
 729                        kctl = snd_ctl_new1(knew, codec);
 730                        if (!kctl)
 731                                return -ENOMEM;
 732                        kctl->private_value = spec->beep_amp;
 733                        err = snd_hda_ctl_add(codec, 0, kctl);
 734                        if (err < 0)
 735                                return err;
 736                }
 737        }
 738#endif
 739
 740        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD);
 741        return 0;
 742}
 743
 744
 745/*
 746 * Common callbacks
 747 */
 748
 749static int alc_init(struct hda_codec *codec)
 750{
 751        struct alc_spec *spec = codec->spec;
 752
 753        if (spec->init_hook)
 754                spec->init_hook(codec);
 755
 756        alc_fix_pll(codec);
 757        alc_auto_init_amp(codec, spec->init_amp);
 758
 759        snd_hda_gen_init(codec);
 760
 761        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
 762
 763        return 0;
 764}
 765
 766static inline void alc_shutup(struct hda_codec *codec)
 767{
 768        struct alc_spec *spec = codec->spec;
 769
 770        if (spec && spec->shutup)
 771                spec->shutup(codec);
 772        else
 773                snd_hda_shutup_pins(codec);
 774}
 775
 776#define alc_free        snd_hda_gen_free
 777
 778#ifdef CONFIG_PM
 779static void alc_power_eapd(struct hda_codec *codec)
 780{
 781        alc_auto_setup_eapd(codec, false);
 782}
 783
 784static int alc_suspend(struct hda_codec *codec)
 785{
 786        struct alc_spec *spec = codec->spec;
 787        alc_shutup(codec);
 788        if (spec && spec->power_hook)
 789                spec->power_hook(codec);
 790        return 0;
 791}
 792#endif
 793
 794#ifdef CONFIG_PM
 795static int alc_resume(struct hda_codec *codec)
 796{
 797        struct alc_spec *spec = codec->spec;
 798
 799        if (!spec->no_depop_delay)
 800                msleep(150); /* to avoid pop noise */
 801        codec->patch_ops.init(codec);
 802        regcache_sync(codec->core.regmap);
 803        hda_call_check_power_status(codec, 0x01);
 804        return 0;
 805}
 806#endif
 807
 808/*
 809 */
 810static const struct hda_codec_ops alc_patch_ops = {
 811        .build_controls = alc_build_controls,
 812        .build_pcms = snd_hda_gen_build_pcms,
 813        .init = alc_init,
 814        .free = alc_free,
 815        .unsol_event = snd_hda_jack_unsol_event,
 816#ifdef CONFIG_PM
 817        .resume = alc_resume,
 818        .suspend = alc_suspend,
 819        .check_power_status = snd_hda_gen_check_power_status,
 820#endif
 821        .reboot_notify = alc_shutup,
 822};
 823
 824
 825/* replace the codec chip_name with the given string */
 826static int alc_codec_rename(struct hda_codec *codec, const char *name)
 827{
 828        kfree(codec->core.chip_name);
 829        codec->core.chip_name = kstrdup(name, GFP_KERNEL);
 830        if (!codec->core.chip_name) {
 831                alc_free(codec);
 832                return -ENOMEM;
 833        }
 834        return 0;
 835}
 836
 837/*
 838 * Rename codecs appropriately from COEF value or subvendor id
 839 */
 840struct alc_codec_rename_table {
 841        unsigned int vendor_id;
 842        unsigned short coef_mask;
 843        unsigned short coef_bits;
 844        const char *name;
 845};
 846
 847struct alc_codec_rename_pci_table {
 848        unsigned int codec_vendor_id;
 849        unsigned short pci_subvendor;
 850        unsigned short pci_subdevice;
 851        const char *name;
 852};
 853
 854static struct alc_codec_rename_table rename_tbl[] = {
 855        { 0x10ec0221, 0xf00f, 0x1003, "ALC231" },
 856        { 0x10ec0269, 0xfff0, 0x3010, "ALC277" },
 857        { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" },
 858        { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" },
 859        { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" },
 860        { 0x10ec0269, 0xffff, 0xa023, "ALC259" },
 861        { 0x10ec0269, 0xffff, 0x6023, "ALC281X" },
 862        { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" },
 863        { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" },
 864        { 0x10ec0662, 0xffff, 0x4020, "ALC656" },
 865        { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" },
 866        { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" },
 867        { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" },
 868        { 0x10ec0899, 0x2000, 0x2000, "ALC899" },
 869        { 0x10ec0892, 0xffff, 0x8020, "ALC661" },
 870        { 0x10ec0892, 0xffff, 0x8011, "ALC661" },
 871        { 0x10ec0892, 0xffff, 0x4011, "ALC656" },
 872        { } /* terminator */
 873};
 874
 875static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
 876        { 0x10ec0280, 0x1028, 0, "ALC3220" },
 877        { 0x10ec0282, 0x1028, 0, "ALC3221" },
 878        { 0x10ec0283, 0x1028, 0, "ALC3223" },
 879        { 0x10ec0288, 0x1028, 0, "ALC3263" },
 880        { 0x10ec0292, 0x1028, 0, "ALC3226" },
 881        { 0x10ec0293, 0x1028, 0, "ALC3235" },
 882        { 0x10ec0255, 0x1028, 0, "ALC3234" },
 883        { 0x10ec0668, 0x1028, 0, "ALC3661" },
 884        { 0x10ec0275, 0x1028, 0, "ALC3260" },
 885        { 0x10ec0899, 0x1028, 0, "ALC3861" },
 886        { 0x10ec0298, 0x1028, 0, "ALC3266" },
 887        { 0x10ec0256, 0x1028, 0, "ALC3246" },
 888        { 0x10ec0670, 0x1025, 0, "ALC669X" },
 889        { 0x10ec0676, 0x1025, 0, "ALC679X" },
 890        { 0x10ec0282, 0x1043, 0, "ALC3229" },
 891        { 0x10ec0233, 0x1043, 0, "ALC3236" },
 892        { 0x10ec0280, 0x103c, 0, "ALC3228" },
 893        { 0x10ec0282, 0x103c, 0, "ALC3227" },
 894        { 0x10ec0286, 0x103c, 0, "ALC3242" },
 895        { 0x10ec0290, 0x103c, 0, "ALC3241" },
 896        { 0x10ec0668, 0x103c, 0, "ALC3662" },
 897        { 0x10ec0283, 0x17aa, 0, "ALC3239" },
 898        { 0x10ec0292, 0x17aa, 0, "ALC3232" },
 899        { } /* terminator */
 900};
 901
 902static int alc_codec_rename_from_preset(struct hda_codec *codec)
 903{
 904        const struct alc_codec_rename_table *p;
 905        const struct alc_codec_rename_pci_table *q;
 906
 907        for (p = rename_tbl; p->vendor_id; p++) {
 908                if (p->vendor_id != codec->core.vendor_id)
 909                        continue;
 910                if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits)
 911                        return alc_codec_rename(codec, p->name);
 912        }
 913
 914        if (!codec->bus->pci)
 915                return 0;
 916        for (q = rename_pci_tbl; q->codec_vendor_id; q++) {
 917                if (q->codec_vendor_id != codec->core.vendor_id)
 918                        continue;
 919                if (q->pci_subvendor != codec->bus->pci->subsystem_vendor)
 920                        continue;
 921                if (!q->pci_subdevice ||
 922                    q->pci_subdevice == codec->bus->pci->subsystem_device)
 923                        return alc_codec_rename(codec, q->name);
 924        }
 925
 926        return 0;
 927}
 928
 929
 930/*
 931 * Digital-beep handlers
 932 */
 933#ifdef CONFIG_SND_HDA_INPUT_BEEP
 934#define set_beep_amp(spec, nid, idx, dir) \
 935        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
 936
 937static const struct snd_pci_quirk beep_white_list[] = {
 938        SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
 939        SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1),
 940        SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
 941        SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1),
 942        SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
 943        SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
 944        SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
 945        SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1),
 946        SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
 947        {}
 948};
 949
 950static inline int has_cdefine_beep(struct hda_codec *codec)
 951{
 952        struct alc_spec *spec = codec->spec;
 953        const struct snd_pci_quirk *q;
 954        q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
 955        if (q)
 956                return q->value;
 957        return spec->cdefine.enable_pcbeep;
 958}
 959#else
 960#define set_beep_amp(spec, nid, idx, dir) /* NOP */
 961#define has_cdefine_beep(codec)         0
 962#endif
 963
 964/* parse the BIOS configuration and set up the alc_spec */
 965/* return 1 if successful, 0 if the proper config is not found,
 966 * or a negative error code
 967 */
 968static int alc_parse_auto_config(struct hda_codec *codec,
 969                                 const hda_nid_t *ignore_nids,
 970                                 const hda_nid_t *ssid_nids)
 971{
 972        struct alc_spec *spec = codec->spec;
 973        struct auto_pin_cfg *cfg = &spec->gen.autocfg;
 974        int err;
 975
 976        err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids,
 977                                       spec->parse_flags);
 978        if (err < 0)
 979                return err;
 980
 981        if (ssid_nids)
 982                alc_ssid_check(codec, ssid_nids);
 983
 984        err = snd_hda_gen_parse_auto_config(codec, cfg);
 985        if (err < 0)
 986                return err;
 987
 988        return 1;
 989}
 990
 991/* common preparation job for alc_spec */
 992static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
 993{
 994        struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 995        int err;
 996
 997        if (!spec)
 998                return -ENOMEM;
 999        codec->spec = spec;
1000        snd_hda_gen_spec_init(&spec->gen);
1001        spec->gen.mixer_nid = mixer_nid;
1002        spec->gen.own_eapd_ctl = 1;
1003        codec->single_adc_amp = 1;
1004        /* FIXME: do we need this for all Realtek codec models? */
1005        codec->spdif_status_reset = 1;
1006        codec->patch_ops = alc_patch_ops;
1007
1008        err = alc_codec_rename_from_preset(codec);
1009        if (err < 0) {
1010                kfree(spec);
1011                return err;
1012        }
1013        return 0;
1014}
1015
1016static int alc880_parse_auto_config(struct hda_codec *codec)
1017{
1018        static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
1019        static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
1020        return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
1021}
1022
1023/*
1024 * ALC880 fix-ups
1025 */
1026enum {
1027        ALC880_FIXUP_GPIO1,
1028        ALC880_FIXUP_GPIO2,
1029        ALC880_FIXUP_MEDION_RIM,
1030        ALC880_FIXUP_LG,
1031        ALC880_FIXUP_LG_LW25,
1032        ALC880_FIXUP_W810,
1033        ALC880_FIXUP_EAPD_COEF,
1034        ALC880_FIXUP_TCL_S700,
1035        ALC880_FIXUP_VOL_KNOB,
1036        ALC880_FIXUP_FUJITSU,
1037        ALC880_FIXUP_F1734,
1038        ALC880_FIXUP_UNIWILL,
1039        ALC880_FIXUP_UNIWILL_DIG,
1040        ALC880_FIXUP_Z71V,
1041        ALC880_FIXUP_ASUS_W5A,
1042        ALC880_FIXUP_3ST_BASE,
1043        ALC880_FIXUP_3ST,
1044        ALC880_FIXUP_3ST_DIG,
1045        ALC880_FIXUP_5ST_BASE,
1046        ALC880_FIXUP_5ST,
1047        ALC880_FIXUP_5ST_DIG,
1048        ALC880_FIXUP_6ST_BASE,
1049        ALC880_FIXUP_6ST,
1050        ALC880_FIXUP_6ST_DIG,
1051        ALC880_FIXUP_6ST_AUTOMUTE,
1052};
1053
1054/* enable the volume-knob widget support on NID 0x21 */
1055static void alc880_fixup_vol_knob(struct hda_codec *codec,
1056                                  const struct hda_fixup *fix, int action)
1057{
1058        if (action == HDA_FIXUP_ACT_PROBE)
1059                snd_hda_jack_detect_enable_callback(codec, 0x21,
1060                                                    alc_update_knob_master);
1061}
1062
1063static const struct hda_fixup alc880_fixups[] = {
1064        [ALC880_FIXUP_GPIO1] = {
1065                .type = HDA_FIXUP_VERBS,
1066                .v.verbs = alc_gpio1_init_verbs,
1067        },
1068        [ALC880_FIXUP_GPIO2] = {
1069                .type = HDA_FIXUP_VERBS,
1070                .v.verbs = alc_gpio2_init_verbs,
1071        },
1072        [ALC880_FIXUP_MEDION_RIM] = {
1073                .type = HDA_FIXUP_VERBS,
1074                .v.verbs = (const struct hda_verb[]) {
1075                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1076                        { 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1077                        { }
1078                },
1079                .chained = true,
1080                .chain_id = ALC880_FIXUP_GPIO2,
1081        },
1082        [ALC880_FIXUP_LG] = {
1083                .type = HDA_FIXUP_PINS,
1084                .v.pins = (const struct hda_pintbl[]) {
1085                        /* disable bogus unused pins */
1086                        { 0x16, 0x411111f0 },
1087                        { 0x18, 0x411111f0 },
1088                        { 0x1a, 0x411111f0 },
1089                        { }
1090                }
1091        },
1092        [ALC880_FIXUP_LG_LW25] = {
1093                .type = HDA_FIXUP_PINS,
1094                .v.pins = (const struct hda_pintbl[]) {
1095                        { 0x1a, 0x0181344f }, /* line-in */
1096                        { 0x1b, 0x0321403f }, /* headphone */
1097                        { }
1098                }
1099        },
1100        [ALC880_FIXUP_W810] = {
1101                .type = HDA_FIXUP_PINS,
1102                .v.pins = (const struct hda_pintbl[]) {
1103                        /* disable bogus unused pins */
1104                        { 0x17, 0x411111f0 },
1105                        { }
1106                },
1107                .chained = true,
1108                .chain_id = ALC880_FIXUP_GPIO2,
1109        },
1110        [ALC880_FIXUP_EAPD_COEF] = {
1111                .type = HDA_FIXUP_VERBS,
1112                .v.verbs = (const struct hda_verb[]) {
1113                        /* change to EAPD mode */
1114                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1115                        { 0x20, AC_VERB_SET_PROC_COEF,  0x3060 },
1116                        {}
1117                },
1118        },
1119        [ALC880_FIXUP_TCL_S700] = {
1120                .type = HDA_FIXUP_VERBS,
1121                .v.verbs = (const struct hda_verb[]) {
1122                        /* change to EAPD mode */
1123                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
1124                        { 0x20, AC_VERB_SET_PROC_COEF,  0x3070 },
1125                        {}
1126                },
1127                .chained = true,
1128                .chain_id = ALC880_FIXUP_GPIO2,
1129        },
1130        [ALC880_FIXUP_VOL_KNOB] = {
1131                .type = HDA_FIXUP_FUNC,
1132                .v.func = alc880_fixup_vol_knob,
1133        },
1134        [ALC880_FIXUP_FUJITSU] = {
1135                /* override all pins as BIOS on old Amilo is broken */
1136                .type = HDA_FIXUP_PINS,
1137                .v.pins = (const struct hda_pintbl[]) {
1138                        { 0x14, 0x0121401f }, /* HP */
1139                        { 0x15, 0x99030120 }, /* speaker */
1140                        { 0x16, 0x99030130 }, /* bass speaker */
1141                        { 0x17, 0x411111f0 }, /* N/A */
1142                        { 0x18, 0x411111f0 }, /* N/A */
1143                        { 0x19, 0x01a19950 }, /* mic-in */
1144                        { 0x1a, 0x411111f0 }, /* N/A */
1145                        { 0x1b, 0x411111f0 }, /* N/A */
1146                        { 0x1c, 0x411111f0 }, /* N/A */
1147                        { 0x1d, 0x411111f0 }, /* N/A */
1148                        { 0x1e, 0x01454140 }, /* SPDIF out */
1149                        { }
1150                },
1151                .chained = true,
1152                .chain_id = ALC880_FIXUP_VOL_KNOB,
1153        },
1154        [ALC880_FIXUP_F1734] = {
1155                /* almost compatible with FUJITSU, but no bass and SPDIF */
1156                .type = HDA_FIXUP_PINS,
1157                .v.pins = (const struct hda_pintbl[]) {
1158                        { 0x14, 0x0121401f }, /* HP */
1159                        { 0x15, 0x99030120 }, /* speaker */
1160                        { 0x16, 0x411111f0 }, /* N/A */
1161                        { 0x17, 0x411111f0 }, /* N/A */
1162                        { 0x18, 0x411111f0 }, /* N/A */
1163                        { 0x19, 0x01a19950 }, /* mic-in */
1164                        { 0x1a, 0x411111f0 }, /* N/A */
1165                        { 0x1b, 0x411111f0 }, /* N/A */
1166                        { 0x1c, 0x411111f0 }, /* N/A */
1167                        { 0x1d, 0x411111f0 }, /* N/A */
1168                        { 0x1e, 0x411111f0 }, /* N/A */
1169                        { }
1170                },
1171                .chained = true,
1172                .chain_id = ALC880_FIXUP_VOL_KNOB,
1173        },
1174        [ALC880_FIXUP_UNIWILL] = {
1175                /* need to fix HP and speaker pins to be parsed correctly */
1176                .type = HDA_FIXUP_PINS,
1177                .v.pins = (const struct hda_pintbl[]) {
1178                        { 0x14, 0x0121411f }, /* HP */
1179                        { 0x15, 0x99030120 }, /* speaker */
1180                        { 0x16, 0x99030130 }, /* bass speaker */
1181                        { }
1182                },
1183        },
1184        [ALC880_FIXUP_UNIWILL_DIG] = {
1185                .type = HDA_FIXUP_PINS,
1186                .v.pins = (const struct hda_pintbl[]) {
1187                        /* disable bogus unused pins */
1188                        { 0x17, 0x411111f0 },
1189                        { 0x19, 0x411111f0 },
1190                        { 0x1b, 0x411111f0 },
1191                        { 0x1f, 0x411111f0 },
1192                        { }
1193                }
1194        },
1195        [ALC880_FIXUP_Z71V] = {
1196                .type = HDA_FIXUP_PINS,
1197                .v.pins = (const struct hda_pintbl[]) {
1198                        /* set up the whole pins as BIOS is utterly broken */
1199                        { 0x14, 0x99030120 }, /* speaker */
1200                        { 0x15, 0x0121411f }, /* HP */
1201                        { 0x16, 0x411111f0 }, /* N/A */
1202                        { 0x17, 0x411111f0 }, /* N/A */
1203                        { 0x18, 0x01a19950 }, /* mic-in */
1204                        { 0x19, 0x411111f0 }, /* N/A */
1205                        { 0x1a, 0x01813031 }, /* line-in */
1206                        { 0x1b, 0x411111f0 }, /* N/A */
1207                        { 0x1c, 0x411111f0 }, /* N/A */
1208                        { 0x1d, 0x411111f0 }, /* N/A */
1209                        { 0x1e, 0x0144111e }, /* SPDIF */
1210                        { }
1211                }
1212        },
1213        [ALC880_FIXUP_ASUS_W5A] = {
1214                .type = HDA_FIXUP_PINS,
1215                .v.pins = (const struct hda_pintbl[]) {
1216                        /* set up the whole pins as BIOS is utterly broken */
1217                        { 0x14, 0x0121411f }, /* HP */
1218                        { 0x15, 0x411111f0 }, /* N/A */
1219                        { 0x16, 0x411111f0 }, /* N/A */
1220                        { 0x17, 0x411111f0 }, /* N/A */
1221                        { 0x18, 0x90a60160 }, /* mic */
1222                        { 0x19, 0x411111f0 }, /* N/A */
1223                        { 0x1a, 0x411111f0 }, /* N/A */
1224                        { 0x1b, 0x411111f0 }, /* N/A */
1225                        { 0x1c, 0x411111f0 }, /* N/A */
1226                        { 0x1d, 0x411111f0 }, /* N/A */
1227                        { 0x1e, 0xb743111e }, /* SPDIF out */
1228                        { }
1229                },
1230                .chained = true,
1231                .chain_id = ALC880_FIXUP_GPIO1,
1232        },
1233        [ALC880_FIXUP_3ST_BASE] = {
1234                .type = HDA_FIXUP_PINS,
1235                .v.pins = (const struct hda_pintbl[]) {
1236                        { 0x14, 0x01014010 }, /* line-out */
1237                        { 0x15, 0x411111f0 }, /* N/A */
1238                        { 0x16, 0x411111f0 }, /* N/A */
1239                        { 0x17, 0x411111f0 }, /* N/A */
1240                        { 0x18, 0x01a19c30 }, /* mic-in */
1241                        { 0x19, 0x0121411f }, /* HP */
1242                        { 0x1a, 0x01813031 }, /* line-in */
1243                        { 0x1b, 0x02a19c40 }, /* front-mic */
1244                        { 0x1c, 0x411111f0 }, /* N/A */
1245                        { 0x1d, 0x411111f0 }, /* N/A */
1246                        /* 0x1e is filled in below */
1247                        { 0x1f, 0x411111f0 }, /* N/A */
1248                        { }
1249                }
1250        },
1251        [ALC880_FIXUP_3ST] = {
1252                .type = HDA_FIXUP_PINS,
1253                .v.pins = (const struct hda_pintbl[]) {
1254                        { 0x1e, 0x411111f0 }, /* N/A */
1255                        { }
1256                },
1257                .chained = true,
1258                .chain_id = ALC880_FIXUP_3ST_BASE,
1259        },
1260        [ALC880_FIXUP_3ST_DIG] = {
1261                .type = HDA_FIXUP_PINS,
1262                .v.pins = (const struct hda_pintbl[]) {
1263                        { 0x1e, 0x0144111e }, /* SPDIF */
1264                        { }
1265                },
1266                .chained = true,
1267                .chain_id = ALC880_FIXUP_3ST_BASE,
1268        },
1269        [ALC880_FIXUP_5ST_BASE] = {
1270                .type = HDA_FIXUP_PINS,
1271                .v.pins = (const struct hda_pintbl[]) {
1272                        { 0x14, 0x01014010 }, /* front */
1273                        { 0x15, 0x411111f0 }, /* N/A */
1274                        { 0x16, 0x01011411 }, /* CLFE */
1275                        { 0x17, 0x01016412 }, /* surr */
1276                        { 0x18, 0x01a19c30 }, /* mic-in */
1277                        { 0x19, 0x0121411f }, /* HP */
1278                        { 0x1a, 0x01813031 }, /* line-in */
1279                        { 0x1b, 0x02a19c40 }, /* front-mic */
1280                        { 0x1c, 0x411111f0 }, /* N/A */
1281                        { 0x1d, 0x411111f0 }, /* N/A */
1282                        /* 0x1e is filled in below */
1283                        { 0x1f, 0x411111f0 }, /* N/A */
1284                        { }
1285                }
1286        },
1287        [ALC880_FIXUP_5ST] = {
1288                .type = HDA_FIXUP_PINS,
1289                .v.pins = (const struct hda_pintbl[]) {
1290                        { 0x1e, 0x411111f0 }, /* N/A */
1291                        { }
1292                },
1293                .chained = true,
1294                .chain_id = ALC880_FIXUP_5ST_BASE,
1295        },
1296        [ALC880_FIXUP_5ST_DIG] = {
1297                .type = HDA_FIXUP_PINS,
1298                .v.pins = (const struct hda_pintbl[]) {
1299                        { 0x1e, 0x0144111e }, /* SPDIF */
1300                        { }
1301                },
1302                .chained = true,
1303                .chain_id = ALC880_FIXUP_5ST_BASE,
1304        },
1305        [ALC880_FIXUP_6ST_BASE] = {
1306                .type = HDA_FIXUP_PINS,
1307                .v.pins = (const struct hda_pintbl[]) {
1308                        { 0x14, 0x01014010 }, /* front */
1309                        { 0x15, 0x01016412 }, /* surr */
1310                        { 0x16, 0x01011411 }, /* CLFE */
1311                        { 0x17, 0x01012414 }, /* side */
1312                        { 0x18, 0x01a19c30 }, /* mic-in */
1313                        { 0x19, 0x02a19c40 }, /* front-mic */
1314                        { 0x1a, 0x01813031 }, /* line-in */
1315                        { 0x1b, 0x0121411f }, /* HP */
1316                        { 0x1c, 0x411111f0 }, /* N/A */
1317                        { 0x1d, 0x411111f0 }, /* N/A */
1318                        /* 0x1e is filled in below */
1319                        { 0x1f, 0x411111f0 }, /* N/A */
1320                        { }
1321                }
1322        },
1323        [ALC880_FIXUP_6ST] = {
1324                .type = HDA_FIXUP_PINS,
1325                .v.pins = (const struct hda_pintbl[]) {
1326                        { 0x1e, 0x411111f0 }, /* N/A */
1327                        { }
1328                },
1329                .chained = true,
1330                .chain_id = ALC880_FIXUP_6ST_BASE,
1331        },
1332        [ALC880_FIXUP_6ST_DIG] = {
1333                .type = HDA_FIXUP_PINS,
1334                .v.pins = (const struct hda_pintbl[]) {
1335                        { 0x1e, 0x0144111e }, /* SPDIF */
1336                        { }
1337                },
1338                .chained = true,
1339                .chain_id = ALC880_FIXUP_6ST_BASE,
1340        },
1341        [ALC880_FIXUP_6ST_AUTOMUTE] = {
1342                .type = HDA_FIXUP_PINS,
1343                .v.pins = (const struct hda_pintbl[]) {
1344                        { 0x1b, 0x0121401f }, /* HP with jack detect */
1345                        { }
1346                },
1347                .chained_before = true,
1348                .chain_id = ALC880_FIXUP_6ST_BASE,
1349        },
1350};
1351
1352static const struct snd_pci_quirk alc880_fixup_tbl[] = {
1353        SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810),
1354        SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A),
1355        SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V),
1356        SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1),
1357        SND_PCI_QUIRK(0x147b, 0x1045, "ABit AA8XE", ALC880_FIXUP_6ST_AUTOMUTE),
1358        SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2),
1359        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF),
1360        SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG),
1361        SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734),
1362        SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL),
1363        SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB),
1364        SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810),
1365        SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM),
1366        SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE),
1367        SND_PCI_QUIRK(0x1734, 0x107c, "FSC Amilo M1437", ALC880_FIXUP_FUJITSU),
1368        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU),
1369        SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734),
1370        SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU),
1371        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG),
1372        SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG),
1373        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG),
1374        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25),
1375        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700),
1376
1377        /* Below is the copied entries from alc880_quirks.c.
1378         * It's not quite sure whether BIOS sets the correct pin-config table
1379         * on these machines, thus they are kept to be compatible with
1380         * the old static quirks.  Once when it's confirmed to work without
1381         * these overrides, it'd be better to remove.
1382         */
1383        SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG),
1384        SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST),
1385        SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG),
1386        SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG),
1387        SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG),
1388        SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG),
1389        SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG),
1390        SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST),
1391        SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG),
1392        SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST),
1393        SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST),
1394        SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST),
1395        SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST),
1396        SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST),
1397        SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG),
1398        SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG),
1399        SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG),
1400        SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG),
1401        SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG),
1402        SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG),
1403        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG),
1404        SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */
1405        SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG),
1406        SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1407        SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1408        SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1409        SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1410        SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1411        SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1412        SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG),
1413        SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1414        SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1415        SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG),
1416        /* default Intel */
1417        SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST),
1418        SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG),
1419        SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG),
1420        {}
1421};
1422
1423static const struct hda_model_fixup alc880_fixup_models[] = {
1424        {.id = ALC880_FIXUP_3ST, .name = "3stack"},
1425        {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"},
1426        {.id = ALC880_FIXUP_5ST, .name = "5stack"},
1427        {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"},
1428        {.id = ALC880_FIXUP_6ST, .name = "6stack"},
1429        {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"},
1430        {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"},
1431        {}
1432};
1433
1434
1435/*
1436 * OK, here we have finally the patch for ALC880
1437 */
1438static int patch_alc880(struct hda_codec *codec)
1439{
1440        struct alc_spec *spec;
1441        int err;
1442
1443        err = alc_alloc_spec(codec, 0x0b);
1444        if (err < 0)
1445                return err;
1446
1447        spec = codec->spec;
1448        spec->gen.need_dac_fix = 1;
1449        spec->gen.beep_nid = 0x01;
1450
1451        codec->patch_ops.unsol_event = alc880_unsol_event;
1452
1453        snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
1454                       alc880_fixups);
1455        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1456
1457        /* automatic parse from the BIOS config */
1458        err = alc880_parse_auto_config(codec);
1459        if (err < 0)
1460                goto error;
1461
1462        if (!spec->gen.no_analog)
1463                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1464
1465        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1466
1467        return 0;
1468
1469 error:
1470        alc_free(codec);
1471        return err;
1472}
1473
1474
1475/*
1476 * ALC260 support
1477 */
1478static int alc260_parse_auto_config(struct hda_codec *codec)
1479{
1480        static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
1481        static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
1482        return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
1483}
1484
1485/*
1486 * Pin config fixes
1487 */
1488enum {
1489        ALC260_FIXUP_HP_DC5750,
1490        ALC260_FIXUP_HP_PIN_0F,
1491        ALC260_FIXUP_COEF,
1492        ALC260_FIXUP_GPIO1,
1493        ALC260_FIXUP_GPIO1_TOGGLE,
1494        ALC260_FIXUP_REPLACER,
1495        ALC260_FIXUP_HP_B1900,
1496        ALC260_FIXUP_KN1,
1497        ALC260_FIXUP_FSC_S7020,
1498        ALC260_FIXUP_FSC_S7020_JWSE,
1499        ALC260_FIXUP_VAIO_PINS,
1500};
1501
1502static void alc260_gpio1_automute(struct hda_codec *codec)
1503{
1504        struct alc_spec *spec = codec->spec;
1505        snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1506                            spec->gen.hp_jack_present);
1507}
1508
1509static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
1510                                      const struct hda_fixup *fix, int action)
1511{
1512        struct alc_spec *spec = codec->spec;
1513        if (action == HDA_FIXUP_ACT_PROBE) {
1514                /* although the machine has only one output pin, we need to
1515                 * toggle GPIO1 according to the jack state
1516                 */
1517                spec->gen.automute_hook = alc260_gpio1_automute;
1518                spec->gen.detect_hp = 1;
1519                spec->gen.automute_speaker = 1;
1520                spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
1521                snd_hda_jack_detect_enable_callback(codec, 0x0f,
1522                                                    snd_hda_gen_hp_automute);
1523                snd_hda_add_verbs(codec, alc_gpio1_init_verbs);
1524        }
1525}
1526
1527static void alc260_fixup_kn1(struct hda_codec *codec,
1528                             const struct hda_fixup *fix, int action)
1529{
1530        struct alc_spec *spec = codec->spec;
1531        static const struct hda_pintbl pincfgs[] = {
1532                { 0x0f, 0x02214000 }, /* HP/speaker */
1533                { 0x12, 0x90a60160 }, /* int mic */
1534                { 0x13, 0x02a19000 }, /* ext mic */
1535                { 0x18, 0x01446000 }, /* SPDIF out */
1536                /* disable bogus I/O pins */
1537                { 0x10, 0x411111f0 },
1538                { 0x11, 0x411111f0 },
1539                { 0x14, 0x411111f0 },
1540                { 0x15, 0x411111f0 },
1541                { 0x16, 0x411111f0 },
1542                { 0x17, 0x411111f0 },
1543                { 0x19, 0x411111f0 },
1544                { }
1545        };
1546
1547        switch (action) {
1548        case HDA_FIXUP_ACT_PRE_PROBE:
1549                snd_hda_apply_pincfgs(codec, pincfgs);
1550                break;
1551        case HDA_FIXUP_ACT_PROBE:
1552                spec->init_amp = ALC_INIT_NONE;
1553                break;
1554        }
1555}
1556
1557static void alc260_fixup_fsc_s7020(struct hda_codec *codec,
1558                                   const struct hda_fixup *fix, int action)
1559{
1560        struct alc_spec *spec = codec->spec;
1561        if (action == HDA_FIXUP_ACT_PROBE)
1562                spec->init_amp = ALC_INIT_NONE;
1563}
1564
1565static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec,
1566                                   const struct hda_fixup *fix, int action)
1567{
1568        struct alc_spec *spec = codec->spec;
1569        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1570                spec->gen.add_jack_modes = 1;
1571                spec->gen.hp_mic = 1;
1572        }
1573}
1574
1575static const struct hda_fixup alc260_fixups[] = {
1576        [ALC260_FIXUP_HP_DC5750] = {
1577                .type = HDA_FIXUP_PINS,
1578                .v.pins = (const struct hda_pintbl[]) {
1579                        { 0x11, 0x90130110 }, /* speaker */
1580                        { }
1581                }
1582        },
1583        [ALC260_FIXUP_HP_PIN_0F] = {
1584                .type = HDA_FIXUP_PINS,
1585                .v.pins = (const struct hda_pintbl[]) {
1586                        { 0x0f, 0x01214000 }, /* HP */
1587                        { }
1588                }
1589        },
1590        [ALC260_FIXUP_COEF] = {
1591                .type = HDA_FIXUP_VERBS,
1592                .v.verbs = (const struct hda_verb[]) {
1593                        { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1594                        { 0x1a, AC_VERB_SET_PROC_COEF,  0x3040 },
1595                        { }
1596                },
1597        },
1598        [ALC260_FIXUP_GPIO1] = {
1599                .type = HDA_FIXUP_VERBS,
1600                .v.verbs = alc_gpio1_init_verbs,
1601        },
1602        [ALC260_FIXUP_GPIO1_TOGGLE] = {
1603                .type = HDA_FIXUP_FUNC,
1604                .v.func = alc260_fixup_gpio1_toggle,
1605                .chained = true,
1606                .chain_id = ALC260_FIXUP_HP_PIN_0F,
1607        },
1608        [ALC260_FIXUP_REPLACER] = {
1609                .type = HDA_FIXUP_VERBS,
1610                .v.verbs = (const struct hda_verb[]) {
1611                        { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 },
1612                        { 0x1a, AC_VERB_SET_PROC_COEF,  0x3050 },
1613                        { }
1614                },
1615                .chained = true,
1616                .chain_id = ALC260_FIXUP_GPIO1_TOGGLE,
1617        },
1618        [ALC260_FIXUP_HP_B1900] = {
1619                .type = HDA_FIXUP_FUNC,
1620                .v.func = alc260_fixup_gpio1_toggle,
1621                .chained = true,
1622                .chain_id = ALC260_FIXUP_COEF,
1623        },
1624        [ALC260_FIXUP_KN1] = {
1625                .type = HDA_FIXUP_FUNC,
1626                .v.func = alc260_fixup_kn1,
1627        },
1628        [ALC260_FIXUP_FSC_S7020] = {
1629                .type = HDA_FIXUP_FUNC,
1630                .v.func = alc260_fixup_fsc_s7020,
1631        },
1632        [ALC260_FIXUP_FSC_S7020_JWSE] = {
1633                .type = HDA_FIXUP_FUNC,
1634                .v.func = alc260_fixup_fsc_s7020_jwse,
1635                .chained = true,
1636                .chain_id = ALC260_FIXUP_FSC_S7020,
1637        },
1638        [ALC260_FIXUP_VAIO_PINS] = {
1639                .type = HDA_FIXUP_PINS,
1640                .v.pins = (const struct hda_pintbl[]) {
1641                        /* Pin configs are missing completely on some VAIOs */
1642                        { 0x0f, 0x01211020 },
1643                        { 0x10, 0x0001003f },
1644                        { 0x11, 0x411111f0 },
1645                        { 0x12, 0x01a15930 },
1646                        { 0x13, 0x411111f0 },
1647                        { 0x14, 0x411111f0 },
1648                        { 0x15, 0x411111f0 },
1649                        { 0x16, 0x411111f0 },
1650                        { 0x17, 0x411111f0 },
1651                        { 0x18, 0x411111f0 },
1652                        { 0x19, 0x411111f0 },
1653                        { }
1654                }
1655        },
1656};
1657
1658static const struct snd_pci_quirk alc260_fixup_tbl[] = {
1659        SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1),
1660        SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF),
1661        SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1),
1662        SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750),
1663        SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900),
1664        SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS),
1665        SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F),
1666        SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020),
1667        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1),
1668        SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1),
1669        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER),
1670        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF),
1671        {}
1672};
1673
1674static const struct hda_model_fixup alc260_fixup_models[] = {
1675        {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"},
1676        {.id = ALC260_FIXUP_COEF, .name = "coef"},
1677        {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"},
1678        {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"},
1679        {}
1680};
1681
1682/*
1683 */
1684static int patch_alc260(struct hda_codec *codec)
1685{
1686        struct alc_spec *spec;
1687        int err;
1688
1689        err = alc_alloc_spec(codec, 0x07);
1690        if (err < 0)
1691                return err;
1692
1693        spec = codec->spec;
1694        /* as quite a few machines require HP amp for speaker outputs,
1695         * it's easier to enable it unconditionally; even if it's unneeded,
1696         * it's almost harmless.
1697         */
1698        spec->gen.prefer_hp_amp = 1;
1699        spec->gen.beep_nid = 0x01;
1700
1701        spec->shutup = alc_eapd_shutup;
1702
1703        snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
1704                           alc260_fixups);
1705        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1706
1707        /* automatic parse from the BIOS config */
1708        err = alc260_parse_auto_config(codec);
1709        if (err < 0)
1710                goto error;
1711
1712        if (!spec->gen.no_analog)
1713                set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
1714
1715        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1716
1717        return 0;
1718
1719 error:
1720        alc_free(codec);
1721        return err;
1722}
1723
1724
1725/*
1726 * ALC882/883/885/888/889 support
1727 *
1728 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
1729 * configuration.  Each pin widget can choose any input DACs and a mixer.
1730 * Each ADC is connected from a mixer of all inputs.  This makes possible
1731 * 6-channel independent captures.
1732 *
1733 * In addition, an independent DAC for the multi-playback (not used in this
1734 * driver yet).
1735 */
1736
1737/*
1738 * Pin config fixes
1739 */
1740enum {
1741        ALC882_FIXUP_ABIT_AW9D_MAX,
1742        ALC882_FIXUP_LENOVO_Y530,
1743        ALC882_FIXUP_PB_M5210,
1744        ALC882_FIXUP_ACER_ASPIRE_7736,
1745        ALC882_FIXUP_ASUS_W90V,
1746        ALC889_FIXUP_CD,
1747        ALC889_FIXUP_FRONT_HP_NO_PRESENCE,
1748        ALC889_FIXUP_VAIO_TT,
1749        ALC888_FIXUP_EEE1601,
1750        ALC882_FIXUP_EAPD,
1751        ALC883_FIXUP_EAPD,
1752        ALC883_FIXUP_ACER_EAPD,
1753        ALC882_FIXUP_GPIO1,
1754        ALC882_FIXUP_GPIO2,
1755        ALC882_FIXUP_GPIO3,
1756        ALC889_FIXUP_COEF,
1757        ALC882_FIXUP_ASUS_W2JC,
1758        ALC882_FIXUP_ACER_ASPIRE_4930G,
1759        ALC882_FIXUP_ACER_ASPIRE_8930G,
1760        ALC882_FIXUP_ASPIRE_8930G_VERBS,
1761        ALC885_FIXUP_MACPRO_GPIO,
1762        ALC889_FIXUP_DAC_ROUTE,
1763        ALC889_FIXUP_MBP_VREF,
1764        ALC889_FIXUP_IMAC91_VREF,
1765        ALC889_FIXUP_MBA11_VREF,
1766        ALC889_FIXUP_MBA21_VREF,
1767        ALC889_FIXUP_MP11_VREF,
1768        ALC882_FIXUP_INV_DMIC,
1769        ALC882_FIXUP_NO_PRIMARY_HP,
1770        ALC887_FIXUP_ASUS_BASS,
1771        ALC887_FIXUP_BASS_CHMAP,
1772};
1773
1774static void alc889_fixup_coef(struct hda_codec *codec,
1775                              const struct hda_fixup *fix, int action)
1776{
1777        if (action != HDA_FIXUP_ACT_INIT)
1778                return;
1779        alc_update_coef_idx(codec, 7, 0, 0x2030);
1780}
1781
1782/* toggle speaker-output according to the hp-jack state */
1783static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1784{
1785        unsigned int gpiostate, gpiomask, gpiodir;
1786
1787        gpiostate = snd_hda_codec_read(codec, codec->core.afg, 0,
1788                                       AC_VERB_GET_GPIO_DATA, 0);
1789
1790        if (!muted)
1791                gpiostate |= (1 << pin);
1792        else
1793                gpiostate &= ~(1 << pin);
1794
1795        gpiomask = snd_hda_codec_read(codec, codec->core.afg, 0,
1796                                      AC_VERB_GET_GPIO_MASK, 0);
1797        gpiomask |= (1 << pin);
1798
1799        gpiodir = snd_hda_codec_read(codec, codec->core.afg, 0,
1800                                     AC_VERB_GET_GPIO_DIRECTION, 0);
1801        gpiodir |= (1 << pin);
1802
1803
1804        snd_hda_codec_write(codec, codec->core.afg, 0,
1805                            AC_VERB_SET_GPIO_MASK, gpiomask);
1806        snd_hda_codec_write(codec, codec->core.afg, 0,
1807                            AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1808
1809        msleep(1);
1810
1811        snd_hda_codec_write(codec, codec->core.afg, 0,
1812                            AC_VERB_SET_GPIO_DATA, gpiostate);
1813}
1814
1815/* set up GPIO at initialization */
1816static void alc885_fixup_macpro_gpio(struct hda_codec *codec,
1817                                     const struct hda_fixup *fix, int action)
1818{
1819        if (action != HDA_FIXUP_ACT_INIT)
1820                return;
1821        alc882_gpio_mute(codec, 0, 0);
1822        alc882_gpio_mute(codec, 1, 0);
1823}
1824
1825/* Fix the connection of some pins for ALC889:
1826 * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't
1827 * work correctly (bko#42740)
1828 */
1829static void alc889_fixup_dac_route(struct hda_codec *codec,
1830                                   const struct hda_fixup *fix, int action)
1831{
1832        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1833                /* fake the connections during parsing the tree */
1834                hda_nid_t conn1[2] = { 0x0c, 0x0d };
1835                hda_nid_t conn2[2] = { 0x0e, 0x0f };
1836                snd_hda_override_conn_list(codec, 0x14, 2, conn1);
1837                snd_hda_override_conn_list(codec, 0x15, 2, conn1);
1838                snd_hda_override_conn_list(codec, 0x18, 2, conn2);
1839                snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
1840        } else if (action == HDA_FIXUP_ACT_PROBE) {
1841                /* restore the connections */
1842                hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
1843                snd_hda_override_conn_list(codec, 0x14, 5, conn);
1844                snd_hda_override_conn_list(codec, 0x15, 5, conn);
1845                snd_hda_override_conn_list(codec, 0x18, 5, conn);
1846                snd_hda_override_conn_list(codec, 0x1a, 5, conn);
1847        }
1848}
1849
1850/* Set VREF on HP pin */
1851static void alc889_fixup_mbp_vref(struct hda_codec *codec,
1852                                  const struct hda_fixup *fix, int action)
1853{
1854        struct alc_spec *spec = codec->spec;
1855        static hda_nid_t nids[2] = { 0x14, 0x15 };
1856        int i;
1857
1858        if (action != HDA_FIXUP_ACT_INIT)
1859                return;
1860        for (i = 0; i < ARRAY_SIZE(nids); i++) {
1861                unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]);
1862                if (get_defcfg_device(val) != AC_JACK_HP_OUT)
1863                        continue;
1864                val = snd_hda_codec_get_pin_target(codec, nids[i]);
1865                val |= AC_PINCTL_VREF_80;
1866                snd_hda_set_pin_ctl(codec, nids[i], val);
1867                spec->gen.keep_vref_in_automute = 1;
1868                break;
1869        }
1870}
1871
1872static void alc889_fixup_mac_pins(struct hda_codec *codec,
1873                                  const hda_nid_t *nids, int num_nids)
1874{
1875        struct alc_spec *spec = codec->spec;
1876        int i;
1877
1878        for (i = 0; i < num_nids; i++) {
1879                unsigned int val;
1880                val = snd_hda_codec_get_pin_target(codec, nids[i]);
1881                val |= AC_PINCTL_VREF_50;
1882                snd_hda_set_pin_ctl(codec, nids[i], val);
1883        }
1884        spec->gen.keep_vref_in_automute = 1;
1885}
1886
1887/* Set VREF on speaker pins on imac91 */
1888static void alc889_fixup_imac91_vref(struct hda_codec *codec,
1889                                     const struct hda_fixup *fix, int action)
1890{
1891        static hda_nid_t nids[2] = { 0x18, 0x1a };
1892
1893        if (action == HDA_FIXUP_ACT_INIT)
1894                alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1895}
1896
1897/* Set VREF on speaker pins on mba11 */
1898static void alc889_fixup_mba11_vref(struct hda_codec *codec,
1899                                    const struct hda_fixup *fix, int action)
1900{
1901        static hda_nid_t nids[1] = { 0x18 };
1902
1903        if (action == HDA_FIXUP_ACT_INIT)
1904                alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1905}
1906
1907/* Set VREF on speaker pins on mba21 */
1908static void alc889_fixup_mba21_vref(struct hda_codec *codec,
1909                                    const struct hda_fixup *fix, int action)
1910{
1911        static hda_nid_t nids[2] = { 0x18, 0x19 };
1912
1913        if (action == HDA_FIXUP_ACT_INIT)
1914                alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
1915}
1916
1917/* Don't take HP output as primary
1918 * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
1919 * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
1920 */
1921static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1922                                       const struct hda_fixup *fix, int action)
1923{
1924        struct alc_spec *spec = codec->spec;
1925        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1926                spec->gen.no_primary_hp = 1;
1927                spec->gen.no_multi_io = 1;
1928        }
1929}
1930
1931static void alc_fixup_bass_chmap(struct hda_codec *codec,
1932                                 const struct hda_fixup *fix, int action);
1933
1934static const struct hda_fixup alc882_fixups[] = {
1935        [ALC882_FIXUP_ABIT_AW9D_MAX] = {
1936                .type = HDA_FIXUP_PINS,
1937                .v.pins = (const struct hda_pintbl[]) {
1938                        { 0x15, 0x01080104 }, /* side */
1939                        { 0x16, 0x01011012 }, /* rear */
1940                        { 0x17, 0x01016011 }, /* clfe */
1941                        { }
1942                }
1943        },
1944        [ALC882_FIXUP_LENOVO_Y530] = {
1945                .type = HDA_FIXUP_PINS,
1946                .v.pins = (const struct hda_pintbl[]) {
1947                        { 0x15, 0x99130112 }, /* rear int speakers */
1948                        { 0x16, 0x99130111 }, /* subwoofer */
1949                        { }
1950                }
1951        },
1952        [ALC882_FIXUP_PB_M5210] = {
1953                .type = HDA_FIXUP_PINCTLS,
1954                .v.pins = (const struct hda_pintbl[]) {
1955                        { 0x19, PIN_VREF50 },
1956                        {}
1957                }
1958        },
1959        [ALC882_FIXUP_ACER_ASPIRE_7736] = {
1960                .type = HDA_FIXUP_FUNC,
1961                .v.func = alc_fixup_sku_ignore,
1962        },
1963        [ALC882_FIXUP_ASUS_W90V] = {
1964                .type = HDA_FIXUP_PINS,
1965                .v.pins = (const struct hda_pintbl[]) {
1966                        { 0x16, 0x99130110 }, /* fix sequence for CLFE */
1967                        { }
1968                }
1969        },
1970        [ALC889_FIXUP_CD] = {
1971                .type = HDA_FIXUP_PINS,
1972                .v.pins = (const struct hda_pintbl[]) {
1973                        { 0x1c, 0x993301f0 }, /* CD */
1974                        { }
1975                }
1976        },
1977        [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = {
1978                .type = HDA_FIXUP_PINS,
1979                .v.pins = (const struct hda_pintbl[]) {
1980                        { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */
1981                        { }
1982                },
1983                .chained = true,
1984                .chain_id = ALC889_FIXUP_CD,
1985        },
1986        [ALC889_FIXUP_VAIO_TT] = {
1987                .type = HDA_FIXUP_PINS,
1988                .v.pins = (const struct hda_pintbl[]) {
1989                        { 0x17, 0x90170111 }, /* hidden surround speaker */
1990                        { }
1991                }
1992        },
1993        [ALC888_FIXUP_EEE1601] = {
1994                .type = HDA_FIXUP_VERBS,
1995                .v.verbs = (const struct hda_verb[]) {
1996                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
1997                        { 0x20, AC_VERB_SET_PROC_COEF,  0x0838 },
1998                        { }
1999                }
2000        },
2001        [ALC882_FIXUP_EAPD] = {
2002                .type = HDA_FIXUP_VERBS,
2003                .v.verbs = (const struct hda_verb[]) {
2004                        /* change to EAPD mode */
2005                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2006                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 },
2007                        { }
2008                }
2009        },
2010        [ALC883_FIXUP_EAPD] = {
2011                .type = HDA_FIXUP_VERBS,
2012                .v.verbs = (const struct hda_verb[]) {
2013                        /* change to EAPD mode */
2014                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2015                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2016                        { }
2017                }
2018        },
2019        [ALC883_FIXUP_ACER_EAPD] = {
2020                .type = HDA_FIXUP_VERBS,
2021                .v.verbs = (const struct hda_verb[]) {
2022                        /* eanable EAPD on Acer laptops */
2023                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2024                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2025                        { }
2026                }
2027        },
2028        [ALC882_FIXUP_GPIO1] = {
2029                .type = HDA_FIXUP_VERBS,
2030                .v.verbs = alc_gpio1_init_verbs,
2031        },
2032        [ALC882_FIXUP_GPIO2] = {
2033                .type = HDA_FIXUP_VERBS,
2034                .v.verbs = alc_gpio2_init_verbs,
2035        },
2036        [ALC882_FIXUP_GPIO3] = {
2037                .type = HDA_FIXUP_VERBS,
2038                .v.verbs = alc_gpio3_init_verbs,
2039        },
2040        [ALC882_FIXUP_ASUS_W2JC] = {
2041                .type = HDA_FIXUP_VERBS,
2042                .v.verbs = alc_gpio1_init_verbs,
2043                .chained = true,
2044                .chain_id = ALC882_FIXUP_EAPD,
2045        },
2046        [ALC889_FIXUP_COEF] = {
2047                .type = HDA_FIXUP_FUNC,
2048                .v.func = alc889_fixup_coef,
2049        },
2050        [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
2051                .type = HDA_FIXUP_PINS,
2052                .v.pins = (const struct hda_pintbl[]) {
2053                        { 0x16, 0x99130111 }, /* CLFE speaker */
2054                        { 0x17, 0x99130112 }, /* surround speaker */
2055                        { }
2056                },
2057                .chained = true,
2058                .chain_id = ALC882_FIXUP_GPIO1,
2059        },
2060        [ALC882_FIXUP_ACER_ASPIRE_8930G] = {
2061                .type = HDA_FIXUP_PINS,
2062                .v.pins = (const struct hda_pintbl[]) {
2063                        { 0x16, 0x99130111 }, /* CLFE speaker */
2064                        { 0x1b, 0x99130112 }, /* surround speaker */
2065                        { }
2066                },
2067                .chained = true,
2068                .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS,
2069        },
2070        [ALC882_FIXUP_ASPIRE_8930G_VERBS] = {
2071                /* additional init verbs for Acer Aspire 8930G */
2072                .type = HDA_FIXUP_VERBS,
2073                .v.verbs = (const struct hda_verb[]) {
2074                        /* Enable all DACs */
2075                        /* DAC DISABLE/MUTE 1? */
2076                        /*  setting bits 1-5 disables DAC nids 0x02-0x06
2077                         *  apparently. Init=0x38 */
2078                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 },
2079                        { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2080                        /* DAC DISABLE/MUTE 2? */
2081                        /*  some bit here disables the other DACs.
2082                         *  Init=0x4900 */
2083                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 },
2084                        { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 },
2085                        /* DMIC fix
2086                         * This laptop has a stereo digital microphone.
2087                         * The mics are only 1cm apart which makes the stereo
2088                         * useless. However, either the mic or the ALC889
2089                         * makes the signal become a difference/sum signal
2090                         * instead of standard stereo, which is annoying.
2091                         * So instead we flip this bit which makes the
2092                         * codec replicate the sum signal to both channels,
2093                         * turning it into a normal mono mic.
2094                         */
2095                        /* DMIC_CONTROL? Init value = 0x0001 */
2096                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b },
2097                        { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 },
2098                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2099                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2100                        { }
2101                },
2102                .chained = true,
2103                .chain_id = ALC882_FIXUP_GPIO1,
2104        },
2105        [ALC885_FIXUP_MACPRO_GPIO] = {
2106                .type = HDA_FIXUP_FUNC,
2107                .v.func = alc885_fixup_macpro_gpio,
2108        },
2109        [ALC889_FIXUP_DAC_ROUTE] = {
2110                .type = HDA_FIXUP_FUNC,
2111                .v.func = alc889_fixup_dac_route,
2112        },
2113        [ALC889_FIXUP_MBP_VREF] = {
2114                .type = HDA_FIXUP_FUNC,
2115                .v.func = alc889_fixup_mbp_vref,
2116                .chained = true,
2117                .chain_id = ALC882_FIXUP_GPIO1,
2118        },
2119        [ALC889_FIXUP_IMAC91_VREF] = {
2120                .type = HDA_FIXUP_FUNC,
2121                .v.func = alc889_fixup_imac91_vref,
2122                .chained = true,
2123                .chain_id = ALC882_FIXUP_GPIO1,
2124        },
2125        [ALC889_FIXUP_MBA11_VREF] = {
2126                .type = HDA_FIXUP_FUNC,
2127                .v.func = alc889_fixup_mba11_vref,
2128                .chained = true,
2129                .chain_id = ALC889_FIXUP_MBP_VREF,
2130        },
2131        [ALC889_FIXUP_MBA21_VREF] = {
2132                .type = HDA_FIXUP_FUNC,
2133                .v.func = alc889_fixup_mba21_vref,
2134                .chained = true,
2135                .chain_id = ALC889_FIXUP_MBP_VREF,
2136        },
2137        [ALC889_FIXUP_MP11_VREF] = {
2138                .type = HDA_FIXUP_FUNC,
2139                .v.func = alc889_fixup_mba11_vref,
2140                .chained = true,
2141                .chain_id = ALC885_FIXUP_MACPRO_GPIO,
2142        },
2143        [ALC882_FIXUP_INV_DMIC] = {
2144                .type = HDA_FIXUP_FUNC,
2145                .v.func = alc_fixup_inv_dmic,
2146        },
2147        [ALC882_FIXUP_NO_PRIMARY_HP] = {
2148                .type = HDA_FIXUP_FUNC,
2149                .v.func = alc882_fixup_no_primary_hp,
2150        },
2151        [ALC887_FIXUP_ASUS_BASS] = {
2152                .type = HDA_FIXUP_PINS,
2153                .v.pins = (const struct hda_pintbl[]) {
2154                        {0x16, 0x99130130}, /* bass speaker */
2155                        {}
2156                },
2157                .chained = true,
2158                .chain_id = ALC887_FIXUP_BASS_CHMAP,
2159        },
2160        [ALC887_FIXUP_BASS_CHMAP] = {
2161                .type = HDA_FIXUP_FUNC,
2162                .v.func = alc_fixup_bass_chmap,
2163        },
2164};
2165
2166static const struct snd_pci_quirk alc882_fixup_tbl[] = {
2167        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD),
2168        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2169        SND_PCI_QUIRK(0x1025, 0x0107, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2170        SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD),
2171        SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD),
2172        SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD),
2173        SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD),
2174        SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2175                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2176        SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2177                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2178        SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2179                      ALC882_FIXUP_ACER_ASPIRE_8930G),
2180        SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2181                      ALC882_FIXUP_ACER_ASPIRE_8930G),
2182        SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2183                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2184        SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2185                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2186        SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2187                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2188        SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210),
2189        SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G",
2190                      ALC882_FIXUP_ACER_ASPIRE_4930G),
2191        SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE),
2192        SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G),
2193        SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736),
2194        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD),
2195        SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V),
2196        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC),
2197        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601),
2198        SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS),
2199        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
2200        SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
2201        SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
2202
2203        /* All Apple entries are in codec SSIDs */
2204        SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
2205        SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF),
2206        SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2207        SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF),
2208        SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO),
2209        SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO),
2210        SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF),
2211        SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF),
2212        SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD),
2213        SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF),
2214        SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF),
2215        SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF),
2216        SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF),
2217        SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO),
2218        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF),
2219        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF),
2220        SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF),
2221        SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO),
2222        SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF),
2223        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF),
2224        SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF),
2225        SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_MBA11_VREF),
2226
2227        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
2228        SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
2229        SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
2230        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
2231        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
2232        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
2233        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
2234        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530),
2235        SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF),
2236        {}
2237};
2238
2239static const struct hda_model_fixup alc882_fixup_models[] = {
2240        {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
2241        {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
2242        {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
2243        {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
2244        {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"},
2245        {}
2246};
2247
2248/*
2249 * BIOS auto configuration
2250 */
2251/* almost identical with ALC880 parser... */
2252static int alc882_parse_auto_config(struct hda_codec *codec)
2253{
2254        static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
2255        static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2256        return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
2257}
2258
2259/*
2260 */
2261static int patch_alc882(struct hda_codec *codec)
2262{
2263        struct alc_spec *spec;
2264        int err;
2265
2266        err = alc_alloc_spec(codec, 0x0b);
2267        if (err < 0)
2268                return err;
2269
2270        spec = codec->spec;
2271
2272        switch (codec->core.vendor_id) {
2273        case 0x10ec0882:
2274        case 0x10ec0885:
2275        case 0x10ec0900:
2276                break;
2277        default:
2278                /* ALC883 and variants */
2279                alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2280                break;
2281        }
2282
2283        snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
2284                       alc882_fixups);
2285        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2286
2287        alc_auto_parse_customize_define(codec);
2288
2289        if (has_cdefine_beep(codec))
2290                spec->gen.beep_nid = 0x01;
2291
2292        /* automatic parse from the BIOS config */
2293        err = alc882_parse_auto_config(codec);
2294        if (err < 0)
2295                goto error;
2296
2297        if (!spec->gen.no_analog && spec->gen.beep_nid)
2298                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2299
2300        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2301
2302        return 0;
2303
2304 error:
2305        alc_free(codec);
2306        return err;
2307}
2308
2309
2310/*
2311 * ALC262 support
2312 */
2313static int alc262_parse_auto_config(struct hda_codec *codec)
2314{
2315        static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
2316        static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2317        return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
2318}
2319
2320/*
2321 * Pin config fixes
2322 */
2323enum {
2324        ALC262_FIXUP_FSC_H270,
2325        ALC262_FIXUP_FSC_S7110,
2326        ALC262_FIXUP_HP_Z200,
2327        ALC262_FIXUP_TYAN,
2328        ALC262_FIXUP_LENOVO_3000,
2329        ALC262_FIXUP_BENQ,
2330        ALC262_FIXUP_BENQ_T31,
2331        ALC262_FIXUP_INV_DMIC,
2332        ALC262_FIXUP_INTEL_BAYLEYBAY,
2333};
2334
2335static const struct hda_fixup alc262_fixups[] = {
2336        [ALC262_FIXUP_FSC_H270] = {
2337                .type = HDA_FIXUP_PINS,
2338                .v.pins = (const struct hda_pintbl[]) {
2339                        { 0x14, 0x99130110 }, /* speaker */
2340                        { 0x15, 0x0221142f }, /* front HP */
2341                        { 0x1b, 0x0121141f }, /* rear HP */
2342                        { }
2343                }
2344        },
2345        [ALC262_FIXUP_FSC_S7110] = {
2346                .type = HDA_FIXUP_PINS,
2347                .v.pins = (const struct hda_pintbl[]) {
2348                        { 0x15, 0x90170110 }, /* speaker */
2349                        { }
2350                },
2351                .chained = true,
2352                .chain_id = ALC262_FIXUP_BENQ,
2353        },
2354        [ALC262_FIXUP_HP_Z200] = {
2355                .type = HDA_FIXUP_PINS,
2356                .v.pins = (const struct hda_pintbl[]) {
2357                        { 0x16, 0x99130120 }, /* internal speaker */
2358                        { }
2359                }
2360        },
2361        [ALC262_FIXUP_TYAN] = {
2362                .type = HDA_FIXUP_PINS,
2363                .v.pins = (const struct hda_pintbl[]) {
2364                        { 0x14, 0x1993e1f0 }, /* int AUX */
2365                        { }
2366                }
2367        },
2368        [ALC262_FIXUP_LENOVO_3000] = {
2369                .type = HDA_FIXUP_PINCTLS,
2370                .v.pins = (const struct hda_pintbl[]) {
2371                        { 0x19, PIN_VREF50 },
2372                        {}
2373                },
2374                .chained = true,
2375                .chain_id = ALC262_FIXUP_BENQ,
2376        },
2377        [ALC262_FIXUP_BENQ] = {
2378                .type = HDA_FIXUP_VERBS,
2379                .v.verbs = (const struct hda_verb[]) {
2380                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2381                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 },
2382                        {}
2383                }
2384        },
2385        [ALC262_FIXUP_BENQ_T31] = {
2386                .type = HDA_FIXUP_VERBS,
2387                .v.verbs = (const struct hda_verb[]) {
2388                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 },
2389                        { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 },
2390                        {}
2391                }
2392        },
2393        [ALC262_FIXUP_INV_DMIC] = {
2394                .type = HDA_FIXUP_FUNC,
2395                .v.func = alc_fixup_inv_dmic,
2396        },
2397        [ALC262_FIXUP_INTEL_BAYLEYBAY] = {
2398                .type = HDA_FIXUP_FUNC,
2399                .v.func = alc_fixup_no_depop_delay,
2400        },
2401};
2402
2403static const struct snd_pci_quirk alc262_fixup_tbl[] = {
2404        SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200),
2405        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110),
2406        SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ),
2407        SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN),
2408        SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270),
2409        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000),
2410        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ),
2411        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31),
2412        SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY),
2413        {}
2414};
2415
2416static const struct hda_model_fixup alc262_fixup_models[] = {
2417        {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
2418        {}
2419};
2420
2421/*
2422 */
2423static int patch_alc262(struct hda_codec *codec)
2424{
2425        struct alc_spec *spec;
2426        int err;
2427
2428        err = alc_alloc_spec(codec, 0x0b);
2429        if (err < 0)
2430                return err;
2431
2432        spec = codec->spec;
2433        spec->gen.shared_mic_vref_pin = 0x18;
2434
2435        spec->shutup = alc_eapd_shutup;
2436
2437#if 0
2438        /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
2439         * under-run
2440         */
2441        alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80);
2442#endif
2443        alc_fix_pll_init(codec, 0x20, 0x0a, 10);
2444
2445        snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
2446                       alc262_fixups);
2447        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2448
2449        alc_auto_parse_customize_define(codec);
2450
2451        if (has_cdefine_beep(codec))
2452                spec->gen.beep_nid = 0x01;
2453
2454        /* automatic parse from the BIOS config */
2455        err = alc262_parse_auto_config(codec);
2456        if (err < 0)
2457                goto error;
2458
2459        if (!spec->gen.no_analog && spec->gen.beep_nid)
2460                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
2461
2462        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2463
2464        return 0;
2465
2466 error:
2467        alc_free(codec);
2468        return err;
2469}
2470
2471/*
2472 *  ALC268
2473 */
2474/* bind Beep switches of both NID 0x0f and 0x10 */
2475static const struct hda_bind_ctls alc268_bind_beep_sw = {
2476        .ops = &snd_hda_bind_sw,
2477        .values = {
2478                HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
2479                HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
2480                0
2481        },
2482};
2483
2484static const struct snd_kcontrol_new alc268_beep_mixer[] = {
2485        HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
2486        HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
2487        { }
2488};
2489
2490/* set PCBEEP vol = 0, mute connections */
2491static const struct hda_verb alc268_beep_init_verbs[] = {
2492        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2493        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2494        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2495        { }
2496};
2497
2498enum {
2499        ALC268_FIXUP_INV_DMIC,
2500        ALC268_FIXUP_HP_EAPD,
2501        ALC268_FIXUP_SPDIF,
2502};
2503
2504static const struct hda_fixup alc268_fixups[] = {
2505        [ALC268_FIXUP_INV_DMIC] = {
2506                .type = HDA_FIXUP_FUNC,
2507                .v.func = alc_fixup_inv_dmic,
2508        },
2509        [ALC268_FIXUP_HP_EAPD] = {
2510                .type = HDA_FIXUP_VERBS,
2511                .v.verbs = (const struct hda_verb[]) {
2512                        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0},
2513                        {}
2514                }
2515        },
2516        [ALC268_FIXUP_SPDIF] = {
2517                .type = HDA_FIXUP_PINS,
2518                .v.pins = (const struct hda_pintbl[]) {
2519                        { 0x1e, 0x014b1180 }, /* enable SPDIF out */
2520                        {}
2521                }
2522        },
2523};
2524
2525static const struct hda_model_fixup alc268_fixup_models[] = {
2526        {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
2527        {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"},
2528        {}
2529};
2530
2531static const struct snd_pci_quirk alc268_fixup_tbl[] = {
2532        SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF),
2533        SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC),
2534        /* below is codec SSID since multiple Toshiba laptops have the
2535         * same PCI SSID 1179:ff00
2536         */
2537        SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD),
2538        {}
2539};
2540
2541/*
2542 * BIOS auto configuration
2543 */
2544static int alc268_parse_auto_config(struct hda_codec *codec)
2545{
2546        static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2547        return alc_parse_auto_config(codec, NULL, alc268_ssids);
2548}
2549
2550/*
2551 */
2552static int patch_alc268(struct hda_codec *codec)
2553{
2554        struct alc_spec *spec;
2555        int err;
2556
2557        /* ALC268 has no aa-loopback mixer */
2558        err = alc_alloc_spec(codec, 0);
2559        if (err < 0)
2560                return err;
2561
2562        spec = codec->spec;
2563        spec->gen.beep_nid = 0x01;
2564
2565        spec->shutup = alc_eapd_shutup;
2566
2567        snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
2568        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2569
2570        /* automatic parse from the BIOS config */
2571        err = alc268_parse_auto_config(codec);
2572        if (err < 0)
2573                goto error;
2574
2575        if (err > 0 && !spec->gen.no_analog &&
2576            spec->gen.autocfg.speaker_pins[0] != 0x1d) {
2577                add_mixer(spec, alc268_beep_mixer);
2578                snd_hda_add_verbs(codec, alc268_beep_init_verbs);
2579                if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
2580                        /* override the amp caps for beep generator */
2581                        snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
2582                                          (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
2583                                          (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
2584                                          (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2585                                          (0 << AC_AMPCAP_MUTE_SHIFT));
2586        }
2587
2588        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2589
2590        return 0;
2591
2592 error:
2593        alc_free(codec);
2594        return err;
2595}
2596
2597/*
2598 * ALC269
2599 */
2600
2601static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
2602        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2603};
2604
2605static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
2606        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
2607};
2608
2609/* different alc269-variants */
2610enum {
2611        ALC269_TYPE_ALC269VA,
2612        ALC269_TYPE_ALC269VB,
2613        ALC269_TYPE_ALC269VC,
2614        ALC269_TYPE_ALC269VD,
2615        ALC269_TYPE_ALC280,
2616        ALC269_TYPE_ALC282,
2617        ALC269_TYPE_ALC283,
2618        ALC269_TYPE_ALC284,
2619        ALC269_TYPE_ALC285,
2620        ALC269_TYPE_ALC286,
2621        ALC269_TYPE_ALC298,
2622        ALC269_TYPE_ALC255,
2623        ALC269_TYPE_ALC256,
2624};
2625
2626/*
2627 * BIOS auto configuration
2628 */
2629static int alc269_parse_auto_config(struct hda_codec *codec)
2630{
2631        static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
2632        static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
2633        static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
2634        struct alc_spec *spec = codec->spec;
2635        const hda_nid_t *ssids;
2636
2637        switch (spec->codec_variant) {
2638        case ALC269_TYPE_ALC269VA:
2639        case ALC269_TYPE_ALC269VC:
2640        case ALC269_TYPE_ALC280:
2641        case ALC269_TYPE_ALC284:
2642        case ALC269_TYPE_ALC285:
2643                ssids = alc269va_ssids;
2644                break;
2645        case ALC269_TYPE_ALC269VB:
2646        case ALC269_TYPE_ALC269VD:
2647        case ALC269_TYPE_ALC282:
2648        case ALC269_TYPE_ALC283:
2649        case ALC269_TYPE_ALC286:
2650        case ALC269_TYPE_ALC298:
2651        case ALC269_TYPE_ALC255:
2652        case ALC269_TYPE_ALC256:
2653                ssids = alc269_ssids;
2654                break;
2655        default:
2656                ssids = alc269_ssids;
2657                break;
2658        }
2659
2660        return alc_parse_auto_config(codec, alc269_ignore, ssids);
2661}
2662
2663static int find_ext_mic_pin(struct hda_codec *codec);
2664
2665static void alc286_shutup(struct hda_codec *codec)
2666{
2667        int i;
2668        int mic_pin = find_ext_mic_pin(codec);
2669        /* don't shut up pins when unloading the driver; otherwise it breaks
2670         * the default pin setup at the next load of the driver
2671         */
2672        if (codec->bus->shutdown)
2673                return;
2674        for (i = 0; i < codec->init_pins.used; i++) {
2675                struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
2676                /* use read here for syncing after issuing each verb */
2677                if (pin->nid != mic_pin)
2678                        snd_hda_codec_read(codec, pin->nid, 0,
2679                                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2680        }
2681        codec->pins_shutup = 1;
2682}
2683
2684static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
2685{
2686        alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
2687}
2688
2689static void alc269_shutup(struct hda_codec *codec)
2690{
2691        struct alc_spec *spec = codec->spec;
2692
2693        if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2694                alc269vb_toggle_power_output(codec, 0);
2695        if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2696                        (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2697                msleep(150);
2698        }
2699        snd_hda_shutup_pins(codec);
2700}
2701
2702static struct coef_fw alc282_coefs[] = {
2703        WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2704        UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2705        WRITE_COEF(0x07, 0x0200), /* DMIC control */
2706        UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2707        UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2708        WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2709        WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2710        WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */
2711        UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2712        UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2713        WRITE_COEF(0x6f, 0x0), /* Class D test 4 */
2714        UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */
2715        WRITE_COEF(0x34, 0xa0c0), /* ANC */
2716        UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */
2717        UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2718        UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2719        WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2720        WRITE_COEF(0x63, 0x2902), /* PLL */
2721        WRITE_COEF(0x68, 0xa080), /* capless control 2 */
2722        WRITE_COEF(0x69, 0x3400), /* capless control 3 */
2723        WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */
2724        WRITE_COEF(0x6b, 0x0), /* capless control 5 */
2725        UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */
2726        WRITE_COEF(0x6e, 0x110a), /* class D test 3 */
2727        UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */
2728        WRITE_COEF(0x71, 0x0014), /* class D test 6 */
2729        WRITE_COEF(0x72, 0xc2ba), /* classD OCP */
2730        UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */
2731        WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */
2732        {}
2733};
2734
2735static void alc282_restore_default_value(struct hda_codec *codec)
2736{
2737        alc_process_coef_fw(codec, alc282_coefs);
2738}
2739
2740static void alc282_init(struct hda_codec *codec)
2741{
2742        struct alc_spec *spec = codec->spec;
2743        hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2744        bool hp_pin_sense;
2745        int coef78;
2746
2747        alc282_restore_default_value(codec);
2748
2749        if (!hp_pin)
2750                return;
2751        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2752        coef78 = alc_read_coef_idx(codec, 0x78);
2753
2754        /* Index 0x78 Direct Drive HP AMP LPM Control 1 */
2755        /* Headphone capless set to high power mode */
2756        alc_write_coef_idx(codec, 0x78, 0x9004);
2757
2758        if (hp_pin_sense)
2759                msleep(2);
2760
2761        snd_hda_codec_write(codec, hp_pin, 0,
2762                            AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2763
2764        if (hp_pin_sense)
2765                msleep(85);
2766
2767        snd_hda_codec_write(codec, hp_pin, 0,
2768                            AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2769
2770        if (hp_pin_sense)
2771                msleep(100);
2772
2773        /* Headphone capless set to normal mode */
2774        alc_write_coef_idx(codec, 0x78, coef78);
2775}
2776
2777static void alc282_shutup(struct hda_codec *codec)
2778{
2779        struct alc_spec *spec = codec->spec;
2780        hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2781        bool hp_pin_sense;
2782        int coef78;
2783
2784        if (!hp_pin) {
2785                alc269_shutup(codec);
2786                return;
2787        }
2788
2789        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2790        coef78 = alc_read_coef_idx(codec, 0x78);
2791        alc_write_coef_idx(codec, 0x78, 0x9004);
2792
2793        if (hp_pin_sense)
2794                msleep(2);
2795
2796        snd_hda_codec_write(codec, hp_pin, 0,
2797                            AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2798
2799        if (hp_pin_sense)
2800                msleep(85);
2801
2802        snd_hda_codec_write(codec, hp_pin, 0,
2803                            AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2804
2805        if (hp_pin_sense)
2806                msleep(100);
2807
2808        alc_auto_setup_eapd(codec, false);
2809        snd_hda_shutup_pins(codec);
2810        alc_write_coef_idx(codec, 0x78, coef78);
2811}
2812
2813static struct coef_fw alc283_coefs[] = {
2814        WRITE_COEF(0x03, 0x0002), /* Power Down Control */
2815        UPDATE_COEF(0x05, 0xff3f, 0x0700), /* FIFO and filter clock */
2816        WRITE_COEF(0x07, 0x0200), /* DMIC control */
2817        UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */
2818        UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */
2819        WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */
2820        WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */
2821        WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */
2822        UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */
2823        UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */
2824        WRITE_COEF(0x3a, 0x0), /* Class D test 4 */
2825        UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */
2826        WRITE_COEF(0x22, 0xa0c0), /* ANC */
2827        UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */
2828        UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */
2829        UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */
2830        WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */
2831        WRITE_COEF(0x2e, 0x2902), /* PLL */
2832        WRITE_COEF(0x33, 0xa080), /* capless control 2 */
2833        WRITE_COEF(0x34, 0x3400), /* capless control 3 */
2834        WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */
2835        WRITE_COEF(0x36, 0x0), /* capless control 5 */
2836        UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */
2837        WRITE_COEF(0x39, 0x110a), /* class D test 3 */
2838        UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */
2839        WRITE_COEF(0x3c, 0x0014), /* class D test 6 */
2840        WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */
2841        UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */
2842        WRITE_COEF(0x49, 0x0), /* test mode */
2843        UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */
2844        UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */
2845        WRITE_COEF(0x37, 0xfc06), /* Class D amp control */
2846        UPDATE_COEF(0x1b, 0x8000, 0), /* HP JD control */
2847        {}
2848};
2849
2850static void alc283_restore_default_value(struct hda_codec *codec)
2851{
2852        alc_process_coef_fw(codec, alc283_coefs);
2853}
2854
2855static void alc283_init(struct hda_codec *codec)
2856{
2857        struct alc_spec *spec = codec->spec;
2858        hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2859        bool hp_pin_sense;
2860
2861        if (!spec->gen.autocfg.hp_outs) {
2862                if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2863                        hp_pin = spec->gen.autocfg.line_out_pins[0];
2864        }
2865
2866        alc283_restore_default_value(codec);
2867
2868        if (!hp_pin)
2869                return;
2870
2871        msleep(30);
2872        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2873
2874        /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2875        /* Headphone capless set to high power mode */
2876        alc_write_coef_idx(codec, 0x43, 0x9004);
2877
2878        snd_hda_codec_write(codec, hp_pin, 0,
2879                            AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2880
2881        if (hp_pin_sense)
2882                msleep(85);
2883
2884        snd_hda_codec_write(codec, hp_pin, 0,
2885                            AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2886
2887        if (hp_pin_sense)
2888                msleep(85);
2889        /* Index 0x46 Combo jack auto switch control 2 */
2890        /* 3k pull low control for Headset jack. */
2891        alc_update_coef_idx(codec, 0x46, 3 << 12, 0);
2892        /* Headphone capless set to normal mode */
2893        alc_write_coef_idx(codec, 0x43, 0x9614);
2894}
2895
2896static void alc283_shutup(struct hda_codec *codec)
2897{
2898        struct alc_spec *spec = codec->spec;
2899        hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2900        bool hp_pin_sense;
2901
2902        if (!spec->gen.autocfg.hp_outs) {
2903                if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT)
2904                        hp_pin = spec->gen.autocfg.line_out_pins[0];
2905        }
2906
2907        if (!hp_pin) {
2908                alc269_shutup(codec);
2909                return;
2910        }
2911
2912        hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2913
2914        alc_write_coef_idx(codec, 0x43, 0x9004);
2915
2916        /*depop hp during suspend*/
2917        alc_write_coef_idx(codec, 0x06, 0x2100);
2918
2919        snd_hda_codec_write(codec, hp_pin, 0,
2920                            AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2921
2922        if (hp_pin_sense)
2923                msleep(100);
2924
2925        snd_hda_codec_write(codec, hp_pin, 0,
2926                            AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2927
2928        alc_update_coef_idx(codec, 0x46, 0, 3 << 12);
2929
2930        if (hp_pin_sense)
2931                msleep(100);
2932        alc_auto_setup_eapd(codec, false);
2933        snd_hda_shutup_pins(codec);
2934        alc_write_coef_idx(codec, 0x43, 0x9614);
2935}
2936
2937static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
2938                             unsigned int val)
2939{
2940        snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2941        snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */
2942        snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */
2943}
2944
2945static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg)
2946{
2947        unsigned int val;
2948
2949        snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1);
2950        val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2951                & 0xffff;
2952        val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0)
2953                << 16;
2954        return val;
2955}
2956
2957static void alc5505_dsp_halt(struct hda_codec *codec)
2958{
2959        unsigned int val;
2960
2961        alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */
2962        alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */
2963        alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */
2964        alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */
2965        alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */
2966        alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */
2967        alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */
2968        val = alc5505_coef_get(codec, 0x6220);
2969        alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */
2970}
2971
2972static void alc5505_dsp_back_from_halt(struct hda_codec *codec)
2973{
2974        alc5505_coef_set(codec, 0x61b8, 0x04133302);
2975        alc5505_coef_set(codec, 0x61b0, 0x00005b16);
2976        alc5505_coef_set(codec, 0x61b4, 0x040a2b02);
2977        alc5505_coef_set(codec, 0x6230, 0xf80d4011);
2978        alc5505_coef_set(codec, 0x6220, 0x2002010f);
2979        alc5505_coef_set(codec, 0x880c, 0x00000004);
2980}
2981
2982static void alc5505_dsp_init(struct hda_codec *codec)
2983{
2984        unsigned int val;
2985
2986        alc5505_dsp_halt(codec);
2987        alc5505_dsp_back_from_halt(codec);
2988        alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */
2989        alc5505_coef_set(codec, 0x61b0, 0x5b16);
2990        alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */
2991        alc5505_coef_set(codec, 0x61b4, 0x04132b02);
2992        alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/
2993        alc5505_coef_set(codec, 0x61b8, 0x041f3302);
2994        snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */
2995        alc5505_coef_set(codec, 0x61b8, 0x041b3302);
2996        alc5505_coef_set(codec, 0x61b8, 0x04173302);
2997        alc5505_coef_set(codec, 0x61b8, 0x04163302);
2998        alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */
2999        alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */
3000        alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */
3001
3002        val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */
3003        if (val <= 3)
3004                alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */
3005        else
3006                alc5505_coef_set(codec, 0x6220, 0x6002018f);
3007
3008        alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/
3009        alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */
3010        alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */
3011        alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */
3012        alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */
3013        alc5505_coef_set(codec, 0x880c, 0x00000003);
3014        alc5505_coef_set(codec, 0x880c, 0x00000010);
3015
3016#ifdef HALT_REALTEK_ALC5505
3017        alc5505_dsp_halt(codec);
3018#endif
3019}
3020
3021#ifdef HALT_REALTEK_ALC5505
3022#define alc5505_dsp_suspend(codec)      /* NOP */
3023#define alc5505_dsp_resume(codec)       /* NOP */
3024#else
3025#define alc5505_dsp_suspend(codec)      alc5505_dsp_halt(codec)
3026#define alc5505_dsp_resume(codec)       alc5505_dsp_back_from_halt(codec)
3027#endif
3028
3029#ifdef CONFIG_PM
3030static int alc269_suspend(struct hda_codec *codec)
3031{
3032        struct alc_spec *spec = codec->spec;
3033
3034        if (spec->has_alc5505_dsp)
3035                alc5505_dsp_suspend(codec);
3036        return alc_suspend(codec);
3037}
3038
3039static int alc269_resume(struct hda_codec *codec)
3040{
3041        struct alc_spec *spec = codec->spec;
3042
3043        if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3044                alc269vb_toggle_power_output(codec, 0);
3045        if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3046                        (alc_get_coef0(codec) & 0x00ff) == 0x018) {
3047                msleep(150);
3048        }
3049
3050        codec->patch_ops.init(codec);
3051
3052        if (spec->codec_variant == ALC269_TYPE_ALC269VB)
3053                alc269vb_toggle_power_output(codec, 1);
3054        if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
3055                        (alc_get_coef0(codec) & 0x00ff) == 0x017) {
3056                msleep(200);
3057        }
3058
3059        regcache_sync(codec->core.regmap);
3060        hda_call_check_power_status(codec, 0x01);
3061
3062        /* on some machine, the BIOS will clear the codec gpio data when enter
3063         * suspend, and won't restore the data after resume, so we restore it
3064         * in the driver.
3065         */
3066        if (spec->gpio_led)
3067                snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA,
3068                            spec->gpio_led);
3069
3070        if (spec->has_alc5505_dsp)
3071                alc5505_dsp_resume(codec);
3072
3073        return 0;
3074}
3075#endif /* CONFIG_PM */
3076
3077static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
3078                                                 const struct hda_fixup *fix, int action)
3079{
3080        struct alc_spec *spec = codec->spec;
3081
3082        if (action == HDA_FIXUP_ACT_PRE_PROBE)
3083                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
3084}
3085
3086static void alc269_fixup_hweq(struct hda_codec *codec,
3087                               const struct hda_fixup *fix, int action)
3088{
3089        if (action == HDA_FIXUP_ACT_INIT)
3090                alc_update_coef_idx(codec, 0x1e, 0, 0x80);
3091}
3092
3093static void alc269_fixup_headset_mic(struct hda_codec *codec,
3094                                       const struct hda_fixup *fix, int action)
3095{
3096        struct alc_spec *spec = codec->spec;
3097
3098        if (action == HDA_FIXUP_ACT_PRE_PROBE)
3099                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3100}
3101
3102static void alc271_fixup_dmic(struct hda_codec *codec,
3103                              const struct hda_fixup *fix, int action)
3104{
3105        static const struct hda_verb verbs[] = {
3106                {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
3107                {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
3108                {}
3109        };
3110        unsigned int cfg;
3111
3112        if (strcmp(codec->core.chip_name, "ALC271X") &&
3113            strcmp(codec->core.chip_name, "ALC269VB"))
3114                return;
3115        cfg = snd_hda_codec_get_pincfg(codec, 0x12);
3116        if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
3117                snd_hda_sequence_write(codec, verbs);
3118}
3119
3120static void alc269_fixup_pcm_44k(struct hda_codec *codec,
3121                                 const struct hda_fixup *fix, int action)
3122{
3123        struct alc_spec *spec = codec->spec;
3124
3125        if (action != HDA_FIXUP_ACT_PROBE)
3126                return;
3127
3128        /* Due to a hardware problem on Lenovo Ideadpad, we need to
3129         * fix the sample rate of analog I/O to 44.1kHz
3130         */
3131        spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback;
3132        spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture;
3133}
3134
3135static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
3136                                     const struct hda_fixup *fix, int action)
3137{
3138        /* The digital-mic unit sends PDM (differential signal) instead of
3139         * the standard PCM, thus you can't record a valid mono stream as is.
3140         * Below is a workaround specific to ALC269 to control the dmic
3141         * signal source as mono.
3142         */
3143        if (action == HDA_FIXUP_ACT_INIT)
3144                alc_update_coef_idx(codec, 0x07, 0, 0x80);
3145}
3146
3147static void alc269_quanta_automute(struct hda_codec *codec)
3148{
3149        snd_hda_gen_update_outputs(codec);
3150
3151        alc_write_coef_idx(codec, 0x0c, 0x680);
3152        alc_write_coef_idx(codec, 0x0c, 0x480);
3153}
3154
3155static void alc269_fixup_quanta_mute(struct hda_codec *codec,
3156                                     const struct hda_fixup *fix, int action)
3157{
3158        struct alc_spec *spec = codec->spec;
3159        if (action != HDA_FIXUP_ACT_PROBE)
3160                return;
3161        spec->gen.automute_hook = alc269_quanta_automute;
3162}
3163
3164static void alc269_x101_hp_automute_hook(struct hda_codec *codec,
3165                                         struct hda_jack_callback *jack)
3166{
3167        struct alc_spec *spec = codec->spec;
3168        int vref;
3169        msleep(200);
3170        snd_hda_gen_hp_automute(codec, jack);
3171
3172        vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3173        msleep(100);
3174        snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3175                            vref);
3176        msleep(500);
3177        snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3178                            vref);
3179}
3180
3181static void alc269_fixup_x101_headset_mic(struct hda_codec *codec,
3182                                     const struct hda_fixup *fix, int action)
3183{
3184        struct alc_spec *spec = codec->spec;
3185        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3186                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
3187                spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook;
3188        }
3189}
3190
3191
3192/* update mute-LED according to the speaker mute state via mic VREF pin */
3193static void alc269_fixup_mic_mute_hook(void *private_data, int enabled)
3194{
3195        struct hda_codec *codec = private_data;
3196        struct alc_spec *spec = codec->spec;
3197        unsigned int pinval;
3198
3199        if (spec->mute_led_polarity)
3200                enabled = !enabled;
3201        pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid);
3202        pinval &= ~AC_PINCTL_VREFEN;
3203        pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80;
3204        if (spec->mute_led_nid)
3205                snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval);
3206}
3207
3208/* Make sure the led works even in runtime suspend */
3209static unsigned int led_power_filter(struct hda_codec *codec,
3210                                                  hda_nid_t nid,
3211                                                  unsigned int power_state)
3212{
3213        struct alc_spec *spec = codec->spec;
3214
3215        if (power_state != AC_PWRST_D3 || nid == 0 ||
3216            (nid != spec->mute_led_nid && nid != spec->cap_mute_led_nid))
3217                return power_state;
3218
3219        /* Set pin ctl again, it might have just been set to 0 */
3220        snd_hda_set_pin_ctl(codec, nid,
3221                            snd_hda_codec_get_pin_target(codec, nid));
3222
3223        return snd_hda_gen_path_power_filter(codec, nid, power_state);
3224}
3225
3226static void alc269_fixup_hp_mute_led(struct hda_codec *codec,
3227                                     const struct hda_fixup *fix, int action)
3228{
3229        struct alc_spec *spec = codec->spec;
3230        const struct dmi_device *dev = NULL;
3231
3232        if (action != HDA_FIXUP_ACT_PRE_PROBE)
3233                return;
3234
3235        while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) {
3236                int pol, pin;
3237                if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2)
3238                        continue;
3239                if (pin < 0x0a || pin >= 0x10)
3240                        break;
3241                spec->mute_led_polarity = pol;
3242                spec->mute_led_nid = pin - 0x0a + 0x18;
3243                spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3244                spec->gen.vmaster_mute_enum = 1;
3245                codec->power_filter = led_power_filter;
3246                codec_dbg(codec,
3247                          "Detected mute LED for %x:%d\n", spec->mute_led_nid,
3248                           spec->mute_led_polarity);
3249                break;
3250        }
3251}
3252
3253static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec,
3254                                const struct hda_fixup *fix, int action)
3255{
3256        struct alc_spec *spec = codec->spec;
3257        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3258                spec->mute_led_polarity = 0;
3259                spec->mute_led_nid = 0x18;
3260                spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3261                spec->gen.vmaster_mute_enum = 1;
3262                codec->power_filter = led_power_filter;
3263        }
3264}
3265
3266static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec,
3267                                const struct hda_fixup *fix, int action)
3268{
3269        struct alc_spec *spec = codec->spec;
3270        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3271                spec->mute_led_polarity = 0;
3272                spec->mute_led_nid = 0x19;
3273                spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3274                spec->gen.vmaster_mute_enum = 1;
3275                codec->power_filter = led_power_filter;
3276        }
3277}
3278
3279/* update LED status via GPIO */
3280static void alc_update_gpio_led(struct hda_codec *codec, unsigned int mask,
3281                                bool enabled)
3282{
3283        struct alc_spec *spec = codec->spec;
3284        unsigned int oldval = spec->gpio_led;
3285
3286        if (spec->mute_led_polarity)
3287                enabled = !enabled;
3288
3289        if (enabled)
3290                spec->gpio_led &= ~mask;
3291        else
3292                spec->gpio_led |= mask;
3293        if (spec->gpio_led != oldval)
3294                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3295                                    spec->gpio_led);
3296}
3297
3298/* turn on/off mute LED via GPIO per vmaster hook */
3299static void alc_fixup_gpio_mute_hook(void *private_data, int enabled)
3300{
3301        struct hda_codec *codec = private_data;
3302        struct alc_spec *spec = codec->spec;
3303
3304        alc_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
3305}
3306
3307/* turn on/off mic-mute LED via GPIO per capture hook */
3308static void alc_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
3309                                         struct snd_kcontrol *kcontrol,
3310                                         struct snd_ctl_elem_value *ucontrol)
3311{
3312        struct alc_spec *spec = codec->spec;
3313
3314        if (ucontrol)
3315                alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
3316                                    ucontrol->value.integer.value[0] ||
3317                                    ucontrol->value.integer.value[1]);
3318}
3319
3320static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
3321                                const struct hda_fixup *fix, int action)
3322{
3323        struct alc_spec *spec = codec->spec;
3324        static const struct hda_verb gpio_init[] = {
3325                { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3326                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3327                {}
3328        };
3329
3330        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3331                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3332                spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3333                spec->gpio_led = 0;
3334                spec->mute_led_polarity = 0;
3335                spec->gpio_mute_led_mask = 0x08;
3336                spec->gpio_mic_led_mask = 0x10;
3337                snd_hda_add_verbs(codec, gpio_init);
3338        }
3339}
3340
3341static void alc286_fixup_hp_gpio_led(struct hda_codec *codec,
3342                                const struct hda_fixup *fix, int action)
3343{
3344        struct alc_spec *spec = codec->spec;
3345        static const struct hda_verb gpio_init[] = {
3346                { 0x01, AC_VERB_SET_GPIO_MASK, 0x22 },
3347                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x22 },
3348                {}
3349        };
3350
3351        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3352                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3353                spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3354                spec->gpio_led = 0;
3355                spec->mute_led_polarity = 0;
3356                spec->gpio_mute_led_mask = 0x02;
3357                spec->gpio_mic_led_mask = 0x20;
3358                snd_hda_add_verbs(codec, gpio_init);
3359        }
3360}
3361
3362/* turn on/off mic-mute LED per capture hook */
3363static void alc269_fixup_hp_cap_mic_mute_hook(struct hda_codec *codec,
3364                                               struct snd_kcontrol *kcontrol,
3365                                               struct snd_ctl_elem_value *ucontrol)
3366{
3367        struct alc_spec *spec = codec->spec;
3368        unsigned int pinval, enable, disable;
3369
3370        pinval = snd_hda_codec_get_pin_target(codec, spec->cap_mute_led_nid);
3371        pinval &= ~AC_PINCTL_VREFEN;
3372        enable  = pinval | AC_PINCTL_VREF_80;
3373        disable = pinval | AC_PINCTL_VREF_HIZ;
3374
3375        if (!ucontrol)
3376                return;
3377
3378        if (ucontrol->value.integer.value[0] ||
3379            ucontrol->value.integer.value[1])
3380                pinval = disable;
3381        else
3382                pinval = enable;
3383
3384        if (spec->cap_mute_led_nid)
3385                snd_hda_set_pin_ctl_cache(codec, spec->cap_mute_led_nid, pinval);
3386}
3387
3388static void alc269_fixup_hp_gpio_mic1_led(struct hda_codec *codec,
3389                                const struct hda_fixup *fix, int action)
3390{
3391        struct alc_spec *spec = codec->spec;
3392        static const struct hda_verb gpio_init[] = {
3393                { 0x01, AC_VERB_SET_GPIO_MASK, 0x08 },
3394                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x08 },
3395                {}
3396        };
3397
3398        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3399                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3400                spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3401                spec->gpio_led = 0;
3402                spec->mute_led_polarity = 0;
3403                spec->gpio_mute_led_mask = 0x08;
3404                spec->cap_mute_led_nid = 0x18;
3405                snd_hda_add_verbs(codec, gpio_init);
3406                codec->power_filter = led_power_filter;
3407        }
3408}
3409
3410static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
3411                                   const struct hda_fixup *fix, int action)
3412{
3413        /* Like hp_gpio_mic1_led, but also needs GPIO4 low to enable headphone amp */
3414        struct alc_spec *spec = codec->spec;
3415        static const struct hda_verb gpio_init[] = {
3416                { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
3417                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
3418                {}
3419        };
3420
3421        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3422                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3423                spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3424                spec->gpio_led = 0;
3425                spec->mute_led_polarity = 0;
3426                spec->gpio_mute_led_mask = 0x08;
3427                spec->cap_mute_led_nid = 0x18;
3428                snd_hda_add_verbs(codec, gpio_init);
3429                codec->power_filter = led_power_filter;
3430        }
3431}
3432
3433static void gpio2_mic_hotkey_event(struct hda_codec *codec,
3434                                   struct hda_jack_callback *event)
3435{
3436        struct alc_spec *spec = codec->spec;
3437
3438        /* GPIO2 just toggles on a keypress/keyrelease cycle. Therefore
3439           send both key on and key off event for every interrupt. */
3440        input_report_key(spec->kb_dev, KEY_MICMUTE, 1);
3441        input_sync(spec->kb_dev);
3442        input_report_key(spec->kb_dev, KEY_MICMUTE, 0);
3443        input_sync(spec->kb_dev);
3444}
3445
3446static void alc280_fixup_hp_gpio2_mic_hotkey(struct hda_codec *codec,
3447                                             const struct hda_fixup *fix, int action)
3448{
3449        /* GPIO1 = set according to SKU external amp
3450           GPIO2 = mic mute hotkey
3451           GPIO3 = mute LED
3452           GPIO4 = mic mute LED */
3453        static const struct hda_verb gpio_init[] = {
3454                { 0x01, AC_VERB_SET_GPIO_MASK, 0x1e },
3455                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x1a },
3456                { 0x01, AC_VERB_SET_GPIO_DATA, 0x02 },
3457                {}
3458        };
3459
3460        struct alc_spec *spec = codec->spec;
3461
3462        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3463                spec->kb_dev = input_allocate_device();
3464                if (!spec->kb_dev) {
3465                        codec_err(codec, "Out of memory (input_allocate_device)\n");
3466                        return;
3467                }
3468                spec->kb_dev->name = "Microphone Mute Button";
3469                spec->kb_dev->evbit[0] = BIT_MASK(EV_KEY);
3470                spec->kb_dev->keybit[BIT_WORD(KEY_MICMUTE)] = BIT_MASK(KEY_MICMUTE);
3471                if (input_register_device(spec->kb_dev)) {
3472                        codec_err(codec, "input_register_device failed\n");
3473                        input_free_device(spec->kb_dev);
3474                        spec->kb_dev = NULL;
3475                        return;
3476                }
3477
3478                snd_hda_add_verbs(codec, gpio_init);
3479                snd_hda_codec_write_cache(codec, codec->core.afg, 0,
3480                                          AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x04);
3481                snd_hda_jack_detect_enable_callback(codec, codec->core.afg,
3482                                                    gpio2_mic_hotkey_event);
3483
3484                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
3485                spec->gen.cap_sync_hook = alc_fixup_gpio_mic_mute_hook;
3486                spec->gpio_led = 0;
3487                spec->mute_led_polarity = 0;
3488                spec->gpio_mute_led_mask = 0x08;
3489                spec->gpio_mic_led_mask = 0x10;
3490                return;
3491        }
3492
3493        if (!spec->kb_dev)
3494                return;
3495
3496        switch (action) {
3497        case HDA_FIXUP_ACT_PROBE:
3498                spec->init_amp = ALC_INIT_DEFAULT;
3499                break;
3500        case HDA_FIXUP_ACT_FREE:
3501                input_unregister_device(spec->kb_dev);
3502                spec->kb_dev = NULL;
3503        }
3504}
3505
3506static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
3507                                const struct hda_fixup *fix, int action)
3508{
3509        struct alc_spec *spec = codec->spec;
3510
3511        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
3512                spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook;
3513                spec->gen.cap_sync_hook = alc269_fixup_hp_cap_mic_mute_hook;
3514                spec->mute_led_polarity = 0;
3515                spec->mute_led_nid = 0x1a;
3516                spec->cap_mute_led_nid = 0x18;
3517                spec->gen.vmaster_mute_enum = 1;
3518                codec->power_filter = led_power_filter;
3519        }
3520}
3521
3522static void alc_headset_mode_unplugged(struct hda_codec *codec)
3523{
3524        static struct coef_fw coef0255[] = {
3525                WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
3526                WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
3527                UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
3528                WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
3529                WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
3530                {}
3531        };
3532        static struct coef_fw coef0233[] = {
3533                WRITE_COEF(0x1b, 0x0c0b),
3534                WRITE_COEF(0x45, 0xc429),
3535                UPDATE_COEF(0x35, 0x4000, 0),
3536                WRITE_COEF(0x06, 0x2104),
3537                WRITE_COEF(0x1a, 0x0001),
3538                WRITE_COEF(0x26, 0x0004),
3539                WRITE_COEF(0x32, 0x42a3),
3540                {}
3541        };
3542        static struct coef_fw coef0288[] = {
3543                UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3544                UPDATE_COEF(0x50, 0x2000, 0x2000),
3545                UPDATE_COEF(0x56, 0x0006, 0x0006),
3546                UPDATE_COEF(0x66, 0x0008, 0),
3547                UPDATE_COEF(0x67, 0x2000, 0),
3548                {}
3549        };
3550        static struct coef_fw coef0292[] = {
3551                WRITE_COEF(0x76, 0x000e),
3552                WRITE_COEF(0x6c, 0x2400),
3553                WRITE_COEF(0x18, 0x7308),
3554                WRITE_COEF(0x6b, 0xc429),
3555                {}
3556        };
3557        static struct coef_fw coef0293[] = {
3558                UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */
3559                UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */
3560                UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */
3561                UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */
3562                WRITE_COEF(0x45, 0xc429), /* Set to TRS type */
3563                UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3564                {}
3565        };
3566        static struct coef_fw coef0668[] = {
3567                WRITE_COEF(0x15, 0x0d40),
3568                WRITE_COEF(0xb7, 0x802b),
3569                {}
3570        };
3571
3572        switch (codec->core.vendor_id) {
3573        case 0x10ec0255:
3574        case 0x10ec0256:
3575                alc_process_coef_fw(codec, coef0255);
3576                break;
3577        case 0x10ec0233:
3578        case 0x10ec0283:
3579                alc_process_coef_fw(codec, coef0233);
3580                break;
3581        case 0x10ec0286:
3582        case 0x10ec0288:
3583        case 0x10ec0298:
3584                alc_process_coef_fw(codec, coef0288);
3585                break;
3586        case 0x10ec0292:
3587                alc_process_coef_fw(codec, coef0292);
3588                break;
3589        case 0x10ec0293:
3590                alc_process_coef_fw(codec, coef0293);
3591                break;
3592        case 0x10ec0668:
3593                alc_process_coef_fw(codec, coef0668);
3594                break;
3595        }
3596        codec_dbg(codec, "Headset jack set to unplugged mode.\n");
3597}
3598
3599
3600static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
3601                                    hda_nid_t mic_pin)
3602{
3603        static struct coef_fw coef0255[] = {
3604                WRITE_COEFEX(0x57, 0x03, 0x8aa6),
3605                WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */
3606                {}
3607        };
3608        static struct coef_fw coef0233[] = {
3609                UPDATE_COEF(0x35, 0, 1<<14),
3610                WRITE_COEF(0x06, 0x2100),
3611                WRITE_COEF(0x1a, 0x0021),
3612                WRITE_COEF(0x26, 0x008c),
3613                {}
3614        };
3615        static struct coef_fw coef0288[] = {
3616                UPDATE_COEF(0x50, 0x2000, 0),
3617                UPDATE_COEF(0x56, 0x0006, 0),
3618                UPDATE_COEF(0x4f, 0xfcc0, 0xc400),
3619                UPDATE_COEF(0x66, 0x0008, 0x0008),
3620                UPDATE_COEF(0x67, 0x2000, 0x2000),
3621                {}
3622        };
3623        static struct coef_fw coef0292[] = {
3624                WRITE_COEF(0x19, 0xa208),
3625                WRITE_COEF(0x2e, 0xacf0),
3626                {}
3627        };
3628        static struct coef_fw coef0293[] = {
3629                UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */
3630                UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */
3631                UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3632                {}
3633        };
3634        static struct coef_fw coef0688[] = {
3635                WRITE_COEF(0xb7, 0x802b),
3636                WRITE_COEF(0xb5, 0x1040),
3637                UPDATE_COEF(0xc3, 0, 1<<12),
3638                {}
3639        };
3640
3641        switch (codec->core.vendor_id) {
3642        case 0x10ec0255:
3643        case 0x10ec0256:
3644                alc_write_coef_idx(codec, 0x45, 0xc489);
3645                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3646                alc_process_coef_fw(codec, coef0255);
3647                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3648                break;
3649        case 0x10ec0233:
3650        case 0x10ec0283:
3651                alc_write_coef_idx(codec, 0x45, 0xc429);
3652                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3653                alc_process_coef_fw(codec, coef0233);
3654                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3655                break;
3656        case 0x10ec0286:
3657        case 0x10ec0288:
3658        case 0x10ec0298:
3659                alc_update_coef_idx(codec, 0x4f, 0x000c, 0);
3660                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3661                alc_process_coef_fw(codec, coef0288);
3662                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3663                break;
3664        case 0x10ec0292:
3665                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3666                alc_process_coef_fw(codec, coef0292);
3667                break;
3668        case 0x10ec0293:
3669                /* Set to TRS mode */
3670                alc_write_coef_idx(codec, 0x45, 0xc429);
3671                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3672                alc_process_coef_fw(codec, coef0293);
3673                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3674                break;
3675        case 0x10ec0662:
3676                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3677                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3678                break;
3679        case 0x10ec0668:
3680                alc_write_coef_idx(codec, 0x11, 0x0001);
3681                snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
3682                alc_process_coef_fw(codec, coef0688);
3683                snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
3684                break;
3685        }
3686        codec_dbg(codec, "Headset jack set to mic-in mode.\n");
3687}
3688
3689static void alc_headset_mode_default(struct hda_codec *codec)
3690{
3691        static struct coef_fw coef0255[] = {
3692                WRITE_COEF(0x45, 0xc089),
3693                WRITE_COEF(0x45, 0xc489),
3694                WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3695                WRITE_COEF(0x49, 0x0049),
3696                {}
3697        };
3698        static struct coef_fw coef0233[] = {
3699                WRITE_COEF(0x06, 0x2100),
3700                WRITE_COEF(0x32, 0x4ea3),
3701                {}
3702        };
3703        static struct coef_fw coef0288[] = {
3704                UPDATE_COEF(0x4f, 0xfcc0, 0xc400), /* Set to TRS type */
3705                UPDATE_COEF(0x50, 0x2000, 0x2000),
3706                UPDATE_COEF(0x56, 0x0006, 0x0006),
3707                UPDATE_COEF(0x66, 0x0008, 0),
3708                UPDATE_COEF(0x67, 0x2000, 0),
3709                {}
3710        };
3711        static struct coef_fw coef0292[] = {
3712                WRITE_COEF(0x76, 0x000e),
3713                WRITE_COEF(0x6c, 0x2400),
3714                WRITE_COEF(0x6b, 0xc429),
3715                WRITE_COEF(0x18, 0x7308),
3716                {}
3717        };
3718        static struct coef_fw coef0293[] = {
3719                UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */
3720                WRITE_COEF(0x45, 0xC429), /* Set to TRS type */
3721                UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */
3722                {}
3723        };
3724        static struct coef_fw coef0688[] = {
3725                WRITE_COEF(0x11, 0x0041),
3726                WRITE_COEF(0x15, 0x0d40),
3727                WRITE_COEF(0xb7, 0x802b),
3728                {}
3729        };
3730
3731        switch (codec->core.vendor_id) {
3732        case 0x10ec0255:
3733        case 0x10ec0256:
3734                alc_process_coef_fw(codec, coef0255);
3735                break;
3736        case 0x10ec0233:
3737        case 0x10ec0283:
3738                alc_process_coef_fw(codec, coef0233);
3739                break;
3740        case 0x10ec0286:
3741        case 0x10ec0288:
3742        case 0x10ec0298:
3743                alc_process_coef_fw(codec, coef0288);
3744                break;
3745        case 0x10ec0292:
3746                alc_process_coef_fw(codec, coef0292);
3747                break;
3748        case 0x10ec0293:
3749                alc_process_coef_fw(codec, coef0293);
3750                break;
3751        case 0x10ec0668:
3752                alc_process_coef_fw(codec, coef0688);
3753                break;
3754        }
3755        codec_dbg(codec, "Headset jack set to headphone (default) mode.\n");
3756}
3757
3758/* Iphone type */
3759static void alc_headset_mode_ctia(struct hda_codec *codec)
3760{
3761        static struct coef_fw coef0255[] = {
3762                WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
3763                WRITE_COEF(0x1b, 0x0c2b),
3764                WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3765                {}
3766        };
3767        static struct coef_fw coef0233[] = {
3768                WRITE_COEF(0x45, 0xd429),
3769                WRITE_COEF(0x1b, 0x0c2b),
3770                WRITE_COEF(0x32, 0x4ea3),
3771                {}
3772        };
3773        static struct coef_fw coef0288[] = {
3774                UPDATE_COEF(0x50, 0x2000, 0x2000),
3775                UPDATE_COEF(0x56, 0x0006, 0x0006),
3776                UPDATE_COEF(0x66, 0x0008, 0),
3777                UPDATE_COEF(0x67, 0x2000, 0),
3778                {}
3779        };
3780        static struct coef_fw coef0292[] = {
3781                WRITE_COEF(0x6b, 0xd429),
3782                WRITE_COEF(0x76, 0x0008),
3783                WRITE_COEF(0x18, 0x7388),
3784                {}
3785        };
3786        static struct coef_fw coef0293[] = {
3787                WRITE_COEF(0x45, 0xd429), /* Set to ctia type */
3788                UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3789                {}
3790        };
3791        static struct coef_fw coef0688[] = {
3792                WRITE_COEF(0x11, 0x0001),
3793                WRITE_COEF(0x15, 0x0d60),
3794                WRITE_COEF(0xc3, 0x0000),
3795                {}
3796        };
3797
3798        switch (codec->core.vendor_id) {
3799        case 0x10ec0255:
3800        case 0x10ec0256:
3801                alc_process_coef_fw(codec, coef0255);
3802                break;
3803        case 0x10ec0233:
3804        case 0x10ec0283:
3805                alc_process_coef_fw(codec, coef0233);
3806                break;
3807        case 0x10ec0298:
3808                alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020);/* Headset output enable */
3809                /* ALC298 jack type setting is the same with ALC286/ALC288 */
3810        case 0x10ec0286:
3811        case 0x10ec0288:
3812                alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xd400);
3813                msleep(300);
3814                alc_process_coef_fw(codec, coef0288);
3815                break;
3816        case 0x10ec0292:
3817                alc_process_coef_fw(codec, coef0292);
3818                break;
3819        case 0x10ec0293:
3820                alc_process_coef_fw(codec, coef0293);
3821                break;
3822        case 0x10ec0668:
3823                alc_process_coef_fw(codec, coef0688);
3824                break;
3825        }
3826        codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n");
3827}
3828
3829/* Nokia type */
3830static void alc_headset_mode_omtp(struct hda_codec *codec)
3831{
3832        static struct coef_fw coef0255[] = {
3833                WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
3834                WRITE_COEF(0x1b, 0x0c2b),
3835                WRITE_COEFEX(0x57, 0x03, 0x8ea6),
3836                {}
3837        };
3838        static struct coef_fw coef0233[] = {
3839                WRITE_COEF(0x45, 0xe429),
3840                WRITE_COEF(0x1b, 0x0c2b),
3841                WRITE_COEF(0x32, 0x4ea3),
3842                {}
3843        };
3844        static struct coef_fw coef0288[] = {
3845                UPDATE_COEF(0x50, 0x2000, 0x2000),
3846                UPDATE_COEF(0x56, 0x0006, 0x0006),
3847                UPDATE_COEF(0x66, 0x0008, 0),
3848                UPDATE_COEF(0x67, 0x2000, 0),
3849                {}
3850        };
3851        static struct coef_fw coef0292[] = {
3852                WRITE_COEF(0x6b, 0xe429),
3853                WRITE_COEF(0x76, 0x0008),
3854                WRITE_COEF(0x18, 0x7388),
3855                {}
3856        };
3857        static struct coef_fw coef0293[] = {
3858                WRITE_COEF(0x45, 0xe429), /* Set to omtp type */
3859                UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */
3860                {}
3861        };
3862        static struct coef_fw coef0688[] = {
3863                WRITE_COEF(0x11, 0x0001),
3864                WRITE_COEF(0x15, 0x0d50),
3865                WRITE_COEF(0xc3, 0x0000),
3866                {}
3867        };
3868
3869        switch (codec->core.vendor_id) {
3870        case 0x10ec0255:
3871        case 0x10ec0256:
3872                alc_process_coef_fw(codec, coef0255);
3873                break;
3874        case 0x10ec0233:
3875        case 0x10ec0283:
3876                alc_process_coef_fw(codec, coef0233);
3877                break;
3878        case 0x10ec0298:
3879                alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0010);/* Headset output enable */
3880                /* ALC298 jack type setting is the same with ALC286/ALC288 */
3881        case 0x10ec0286:
3882        case 0x10ec0288:
3883                alc_update_coef_idx(codec, 0x4f, 0xfcc0, 0xe400);
3884                msleep(300);
3885                alc_process_coef_fw(codec, coef0288);
3886                break;
3887        case 0x10ec0292:
3888                alc_process_coef_fw(codec, coef0292);
3889                break;
3890        case 0x10ec0293:
3891                alc_process_coef_fw(codec, coef0293);
3892                break;
3893        case 0x10ec0668:
3894                alc_process_coef_fw(codec, coef0688);
3895                break;
3896        }
3897        codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n");
3898}
3899
3900static void alc_determine_headset_type(struct hda_codec *codec)
3901{
3902        int val;
3903        bool is_ctia = false;
3904        struct alc_spec *spec = codec->spec;
3905        static struct coef_fw coef0255[] = {
3906                WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/
3907                WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref
3908 conteol) */
3909                {}
3910        };
3911        static struct coef_fw coef0288[] = {
3912                UPDATE_COEF(0x4f, 0xfcc0, 0xd400), /* Check Type */
3913                {}
3914        };
3915        static struct coef_fw coef0293[] = {
3916                UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */
3917                WRITE_COEF(0x45, 0xD429), /* Set to ctia type */
3918                {}
3919        };
3920        static struct coef_fw coef0688[] = {
3921                WRITE_COEF(0x11, 0x0001),
3922                WRITE_COEF(0xb7, 0x802b),
3923                WRITE_COEF(0x15, 0x0d60),
3924                WRITE_COEF(0xc3, 0x0c00),
3925                {}
3926        };
3927
3928        switch (codec->core.vendor_id) {
3929        case 0x10ec0255:
3930        case 0x10ec0256:
3931                alc_process_coef_fw(codec, coef0255);
3932                msleep(300);
3933                val = alc_read_coef_idx(codec, 0x46);
3934                is_ctia = (val & 0x0070) == 0x0070;
3935                break;
3936        case 0x10ec0233:
3937        case 0x10ec0283:
3938                alc_write_coef_idx(codec, 0x45, 0xd029);
3939                msleep(300);
3940                val = alc_read_coef_idx(codec, 0x46);
3941                is_ctia = (val & 0x0070) == 0x0070;
3942                break;
3943        case 0x10ec0298:
3944                alc_update_coef_idx(codec, 0x8e, 0x0070, 0x0020); /* Headset output enable */
3945                /* ALC298 check jack type is the same with ALC286/ALC288 */
3946        case 0x10ec0286:
3947        case 0x10ec0288:
3948                alc_process_coef_fw(codec, coef0288);
3949                msleep(350);
3950                val = alc_read_coef_idx(codec, 0x50);
3951                is_ctia = (val & 0x0070) == 0x0070;
3952                break;
3953        case 0x10ec0292:
3954                alc_write_coef_idx(codec, 0x6b, 0xd429);
3955                msleep(300);
3956                val = alc_read_coef_idx(codec, 0x6c);
3957                is_ctia = (val & 0x001c) == 0x001c;
3958                break;
3959        case 0x10ec0293:
3960                alc_process_coef_fw(codec, coef0293);
3961                msleep(300);
3962                val = alc_read_coef_idx(codec, 0x46);
3963                is_ctia = (val & 0x0070) == 0x0070;
3964                break;
3965        case 0x10ec0668:
3966                alc_process_coef_fw(codec, coef0688);
3967                msleep(300);
3968                val = alc_read_coef_idx(codec, 0xbe);
3969                is_ctia = (val & 0x1c02) == 0x1c02;
3970                break;
3971        }
3972
3973        codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n",
3974                    is_ctia ? "yes" : "no");
3975        spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP;
3976}
3977
3978static void alc_update_headset_mode(struct hda_codec *codec)
3979{
3980        struct alc_spec *spec = codec->spec;
3981
3982        hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3983        hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
3984
3985        int new_headset_mode;
3986
3987        if (!snd_hda_jack_detect(codec, hp_pin))
3988                new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED;
3989        else if (mux_pin == spec->headset_mic_pin)
3990                new_headset_mode = ALC_HEADSET_MODE_HEADSET;
3991        else if (mux_pin == spec->headphone_mic_pin)
3992                new_headset_mode = ALC_HEADSET_MODE_MIC;
3993        else
3994                new_headset_mode = ALC_HEADSET_MODE_HEADPHONE;
3995
3996        if (new_headset_mode == spec->current_headset_mode) {
3997                snd_hda_gen_update_outputs(codec);
3998                return;
3999        }
4000
4001        switch (new_headset_mode) {
4002        case ALC_HEADSET_MODE_UNPLUGGED:
4003                alc_headset_mode_unplugged(codec);
4004                spec->gen.hp_jack_present = false;
4005                break;
4006        case ALC_HEADSET_MODE_HEADSET:
4007                if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN)
4008                        alc_determine_headset_type(codec);
4009                if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA)
4010                        alc_headset_mode_ctia(codec);
4011                else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP)
4012                        alc_headset_mode_omtp(codec);
4013                spec->gen.hp_jack_present = true;
4014                break;
4015        case ALC_HEADSET_MODE_MIC:
4016                alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin);
4017                spec->gen.hp_jack_present = false;
4018                break;
4019        case ALC_HEADSET_MODE_HEADPHONE:
4020                alc_headset_mode_default(codec);
4021                spec->gen.hp_jack_present = true;
4022                break;
4023        }
4024        if (new_headset_mode != ALC_HEADSET_MODE_MIC) {
4025                snd_hda_set_pin_ctl_cache(codec, hp_pin,
4026                                          AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
4027                if (spec->headphone_mic_pin && spec->headphone_mic_pin != hp_pin)
4028                        snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin,
4029                                                  PIN_VREFHIZ);
4030        }
4031        spec->current_headset_mode = new_headset_mode;
4032
4033        snd_hda_gen_update_outputs(codec);
4034}
4035
4036static void alc_update_headset_mode_hook(struct hda_codec *codec,
4037                                         struct snd_kcontrol *kcontrol,
4038                                         struct snd_ctl_elem_value *ucontrol)
4039{
4040        alc_update_headset_mode(codec);
4041}
4042
4043static void alc_update_headset_jack_cb(struct hda_codec *codec,
4044                                       struct hda_jack_callback *jack)
4045{
4046        struct alc_spec *spec = codec->spec;
4047        spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN;
4048        snd_hda_gen_hp_automute(codec, jack);
4049}
4050
4051static void alc_probe_headset_mode(struct hda_codec *codec)
4052{
4053        int i;
4054        struct alc_spec *spec = codec->spec;
4055        struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4056
4057        /* Find mic pins */
4058        for (i = 0; i < cfg->num_inputs; i++) {
4059                if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin)
4060                        spec->headset_mic_pin = cfg->inputs[i].pin;
4061                if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin)
4062                        spec->headphone_mic_pin = cfg->inputs[i].pin;
4063        }
4064
4065        spec->gen.cap_sync_hook = alc_update_headset_mode_hook;
4066        spec->gen.automute_hook = alc_update_headset_mode;
4067        spec->gen.hp_automute_hook = alc_update_headset_jack_cb;
4068}
4069
4070static void alc_fixup_headset_mode(struct hda_codec *codec,
4071                                const struct hda_fixup *fix, int action)
4072{
4073        struct alc_spec *spec = codec->spec;
4074
4075        switch (action) {
4076        case HDA_FIXUP_ACT_PRE_PROBE:
4077                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC;
4078                break;
4079        case HDA_FIXUP_ACT_PROBE:
4080                alc_probe_headset_mode(codec);
4081                break;
4082        case HDA_FIXUP_ACT_INIT:
4083                spec->current_headset_mode = 0;
4084                alc_update_headset_mode(codec);
4085                break;
4086        }
4087}
4088
4089static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
4090                                const struct hda_fixup *fix, int action)
4091{
4092        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4093                struct alc_spec *spec = codec->spec;
4094                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4095        }
4096        else
4097                alc_fixup_headset_mode(codec, fix, action);
4098}
4099
4100static void alc255_set_default_jack_type(struct hda_codec *codec)
4101{
4102        /* Set to iphone type */
4103        static struct coef_fw fw[] = {
4104                WRITE_COEF(0x1b, 0x880b),
4105                WRITE_COEF(0x45, 0xd089),
4106                WRITE_COEF(0x1b, 0x080b),
4107                WRITE_COEF(0x46, 0x0004),
4108                WRITE_COEF(0x1b, 0x0c0b),
4109                {}
4110        };
4111        alc_process_coef_fw(codec, fw);
4112        msleep(30);
4113}
4114
4115static void alc_fixup_headset_mode_alc255(struct hda_codec *codec,
4116                                const struct hda_fixup *fix, int action)
4117{
4118        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4119                alc255_set_default_jack_type(codec);
4120        }
4121        alc_fixup_headset_mode(codec, fix, action);
4122}
4123
4124static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec,
4125                                const struct hda_fixup *fix, int action)
4126{
4127        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4128                struct alc_spec *spec = codec->spec;
4129                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4130                alc255_set_default_jack_type(codec);
4131        } 
4132        else
4133                alc_fixup_headset_mode(codec, fix, action);
4134}
4135
4136static void alc288_update_headset_jack_cb(struct hda_codec *codec,
4137                                       struct hda_jack_callback *jack)
4138{
4139        struct alc_spec *spec = codec->spec;
4140        int present;
4141
4142        alc_update_headset_jack_cb(codec, jack);
4143        /* Headset Mic enable or disable, only for Dell Dino */
4144        present = spec->gen.hp_jack_present ? 0x40 : 0;
4145        snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4146                                present);
4147}
4148
4149static void alc_fixup_headset_mode_dell_alc288(struct hda_codec *codec,
4150                                const struct hda_fixup *fix, int action)
4151{
4152        alc_fixup_headset_mode(codec, fix, action);
4153        if (action == HDA_FIXUP_ACT_PROBE) {
4154                struct alc_spec *spec = codec->spec;
4155                spec->gen.hp_automute_hook = alc288_update_headset_jack_cb;
4156        }
4157}
4158
4159static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec,
4160                                        const struct hda_fixup *fix, int action)
4161{
4162        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4163                struct alc_spec *spec = codec->spec;
4164                spec->gen.auto_mute_via_amp = 1;
4165        }
4166}
4167
4168static void alc_no_shutup(struct hda_codec *codec)
4169{
4170}
4171
4172static void alc_fixup_no_shutup(struct hda_codec *codec,
4173                                const struct hda_fixup *fix, int action)
4174{
4175        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4176                struct alc_spec *spec = codec->spec;
4177                spec->shutup = alc_no_shutup;
4178        }
4179}
4180
4181static void alc_fixup_disable_aamix(struct hda_codec *codec,
4182                                    const struct hda_fixup *fix, int action)
4183{
4184        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4185                struct alc_spec *spec = codec->spec;
4186                /* Disable AA-loopback as it causes white noise */
4187                spec->gen.mixer_nid = 0;
4188        }
4189}
4190
4191/* fixup for Thinkpad docks: add dock pins, avoid HP parser fixup */
4192static void alc_fixup_tpt440_dock(struct hda_codec *codec,
4193                                  const struct hda_fixup *fix, int action)
4194{
4195        static const struct hda_pintbl pincfgs[] = {
4196                { 0x16, 0x21211010 }, /* dock headphone */
4197                { 0x19, 0x21a11010 }, /* dock mic */
4198                { }
4199        };
4200        struct alc_spec *spec = codec->spec;
4201
4202        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4203                spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
4204                codec->power_save_node = 0; /* avoid click noises */
4205                snd_hda_apply_pincfgs(codec, pincfgs);
4206        }
4207}
4208
4209static void alc_shutup_dell_xps13(struct hda_codec *codec)
4210{
4211        struct alc_spec *spec = codec->spec;
4212        int hp_pin = spec->gen.autocfg.hp_pins[0];
4213
4214        /* Prevent pop noises when headphones are plugged in */
4215        snd_hda_codec_write(codec, hp_pin, 0,
4216                            AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
4217        msleep(20);
4218}
4219
4220static void alc_fixup_dell_xps13(struct hda_codec *codec,
4221                                const struct hda_fixup *fix, int action)
4222{
4223        struct alc_spec *spec = codec->spec;
4224        struct hda_input_mux *imux = &spec->gen.input_mux;
4225        int i;
4226
4227        switch (action) {
4228        case HDA_FIXUP_ACT_PRE_PROBE:
4229                /* mic pin 0x19 must be initialized with Vref Hi-Z, otherwise
4230                 * it causes a click noise at start up
4231                 */
4232                snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
4233                break;
4234        case HDA_FIXUP_ACT_PROBE:
4235                spec->shutup = alc_shutup_dell_xps13;
4236
4237                /* Make the internal mic the default input source. */
4238                for (i = 0; i < imux->num_items; i++) {
4239                        if (spec->gen.imux_pins[i] == 0x12) {
4240                                spec->gen.cur_mux[0] = i;
4241                                break;
4242                        }
4243                }
4244                break;
4245        }
4246}
4247
4248static void alc_fixup_headset_mode_alc662(struct hda_codec *codec,
4249                                const struct hda_fixup *fix, int action)
4250{
4251        struct alc_spec *spec = codec->spec;
4252
4253        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4254                spec->parse_flags |= HDA_PINCFG_HEADSET_MIC;
4255                spec->gen.hp_mic = 1; /* Mic-in is same pin as headphone */
4256
4257                /* Disable boost for mic-in permanently. (This code is only called
4258                   from quirks that guarantee that the headphone is at NID 0x1b.) */
4259                snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000);
4260                snd_hda_override_wcaps(codec, 0x1b, get_wcaps(codec, 0x1b) & ~AC_WCAP_IN_AMP);
4261        } else
4262                alc_fixup_headset_mode(codec, fix, action);
4263}
4264
4265static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
4266                                const struct hda_fixup *fix, int action)
4267{
4268        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4269                alc_write_coef_idx(codec, 0xc4, 0x8000);
4270                alc_update_coef_idx(codec, 0xc2, ~0xfe, 0);
4271                snd_hda_set_pin_ctl_cache(codec, 0x18, 0);
4272        }
4273        alc_fixup_headset_mode(codec, fix, action);
4274}
4275
4276/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
4277static int find_ext_mic_pin(struct hda_codec *codec)
4278{
4279        struct alc_spec *spec = codec->spec;
4280        struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4281        hda_nid_t nid;
4282        unsigned int defcfg;
4283        int i;
4284
4285        for (i = 0; i < cfg->num_inputs; i++) {
4286                if (cfg->inputs[i].type != AUTO_PIN_MIC)
4287                        continue;
4288                nid = cfg->inputs[i].pin;
4289                defcfg = snd_hda_codec_get_pincfg(codec, nid);
4290                if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
4291                        continue;
4292                return nid;
4293        }
4294
4295        return 0;
4296}
4297
4298static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
4299                                    const struct hda_fixup *fix,
4300                                    int action)
4301{
4302        struct alc_spec *spec = codec->spec;
4303
4304        if (action == HDA_FIXUP_ACT_PROBE) {
4305                int mic_pin = find_ext_mic_pin(codec);
4306                int hp_pin = spec->gen.autocfg.hp_pins[0];
4307
4308                if (snd_BUG_ON(!mic_pin || !hp_pin))
4309                        return;
4310                snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
4311        }
4312}
4313
4314static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
4315                                             const struct hda_fixup *fix,
4316                                             int action)
4317{
4318        struct alc_spec *spec = codec->spec;
4319        struct auto_pin_cfg *cfg = &spec->gen.autocfg;
4320        int i;
4321
4322        /* The mic boosts on level 2 and 3 are too noisy
4323           on the internal mic input.
4324           Therefore limit the boost to 0 or 1. */
4325
4326        if (action != HDA_FIXUP_ACT_PROBE)
4327                return;
4328
4329        for (i = 0; i < cfg->num_inputs; i++) {
4330                hda_nid_t nid = cfg->inputs[i].pin;
4331                unsigned int defcfg;
4332                if (cfg->inputs[i].type != AUTO_PIN_MIC)
4333                        continue;
4334                defcfg = snd_hda_codec_get_pincfg(codec, nid);
4335                if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
4336                        continue;
4337
4338                snd_hda_override_amp_caps(codec, nid, HDA_INPUT,
4339                                          (0x00 << AC_AMPCAP_OFFSET_SHIFT) |
4340                                          (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4341                                          (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) |
4342                                          (0 << AC_AMPCAP_MUTE_SHIFT));
4343        }
4344}
4345
4346static void alc283_hp_automute_hook(struct hda_codec *codec,
4347                                    struct hda_jack_callback *jack)
4348{
4349        struct alc_spec *spec = codec->spec;
4350        int vref;
4351
4352        msleep(200);
4353        snd_hda_gen_hp_automute(codec, jack);
4354
4355        vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
4356
4357        msleep(600);
4358        snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4359                            vref);
4360}
4361
4362static void alc283_fixup_chromebook(struct hda_codec *codec,
4363                                    const struct hda_fixup *fix, int action)
4364{
4365        struct alc_spec *spec = codec->spec;
4366
4367        switch (action) {
4368        case HDA_FIXUP_ACT_PRE_PROBE:
4369                snd_hda_override_wcaps(codec, 0x03, 0);
4370                /* Disable AA-loopback as it causes white noise */
4371                spec->gen.mixer_nid = 0;
4372                break;
4373        case HDA_FIXUP_ACT_INIT:
4374                /* MIC2-VREF control */
4375                /* Set to manual mode */
4376                alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4377                /* Enable Line1 input control by verb */
4378                alc_update_coef_idx(codec, 0x1a, 0, 1 << 4);
4379                break;
4380        }
4381}
4382
4383static void alc283_fixup_sense_combo_jack(struct hda_codec *codec,
4384                                    const struct hda_fixup *fix, int action)
4385{
4386        struct alc_spec *spec = codec->spec;
4387
4388        switch (action) {
4389        case HDA_FIXUP_ACT_PRE_PROBE:
4390                spec->gen.hp_automute_hook = alc283_hp_automute_hook;
4391                break;
4392        case HDA_FIXUP_ACT_INIT:
4393                /* MIC2-VREF control */
4394                /* Set to manual mode */
4395                alc_update_coef_idx(codec, 0x06, 0x000c, 0);
4396                break;
4397        }
4398}
4399
4400/* mute tablet speaker pin (0x14) via dock plugging in addition */
4401static void asus_tx300_automute(struct hda_codec *codec)
4402{
4403        struct alc_spec *spec = codec->spec;
4404        snd_hda_gen_update_outputs(codec);
4405        if (snd_hda_jack_detect(codec, 0x1b))
4406                spec->gen.mute_bits |= (1ULL << 0x14);
4407}
4408
4409static void alc282_fixup_asus_tx300(struct hda_codec *codec,
4410                                    const struct hda_fixup *fix, int action)
4411{
4412        struct alc_spec *spec = codec->spec;
4413        /* TX300 needs to set up GPIO2 for the speaker amp */
4414        static const struct hda_verb gpio2_verbs[] = {
4415                { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 },
4416                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 },
4417                { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 },
4418                {}
4419        };
4420        static const struct hda_pintbl dock_pins[] = {
4421                { 0x1b, 0x21114000 }, /* dock speaker pin */
4422                {}
4423        };
4424        struct snd_kcontrol *kctl;
4425
4426        switch (action) {
4427        case HDA_FIXUP_ACT_PRE_PROBE:
4428                snd_hda_add_verbs(codec, gpio2_verbs);
4429                snd_hda_apply_pincfgs(codec, dock_pins);
4430                spec->gen.auto_mute_via_amp = 1;
4431                spec->gen.automute_hook = asus_tx300_automute;
4432                snd_hda_jack_detect_enable_callback(codec, 0x1b,
4433                                                    snd_hda_gen_hp_automute);
4434                break;
4435        case HDA_FIXUP_ACT_BUILD:
4436                /* this is a bit tricky; give more sane names for the main
4437                 * (tablet) speaker and the dock speaker, respectively
4438                 */
4439                kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
4440                if (kctl)
4441                        strcpy(kctl->id.name, "Dock Speaker Playback Switch");
4442                kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
4443                if (kctl)
4444                        strcpy(kctl->id.name, "Speaker Playback Switch");
4445                break;
4446        }
4447}
4448
4449static void alc290_fixup_mono_speakers(struct hda_codec *codec,
4450                                       const struct hda_fixup *fix, int action)
4451{
4452        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4453                /* DAC node 0x03 is giving mono output. We therefore want to
4454                   make sure 0x14 (front speaker) and 0x15 (headphones) use the
4455                   stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */
4456                hda_nid_t conn1[2] = { 0x0c };
4457                snd_hda_override_conn_list(codec, 0x14, 1, conn1);
4458                snd_hda_override_conn_list(codec, 0x15, 1, conn1);
4459        }
4460}
4461
4462/* Hook to update amp GPIO4 for automute */
4463static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
4464                                          struct hda_jack_callback *jack)
4465{
4466        struct alc_spec *spec = codec->spec;
4467
4468        snd_hda_gen_hp_automute(codec, jack);
4469        /* mute_led_polarity is set to 0, so we pass inverted value here */
4470        alc_update_gpio_led(codec, 0x10, !spec->gen.hp_jack_present);
4471}
4472
4473/* Manage GPIOs for HP EliteBook Folio 9480m.
4474 *
4475 * GPIO4 is the headphone amplifier power control
4476 * GPIO3 is the audio output mute indicator LED
4477 */
4478
4479static void alc280_fixup_hp_9480m(struct hda_codec *codec,
4480                                  const struct hda_fixup *fix,
4481                                  int action)
4482{
4483        struct alc_spec *spec = codec->spec;
4484        static const struct hda_verb gpio_init[] = {
4485                { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 },
4486                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 },
4487                {}
4488        };
4489
4490        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
4491                /* Set the hooks to turn the headphone amp on/off
4492                 * as needed
4493                 */
4494                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
4495                spec->gen.hp_automute_hook = alc280_hp_gpio4_automute_hook;
4496
4497                /* The GPIOs are currently off */
4498                spec->gpio_led = 0;
4499
4500                /* GPIO3 is connected to the output mute LED,
4501                 * high is on, low is off
4502                 */
4503                spec->mute_led_polarity = 0;
4504                spec->gpio_mute_led_mask = 0x08;
4505
4506                /* Initialize GPIO configuration */
4507                snd_hda_add_verbs(codec, gpio_init);
4508        }
4509}
4510
4511/* for hda_fixup_thinkpad_acpi() */
4512#include "thinkpad_helper.c"
4513
4514/* for dell wmi mic mute led */
4515#include "dell_wmi_helper.c"
4516
4517enum {
4518        ALC269_FIXUP_SONY_VAIO,
4519        ALC275_FIXUP_SONY_VAIO_GPIO2,
4520        ALC269_FIXUP_DELL_M101Z,
4521        ALC269_FIXUP_SKU_IGNORE,
4522        ALC269_FIXUP_ASUS_G73JW,
4523        ALC269_FIXUP_LENOVO_EAPD,
4524        ALC275_FIXUP_SONY_HWEQ,
4525        ALC275_FIXUP_SONY_DISABLE_AAMIX,
4526        ALC271_FIXUP_DMIC,
4527        ALC269_FIXUP_PCM_44K,
4528        ALC269_FIXUP_STEREO_DMIC,
4529        ALC269_FIXUP_HEADSET_MIC,
4530        ALC269_FIXUP_QUANTA_MUTE,
4531        ALC269_FIXUP_LIFEBOOK,
4532        ALC269_FIXUP_LIFEBOOK_EXTMIC,
4533        ALC269_FIXUP_LIFEBOOK_HP_PIN,
4534        ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT,
4535        ALC269_FIXUP_AMIC,
4536        ALC269_FIXUP_DMIC,
4537        ALC269VB_FIXUP_AMIC,
4538        ALC269VB_FIXUP_DMIC,
4539        ALC269_FIXUP_HP_MUTE_LED,
4540        ALC269_FIXUP_HP_MUTE_LED_MIC1,
4541        ALC269_FIXUP_HP_MUTE_LED_MIC2,
4542        ALC269_FIXUP_HP_GPIO_LED,
4543        ALC269_FIXUP_HP_GPIO_MIC1_LED,
4544        ALC269_FIXUP_HP_LINE1_MIC1_LED,
4545        ALC269_FIXUP_INV_DMIC,
4546        ALC269_FIXUP_LENOVO_DOCK,
4547        ALC269_FIXUP_NO_SHUTUP,
4548        ALC286_FIXUP_SONY_MIC_NO_PRESENCE,
4549        ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
4550        ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
4551        ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
4552        ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
4553        ALC269_FIXUP_HEADSET_MODE,
4554        ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC,
4555        ALC269_FIXUP_ASPIRE_HEADSET_MIC,
4556        ALC269_FIXUP_ASUS_X101_FUNC,
4557        ALC269_FIXUP_ASUS_X101_VERB,
4558        ALC269_FIXUP_ASUS_X101,
4559        ALC271_FIXUP_AMIC_MIC2,
4560        ALC271_FIXUP_HP_GATE_MIC_JACK,
4561        ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572,
4562        ALC269_FIXUP_ACER_AC700,
4563        ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
4564        ALC269VB_FIXUP_ASUS_ZENBOOK,
4565        ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A,
4566        ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED,
4567        ALC269VB_FIXUP_ORDISSIMO_EVE2,
4568        ALC283_FIXUP_CHROME_BOOK,
4569        ALC283_FIXUP_SENSE_COMBO_JACK,
4570        ALC282_FIXUP_ASUS_TX300,
4571        ALC283_FIXUP_INT_MIC,
4572        ALC290_FIXUP_MONO_SPEAKERS,
4573        ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4574        ALC290_FIXUP_SUBWOOFER,
4575        ALC290_FIXUP_SUBWOOFER_HSJACK,
4576        ALC269_FIXUP_THINKPAD_ACPI,
4577        ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
4578        ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
4579        ALC255_FIXUP_HEADSET_MODE,
4580        ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC,
4581        ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
4582        ALC292_FIXUP_TPT440_DOCK,
4583        ALC283_FIXUP_BXBT2807_MIC,
4584        ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
4585        ALC282_FIXUP_ASPIRE_V5_PINS,
4586        ALC280_FIXUP_HP_GPIO4,
4587        ALC286_FIXUP_HP_GPIO_LED,
4588        ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY,
4589        ALC280_FIXUP_HP_DOCK_PINS,
4590        ALC280_FIXUP_HP_9480M,
4591        ALC288_FIXUP_DELL_HEADSET_MODE,
4592        ALC288_FIXUP_DELL1_MIC_NO_PRESENCE,
4593        ALC288_FIXUP_DELL_XPS_13_GPIO6,
4594        ALC288_FIXUP_DELL_XPS_13,
4595        ALC288_FIXUP_DISABLE_AAMIX,
4596        ALC292_FIXUP_DELL_E7X,
4597        ALC292_FIXUP_DISABLE_AAMIX,
4598        ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
4599};
4600
4601static const struct hda_fixup alc269_fixups[] = {
4602        [ALC269_FIXUP_SONY_VAIO] = {
4603                .type = HDA_FIXUP_PINCTLS,
4604                .v.pins = (const struct hda_pintbl[]) {
4605                        {0x19, PIN_VREFGRD},
4606                        {}
4607                }
4608        },
4609        [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
4610                .type = HDA_FIXUP_VERBS,
4611                .v.verbs = (const struct hda_verb[]) {
4612                        {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
4613                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
4614                        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4615                        { }
4616                },
4617                .chained = true,
4618                .chain_id = ALC269_FIXUP_SONY_VAIO
4619        },
4620        [ALC269_FIXUP_DELL_M101Z] = {
4621                .type = HDA_FIXUP_VERBS,
4622                .v.verbs = (const struct hda_verb[]) {
4623                        /* Enables internal speaker */
4624                        {0x20, AC_VERB_SET_COEF_INDEX, 13},
4625                        {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
4626                        {}
4627                }
4628        },
4629        [ALC269_FIXUP_SKU_IGNORE] = {
4630                .type = HDA_FIXUP_FUNC,
4631                .v.func = alc_fixup_sku_ignore,
4632        },
4633        [ALC269_FIXUP_ASUS_G73JW] = {
4634                .type = HDA_FIXUP_PINS,
4635                .v.pins = (const struct hda_pintbl[]) {
4636                        { 0x17, 0x99130111 }, /* subwoofer */
4637                        { }
4638                }
4639        },
4640        [ALC269_FIXUP_LENOVO_EAPD] = {
4641                .type = HDA_FIXUP_VERBS,
4642                .v.verbs = (const struct hda_verb[]) {
4643                        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
4644                        {}
4645                }
4646        },
4647        [ALC275_FIXUP_SONY_HWEQ] = {
4648                .type = HDA_FIXUP_FUNC,
4649                .v.func = alc269_fixup_hweq,
4650                .chained = true,
4651                .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
4652        },
4653        [ALC275_FIXUP_SONY_DISABLE_AAMIX] = {
4654                .type = HDA_FIXUP_FUNC,
4655                .v.func = alc_fixup_disable_aamix,
4656                .chained = true,
4657                .chain_id = ALC269_FIXUP_SONY_VAIO
4658        },
4659        [ALC271_FIXUP_DMIC] = {
4660                .type = HDA_FIXUP_FUNC,
4661                .v.func = alc271_fixup_dmic,
4662        },
4663        [ALC269_FIXUP_PCM_44K] = {
4664                .type = HDA_FIXUP_FUNC,
4665                .v.func = alc269_fixup_pcm_44k,
4666                .chained = true,
4667                .chain_id = ALC269_FIXUP_QUANTA_MUTE
4668        },
4669        [ALC269_FIXUP_STEREO_DMIC] = {
4670                .type = HDA_FIXUP_FUNC,
4671                .v.func = alc269_fixup_stereo_dmic,
4672        },
4673        [ALC269_FIXUP_HEADSET_MIC] = {
4674                .type = HDA_FIXUP_FUNC,
4675                .v.func = alc269_fixup_headset_mic,
4676        },
4677        [ALC269_FIXUP_QUANTA_MUTE] = {
4678                .type = HDA_FIXUP_FUNC,
4679                .v.func = alc269_fixup_quanta_mute,
4680        },
4681        [ALC269_FIXUP_LIFEBOOK] = {
4682                .type = HDA_FIXUP_PINS,
4683                .v.pins = (const struct hda_pintbl[]) {
4684                        { 0x1a, 0x2101103f }, /* dock line-out */
4685                        { 0x1b, 0x23a11040 }, /* dock mic-in */
4686                        { }
4687                },
4688                .chained = true,
4689                .chain_id = ALC269_FIXUP_QUANTA_MUTE
4690        },
4691        [ALC269_FIXUP_LIFEBOOK_EXTMIC] = {
4692                .type = HDA_FIXUP_PINS,
4693                .v.pins = (const struct hda_pintbl[]) {
4694                        { 0x19, 0x01a1903c }, /* headset mic, with jack detect */
4695                        { }
4696                },
4697        },
4698        [ALC269_FIXUP_LIFEBOOK_HP_PIN] = {
4699                .type = HDA_FIXUP_PINS,
4700                .v.pins = (const struct hda_pintbl[]) {
4701                        { 0x21, 0x0221102f }, /* HP out */
4702                        { }
4703                },
4704        },
4705        [ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT] = {
4706                .type = HDA_FIXUP_FUNC,
4707                .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4708        },
4709        [ALC269_FIXUP_AMIC] = {
4710                .type = HDA_FIXUP_PINS,
4711                .v.pins = (const struct hda_pintbl[]) {
4712                        { 0x14, 0x99130110 }, /* speaker */
4713                        { 0x15, 0x0121401f }, /* HP out */
4714                        { 0x18, 0x01a19c20 }, /* mic */
4715                        { 0x19, 0x99a3092f }, /* int-mic */
4716                        { }
4717                },
4718        },
4719        [ALC269_FIXUP_DMIC] = {
4720                .type = HDA_FIXUP_PINS,
4721                .v.pins = (const struct hda_pintbl[]) {
4722                        { 0x12, 0x99a3092f }, /* int-mic */
4723                        { 0x14, 0x99130110 }, /* speaker */
4724                        { 0x15, 0x0121401f }, /* HP out */
4725                        { 0x18, 0x01a19c20 }, /* mic */
4726                        { }
4727                },
4728        },
4729        [ALC269VB_FIXUP_AMIC] = {
4730                .type = HDA_FIXUP_PINS,
4731                .v.pins = (const struct hda_pintbl[]) {
4732                        { 0x14, 0x99130110 }, /* speaker */
4733                        { 0x18, 0x01a19c20 }, /* mic */
4734                        { 0x19, 0x99a3092f }, /* int-mic */
4735                        { 0x21, 0x0121401f }, /* HP out */
4736                        { }
4737                },
4738        },
4739        [ALC269VB_FIXUP_DMIC] = {
4740                .type = HDA_FIXUP_PINS,
4741                .v.pins = (const struct hda_pintbl[]) {
4742                        { 0x12, 0x99a3092f }, /* int-mic */
4743                        { 0x14, 0x99130110 }, /* speaker */
4744                        { 0x18, 0x01a19c20 }, /* mic */
4745                        { 0x21, 0x0121401f }, /* HP out */
4746                        { }
4747                },
4748        },
4749        [ALC269_FIXUP_HP_MUTE_LED] = {
4750                .type = HDA_FIXUP_FUNC,
4751                .v.func = alc269_fixup_hp_mute_led,
4752        },
4753        [ALC269_FIXUP_HP_MUTE_LED_MIC1] = {
4754                .type = HDA_FIXUP_FUNC,
4755                .v.func = alc269_fixup_hp_mute_led_mic1,
4756        },
4757        [ALC269_FIXUP_HP_MUTE_LED_MIC2] = {
4758                .type = HDA_FIXUP_FUNC,
4759                .v.func = alc269_fixup_hp_mute_led_mic2,
4760        },
4761        [ALC269_FIXUP_HP_GPIO_LED] = {
4762                .type = HDA_FIXUP_FUNC,
4763                .v.func = alc269_fixup_hp_gpio_led,
4764        },
4765        [ALC269_FIXUP_HP_GPIO_MIC1_LED] = {
4766                .type = HDA_FIXUP_FUNC,
4767                .v.func = alc269_fixup_hp_gpio_mic1_led,
4768        },
4769        [ALC269_FIXUP_HP_LINE1_MIC1_LED] = {
4770                .type = HDA_FIXUP_FUNC,
4771                .v.func = alc269_fixup_hp_line1_mic1_led,
4772        },
4773        [ALC269_FIXUP_INV_DMIC] = {
4774                .type = HDA_FIXUP_FUNC,
4775                .v.func = alc_fixup_inv_dmic,
4776        },
4777        [ALC269_FIXUP_NO_SHUTUP] = {
4778                .type = HDA_FIXUP_FUNC,
4779                .v.func = alc_fixup_no_shutup,
4780        },
4781        [ALC269_FIXUP_LENOVO_DOCK] = {
4782                .type = HDA_FIXUP_PINS,
4783                .v.pins = (const struct hda_pintbl[]) {
4784                        { 0x19, 0x23a11040 }, /* dock mic */
4785                        { 0x1b, 0x2121103f }, /* dock headphone */
4786                        { }
4787                },
4788                .chained = true,
4789                .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
4790        },
4791        [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
4792                .type = HDA_FIXUP_FUNC,
4793                .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
4794                .chained = true,
4795                .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4796        },
4797        [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = {
4798                .type = HDA_FIXUP_PINS,
4799                .v.pins = (const struct hda_pintbl[]) {
4800                        { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4801                        { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
4802                        { }
4803                },
4804                .chained = true,
4805                .chain_id = ALC269_FIXUP_HEADSET_MODE
4806        },
4807        [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = {
4808                .type = HDA_FIXUP_PINS,
4809                .v.pins = (const struct hda_pintbl[]) {
4810                        { 0x16, 0x21014020 }, /* dock line out */
4811                        { 0x19, 0x21a19030 }, /* dock mic */
4812                        { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4813                        { }
4814                },
4815                .chained = true,
4816                .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4817        },
4818        [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = {
4819                .type = HDA_FIXUP_PINS,
4820                .v.pins = (const struct hda_pintbl[]) {
4821                        { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4822                        { }
4823                },
4824                .chained = true,
4825                .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
4826        },
4827        [ALC269_FIXUP_HEADSET_MODE] = {
4828                .type = HDA_FIXUP_FUNC,
4829                .v.func = alc_fixup_headset_mode,
4830                .chained = true,
4831                .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
4832        },
4833        [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
4834                .type = HDA_FIXUP_FUNC,
4835                .v.func = alc_fixup_headset_mode_no_hp_mic,
4836        },
4837        [ALC269_FIXUP_ASPIRE_HEADSET_MIC] = {
4838                .type = HDA_FIXUP_PINS,
4839                .v.pins = (const struct hda_pintbl[]) {
4840                        { 0x19, 0x01a1913c }, /* headset mic w/o jack detect */
4841                        { }
4842                },
4843                .chained = true,
4844                .chain_id = ALC269_FIXUP_HEADSET_MODE,
4845        },
4846        [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = {
4847                .type = HDA_FIXUP_PINS,
4848                .v.pins = (const struct hda_pintbl[]) {
4849                        { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
4850                        { }
4851                },
4852                .chained = true,
4853                .chain_id = ALC269_FIXUP_HEADSET_MIC
4854        },
4855        [ALC269_FIXUP_ASUS_X101_FUNC] = {
4856                .type = HDA_FIXUP_FUNC,
4857                .v.func = alc269_fixup_x101_headset_mic,
4858        },
4859        [ALC269_FIXUP_ASUS_X101_VERB] = {
4860                .type = HDA_FIXUP_VERBS,
4861                .v.verbs = (const struct hda_verb[]) {
4862                        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4863                        {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
4864                        {0x20, AC_VERB_SET_PROC_COEF,  0x0310},
4865                        { }
4866                },
4867                .chained = true,
4868                .chain_id = ALC269_FIXUP_ASUS_X101_FUNC
4869        },
4870        [ALC269_FIXUP_ASUS_X101] = {
4871                .type = HDA_FIXUP_PINS,
4872                .v.pins = (const struct hda_pintbl[]) {
4873                        { 0x18, 0x04a1182c }, /* Headset mic */
4874                        { }
4875                },
4876                .chained = true,
4877                .chain_id = ALC269_FIXUP_ASUS_X101_VERB
4878        },
4879        [ALC271_FIXUP_AMIC_MIC2] = {
4880                .type = HDA_FIXUP_PINS,
4881                .v.pins = (const struct hda_pintbl[]) {
4882                        { 0x14, 0x99130110 }, /* speaker */
4883                        { 0x19, 0x01a19c20 }, /* mic */
4884                        { 0x1b, 0x99a7012f }, /* int-mic */
4885                        { 0x21, 0x0121401f }, /* HP out */
4886                        { }
4887                },
4888        },
4889        [ALC271_FIXUP_HP_GATE_MIC_JACK] = {
4890                .type = HDA_FIXUP_FUNC,
4891                .v.func = alc271_hp_gate_mic_jack,
4892                .chained = true,
4893                .chain_id = ALC271_FIXUP_AMIC_MIC2,
4894        },
4895        [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = {
4896                .type = HDA_FIXUP_FUNC,
4897                .v.func = alc269_fixup_limit_int_mic_boost,
4898                .chained = true,
4899                .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK,
4900        },
4901        [ALC269_FIXUP_ACER_AC700] = {
4902                .type = HDA_FIXUP_PINS,
4903                .v.pins = (const struct hda_pintbl[]) {
4904                        { 0x12, 0x99a3092f }, /* int-mic */
4905                        { 0x14, 0x99130110 }, /* speaker */
4906                        { 0x18, 0x03a11c20 }, /* mic */
4907                        { 0x1e, 0x0346101e }, /* SPDIF1 */
4908                        { 0x21, 0x0321101f }, /* HP out */
4909                        { }
4910                },
4911                .chained = true,
4912                .chain_id = ALC271_FIXUP_DMIC,
4913        },
4914        [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = {
4915                .type = HDA_FIXUP_FUNC,
4916                .v.func = alc269_fixup_limit_int_mic_boost,
4917                .chained = true,
4918                .chain_id = ALC269_FIXUP_THINKPAD_ACPI,
4919        },
4920        [ALC269VB_FIXUP_ASUS_ZENBOOK] = {
4921                .type = HDA_FIXUP_FUNC,
4922                .v.func = alc269_fixup_limit_int_mic_boost,
4923                .chained = true,
4924                .chain_id = ALC269VB_FIXUP_DMIC,
4925        },
4926        [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = {
4927                .type = HDA_FIXUP_VERBS,
4928                .v.verbs = (const struct hda_verb[]) {
4929                        /* class-D output amp +5dB */
4930                        { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 },
4931                        { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 },
4932                        {}
4933                },
4934                .chained = true,
4935                .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK,
4936        },
4937        [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = {
4938                .type = HDA_FIXUP_FUNC,
4939                .v.func = alc269_fixup_limit_int_mic_boost,
4940                .chained = true,
4941                .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1,
4942        },
4943        [ALC269VB_FIXUP_ORDISSIMO_EVE2] = {
4944                .type = HDA_FIXUP_PINS,
4945                .v.pins = (const struct hda_pintbl[]) {
4946                        { 0x12, 0x99a3092f }, /* int-mic */
4947                        { 0x18, 0x03a11d20 }, /* mic */
4948                        { 0x19, 0x411111f0 }, /* Unused bogus pin */
4949                        { }
4950                },
4951        },
4952        [ALC283_FIXUP_CHROME_BOOK] = {
4953                .type = HDA_FIXUP_FUNC,
4954                .v.func = alc283_fixup_chromebook,
4955        },
4956        [ALC283_FIXUP_SENSE_COMBO_JACK] = {
4957                .type = HDA_FIXUP_FUNC,
4958                .v.func = alc283_fixup_sense_combo_jack,
4959                .chained = true,
4960                .chain_id = ALC283_FIXUP_CHROME_BOOK,
4961        },
4962        [ALC282_FIXUP_ASUS_TX300] = {
4963                .type = HDA_FIXUP_FUNC,
4964                .v.func = alc282_fixup_asus_tx300,
4965        },
4966        [ALC283_FIXUP_INT_MIC] = {
4967                .type = HDA_FIXUP_VERBS,
4968                .v.verbs = (const struct hda_verb[]) {
4969                        {0x20, AC_VERB_SET_COEF_INDEX, 0x1a},
4970                        {0x20, AC_VERB_SET_PROC_COEF, 0x0011},
4971                        { }
4972                },
4973                .chained = true,
4974                .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
4975        },
4976        [ALC290_FIXUP_SUBWOOFER_HSJACK] = {
4977                .type = HDA_FIXUP_PINS,
4978                .v.pins = (const struct hda_pintbl[]) {
4979                        { 0x17, 0x90170112 }, /* subwoofer */
4980                        { }
4981                },
4982                .chained = true,
4983                .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK,
4984        },
4985        [ALC290_FIXUP_SUBWOOFER] = {
4986                .type = HDA_FIXUP_PINS,
4987                .v.pins = (const struct hda_pintbl[]) {
4988                        { 0x17, 0x90170112 }, /* subwoofer */
4989                        { }
4990                },
4991                .chained = true,
4992                .chain_id = ALC290_FIXUP_MONO_SPEAKERS,
4993        },
4994        [ALC290_FIXUP_MONO_SPEAKERS] = {
4995                .type = HDA_FIXUP_FUNC,
4996                .v.func = alc290_fixup_mono_speakers,
4997        },
4998        [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = {
4999                .type = HDA_FIXUP_FUNC,
5000                .v.func = alc290_fixup_mono_speakers,
5001                .chained = true,
5002                .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5003        },
5004        [ALC269_FIXUP_THINKPAD_ACPI] = {
5005                .type = HDA_FIXUP_FUNC,
5006                .v.func = hda_fixup_thinkpad_acpi,
5007        },
5008        [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5009                .type = HDA_FIXUP_PINS,
5010                .v.pins = (const struct hda_pintbl[]) {
5011                        { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5012                        { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5013                        { }
5014                },
5015                .chained = true,
5016                .chain_id = ALC255_FIXUP_HEADSET_MODE
5017        },
5018        [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = {
5019                .type = HDA_FIXUP_PINS,
5020                .v.pins = (const struct hda_pintbl[]) {
5021                        { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5022                        { }
5023                },
5024                .chained = true,
5025                .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC
5026        },
5027        [ALC255_FIXUP_HEADSET_MODE] = {
5028                .type = HDA_FIXUP_FUNC,
5029                .v.func = alc_fixup_headset_mode_alc255,
5030                .chained = true,
5031                .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5032        },
5033        [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = {
5034                .type = HDA_FIXUP_FUNC,
5035                .v.func = alc_fixup_headset_mode_alc255_no_hp_mic,
5036        },
5037        [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5038                .type = HDA_FIXUP_PINS,
5039                .v.pins = (const struct hda_pintbl[]) {
5040                        { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5041                        { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5042                        { }
5043                },
5044                .chained = true,
5045                .chain_id = ALC269_FIXUP_HEADSET_MODE
5046        },
5047        [ALC292_FIXUP_TPT440_DOCK] = {
5048                .type = HDA_FIXUP_FUNC,
5049                .v.func = alc_fixup_tpt440_dock,
5050                .chained = true,
5051                .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST
5052        },
5053        [ALC283_FIXUP_BXBT2807_MIC] = {
5054                .type = HDA_FIXUP_PINS,
5055                .v.pins = (const struct hda_pintbl[]) {
5056                        { 0x19, 0x04a110f0 },
5057                        { },
5058                },
5059        },
5060        [ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED] = {
5061                .type = HDA_FIXUP_FUNC,
5062                .v.func = alc_fixup_dell_wmi,
5063        },
5064        [ALC282_FIXUP_ASPIRE_V5_PINS] = {
5065                .type = HDA_FIXUP_PINS,
5066                .v.pins = (const struct hda_pintbl[]) {
5067                        { 0x12, 0x90a60130 },
5068                        { 0x14, 0x90170110 },
5069                        { 0x17, 0x40000008 },
5070                        { 0x18, 0x411111f0 },
5071                        { 0x19, 0x01a1913c },
5072                        { 0x1a, 0x411111f0 },
5073                        { 0x1b, 0x411111f0 },
5074                        { 0x1d, 0x40f89b2d },
5075                        { 0x1e, 0x411111f0 },
5076                        { 0x21, 0x0321101f },
5077                        { },
5078                },
5079        },
5080        [ALC280_FIXUP_HP_GPIO4] = {
5081                .type = HDA_FIXUP_FUNC,
5082                .v.func = alc280_fixup_hp_gpio4,
5083        },
5084        [ALC286_FIXUP_HP_GPIO_LED] = {
5085                .type = HDA_FIXUP_FUNC,
5086                .v.func = alc286_fixup_hp_gpio_led,
5087        },
5088        [ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY] = {
5089                .type = HDA_FIXUP_FUNC,
5090                .v.func = alc280_fixup_hp_gpio2_mic_hotkey,
5091        },
5092        [ALC280_FIXUP_HP_DOCK_PINS] = {
5093                .type = HDA_FIXUP_PINS,
5094                .v.pins = (const struct hda_pintbl[]) {
5095                        { 0x1b, 0x21011020 }, /* line-out */
5096                        { 0x1a, 0x01a1903c }, /* headset mic */
5097                        { 0x18, 0x2181103f }, /* line-in */
5098                        { },
5099                },
5100                .chained = true,
5101                .chain_id = ALC280_FIXUP_HP_GPIO4
5102        },
5103        [ALC280_FIXUP_HP_9480M] = {
5104                .type = HDA_FIXUP_FUNC,
5105                .v.func = alc280_fixup_hp_9480m,
5106        },
5107        [ALC288_FIXUP_DELL_HEADSET_MODE] = {
5108                .type = HDA_FIXUP_FUNC,
5109                .v.func = alc_fixup_headset_mode_dell_alc288,
5110                .chained = true,
5111                .chain_id = ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED
5112        },
5113        [ALC288_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5114                .type = HDA_FIXUP_PINS,
5115                .v.pins = (const struct hda_pintbl[]) {
5116                        { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5117                        { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5118                        { }
5119                },
5120                .chained = true,
5121                .chain_id = ALC288_FIXUP_DELL_HEADSET_MODE
5122        },
5123        [ALC288_FIXUP_DELL_XPS_13_GPIO6] = {
5124                .type = HDA_FIXUP_VERBS,
5125                .v.verbs = (const struct hda_verb[]) {
5126                        {0x01, AC_VERB_SET_GPIO_MASK, 0x40},
5127                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x40},
5128                        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5129                        { }
5130                },
5131                .chained = true,
5132                .chain_id = ALC288_FIXUP_DELL1_MIC_NO_PRESENCE
5133        },
5134        [ALC288_FIXUP_DISABLE_AAMIX] = {
5135                .type = HDA_FIXUP_FUNC,
5136                .v.func = alc_fixup_disable_aamix,
5137                .chained = true,
5138                .chain_id = ALC288_FIXUP_DELL_XPS_13_GPIO6
5139        },
5140        [ALC288_FIXUP_DELL_XPS_13] = {
5141                .type = HDA_FIXUP_FUNC,
5142                .v.func = alc_fixup_dell_xps13,
5143                .chained = true,
5144                .chain_id = ALC288_FIXUP_DISABLE_AAMIX
5145        },
5146        [ALC292_FIXUP_DISABLE_AAMIX] = {
5147                .type = HDA_FIXUP_FUNC,
5148                .v.func = alc_fixup_disable_aamix,
5149                .chained = true,
5150                .chain_id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE
5151        },
5152        [ALC292_FIXUP_DELL_E7X] = {
5153                .type = HDA_FIXUP_FUNC,
5154                .v.func = alc_fixup_dell_xps13,
5155                .chained = true,
5156                .chain_id = ALC292_FIXUP_DISABLE_AAMIX
5157        },
5158        [ALC298_FIXUP_DELL1_MIC_NO_PRESENCE] = {
5159                .type = HDA_FIXUP_PINS,
5160                .v.pins = (const struct hda_pintbl[]) {
5161                        { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */
5162                        { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */
5163                        { }
5164                },
5165                .chained = true,
5166                .chain_id = ALC269_FIXUP_HEADSET_MODE
5167        },
5168};
5169
5170static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5171        SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC),
5172        SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
5173        SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5174        SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
5175        SND_PCI_QUIRK(0x1025, 0x072d, "Acer Aspire V5-571G", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5176        SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5177        SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5178        SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
5179        SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5180        SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5181        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
5182        SND_PCI_QUIRK(0x1028, 0x05ca, "Dell Latitude E7240", ALC292_FIXUP_DELL_E7X),
5183        SND_PCI_QUIRK(0x1028, 0x05cb, "Dell Latitude E7440", ALC292_FIXUP_DELL_E7X),
5184        SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER),
5185        SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5186        SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5187        SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
5188        SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5189        SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK),
5190        SND_PCI_QUIRK(0x1028, 0x062e, "Dell Latitude E7450", ALC292_FIXUP_DELL_E7X),
5191        SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK),
5192        SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5193        SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5194        SND_PCI_QUIRK(0x1028, 0x0665, "Dell XPS 13", ALC288_FIXUP_DELL_XPS_13),
5195        SND_PCI_QUIRK(0x1028, 0x069a, "Dell Vostro 5480", ALC290_FIXUP_SUBWOOFER_HSJACK),
5196        SND_PCI_QUIRK(0x1028, 0x06c7, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
5197        SND_PCI_QUIRK(0x1028, 0x06d9, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5198        SND_PCI_QUIRK(0x1028, 0x06da, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5199        SND_PCI_QUIRK(0x1028, 0x06db, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
5200        SND_PCI_QUIRK(0x1028, 0x06dd, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
5201        SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
5202        SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
5203        SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC292_FIXUP_DISABLE_AAMIX),
5204        SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5205        SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
5206        SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
5207        SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
5208        SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED),
5209        SND_PCI_QUIRK(0x103c, 0x225f, "HP", ALC280_FIXUP_HP_GPIO2_MIC_HOTKEY),
5210        /* ALC282 */
5211        SND_PCI_QUIRK(0x103c, 0x21f9, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5212        SND_PCI_QUIRK(0x103c, 0x2210, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5213        SND_PCI_QUIRK(0x103c, 0x2214, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5214        SND_PCI_QUIRK(0x103c, 0x2236, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5215        SND_PCI_QUIRK(0x103c, 0x2237, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5216        SND_PCI_QUIRK(0x103c, 0x2238, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5217        SND_PCI_QUIRK(0x103c, 0x2239, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5218        SND_PCI_QUIRK(0x103c, 0x224b, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED),
5219        SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5220        SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5221        SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5222        SND_PCI_QUIRK(0x103c, 0x226e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5223        SND_PCI_QUIRK(0x103c, 0x2271, "HP", ALC286_FIXUP_HP_GPIO_LED),
5224        SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5225        SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC280_FIXUP_HP_DOCK_PINS),
5226        SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5227        SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5228        SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5229        SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5230        SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5231        SND_PCI_QUIRK(0x103c, 0x22db, "HP", ALC280_FIXUP_HP_9480M),
5232        SND_PCI_QUIRK(0x103c, 0x22dc, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5233        SND_PCI_QUIRK(0x103c, 0x22fb, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5234        /* ALC290 */
5235        SND_PCI_QUIRK(0x103c, 0x221b, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5236        SND_PCI_QUIRK(0x103c, 0x2221, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5237        SND_PCI_QUIRK(0x103c, 0x2225, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5238        SND_PCI_QUIRK(0x103c, 0x2253, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5239        SND_PCI_QUIRK(0x103c, 0x2254, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5240        SND_PCI_QUIRK(0x103c, 0x2255, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5241        SND_PCI_QUIRK(0x103c, 0x2256, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5242        SND_PCI_QUIRK(0x103c, 0x2257, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5243        SND_PCI_QUIRK(0x103c, 0x2259, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5244        SND_PCI_QUIRK(0x103c, 0x225a, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5245        SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5246        SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5247        SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5248        SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5249        SND_PCI_QUIRK(0x103c, 0x2272, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5250        SND_PCI_QUIRK(0x103c, 0x2273, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5251        SND_PCI_QUIRK(0x103c, 0x2278, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED),
5252        SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5253        SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5254        SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5255        SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5256        SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5257        SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5258        SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5259        SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5260        SND_PCI_QUIRK(0x103c, 0x2334, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5261        SND_PCI_QUIRK(0x103c, 0x2335, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5262        SND_PCI_QUIRK(0x103c, 0x2336, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5263        SND_PCI_QUIRK(0x103c, 0x2337, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1),
5264        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
5265        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5266        SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5267        SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
5268        SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
5269        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5270        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
5271        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5272        SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5273        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5274        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
5275        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5276        SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
5277        SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101),
5278        SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5279        SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE),
5280        SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
5281        SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5282        SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
5283        SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX),
5284        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
5285        SND_PCI_QUIRK(0x10cf, 0x159f, "Lifebook E780", ALC269_FIXUP_LIFEBOOK_NO_HP_TO_LINEOUT),
5286        SND_PCI_QUIRK(0x10cf, 0x15dc, "Lifebook T731", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5287        SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
5288        SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
5289        SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
5290        SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
5291        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
5292        SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
5293        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5294        SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5295        SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
5296        SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK),
5297        SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
5298        SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
5299        SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
5300        SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5301        SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
5302        SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK),
5303        SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK),
5304        SND_PCI_QUIRK(0x17aa, 0x2210, "Thinkpad T540p", ALC292_FIXUP_TPT440_DOCK),
5305        SND_PCI_QUIRK(0x17aa, 0x2211, "Thinkpad W541", ALC292_FIXUP_TPT440_DOCK),
5306        SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad T440", ALC292_FIXUP_TPT440_DOCK),
5307        SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad X240", ALC292_FIXUP_TPT440_DOCK),
5308        SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5309        SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
5310        SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
5311        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
5312        SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
5313        SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5314        SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
5315        SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
5316        SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5317        SND_PCI_QUIRK(0x17aa, 0x5034, "Thinkpad T450", ALC292_FIXUP_TPT440_DOCK),
5318        SND_PCI_QUIRK(0x17aa, 0x5036, "Thinkpad T450s", ALC292_FIXUP_TPT440_DOCK),
5319        SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
5320        SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
5321        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
5322        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
5323        SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
5324
5325#if 0
5326        /* Below is a quirk table taken from the old code.
5327         * Basically the device should work as is without the fixup table.
5328         * If BIOS doesn't give a proper info, enable the corresponding
5329         * fixup entry.
5330         */
5331        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
5332                      ALC269_FIXUP_AMIC),
5333        SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC),
5334        SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC),
5335        SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC),
5336        SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC),
5337        SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC),
5338        SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC),
5339        SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC),
5340        SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC),
5341        SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC),
5342        SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC),
5343        SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC),
5344        SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC),
5345        SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC),
5346        SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC),
5347        SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC),
5348        SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC),
5349        SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC),
5350        SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC),
5351        SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC),
5352        SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC),
5353        SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC),
5354        SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC),
5355        SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC),
5356        SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC),
5357        SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC),
5358        SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC),
5359        SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC),
5360        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC),
5361        SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC),
5362        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC),
5363        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC),
5364        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC),
5365        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC),
5366        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC),
5367        SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC),
5368        SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC),
5369        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC),
5370        SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC),
5371        SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC),
5372#endif
5373        {}
5374};
5375
5376static const struct snd_pci_quirk alc269_fixup_vendor_tbl[] = {
5377        SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
5378        SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
5379        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
5380        SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
5381        {}
5382};
5383
5384static const struct hda_model_fixup alc269_fixup_models[] = {
5385        {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
5386        {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
5387        {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
5388        {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
5389        {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
5390        {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"},
5391        {.id = ALC269_FIXUP_HEADSET_MODE, .name = "headset-mode"},
5392        {.id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, .name = "headset-mode-no-hp-mic"},
5393        {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
5394        {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"},
5395        {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
5396        {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"},
5397        {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"},
5398        {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"},
5399        {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"},
5400        {}
5401};
5402
5403#define ALC256_STANDARD_PINS \
5404        {0x12, 0x90a60140}, \
5405        {0x14, 0x90170110}, \
5406        {0x21, 0x02211020}
5407
5408#define ALC282_STANDARD_PINS \
5409        {0x14, 0x90170110}
5410
5411#define ALC290_STANDARD_PINS \
5412        {0x12, 0x99a30130}
5413
5414#define ALC292_STANDARD_PINS \
5415        {0x14, 0x90170110}, \
5416        {0x15, 0x0221401f}
5417
5418#define ALC298_STANDARD_PINS \
5419        {0x12, 0x90a60130}, \
5420        {0x21, 0x03211020}
5421
5422static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
5423        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
5424                {0x14, 0x90170110},
5425                {0x21, 0x02211020}),
5426        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5427                {0x12, 0x90a60140},
5428                {0x14, 0x90170110},
5429                {0x21, 0x02211020}),
5430        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5431                {0x12, 0x90a60160},
5432                {0x14, 0x90170120},
5433                {0x21, 0x02211030}),
5434        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5435                {0x14, 0x90170130},
5436                {0x1b, 0x01014020},
5437                {0x21, 0x0221103f}),
5438        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5439                {0x14, 0x90170150},
5440                {0x1b, 0x02011020},
5441                {0x21, 0x0221105f}),
5442        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5443                {0x14, 0x90170110},
5444                {0x1b, 0x01014020},
5445                {0x21, 0x0221101f}),
5446        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5447                {0x12, 0x90a60160},
5448                {0x14, 0x90170120},
5449                {0x17, 0x90170140},
5450                {0x21, 0x0321102f}),
5451        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5452                {0x12, 0x90a60160},
5453                {0x14, 0x90170130},
5454                {0x21, 0x02211040}),
5455        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5456                {0x12, 0x90a60160},
5457                {0x14, 0x90170140},
5458                {0x21, 0x02211050}),
5459        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5460                {0x12, 0x90a60170},
5461                {0x14, 0x90170120},
5462                {0x21, 0x02211030}),
5463        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5464                {0x12, 0x90a60170},
5465                {0x14, 0x90170130},
5466                {0x21, 0x02211040}),
5467        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5468                {0x12, 0x90a60170},
5469                {0x14, 0x90170140},
5470                {0x21, 0x02211050}),
5471        SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5548", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5472                {0x12, 0x90a60180},
5473                {0x14, 0x90170130},
5474                {0x21, 0x02211040}),
5475        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5476                {0x12, 0x90a60160},
5477                {0x14, 0x90170120},
5478                {0x21, 0x02211030}),
5479        SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
5480                ALC256_STANDARD_PINS),
5481        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
5482                {0x12, 0x90a60130},
5483                {0x14, 0x90170110},
5484                {0x15, 0x0421101f},
5485                {0x1a, 0x04a11020}),
5486        SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC269_FIXUP_HP_GPIO_MIC1_LED,
5487                {0x12, 0x90a60140},
5488                {0x14, 0x90170110},
5489                {0x15, 0x0421101f},
5490                {0x18, 0x02811030},
5491                {0x1a, 0x04a1103f},
5492                {0x1b, 0x02011020}),
5493        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP 15 Touchsmart", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5494                ALC282_STANDARD_PINS,
5495                {0x12, 0x99a30130},
5496                {0x19, 0x03a11020},
5497                {0x21, 0x0321101f}),
5498        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5499                ALC282_STANDARD_PINS,
5500                {0x12, 0x99a30130},
5501                {0x19, 0x03a11020},
5502                {0x21, 0x03211040}),
5503        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5504                ALC282_STANDARD_PINS,
5505                {0x12, 0x99a30130},
5506                {0x19, 0x03a11030},
5507                {0x21, 0x03211020}),
5508        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5509                ALC282_STANDARD_PINS,
5510                {0x12, 0x99a30130},
5511                {0x19, 0x04a11020},
5512                {0x21, 0x0421101f}),
5513        SND_HDA_PIN_QUIRK(0x10ec0282, 0x103c, "HP", ALC269_FIXUP_HP_LINE1_MIC1_LED,
5514                ALC282_STANDARD_PINS,
5515                {0x12, 0x90a60140},
5516                {0x19, 0x04a11030},
5517                {0x21, 0x04211020}),
5518        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5519                ALC282_STANDARD_PINS,
5520                {0x12, 0x90a60130},
5521                {0x21, 0x0321101f}),
5522        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5523                {0x12, 0x90a60160},
5524                {0x14, 0x90170120},
5525                {0x21, 0x02211030}),
5526        SND_HDA_PIN_QUIRK(0x10ec0283, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
5527                ALC282_STANDARD_PINS,
5528                {0x12, 0x90a60130},
5529                {0x19, 0x03a11020},
5530                {0x21, 0x0321101f}),
5531        SND_HDA_PIN_QUIRK(0x10ec0288, 0x1028, "Dell", ALC288_FIXUP_DELL_XPS_13_GPIO6,
5532                {0x12, 0x90a60120},
5533                {0x14, 0x90170110},
5534                {0x21, 0x0321101f}),
5535        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5536                ALC290_STANDARD_PINS,
5537                {0x15, 0x04211040},
5538                {0x18, 0x90170112},
5539                {0x1a, 0x04a11020}),
5540        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5541                ALC290_STANDARD_PINS,
5542                {0x15, 0x04211040},
5543                {0x18, 0x90170110},
5544                {0x1a, 0x04a11020}),
5545        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5546                ALC290_STANDARD_PINS,
5547                {0x15, 0x0421101f},
5548                {0x1a, 0x04a11020}),
5549        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5550                ALC290_STANDARD_PINS,
5551                {0x15, 0x04211020},
5552                {0x1a, 0x04a11040}),
5553        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5554                ALC290_STANDARD_PINS,
5555                {0x14, 0x90170110},
5556                {0x15, 0x04211020},
5557                {0x1a, 0x04a11040}),
5558        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5559                ALC290_STANDARD_PINS,
5560                {0x14, 0x90170110},
5561                {0x15, 0x04211020},
5562                {0x1a, 0x04a11020}),
5563        SND_HDA_PIN_QUIRK(0x10ec0290, 0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1,
5564                ALC290_STANDARD_PINS,
5565                {0x14, 0x90170110},
5566                {0x15, 0x0421101f},
5567                {0x1a, 0x04a11020}),
5568        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5569                ALC292_STANDARD_PINS,
5570                {0x12, 0x90a60140},
5571                {0x16, 0x01014020},
5572                {0x19, 0x01a19030}),
5573        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE,
5574                ALC292_STANDARD_PINS,
5575                {0x12, 0x90a60140},
5576                {0x16, 0x01014020},
5577                {0x18, 0x02a19031},
5578                {0x19, 0x01a1903e}),
5579        SND_HDA_PIN_QUIRK(0x10ec0292, 0x1028, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE,
5580                ALC292_STANDARD_PINS,
5581                {0x12, 0x90a60140}),
5582        SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5583                ALC292_STANDARD_PINS,
5584                {0x13, 0x90a60140},
5585                {0x16, 0x21014020},
5586                {0x19, 0x21a19030}),
5587        SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
5588                ALC292_STANDARD_PINS,
5589                {0x13, 0x90a60140}),
5590        SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
5591                ALC298_STANDARD_PINS,
5592                {0x17, 0x90170110}),
5593        SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
5594                ALC298_STANDARD_PINS,
5595                {0x17, 0x90170140}),
5596        SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
5597                ALC298_STANDARD_PINS,
5598                {0x17, 0x90170150}),
5599        {}
5600};
5601
5602static void alc269_fill_coef(struct hda_codec *codec)
5603{
5604        struct alc_spec *spec = codec->spec;
5605        int val;
5606
5607        if (spec->codec_variant != ALC269_TYPE_ALC269VB)
5608                return;
5609
5610        if ((alc_get_coef0(codec) & 0x00ff) < 0x015) {
5611                alc_write_coef_idx(codec, 0xf, 0x960b);
5612                alc_write_coef_idx(codec, 0xe, 0x8817);
5613        }
5614
5615        if ((alc_get_coef0(codec) & 0x00ff) == 0x016) {
5616                alc_write_coef_idx(codec, 0xf, 0x960b);
5617                alc_write_coef_idx(codec, 0xe, 0x8814);
5618        }
5619
5620        if ((alc_get_coef0(codec) & 0x00ff) == 0x017) {
5621                /* Power up output pin */
5622                alc_update_coef_idx(codec, 0x04, 0, 1<<11);
5623        }
5624
5625        if ((alc_get_coef0(codec) & 0x00ff) == 0x018) {
5626                val = alc_read_coef_idx(codec, 0xd);
5627                if (val != -1 && (val & 0x0c00) >> 10 != 0x1) {
5628                        /* Capless ramp up clock control */
5629                        alc_write_coef_idx(codec, 0xd, val | (1<<10));
5630                }
5631                val = alc_read_coef_idx(codec, 0x17);
5632                if (val != -1 && (val & 0x01c0) >> 6 != 0x4) {
5633                        /* Class D power on reset */
5634                        alc_write_coef_idx(codec, 0x17, val | (1<<7));
5635                }
5636        }
5637
5638        /* HP */
5639        alc_update_coef_idx(codec, 0x4, 0, 1<<11);
5640}
5641
5642/*
5643 */
5644static int patch_alc269(struct hda_codec *codec)
5645{
5646        struct alc_spec *spec;
5647        int err;
5648
5649        err = alc_alloc_spec(codec, 0x0b);
5650        if (err < 0)
5651                return err;
5652
5653        spec = codec->spec;
5654        spec->gen.shared_mic_vref_pin = 0x18;
5655        codec->power_save_node = 1;
5656
5657#ifdef CONFIG_PM
5658        codec->patch_ops.suspend = alc269_suspend;
5659        codec->patch_ops.resume = alc269_resume;
5660#endif
5661        spec->shutup = alc269_shutup;
5662
5663        snd_hda_pick_fixup(codec, alc269_fixup_models,
5664                       alc269_fixup_tbl, alc269_fixups);
5665        snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
5666        snd_hda_pick_fixup(codec, NULL, alc269_fixup_vendor_tbl,
5667                           alc269_fixups);
5668        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5669
5670        alc_auto_parse_customize_define(codec);
5671
5672        if (has_cdefine_beep(codec))
5673                spec->gen.beep_nid = 0x01;
5674
5675        switch (codec->core.vendor_id) {
5676        case 0x10ec0269:
5677                spec->codec_variant = ALC269_TYPE_ALC269VA;
5678                switch (alc_get_coef0(codec) & 0x00f0) {
5679                case 0x0010:
5680                        if (codec->bus->pci &&
5681                            codec->bus->pci->subsystem_vendor == 0x1025 &&
5682                            spec->cdefine.platform_type == 1)
5683                                err = alc_codec_rename(codec, "ALC271X");
5684                        spec->codec_variant = ALC269_TYPE_ALC269VB;
5685                        break;
5686                case 0x0020:
5687                        if (codec->bus->pci &&
5688                            codec->bus->pci->subsystem_vendor == 0x17aa &&
5689                            codec->bus->pci->subsystem_device == 0x21f3)
5690                                err = alc_codec_rename(codec, "ALC3202");
5691                        spec->codec_variant = ALC269_TYPE_ALC269VC;
5692                        break;
5693                case 0x0030:
5694                        spec->codec_variant = ALC269_TYPE_ALC269VD;
5695                        break;
5696                default:
5697                        alc_fix_pll_init(codec, 0x20, 0x04, 15);
5698                }
5699                if (err < 0)
5700                        goto error;
5701                spec->init_hook = alc269_fill_coef;
5702                alc269_fill_coef(codec);
5703                break;
5704
5705        case 0x10ec0280:
5706        case 0x10ec0290:
5707                spec->codec_variant = ALC269_TYPE_ALC280;
5708                break;
5709        case 0x10ec0282:
5710                spec->codec_variant = ALC269_TYPE_ALC282;
5711                spec->shutup = alc282_shutup;
5712                spec->init_hook = alc282_init;
5713                break;
5714        case 0x10ec0233:
5715        case 0x10ec0283:
5716                spec->codec_variant = ALC269_TYPE_ALC283;
5717                spec->shutup = alc283_shutup;
5718                spec->init_hook = alc283_init;
5719                break;
5720        case 0x10ec0284:
5721        case 0x10ec0292:
5722                spec->codec_variant = ALC269_TYPE_ALC284;
5723                break;
5724        case 0x10ec0285:
5725        case 0x10ec0293:
5726                spec->codec_variant = ALC269_TYPE_ALC285;
5727                break;
5728        case 0x10ec0286:
5729        case 0x10ec0288:
5730                spec->codec_variant = ALC269_TYPE_ALC286;
5731                spec->shutup = alc286_shutup;
5732                break;
5733        case 0x10ec0298:
5734                spec->codec_variant = ALC269_TYPE_ALC298;
5735                break;
5736        case 0x10ec0255:
5737                spec->codec_variant = ALC269_TYPE_ALC255;
5738                break;
5739        case 0x10ec0256:
5740                spec->codec_variant = ALC269_TYPE_ALC256;
5741                spec->gen.mixer_nid = 0; /* ALC256 does not have any loopback mixer path */
5742                alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
5743                break;
5744        }
5745
5746        if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
5747                spec->has_alc5505_dsp = 1;
5748                spec->init_hook = alc5505_dsp_init;
5749        }
5750
5751        /* automatic parse from the BIOS config */
5752        err = alc269_parse_auto_config(codec);
5753        if (err < 0)
5754                goto error;
5755
5756        if (!spec->gen.no_analog && spec->gen.beep_nid && spec->gen.mixer_nid)
5757                set_beep_amp(spec, spec->gen.mixer_nid, 0x04, HDA_INPUT);
5758
5759        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5760
5761        return 0;
5762
5763 error:
5764        alc_free(codec);
5765        return err;
5766}
5767
5768/*
5769 * ALC861
5770 */
5771
5772static int alc861_parse_auto_config(struct hda_codec *codec)
5773{
5774        static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
5775        static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
5776        return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
5777}
5778
5779/* Pin config fixes */
5780enum {
5781        ALC861_FIXUP_FSC_AMILO_PI1505,
5782        ALC861_FIXUP_AMP_VREF_0F,
5783        ALC861_FIXUP_NO_JACK_DETECT,
5784        ALC861_FIXUP_ASUS_A6RP,
5785        ALC660_FIXUP_ASUS_W7J,
5786};
5787
5788/* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */
5789static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
5790                        const struct hda_fixup *fix, int action)
5791{
5792        struct alc_spec *spec = codec->spec;
5793        unsigned int val;
5794
5795        if (action != HDA_FIXUP_ACT_INIT)
5796                return;
5797        val = snd_hda_codec_get_pin_target(codec, 0x0f);
5798        if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
5799                val |= AC_PINCTL_IN_EN;
5800        val |= AC_PINCTL_VREF_50;
5801        snd_hda_set_pin_ctl(codec, 0x0f, val);
5802        spec->gen.keep_vref_in_automute = 1;
5803}
5804
5805/* suppress the jack-detection */
5806static void alc_fixup_no_jack_detect(struct hda_codec *codec,
5807                                     const struct hda_fixup *fix, int action)
5808{
5809        if (action == HDA_FIXUP_ACT_PRE_PROBE)
5810                codec->no_jack_detect = 1;
5811}
5812
5813static const struct hda_fixup alc861_fixups[] = {
5814        [ALC861_FIXUP_FSC_AMILO_PI1505] = {
5815                .type = HDA_FIXUP_PINS,
5816                .v.pins = (const struct hda_pintbl[]) {
5817                        { 0x0b, 0x0221101f }, /* HP */
5818                        { 0x0f, 0x90170310 }, /* speaker */
5819                        { }
5820                }
5821        },
5822        [ALC861_FIXUP_AMP_VREF_0F] = {
5823                .type = HDA_FIXUP_FUNC,
5824                .v.func = alc861_fixup_asus_amp_vref_0f,
5825        },
5826        [ALC861_FIXUP_NO_JACK_DETECT] = {
5827                .type = HDA_FIXUP_FUNC,
5828                .v.func = alc_fixup_no_jack_detect,
5829        },
5830        [ALC861_FIXUP_ASUS_A6RP] = {
5831                .type = HDA_FIXUP_FUNC,
5832                .v.func = alc861_fixup_asus_amp_vref_0f,
5833                .chained = true,
5834                .chain_id = ALC861_FIXUP_NO_JACK_DETECT,
5835        },
5836        [ALC660_FIXUP_ASUS_W7J] = {
5837                .type = HDA_FIXUP_VERBS,
5838                .v.verbs = (const struct hda_verb[]) {
5839                        /* ASUS W7J needs a magic pin setup on unused NID 0x10
5840                         * for enabling outputs
5841                         */
5842                        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5843                        { }
5844                },
5845        }
5846};
5847
5848static const struct snd_pci_quirk alc861_fixup_tbl[] = {
5849        SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J),
5850        SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J),
5851        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP),
5852        SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F),
5853        SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT),
5854        SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F),
5855        SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F),
5856        SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505),
5857        {}
5858};
5859
5860/*
5861 */
5862static int patch_alc861(struct hda_codec *codec)
5863{
5864        struct alc_spec *spec;
5865        int err;
5866
5867        err = alc_alloc_spec(codec, 0x15);
5868        if (err < 0)
5869                return err;
5870
5871        spec = codec->spec;
5872        spec->gen.beep_nid = 0x23;
5873
5874#ifdef CONFIG_PM
5875        spec->power_hook = alc_power_eapd;
5876#endif
5877
5878        snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
5879        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5880
5881        /* automatic parse from the BIOS config */
5882        err = alc861_parse_auto_config(codec);
5883        if (err < 0)
5884                goto error;
5885
5886        if (!spec->gen.no_analog)
5887                set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
5888
5889        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5890
5891        return 0;
5892
5893 error:
5894        alc_free(codec);
5895        return err;
5896}
5897
5898/*
5899 * ALC861-VD support
5900 *
5901 * Based on ALC882
5902 *
5903 * In addition, an independent DAC
5904 */
5905static int alc861vd_parse_auto_config(struct hda_codec *codec)
5906{
5907        static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
5908        static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
5909        return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
5910}
5911
5912enum {
5913        ALC660VD_FIX_ASUS_GPIO1,
5914        ALC861VD_FIX_DALLAS,
5915};
5916
5917/* exclude VREF80 */
5918static void alc861vd_fixup_dallas(struct hda_codec *codec,
5919                                  const struct hda_fixup *fix, int action)
5920{
5921        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
5922                snd_hda_override_pin_caps(codec, 0x18, 0x00000734);
5923                snd_hda_override_pin_caps(codec, 0x19, 0x0000073c);
5924        }
5925}
5926
5927static const struct hda_fixup alc861vd_fixups[] = {
5928        [ALC660VD_FIX_ASUS_GPIO1] = {
5929                .type = HDA_FIXUP_VERBS,
5930                .v.verbs = (const struct hda_verb[]) {
5931                        /* reset GPIO1 */
5932                        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5933                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5934                        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5935                        { }
5936                }
5937        },
5938        [ALC861VD_FIX_DALLAS] = {
5939                .type = HDA_FIXUP_FUNC,
5940                .v.func = alc861vd_fixup_dallas,
5941        },
5942};
5943
5944static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
5945        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS),
5946        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
5947        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS),
5948        {}
5949};
5950
5951/*
5952 */
5953static int patch_alc861vd(struct hda_codec *codec)
5954{
5955        struct alc_spec *spec;
5956        int err;
5957
5958        err = alc_alloc_spec(codec, 0x0b);
5959        if (err < 0)
5960                return err;
5961
5962        spec = codec->spec;
5963        spec->gen.beep_nid = 0x23;
5964
5965        spec->shutup = alc_eapd_shutup;
5966
5967        snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
5968        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
5969
5970        /* automatic parse from the BIOS config */
5971        err = alc861vd_parse_auto_config(codec);
5972        if (err < 0)
5973                goto error;
5974
5975        if (!spec->gen.no_analog)
5976                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5977
5978        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
5979
5980        return 0;
5981
5982 error:
5983        alc_free(codec);
5984        return err;
5985}
5986
5987/*
5988 * ALC662 support
5989 *
5990 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
5991 * configuration.  Each pin widget can choose any input DACs and a mixer.
5992 * Each ADC is connected from a mixer of all inputs.  This makes possible
5993 * 6-channel independent captures.
5994 *
5995 * In addition, an independent DAC for the multi-playback (not used in this
5996 * driver yet).
5997 */
5998
5999/*
6000 * BIOS auto configuration
6001 */
6002
6003static int alc662_parse_auto_config(struct hda_codec *codec)
6004{
6005        static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
6006        static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
6007        static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6008        const hda_nid_t *ssids;
6009
6010        if (codec->core.vendor_id == 0x10ec0272 || codec->core.vendor_id == 0x10ec0663 ||
6011            codec->core.vendor_id == 0x10ec0665 || codec->core.vendor_id == 0x10ec0670 ||
6012            codec->core.vendor_id == 0x10ec0671)
6013                ssids = alc663_ssids;
6014        else
6015                ssids = alc662_ssids;
6016        return alc_parse_auto_config(codec, alc662_ignore, ssids);
6017}
6018
6019static void alc272_fixup_mario(struct hda_codec *codec,
6020                               const struct hda_fixup *fix, int action)
6021{
6022        if (action != HDA_FIXUP_ACT_PRE_PROBE)
6023                return;
6024        if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
6025                                      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
6026                                      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
6027                                      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
6028                                      (0 << AC_AMPCAP_MUTE_SHIFT)))
6029                codec_warn(codec, "failed to override amp caps for NID 0x2\n");
6030}
6031
6032static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = {
6033        { .channels = 2,
6034          .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
6035        { .channels = 4,
6036          .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
6037                   SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */
6038        { }
6039};
6040
6041/* override the 2.1 chmap */
6042static void alc_fixup_bass_chmap(struct hda_codec *codec,
6043                                    const struct hda_fixup *fix, int action)
6044{
6045        if (action == HDA_FIXUP_ACT_BUILD) {
6046                struct alc_spec *spec = codec->spec;
6047                spec->gen.pcm_rec[0]->stream[0].chmap = asus_pcm_2_1_chmaps;
6048        }
6049}
6050
6051/* avoid D3 for keeping GPIO up */
6052static unsigned int gpio_led_power_filter(struct hda_codec *codec,
6053                                          hda_nid_t nid,
6054                                          unsigned int power_state)
6055{
6056        struct alc_spec *spec = codec->spec;
6057        if (nid == codec->core.afg && power_state == AC_PWRST_D3 && spec->gpio_led)
6058                return AC_PWRST_D0;
6059        return power_state;
6060}
6061
6062static void alc662_fixup_led_gpio1(struct hda_codec *codec,
6063                                   const struct hda_fixup *fix, int action)
6064{
6065        struct alc_spec *spec = codec->spec;
6066        static const struct hda_verb gpio_init[] = {
6067                { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 },
6068                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 },
6069                {}
6070        };
6071
6072        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
6073                spec->gen.vmaster_mute.hook = alc_fixup_gpio_mute_hook;
6074                spec->gpio_led = 0;
6075                spec->mute_led_polarity = 1;
6076                spec->gpio_mute_led_mask = 0x01;
6077                snd_hda_add_verbs(codec, gpio_init);
6078                codec->power_filter = gpio_led_power_filter;
6079        }
6080}
6081
6082static struct coef_fw alc668_coefs[] = {
6083        WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03,    0x0),
6084        WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06,    0x0), WRITE_COEF(0x07, 0x0f80),
6085        WRITE_COEF(0x08, 0x0031), WRITE_COEF(0x0a, 0x0060), WRITE_COEF(0x0b,    0x0),
6086        WRITE_COEF(0x0c, 0x7cf7), WRITE_COEF(0x0d, 0x1080), WRITE_COEF(0x0e, 0x7f7f),
6087        WRITE_COEF(0x0f, 0xcccc), WRITE_COEF(0x10, 0xddcc), WRITE_COEF(0x11, 0x0001),
6088        WRITE_COEF(0x13,    0x0), WRITE_COEF(0x14, 0x2aa0), WRITE_COEF(0x17, 0xa940),
6089        WRITE_COEF(0x19,    0x0), WRITE_COEF(0x1a,    0x0), WRITE_COEF(0x1b,    0x0),
6090        WRITE_COEF(0x1c,    0x0), WRITE_COEF(0x1d,    0x0), WRITE_COEF(0x1e, 0x7418),
6091        WRITE_COEF(0x1f, 0x0804), WRITE_COEF(0x20, 0x4200), WRITE_COEF(0x21, 0x0468),
6092        WRITE_COEF(0x22, 0x8ccc), WRITE_COEF(0x23, 0x0250), WRITE_COEF(0x24, 0x7418),
6093        WRITE_COEF(0x27,    0x0), WRITE_COEF(0x28, 0x8ccc), WRITE_COEF(0x2a, 0xff00),
6094        WRITE_COEF(0x2b, 0x8000), WRITE_COEF(0xa7, 0xff00), WRITE_COEF(0xa8, 0x8000),
6095        WRITE_COEF(0xaa, 0x2e17), WRITE_COEF(0xab, 0xa0c0), WRITE_COEF(0xac,    0x0),
6096        WRITE_COEF(0xad,    0x0), WRITE_COEF(0xae, 0x2ac6), WRITE_COEF(0xaf, 0xa480),
6097        WRITE_COEF(0xb0,    0x0), WRITE_COEF(0xb1,    0x0), WRITE_COEF(0xb2,    0x0),
6098        WRITE_COEF(0xb3,    0x0), WRITE_COEF(0xb4,    0x0), WRITE_COEF(0xb5, 0x1040),
6099        WRITE_COEF(0xb6, 0xd697), WRITE_COEF(0xb7, 0x902b), WRITE_COEF(0xb8, 0xd697),
6100        WRITE_COEF(0xb9, 0x902b), WRITE_COEF(0xba, 0xb8ba), WRITE_COEF(0xbb, 0xaaab),
6101        WRITE_COEF(0xbc, 0xaaaf), WRITE_COEF(0xbd, 0x6aaa), WRITE_COEF(0xbe, 0x1c02),
6102        WRITE_COEF(0xc0, 0x00ff), WRITE_COEF(0xc1, 0x0fa6),
6103        {}
6104};
6105
6106static void alc668_restore_default_value(struct hda_codec *codec)
6107{
6108        alc_process_coef_fw(codec, alc668_coefs);
6109}
6110
6111enum {
6112        ALC662_FIXUP_ASPIRE,
6113        ALC662_FIXUP_LED_GPIO1,
6114        ALC662_FIXUP_IDEAPAD,
6115        ALC272_FIXUP_MARIO,
6116        ALC662_FIXUP_CZC_P10T,
6117        ALC662_FIXUP_SKU_IGNORE,
6118        ALC662_FIXUP_HP_RP5800,
6119        ALC662_FIXUP_ASUS_MODE1,
6120        ALC662_FIXUP_ASUS_MODE2,
6121        ALC662_FIXUP_ASUS_MODE3,
6122        ALC662_FIXUP_ASUS_MODE4,
6123        ALC662_FIXUP_ASUS_MODE5,
6124        ALC662_FIXUP_ASUS_MODE6,
6125        ALC662_FIXUP_ASUS_MODE7,
6126        ALC662_FIXUP_ASUS_MODE8,
6127        ALC662_FIXUP_NO_JACK_DETECT,
6128        ALC662_FIXUP_ZOTAC_Z68,
6129        ALC662_FIXUP_INV_DMIC,
6130        ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6131        ALC668_FIXUP_DELL_MIC_NO_PRESENCE,
6132        ALC662_FIXUP_HEADSET_MODE,
6133        ALC668_FIXUP_HEADSET_MODE,
6134        ALC662_FIXUP_BASS_MODE4_CHMAP,
6135        ALC662_FIXUP_BASS_16,
6136        ALC662_FIXUP_BASS_1A,
6137        ALC662_FIXUP_BASS_CHMAP,
6138        ALC668_FIXUP_AUTO_MUTE,
6139        ALC668_FIXUP_DELL_DISABLE_AAMIX,
6140        ALC668_FIXUP_DELL_XPS13,
6141};
6142
6143static const struct hda_fixup alc662_fixups[] = {
6144        [ALC662_FIXUP_ASPIRE] = {
6145                .type = HDA_FIXUP_PINS,
6146                .v.pins = (const struct hda_pintbl[]) {
6147                        { 0x15, 0x99130112 }, /* subwoofer */
6148                        { }
6149                }
6150        },
6151        [ALC662_FIXUP_LED_GPIO1] = {
6152                .type = HDA_FIXUP_FUNC,
6153                .v.func = alc662_fixup_led_gpio1,
6154        },
6155        [ALC662_FIXUP_IDEAPAD] = {
6156                .type = HDA_FIXUP_PINS,
6157                .v.pins = (const struct hda_pintbl[]) {
6158                        { 0x17, 0x99130112 }, /* subwoofer */
6159                        { }
6160                },
6161                .chained = true,
6162                .chain_id = ALC662_FIXUP_LED_GPIO1,
6163        },
6164        [ALC272_FIXUP_MARIO] = {
6165                .type = HDA_FIXUP_FUNC,
6166                .v.func = alc272_fixup_mario,
6167        },
6168        [ALC662_FIXUP_CZC_P10T] = {
6169                .type = HDA_FIXUP_VERBS,
6170                .v.verbs = (const struct hda_verb[]) {
6171                        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
6172                        {}
6173                }
6174        },
6175        [ALC662_FIXUP_SKU_IGNORE] = {
6176                .type = HDA_FIXUP_FUNC,
6177                .v.func = alc_fixup_sku_ignore,
6178        },
6179        [ALC662_FIXUP_HP_RP5800] = {
6180                .type = HDA_FIXUP_PINS,
6181                .v.pins = (const struct hda_pintbl[]) {
6182                        { 0x14, 0x0221201f }, /* HP out */
6183                        { }
6184                },
6185                .chained = true,
6186                .chain_id = ALC662_FIXUP_SKU_IGNORE
6187        },
6188        [ALC662_FIXUP_ASUS_MODE1] = {
6189                .type = HDA_FIXUP_PINS,
6190                .v.pins = (const struct hda_pintbl[]) {
6191                        { 0x14, 0x99130110 }, /* speaker */
6192                        { 0x18, 0x01a19c20 }, /* mic */
6193                        { 0x19, 0x99a3092f }, /* int-mic */
6194                        { 0x21, 0x0121401f }, /* HP out */
6195                        { }
6196                },
6197                .chained = true,
6198                .chain_id = ALC662_FIXUP_SKU_IGNORE
6199        },
6200        [ALC662_FIXUP_ASUS_MODE2] = {
6201                .type = HDA_FIXUP_PINS,
6202                .v.pins = (const struct hda_pintbl[]) {
6203                        { 0x14, 0x99130110 }, /* speaker */
6204                        { 0x18, 0x01a19820 }, /* mic */
6205                        { 0x19, 0x99a3092f }, /* int-mic */
6206                        { 0x1b, 0x0121401f }, /* HP out */
6207                        { }
6208                },
6209                .chained = true,
6210                .chain_id = ALC662_FIXUP_SKU_IGNORE
6211        },
6212        [ALC662_FIXUP_ASUS_MODE3] = {
6213                .type = HDA_FIXUP_PINS,
6214                .v.pins = (const struct hda_pintbl[]) {
6215                        { 0x14, 0x99130110 }, /* speaker */
6216                        { 0x15, 0x0121441f }, /* HP */
6217                        { 0x18, 0x01a19840 }, /* mic */
6218                        { 0x19, 0x99a3094f }, /* int-mic */
6219                        { 0x21, 0x01211420 }, /* HP2 */
6220                        { }
6221                },
6222                .chained = true,
6223                .chain_id = ALC662_FIXUP_SKU_IGNORE
6224        },
6225        [ALC662_FIXUP_ASUS_MODE4] = {
6226                .type = HDA_FIXUP_PINS,
6227                .v.pins = (const struct hda_pintbl[]) {
6228                        { 0x14, 0x99130110 }, /* speaker */
6229                        { 0x16, 0x99130111 }, /* speaker */
6230                        { 0x18, 0x01a19840 }, /* mic */
6231                        { 0x19, 0x99a3094f }, /* int-mic */
6232                        { 0x21, 0x0121441f }, /* HP */
6233                        { }
6234                },
6235                .chained = true,
6236                .chain_id = ALC662_FIXUP_SKU_IGNORE
6237        },
6238        [ALC662_FIXUP_ASUS_MODE5] = {
6239                .type = HDA_FIXUP_PINS,
6240                .v.pins = (const struct hda_pintbl[]) {
6241                        { 0x14, 0x99130110 }, /* speaker */
6242                        { 0x15, 0x0121441f }, /* HP */
6243                        { 0x16, 0x99130111 }, /* speaker */
6244                        { 0x18, 0x01a19840 }, /* mic */
6245                        { 0x19, 0x99a3094f }, /* int-mic */
6246                        { }
6247                },
6248                .chained = true,
6249                .chain_id = ALC662_FIXUP_SKU_IGNORE
6250        },
6251        [ALC662_FIXUP_ASUS_MODE6] = {
6252                .type = HDA_FIXUP_PINS,
6253                .v.pins = (const struct hda_pintbl[]) {
6254                        { 0x14, 0x99130110 }, /* speaker */
6255                        { 0x15, 0x01211420 }, /* HP2 */
6256                        { 0x18, 0x01a19840 }, /* mic */
6257                        { 0x19, 0x99a3094f }, /* int-mic */
6258                        { 0x1b, 0x0121441f }, /* HP */
6259                        { }
6260                },
6261                .chained = true,
6262                .chain_id = ALC662_FIXUP_SKU_IGNORE
6263        },
6264        [ALC662_FIXUP_ASUS_MODE7] = {
6265                .type = HDA_FIXUP_PINS,
6266                .v.pins = (const struct hda_pintbl[]) {
6267                        { 0x14, 0x99130110 }, /* speaker */
6268                        { 0x17, 0x99130111 }, /* speaker */
6269                        { 0x18, 0x01a19840 }, /* mic */
6270                        { 0x19, 0x99a3094f }, /* int-mic */
6271                        { 0x1b, 0x01214020 }, /* HP */
6272                        { 0x21, 0x0121401f }, /* HP */
6273                        { }
6274                },
6275                .chained = true,
6276                .chain_id = ALC662_FIXUP_SKU_IGNORE
6277        },
6278        [ALC662_FIXUP_ASUS_MODE8] = {
6279                .type = HDA_FIXUP_PINS,
6280                .v.pins = (const struct hda_pintbl[]) {
6281                        { 0x14, 0x99130110 }, /* speaker */
6282                        { 0x12, 0x99a30970 }, /* int-mic */
6283                        { 0x15, 0x01214020 }, /* HP */
6284                        { 0x17, 0x99130111 }, /* speaker */
6285                        { 0x18, 0x01a19840 }, /* mic */
6286                        { 0x21, 0x0121401f }, /* HP */
6287                        { }
6288                },
6289                .chained = true,
6290                .chain_id = ALC662_FIXUP_SKU_IGNORE
6291        },
6292        [ALC662_FIXUP_NO_JACK_DETECT] = {
6293                .type = HDA_FIXUP_FUNC,
6294                .v.func = alc_fixup_no_jack_detect,
6295        },
6296        [ALC662_FIXUP_ZOTAC_Z68] = {
6297                .type = HDA_FIXUP_PINS,
6298                .v.pins = (const struct hda_pintbl[]) {
6299                        { 0x1b, 0x02214020 }, /* Front HP */
6300                        { }
6301                }
6302        },
6303        [ALC662_FIXUP_INV_DMIC] = {
6304                .type = HDA_FIXUP_FUNC,
6305                .v.func = alc_fixup_inv_dmic,
6306        },
6307        [ALC668_FIXUP_DELL_XPS13] = {
6308                .type = HDA_FIXUP_FUNC,
6309                .v.func = alc_fixup_dell_xps13,
6310                .chained = true,
6311                .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX
6312        },
6313        [ALC668_FIXUP_DELL_DISABLE_AAMIX] = {
6314                .type = HDA_FIXUP_FUNC,
6315                .v.func = alc_fixup_disable_aamix,
6316                .chained = true,
6317                .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6318        },
6319        [ALC668_FIXUP_AUTO_MUTE] = {
6320                .type = HDA_FIXUP_FUNC,
6321                .v.func = alc_fixup_auto_mute_via_amp,
6322                .chained = true,
6323                .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE
6324        },
6325        [ALC662_FIXUP_DELL_MIC_NO_PRESENCE] = {
6326                .type = HDA_FIXUP_PINS,
6327                .v.pins = (const struct hda_pintbl[]) {
6328                        { 0x19, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6329                        /* headphone mic by setting pin control of 0x1b (headphone out) to in + vref_50 */
6330                        { }
6331                },
6332                .chained = true,
6333                .chain_id = ALC662_FIXUP_HEADSET_MODE
6334        },
6335        [ALC662_FIXUP_HEADSET_MODE] = {
6336                .type = HDA_FIXUP_FUNC,
6337                .v.func = alc_fixup_headset_mode_alc662,
6338        },
6339        [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = {
6340                .type = HDA_FIXUP_PINS,
6341                .v.pins = (const struct hda_pintbl[]) {
6342                        { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
6343                        { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */
6344                        { }
6345                },
6346                .chained = true,
6347                .chain_id = ALC668_FIXUP_HEADSET_MODE
6348        },
6349        [ALC668_FIXUP_HEADSET_MODE] = {
6350                .type = HDA_FIXUP_FUNC,
6351                .v.func = alc_fixup_headset_mode_alc668,
6352        },
6353        [ALC662_FIXUP_BASS_MODE4_CHMAP] = {
6354                .type = HDA_FIXUP_FUNC,
6355                .v.func = alc_fixup_bass_chmap,
6356                .chained = true,
6357                .chain_id = ALC662_FIXUP_ASUS_MODE4
6358        },
6359        [ALC662_FIXUP_BASS_16] = {
6360                .type = HDA_FIXUP_PINS,
6361                .v.pins = (const struct hda_pintbl[]) {
6362                        {0x16, 0x80106111}, /* bass speaker */
6363                        {}
6364                },
6365                .chained = true,
6366                .chain_id = ALC662_FIXUP_BASS_CHMAP,
6367        },
6368        [ALC662_FIXUP_BASS_1A] = {
6369                .type = HDA_FIXUP_PINS,
6370                .v.pins = (const struct hda_pintbl[]) {
6371                        {0x1a, 0x80106111}, /* bass speaker */
6372                        {}
6373                },
6374                .chained = true,
6375                .chain_id = ALC662_FIXUP_BASS_CHMAP,
6376        },
6377        [ALC662_FIXUP_BASS_CHMAP] = {
6378                .type = HDA_FIXUP_FUNC,
6379                .v.func = alc_fixup_bass_chmap,
6380        },
6381};
6382
6383static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6384        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6385        SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC),
6386        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6387        SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6388        SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6389        SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC),
6390        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6391        SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6392        SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6393        SND_PCI_QUIRK(0x1028, 0x05fe, "Dell XPS 15", ALC668_FIXUP_DELL_XPS13),
6394        SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13),
6395        SND_PCI_QUIRK(0x1028, 0x060d, "Dell M3800", ALC668_FIXUP_DELL_XPS13),
6396        SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6397        SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6398        SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6399        SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6400        SND_PCI_QUIRK(0x1028, 0x069f, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
6401        SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6402        SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
6403        SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6404        SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16),
6405        SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16),
6406        SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
6407        SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
6408        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2),
6409        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
6410        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6411        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
6412        SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
6413        SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6414
6415#if 0
6416        /* Below is a quirk table taken from the old code.
6417         * Basically the device should work as is without the fixup table.
6418         * If BIOS doesn't give a proper info, enable the corresponding
6419         * fixup entry.
6420         */
6421        SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1),
6422        SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3),
6423        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1),
6424        SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3),
6425        SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6426        SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6427        SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6428        SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1),
6429        SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1),
6430        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6431        SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7),
6432        SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7),
6433        SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8),
6434        SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3),
6435        SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1),
6436        SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6437        SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2),
6438        SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1),
6439        SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6440        SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6441        SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6442        SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6443        SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1),
6444        SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3),
6445        SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2),
6446        SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6447        SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5),
6448        SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6),
6449        SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6450        SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1),
6451        SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6452        SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6453        SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3),
6454        SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3),
6455        SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1),
6456        SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1),
6457        SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1),
6458        SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1),
6459        SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1),
6460        SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2),
6461        SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2),
6462        SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1),
6463        SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6464        SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3),
6465        SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1),
6466        SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1),
6467        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1),
6468        SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2),
6469        SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1),
6470        SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4),
6471#endif
6472        {}
6473};
6474
6475static const struct hda_model_fixup alc662_fixup_models[] = {
6476        {.id = ALC272_FIXUP_MARIO, .name = "mario"},
6477        {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"},
6478        {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"},
6479        {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"},
6480        {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"},
6481        {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"},
6482        {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6483        {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6484        {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6485        {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6486        {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"},
6487        {}
6488};
6489
6490static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
6491        SND_HDA_PIN_QUIRK(0x10ec0662, 0x1028, "Dell", ALC662_FIXUP_DELL_MIC_NO_PRESENCE,
6492                {0x14, 0x01014010},
6493                {0x18, 0x01a19020},
6494                {0x1a, 0x0181302f},
6495                {0x1b, 0x0221401f}),
6496        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6497                {0x12, 0x99a30130},
6498                {0x14, 0x90170110},
6499                {0x15, 0x0321101f},
6500                {0x16, 0x03011020}),
6501        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6502                {0x12, 0x99a30140},
6503                {0x14, 0x90170110},
6504                {0x15, 0x0321101f},
6505                {0x16, 0x03011020}),
6506        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6507                {0x12, 0x99a30150},
6508                {0x14, 0x90170110},
6509                {0x15, 0x0321101f},
6510                {0x16, 0x03011020}),
6511        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell", ALC668_FIXUP_AUTO_MUTE,
6512                {0x14, 0x90170110},
6513                {0x15, 0x0321101f},
6514                {0x16, 0x03011020}),
6515        SND_HDA_PIN_QUIRK(0x10ec0668, 0x1028, "Dell XPS 15", ALC668_FIXUP_AUTO_MUTE,
6516                {0x12, 0x90a60130},
6517                {0x14, 0x90170110},
6518                {0x15, 0x0321101f}),
6519        {}
6520};
6521
6522/*
6523 */
6524static int patch_alc662(struct hda_codec *codec)
6525{
6526        struct alc_spec *spec;
6527        int err;
6528
6529        err = alc_alloc_spec(codec, 0x0b);
6530        if (err < 0)
6531                return err;
6532
6533        spec = codec->spec;
6534
6535        spec->shutup = alc_eapd_shutup;
6536
6537        /* handle multiple HPs as is */
6538        spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
6539
6540        alc_fix_pll_init(codec, 0x20, 0x04, 15);
6541
6542        switch (codec->core.vendor_id) {
6543        case 0x10ec0668:
6544                spec->init_hook = alc668_restore_default_value;
6545                break;
6546        }
6547
6548        snd_hda_pick_fixup(codec, alc662_fixup_models,
6549                       alc662_fixup_tbl, alc662_fixups);
6550        snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
6551        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
6552
6553        alc_auto_parse_customize_define(codec);
6554
6555        if (has_cdefine_beep(codec))
6556                spec->gen.beep_nid = 0x01;
6557
6558        if ((alc_get_coef0(codec) & (1 << 14)) &&
6559            codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 &&
6560            spec->cdefine.platform_type == 1) {
6561                err = alc_codec_rename(codec, "ALC272X");
6562                if (err < 0)
6563                        goto error;
6564        }
6565
6566        /* automatic parse from the BIOS config */
6567        err = alc662_parse_auto_config(codec);
6568        if (err < 0)
6569                goto error;
6570
6571        if (!spec->gen.no_analog && spec->gen.beep_nid) {
6572                switch (codec->core.vendor_id) {
6573                case 0x10ec0662:
6574                        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6575                        break;
6576                case 0x10ec0272:
6577                case 0x10ec0663:
6578                case 0x10ec0665:
6579                case 0x10ec0668:
6580                        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
6581                        break;
6582                case 0x10ec0273:
6583                        set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
6584                        break;
6585                }
6586        }
6587
6588        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
6589
6590        return 0;
6591
6592 error:
6593        alc_free(codec);
6594        return err;
6595}
6596
6597/*
6598 * ALC680 support
6599 */
6600
6601static int alc680_parse_auto_config(struct hda_codec *codec)
6602{
6603        return alc_parse_auto_config(codec, NULL, NULL);
6604}
6605
6606/*
6607 */
6608static int patch_alc680(struct hda_codec *codec)
6609{
6610        int err;
6611
6612        /* ALC680 has no aa-loopback mixer */
6613        err = alc_alloc_spec(codec, 0);
6614        if (err < 0)
6615                return err;
6616
6617        /* automatic parse from the BIOS config */
6618        err = alc680_parse_auto_config(codec);
6619        if (err < 0) {
6620                alc_free(codec);
6621                return err;
6622        }
6623
6624        return 0;
6625}
6626
6627/*
6628 * patch entries
6629 */
6630static const struct hda_codec_preset snd_hda_preset_realtek[] = {
6631        { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
6632        { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 },
6633        { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 },
6634        { .id = 0x10ec0235, .name = "ALC233", .patch = patch_alc269 },
6635        { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 },
6636        { .id = 0x10ec0256, .name = "ALC256", .patch = patch_alc269 },
6637        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
6638        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
6639        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
6640        { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
6641        { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
6642        { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
6643        { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
6644        { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
6645        { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
6646        { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
6647        { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
6648        { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
6649        { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
6650        { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
6651        { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
6652        { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
6653        { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
6654        { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
6655        { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
6656        { .id = 0x10ec0298, .name = "ALC298", .patch = patch_alc269 },
6657        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6658          .patch = patch_alc861 },
6659        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
6660        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
6661        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
6662        { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
6663          .patch = patch_alc882 },
6664        { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
6665          .patch = patch_alc662 },
6666        { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
6667          .patch = patch_alc662 },
6668        { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
6669        { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6670        { .id = 0x10ec0667, .name = "ALC667", .patch = patch_alc662 },
6671        { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 },
6672        { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
6673        { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 },
6674        { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
6675        { .id = 0x10ec0867, .name = "ALC891", .patch = patch_alc882 },
6676        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
6677        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
6678        { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
6679        { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
6680          .patch = patch_alc882 },
6681        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
6682          .patch = patch_alc882 },
6683        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
6684        { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
6685        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
6686          .patch = patch_alc882 },
6687        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
6688        { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
6689        { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
6690        { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 },
6691        { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 },
6692        {} /* terminator */
6693};
6694
6695MODULE_ALIAS("snd-hda-codec-id:10ec*");
6696
6697MODULE_LICENSE("GPL");
6698MODULE_DESCRIPTION("Realtek HD-audio codec");
6699
6700static struct hda_codec_driver realtek_driver = {
6701        .preset = snd_hda_preset_realtek,
6702};
6703
6704module_hda_codec_driver(realtek_driver);
6705