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