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