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