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