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 ALC 260/880/882 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@physics.adelaide.edu.au>
  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 <sound/core.h>
  31#include <sound/jack.h>
  32#include "hda_codec.h"
  33#include "hda_local.h"
  34#include "hda_beep.h"
  35
  36#define ALC880_FRONT_EVENT              0x01
  37#define ALC880_DCVOL_EVENT              0x02
  38#define ALC880_HP_EVENT                 0x04
  39#define ALC880_MIC_EVENT                0x08
  40
  41/* ALC880 board config type */
  42enum {
  43        ALC880_3ST,
  44        ALC880_3ST_DIG,
  45        ALC880_5ST,
  46        ALC880_5ST_DIG,
  47        ALC880_W810,
  48        ALC880_Z71V,
  49        ALC880_6ST,
  50        ALC880_6ST_DIG,
  51        ALC880_F1734,
  52        ALC880_ASUS,
  53        ALC880_ASUS_DIG,
  54        ALC880_ASUS_W1V,
  55        ALC880_ASUS_DIG2,
  56        ALC880_FUJITSU,
  57        ALC880_UNIWILL_DIG,
  58        ALC880_UNIWILL,
  59        ALC880_UNIWILL_P53,
  60        ALC880_CLEVO,
  61        ALC880_TCL_S700,
  62        ALC880_LG,
  63        ALC880_LG_LW,
  64        ALC880_MEDION_RIM,
  65#ifdef CONFIG_SND_DEBUG
  66        ALC880_TEST,
  67#endif
  68        ALC880_AUTO,
  69        ALC880_MODEL_LAST /* last tag */
  70};
  71
  72/* ALC260 models */
  73enum {
  74        ALC260_BASIC,
  75        ALC260_HP,
  76        ALC260_HP_DC7600,
  77        ALC260_HP_3013,
  78        ALC260_FUJITSU_S702X,
  79        ALC260_ACER,
  80        ALC260_WILL,
  81        ALC260_REPLACER_672V,
  82        ALC260_FAVORIT100,
  83#ifdef CONFIG_SND_DEBUG
  84        ALC260_TEST,
  85#endif
  86        ALC260_AUTO,
  87        ALC260_MODEL_LAST /* last tag */
  88};
  89
  90/* ALC262 models */
  91enum {
  92        ALC262_BASIC,
  93        ALC262_HIPPO,
  94        ALC262_HIPPO_1,
  95        ALC262_FUJITSU,
  96        ALC262_HP_BPC,
  97        ALC262_HP_BPC_D7000_WL,
  98        ALC262_HP_BPC_D7000_WF,
  99        ALC262_HP_TC_T5735,
 100        ALC262_HP_RP5700,
 101        ALC262_BENQ_ED8,
 102        ALC262_SONY_ASSAMD,
 103        ALC262_BENQ_T31,
 104        ALC262_ULTRA,
 105        ALC262_LENOVO_3000,
 106        ALC262_NEC,
 107        ALC262_TOSHIBA_S06,
 108        ALC262_TOSHIBA_RX1,
 109        ALC262_TYAN,
 110        ALC262_AUTO,
 111        ALC262_MODEL_LAST /* last tag */
 112};
 113
 114/* ALC268 models */
 115enum {
 116        ALC267_QUANTA_IL1,
 117        ALC268_3ST,
 118        ALC268_TOSHIBA,
 119        ALC268_ACER,
 120        ALC268_ACER_DMIC,
 121        ALC268_ACER_ASPIRE_ONE,
 122        ALC268_DELL,
 123        ALC268_ZEPTO,
 124#ifdef CONFIG_SND_DEBUG
 125        ALC268_TEST,
 126#endif
 127        ALC268_AUTO,
 128        ALC268_MODEL_LAST /* last tag */
 129};
 130
 131/* ALC269 models */
 132enum {
 133        ALC269_BASIC,
 134        ALC269_QUANTA_FL1,
 135        ALC269_AMIC,
 136        ALC269_DMIC,
 137        ALC269VB_AMIC,
 138        ALC269VB_DMIC,
 139        ALC269_FUJITSU,
 140        ALC269_LIFEBOOK,
 141        ALC271_ACER,
 142        ALC269_AUTO,
 143        ALC269_MODEL_LAST /* last tag */
 144};
 145
 146/* ALC861 models */
 147enum {
 148        ALC861_3ST,
 149        ALC660_3ST,
 150        ALC861_3ST_DIG,
 151        ALC861_6ST_DIG,
 152        ALC861_UNIWILL_M31,
 153        ALC861_TOSHIBA,
 154        ALC861_ASUS,
 155        ALC861_ASUS_LAPTOP,
 156        ALC861_AUTO,
 157        ALC861_MODEL_LAST,
 158};
 159
 160/* ALC861-VD models */
 161enum {
 162        ALC660VD_3ST,
 163        ALC660VD_3ST_DIG,
 164        ALC660VD_ASUS_V1S,
 165        ALC861VD_3ST,
 166        ALC861VD_3ST_DIG,
 167        ALC861VD_6ST_DIG,
 168        ALC861VD_LENOVO,
 169        ALC861VD_DALLAS,
 170        ALC861VD_HP,
 171        ALC861VD_AUTO,
 172        ALC861VD_MODEL_LAST,
 173};
 174
 175/* ALC662 models */
 176enum {
 177        ALC662_3ST_2ch_DIG,
 178        ALC662_3ST_6ch_DIG,
 179        ALC662_3ST_6ch,
 180        ALC662_5ST_DIG,
 181        ALC662_LENOVO_101E,
 182        ALC662_ASUS_EEEPC_P701,
 183        ALC662_ASUS_EEEPC_EP20,
 184        ALC663_ASUS_M51VA,
 185        ALC663_ASUS_G71V,
 186        ALC663_ASUS_H13,
 187        ALC663_ASUS_G50V,
 188        ALC662_ECS,
 189        ALC663_ASUS_MODE1,
 190        ALC662_ASUS_MODE2,
 191        ALC663_ASUS_MODE3,
 192        ALC663_ASUS_MODE4,
 193        ALC663_ASUS_MODE5,
 194        ALC663_ASUS_MODE6,
 195        ALC663_ASUS_MODE7,
 196        ALC663_ASUS_MODE8,
 197        ALC272_DELL,
 198        ALC272_DELL_ZM1,
 199        ALC272_SAMSUNG_NC10,
 200        ALC662_AUTO,
 201        ALC662_MODEL_LAST,
 202};
 203
 204/* ALC882 models */
 205enum {
 206        ALC882_3ST_DIG,
 207        ALC882_6ST_DIG,
 208        ALC882_ARIMA,
 209        ALC882_W2JC,
 210        ALC882_TARGA,
 211        ALC882_ASUS_A7J,
 212        ALC882_ASUS_A7M,
 213        ALC885_MACPRO,
 214        ALC885_MBA21,
 215        ALC885_MBP3,
 216        ALC885_MB5,
 217        ALC885_MACMINI3,
 218        ALC885_IMAC24,
 219        ALC885_IMAC91,
 220        ALC883_3ST_2ch_DIG,
 221        ALC883_3ST_6ch_DIG,
 222        ALC883_3ST_6ch,
 223        ALC883_6ST_DIG,
 224        ALC883_TARGA_DIG,
 225        ALC883_TARGA_2ch_DIG,
 226        ALC883_TARGA_8ch_DIG,
 227        ALC883_ACER,
 228        ALC883_ACER_ASPIRE,
 229        ALC888_ACER_ASPIRE_4930G,
 230        ALC888_ACER_ASPIRE_6530G,
 231        ALC888_ACER_ASPIRE_8930G,
 232        ALC888_ACER_ASPIRE_7730G,
 233        ALC883_MEDION,
 234        ALC883_MEDION_WIM2160,
 235        ALC883_LAPTOP_EAPD,
 236        ALC883_LENOVO_101E_2ch,
 237        ALC883_LENOVO_NB0763,
 238        ALC888_LENOVO_MS7195_DIG,
 239        ALC888_LENOVO_SKY,
 240        ALC883_HAIER_W66,
 241        ALC888_3ST_HP,
 242        ALC888_6ST_DELL,
 243        ALC883_MITAC,
 244        ALC883_CLEVO_M540R,
 245        ALC883_CLEVO_M720,
 246        ALC883_FUJITSU_PI2515,
 247        ALC888_FUJITSU_XA3530,
 248        ALC883_3ST_6ch_INTEL,
 249        ALC889A_INTEL,
 250        ALC889_INTEL,
 251        ALC888_ASUS_M90V,
 252        ALC888_ASUS_EEE1601,
 253        ALC889A_MB31,
 254        ALC1200_ASUS_P5Q,
 255        ALC883_SONY_VAIO_TT,
 256        ALC882_AUTO,
 257        ALC882_MODEL_LAST,
 258};
 259
 260/* ALC680 models */
 261enum {
 262        ALC680_BASE,
 263        ALC680_AUTO,
 264        ALC680_MODEL_LAST,
 265};
 266
 267/* for GPIO Poll */
 268#define GPIO_MASK       0x03
 269
 270/* extra amp-initialization sequence types */
 271enum {
 272        ALC_INIT_NONE,
 273        ALC_INIT_DEFAULT,
 274        ALC_INIT_GPIO1,
 275        ALC_INIT_GPIO2,
 276        ALC_INIT_GPIO3,
 277};
 278
 279struct alc_mic_route {
 280        hda_nid_t pin;
 281        unsigned char mux_idx;
 282        unsigned char amix_idx;
 283};
 284
 285struct alc_jack {
 286        hda_nid_t nid;
 287        int type;
 288        struct snd_jack *jack;
 289};
 290
 291#define MUX_IDX_UNDEF   ((unsigned char)-1)
 292
 293struct alc_customize_define {
 294        unsigned int  sku_cfg;
 295        unsigned char port_connectivity;
 296        unsigned char check_sum;
 297        unsigned char customization;
 298        unsigned char external_amp;
 299        unsigned int  enable_pcbeep:1;
 300        unsigned int  platform_type:1;
 301        unsigned int  swap:1;
 302        unsigned int  override:1;
 303        unsigned int  fixup:1; /* Means that this sku is set by driver, not read from hw */
 304};
 305
 306struct alc_fixup;
 307
 308struct alc_spec {
 309        /* codec parameterization */
 310        struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
 311        unsigned int num_mixers;
 312        struct snd_kcontrol_new *cap_mixer;     /* capture mixer */
 313        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
 314
 315        const struct hda_verb *init_verbs[10];  /* initialization verbs
 316                                                 * don't forget NULL
 317                                                 * termination!
 318                                                 */
 319        unsigned int num_init_verbs;
 320
 321        char stream_name_analog[32];    /* analog PCM stream */
 322        struct hda_pcm_stream *stream_analog_playback;
 323        struct hda_pcm_stream *stream_analog_capture;
 324        struct hda_pcm_stream *stream_analog_alt_playback;
 325        struct hda_pcm_stream *stream_analog_alt_capture;
 326
 327        char stream_name_digital[32];   /* digital PCM stream */
 328        struct hda_pcm_stream *stream_digital_playback;
 329        struct hda_pcm_stream *stream_digital_capture;
 330
 331        /* playback */
 332        struct hda_multi_out multiout;  /* playback set-up
 333                                         * max_channels, dacs must be set
 334                                         * dig_out_nid and hp_nid are optional
 335                                         */
 336        hda_nid_t alt_dac_nid;
 337        hda_nid_t slave_dig_outs[3];    /* optional - for auto-parsing */
 338        int dig_out_type;
 339
 340        /* capture */
 341        unsigned int num_adc_nids;
 342        hda_nid_t *adc_nids;
 343        hda_nid_t *capsrc_nids;
 344        hda_nid_t dig_in_nid;           /* digital-in NID; optional */
 345
 346        /* capture setup for dynamic dual-adc switch */
 347        unsigned int cur_adc_idx;
 348        hda_nid_t cur_adc;
 349        unsigned int cur_adc_stream_tag;
 350        unsigned int cur_adc_format;
 351
 352        /* capture source */
 353        unsigned int num_mux_defs;
 354        const struct hda_input_mux *input_mux;
 355        unsigned int cur_mux[3];
 356        struct alc_mic_route ext_mic;
 357        struct alc_mic_route int_mic;
 358
 359        /* channel model */
 360        const struct hda_channel_mode *channel_mode;
 361        int num_channel_mode;
 362        int need_dac_fix;
 363        int const_channel_count;
 364        int ext_channel_count;
 365
 366        /* PCM information */
 367        struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
 368
 369        /* jack detection */
 370        struct snd_array jacks;
 371
 372        /* dynamic controls, init_verbs and input_mux */
 373        struct auto_pin_cfg autocfg;
 374        struct alc_customize_define cdefine;
 375        struct snd_array kctls;
 376        struct hda_input_mux private_imux[3];
 377        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 378        hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
 379        hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
 380
 381        /* hooks */
 382        void (*init_hook)(struct hda_codec *codec);
 383        void (*unsol_event)(struct hda_codec *codec, unsigned int res);
 384#ifdef CONFIG_SND_HDA_POWER_SAVE
 385        void (*power_hook)(struct hda_codec *codec);
 386#endif
 387
 388        /* for pin sensing */
 389        unsigned int sense_updated: 1;
 390        unsigned int jack_present: 1;
 391        unsigned int master_sw: 1;
 392        unsigned int auto_mic:1;
 393
 394        /* other flags */
 395        unsigned int no_analog :1; /* digital I/O only */
 396        unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
 397        int init_amp;
 398        int codec_variant;      /* flag for other variants */
 399
 400        /* for virtual master */
 401        hda_nid_t vmaster_nid;
 402#ifdef CONFIG_SND_HDA_POWER_SAVE
 403        struct hda_loopback_check loopback;
 404#endif
 405
 406        /* for PLL fix */
 407        hda_nid_t pll_nid;
 408        unsigned int pll_coef_idx, pll_coef_bit;
 409
 410        /* fix-up list */
 411        int fixup_id;
 412        const struct alc_fixup *fixup_list;
 413        const char *fixup_name;
 414};
 415
 416/*
 417 * configuration template - to be copied to the spec instance
 418 */
 419struct alc_config_preset {
 420        struct snd_kcontrol_new *mixers[5]; /* should be identical size
 421                                             * with spec
 422                                             */
 423        struct snd_kcontrol_new *cap_mixer; /* capture mixer */
 424        const struct hda_verb *init_verbs[5];
 425        unsigned int num_dacs;
 426        hda_nid_t *dac_nids;
 427        hda_nid_t dig_out_nid;          /* optional */
 428        hda_nid_t hp_nid;               /* optional */
 429        hda_nid_t *slave_dig_outs;
 430        unsigned int num_adc_nids;
 431        hda_nid_t *adc_nids;
 432        hda_nid_t *capsrc_nids;
 433        hda_nid_t dig_in_nid;
 434        unsigned int num_channel_mode;
 435        const struct hda_channel_mode *channel_mode;
 436        int need_dac_fix;
 437        int const_channel_count;
 438        unsigned int num_mux_defs;
 439        const struct hda_input_mux *input_mux;
 440        void (*unsol_event)(struct hda_codec *, unsigned int);
 441        void (*setup)(struct hda_codec *);
 442        void (*init_hook)(struct hda_codec *);
 443#ifdef CONFIG_SND_HDA_POWER_SAVE
 444        struct hda_amp_list *loopbacks;
 445        void (*power_hook)(struct hda_codec *codec);
 446#endif
 447};
 448
 449
 450/*
 451 * input MUX handling
 452 */
 453static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
 454                             struct snd_ctl_elem_info *uinfo)
 455{
 456        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 457        struct alc_spec *spec = codec->spec;
 458        unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
 459        if (mux_idx >= spec->num_mux_defs)
 460                mux_idx = 0;
 461        if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
 462                mux_idx = 0;
 463        return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
 464}
 465
 466static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
 467                            struct snd_ctl_elem_value *ucontrol)
 468{
 469        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 470        struct alc_spec *spec = codec->spec;
 471        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 472
 473        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 474        return 0;
 475}
 476
 477static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
 478                            struct snd_ctl_elem_value *ucontrol)
 479{
 480        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 481        struct alc_spec *spec = codec->spec;
 482        const struct hda_input_mux *imux;
 483        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 484        unsigned int mux_idx;
 485        hda_nid_t nid = spec->capsrc_nids ?
 486                spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
 487        unsigned int type;
 488
 489        mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
 490        imux = &spec->input_mux[mux_idx];
 491        if (!imux->num_items && mux_idx > 0)
 492                imux = &spec->input_mux[0];
 493
 494        type = get_wcaps_type(get_wcaps(codec, nid));
 495        if (type == AC_WID_AUD_MIX) {
 496                /* Matrix-mixer style (e.g. ALC882) */
 497                unsigned int *cur_val = &spec->cur_mux[adc_idx];
 498                unsigned int i, idx;
 499
 500                idx = ucontrol->value.enumerated.item[0];
 501                if (idx >= imux->num_items)
 502                        idx = imux->num_items - 1;
 503                if (*cur_val == idx)
 504                        return 0;
 505                for (i = 0; i < imux->num_items; i++) {
 506                        unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
 507                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
 508                                                 imux->items[i].index,
 509                                                 HDA_AMP_MUTE, v);
 510                }
 511                *cur_val = idx;
 512                return 1;
 513        } else {
 514                /* MUX style (e.g. ALC880) */
 515                return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
 516                                             &spec->cur_mux[adc_idx]);
 517        }
 518}
 519
 520/*
 521 * channel mode setting
 522 */
 523static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
 524                            struct snd_ctl_elem_info *uinfo)
 525{
 526        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 527        struct alc_spec *spec = codec->spec;
 528        return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
 529                                    spec->num_channel_mode);
 530}
 531
 532static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
 533                           struct snd_ctl_elem_value *ucontrol)
 534{
 535        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 536        struct alc_spec *spec = codec->spec;
 537        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
 538                                   spec->num_channel_mode,
 539                                   spec->ext_channel_count);
 540}
 541
 542static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
 543                           struct snd_ctl_elem_value *ucontrol)
 544{
 545        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 546        struct alc_spec *spec = codec->spec;
 547        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
 548                                      spec->num_channel_mode,
 549                                      &spec->ext_channel_count);
 550        if (err >= 0 && !spec->const_channel_count) {
 551                spec->multiout.max_channels = spec->ext_channel_count;
 552                if (spec->need_dac_fix)
 553                        spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 554        }
 555        return err;
 556}
 557
 558/*
 559 * Control the mode of pin widget settings via the mixer.  "pc" is used
 560 * instead of "%" to avoid consequences of accidently treating the % as
 561 * being part of a format specifier.  Maximum allowed length of a value is
 562 * 63 characters plus NULL terminator.
 563 *
 564 * Note: some retasking pin complexes seem to ignore requests for input
 565 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
 566 * are requested.  Therefore order this list so that this behaviour will not
 567 * cause problems when mixer clients move through the enum sequentially.
 568 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
 569 * March 2006.
 570 */
 571static char *alc_pin_mode_names[] = {
 572        "Mic 50pc bias", "Mic 80pc bias",
 573        "Line in", "Line out", "Headphone out",
 574};
 575static unsigned char alc_pin_mode_values[] = {
 576        PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
 577};
 578/* The control can present all 5 options, or it can limit the options based
 579 * in the pin being assumed to be exclusively an input or an output pin.  In
 580 * addition, "input" pins may or may not process the mic bias option
 581 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
 582 * accept requests for bias as of chip versions up to March 2006) and/or
 583 * wiring in the computer.
 584 */
 585#define ALC_PIN_DIR_IN              0x00
 586#define ALC_PIN_DIR_OUT             0x01
 587#define ALC_PIN_DIR_INOUT           0x02
 588#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
 589#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
 590
 591/* Info about the pin modes supported by the different pin direction modes.
 592 * For each direction the minimum and maximum values are given.
 593 */
 594static signed char alc_pin_mode_dir_info[5][2] = {
 595        { 0, 2 },    /* ALC_PIN_DIR_IN */
 596        { 3, 4 },    /* ALC_PIN_DIR_OUT */
 597        { 0, 4 },    /* ALC_PIN_DIR_INOUT */
 598        { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
 599        { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
 600};
 601#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
 602#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
 603#define alc_pin_mode_n_items(_dir) \
 604        (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
 605
 606static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
 607                             struct snd_ctl_elem_info *uinfo)
 608{
 609        unsigned int item_num = uinfo->value.enumerated.item;
 610        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 611
 612        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 613        uinfo->count = 1;
 614        uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
 615
 616        if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
 617                item_num = alc_pin_mode_min(dir);
 618        strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
 619        return 0;
 620}
 621
 622static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
 623                            struct snd_ctl_elem_value *ucontrol)
 624{
 625        unsigned int i;
 626        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 627        hda_nid_t nid = kcontrol->private_value & 0xffff;
 628        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 629        long *valp = ucontrol->value.integer.value;
 630        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
 631                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
 632                                                 0x00);
 633
 634        /* Find enumerated value for current pinctl setting */
 635        i = alc_pin_mode_min(dir);
 636        while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
 637                i++;
 638        *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
 639        return 0;
 640}
 641
 642static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
 643                            struct snd_ctl_elem_value *ucontrol)
 644{
 645        signed int change;
 646        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 647        hda_nid_t nid = kcontrol->private_value & 0xffff;
 648        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 649        long val = *ucontrol->value.integer.value;
 650        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
 651                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
 652                                                 0x00);
 653
 654        if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
 655                val = alc_pin_mode_min(dir);
 656
 657        change = pinctl != alc_pin_mode_values[val];
 658        if (change) {
 659                /* Set pin mode to that requested */
 660                snd_hda_codec_write_cache(codec, nid, 0,
 661                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
 662                                          alc_pin_mode_values[val]);
 663
 664                /* Also enable the retasking pin's input/output as required
 665                 * for the requested pin mode.  Enum values of 2 or less are
 666                 * input modes.
 667                 *
 668                 * Dynamically switching the input/output buffers probably
 669                 * reduces noise slightly (particularly on input) so we'll
 670                 * do it.  However, having both input and output buffers
 671                 * enabled simultaneously doesn't seem to be problematic if
 672                 * this turns out to be necessary in the future.
 673                 */
 674                if (val <= 2) {
 675                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 676                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
 677                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
 678                                                 HDA_AMP_MUTE, 0);
 679                } else {
 680                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
 681                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
 682                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 683                                                 HDA_AMP_MUTE, 0);
 684                }
 685        }
 686        return change;
 687}
 688
 689#define ALC_PIN_MODE(xname, nid, dir) \
 690        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 691          .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
 692          .info = alc_pin_mode_info, \
 693          .get = alc_pin_mode_get, \
 694          .put = alc_pin_mode_put, \
 695          .private_value = nid | (dir<<16) }
 696
 697/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
 698 * together using a mask with more than one bit set.  This control is
 699 * currently used only by the ALC260 test model.  At this stage they are not
 700 * needed for any "production" models.
 701 */
 702#ifdef CONFIG_SND_DEBUG
 703#define alc_gpio_data_info      snd_ctl_boolean_mono_info
 704
 705static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
 706                             struct snd_ctl_elem_value *ucontrol)
 707{
 708        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 709        hda_nid_t nid = kcontrol->private_value & 0xffff;
 710        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 711        long *valp = ucontrol->value.integer.value;
 712        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 713                                              AC_VERB_GET_GPIO_DATA, 0x00);
 714
 715        *valp = (val & mask) != 0;
 716        return 0;
 717}
 718static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
 719                             struct snd_ctl_elem_value *ucontrol)
 720{
 721        signed int change;
 722        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 723        hda_nid_t nid = kcontrol->private_value & 0xffff;
 724        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 725        long val = *ucontrol->value.integer.value;
 726        unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
 727                                                    AC_VERB_GET_GPIO_DATA,
 728                                                    0x00);
 729
 730        /* Set/unset the masked GPIO bit(s) as needed */
 731        change = (val == 0 ? 0 : mask) != (gpio_data & mask);
 732        if (val == 0)
 733                gpio_data &= ~mask;
 734        else
 735                gpio_data |= mask;
 736        snd_hda_codec_write_cache(codec, nid, 0,
 737                                  AC_VERB_SET_GPIO_DATA, gpio_data);
 738
 739        return change;
 740}
 741#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
 742        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 743          .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
 744          .info = alc_gpio_data_info, \
 745          .get = alc_gpio_data_get, \
 746          .put = alc_gpio_data_put, \
 747          .private_value = nid | (mask<<16) }
 748#endif   /* CONFIG_SND_DEBUG */
 749
 750/* A switch control to allow the enabling of the digital IO pins on the
 751 * ALC260.  This is incredibly simplistic; the intention of this control is
 752 * to provide something in the test model allowing digital outputs to be
 753 * identified if present.  If models are found which can utilise these
 754 * outputs a more complete mixer control can be devised for those models if
 755 * necessary.
 756 */
 757#ifdef CONFIG_SND_DEBUG
 758#define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
 759
 760static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
 761                              struct snd_ctl_elem_value *ucontrol)
 762{
 763        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 764        hda_nid_t nid = kcontrol->private_value & 0xffff;
 765        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 766        long *valp = ucontrol->value.integer.value;
 767        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 768                                              AC_VERB_GET_DIGI_CONVERT_1, 0x00);
 769
 770        *valp = (val & mask) != 0;
 771        return 0;
 772}
 773static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
 774                              struct snd_ctl_elem_value *ucontrol)
 775{
 776        signed int change;
 777        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 778        hda_nid_t nid = kcontrol->private_value & 0xffff;
 779        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 780        long val = *ucontrol->value.integer.value;
 781        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
 782                                                    AC_VERB_GET_DIGI_CONVERT_1,
 783                                                    0x00);
 784
 785        /* Set/unset the masked control bit(s) as needed */
 786        change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
 787        if (val==0)
 788                ctrl_data &= ~mask;
 789        else
 790                ctrl_data |= mask;
 791        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 792                                  ctrl_data);
 793
 794        return change;
 795}
 796#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
 797        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 798          .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
 799          .info = alc_spdif_ctrl_info, \
 800          .get = alc_spdif_ctrl_get, \
 801          .put = alc_spdif_ctrl_put, \
 802          .private_value = nid | (mask<<16) }
 803#endif   /* CONFIG_SND_DEBUG */
 804
 805/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
 806 * Again, this is only used in the ALC26x test models to help identify when
 807 * the EAPD line must be asserted for features to work.
 808 */
 809#ifdef CONFIG_SND_DEBUG
 810#define alc_eapd_ctrl_info      snd_ctl_boolean_mono_info
 811
 812static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
 813                              struct snd_ctl_elem_value *ucontrol)
 814{
 815        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 816        hda_nid_t nid = kcontrol->private_value & 0xffff;
 817        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 818        long *valp = ucontrol->value.integer.value;
 819        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 820                                              AC_VERB_GET_EAPD_BTLENABLE, 0x00);
 821
 822        *valp = (val & mask) != 0;
 823        return 0;
 824}
 825
 826static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
 827                              struct snd_ctl_elem_value *ucontrol)
 828{
 829        int change;
 830        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 831        hda_nid_t nid = kcontrol->private_value & 0xffff;
 832        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 833        long val = *ucontrol->value.integer.value;
 834        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
 835                                                    AC_VERB_GET_EAPD_BTLENABLE,
 836                                                    0x00);
 837
 838        /* Set/unset the masked control bit(s) as needed */
 839        change = (!val ? 0 : mask) != (ctrl_data & mask);
 840        if (!val)
 841                ctrl_data &= ~mask;
 842        else
 843                ctrl_data |= mask;
 844        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
 845                                  ctrl_data);
 846
 847        return change;
 848}
 849
 850#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
 851        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 852          .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
 853          .info = alc_eapd_ctrl_info, \
 854          .get = alc_eapd_ctrl_get, \
 855          .put = alc_eapd_ctrl_put, \
 856          .private_value = nid | (mask<<16) }
 857#endif   /* CONFIG_SND_DEBUG */
 858
 859/*
 860 * set up the input pin config (depending on the given auto-pin type)
 861 */
 862static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
 863                              int auto_pin_type)
 864{
 865        unsigned int val = PIN_IN;
 866
 867        if (auto_pin_type == AUTO_PIN_MIC) {
 868                unsigned int pincap;
 869                unsigned int oldval;
 870                oldval = snd_hda_codec_read(codec, nid, 0,
 871                                            AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
 872                pincap = snd_hda_query_pin_caps(codec, nid);
 873                pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
 874                /* if the default pin setup is vref50, we give it priority */
 875                if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
 876                        val = PIN_VREF80;
 877                else if (pincap & AC_PINCAP_VREF_50)
 878                        val = PIN_VREF50;
 879                else if (pincap & AC_PINCAP_VREF_100)
 880                        val = PIN_VREF100;
 881                else if (pincap & AC_PINCAP_VREF_GRD)
 882                        val = PIN_VREFGRD;
 883        }
 884        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
 885}
 886
 887static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
 888{
 889        struct alc_spec *spec = codec->spec;
 890        struct auto_pin_cfg *cfg = &spec->autocfg;
 891
 892        if (!cfg->line_outs) {
 893                while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
 894                       cfg->line_out_pins[cfg->line_outs])
 895                        cfg->line_outs++;
 896        }
 897        if (!cfg->speaker_outs) {
 898                while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
 899                       cfg->speaker_pins[cfg->speaker_outs])
 900                        cfg->speaker_outs++;
 901        }
 902        if (!cfg->hp_outs) {
 903                while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
 904                       cfg->hp_pins[cfg->hp_outs])
 905                        cfg->hp_outs++;
 906        }
 907}
 908
 909/*
 910 */
 911static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
 912{
 913        if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
 914                return;
 915        spec->mixers[spec->num_mixers++] = mix;
 916}
 917
 918static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
 919{
 920        if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
 921                return;
 922        spec->init_verbs[spec->num_init_verbs++] = verb;
 923}
 924
 925/*
 926 * set up from the preset table
 927 */
 928static void setup_preset(struct hda_codec *codec,
 929                         const struct alc_config_preset *preset)
 930{
 931        struct alc_spec *spec = codec->spec;
 932        int i;
 933
 934        for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
 935                add_mixer(spec, preset->mixers[i]);
 936        spec->cap_mixer = preset->cap_mixer;
 937        for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
 938             i++)
 939                add_verb(spec, preset->init_verbs[i]);
 940
 941        spec->channel_mode = preset->channel_mode;
 942        spec->num_channel_mode = preset->num_channel_mode;
 943        spec->need_dac_fix = preset->need_dac_fix;
 944        spec->const_channel_count = preset->const_channel_count;
 945
 946        if (preset->const_channel_count)
 947                spec->multiout.max_channels = preset->const_channel_count;
 948        else
 949                spec->multiout.max_channels = spec->channel_mode[0].channels;
 950        spec->ext_channel_count = spec->channel_mode[0].channels;
 951
 952        spec->multiout.num_dacs = preset->num_dacs;
 953        spec->multiout.dac_nids = preset->dac_nids;
 954        spec->multiout.dig_out_nid = preset->dig_out_nid;
 955        spec->multiout.slave_dig_outs = preset->slave_dig_outs;
 956        spec->multiout.hp_nid = preset->hp_nid;
 957
 958        spec->num_mux_defs = preset->num_mux_defs;
 959        if (!spec->num_mux_defs)
 960                spec->num_mux_defs = 1;
 961        spec->input_mux = preset->input_mux;
 962
 963        spec->num_adc_nids = preset->num_adc_nids;
 964        spec->adc_nids = preset->adc_nids;
 965        spec->capsrc_nids = preset->capsrc_nids;
 966        spec->dig_in_nid = preset->dig_in_nid;
 967
 968        spec->unsol_event = preset->unsol_event;
 969        spec->init_hook = preset->init_hook;
 970#ifdef CONFIG_SND_HDA_POWER_SAVE
 971        spec->power_hook = preset->power_hook;
 972        spec->loopback.amplist = preset->loopbacks;
 973#endif
 974
 975        if (preset->setup)
 976                preset->setup(codec);
 977
 978        alc_fixup_autocfg_pin_nums(codec);
 979}
 980
 981/* Enable GPIO mask and set output */
 982static struct hda_verb alc_gpio1_init_verbs[] = {
 983        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 984        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 985        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 986        { }
 987};
 988
 989static struct hda_verb alc_gpio2_init_verbs[] = {
 990        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 991        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 992        {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
 993        { }
 994};
 995
 996static struct hda_verb alc_gpio3_init_verbs[] = {
 997        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 998        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 999        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1000        { }
1001};
1002
1003/*
1004 * Fix hardware PLL issue
1005 * On some codecs, the analog PLL gating control must be off while
1006 * the default value is 1.
1007 */
1008static void alc_fix_pll(struct hda_codec *codec)
1009{
1010        struct alc_spec *spec = codec->spec;
1011        unsigned int val;
1012
1013        if (!spec->pll_nid)
1014                return;
1015        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1016                            spec->pll_coef_idx);
1017        val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1018                                 AC_VERB_GET_PROC_COEF, 0);
1019        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1020                            spec->pll_coef_idx);
1021        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1022                            val & ~(1 << spec->pll_coef_bit));
1023}
1024
1025static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1026                             unsigned int coef_idx, unsigned int coef_bit)
1027{
1028        struct alc_spec *spec = codec->spec;
1029        spec->pll_nid = nid;
1030        spec->pll_coef_idx = coef_idx;
1031        spec->pll_coef_bit = coef_bit;
1032        alc_fix_pll(codec);
1033}
1034
1035#ifdef CONFIG_SND_HDA_INPUT_JACK
1036static void alc_free_jack_priv(struct snd_jack *jack)
1037{
1038        struct alc_jack *jacks = jack->private_data;
1039        jacks->nid = 0;
1040        jacks->jack = NULL;
1041}
1042
1043static int alc_add_jack(struct hda_codec *codec,
1044                hda_nid_t nid, int type)
1045{
1046        struct alc_spec *spec;
1047        struct alc_jack *jack;
1048        const char *name;
1049        int err;
1050
1051        spec = codec->spec;
1052        snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053        jack = snd_array_new(&spec->jacks);
1054        if (!jack)
1055                return -ENOMEM;
1056
1057        jack->nid = nid;
1058        jack->type = type;
1059        name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1060
1061        err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1062        if (err < 0)
1063                return err;
1064        jack->jack->private_data = jack;
1065        jack->jack->private_free = alc_free_jack_priv;
1066        return 0;
1067}
1068
1069static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1070{
1071        struct alc_spec *spec = codec->spec;
1072        struct alc_jack *jacks = spec->jacks.list;
1073
1074        if (jacks) {
1075                int i;
1076                for (i = 0; i < spec->jacks.used; i++) {
1077                        if (jacks->nid == nid) {
1078                                unsigned int present;
1079                                present = snd_hda_jack_detect(codec, nid);
1080
1081                                present = (present) ? jacks->type : 0;
1082
1083                                snd_jack_report(jacks->jack, present);
1084                        }
1085                        jacks++;
1086                }
1087        }
1088}
1089
1090static int alc_init_jacks(struct hda_codec *codec)
1091{
1092        struct alc_spec *spec = codec->spec;
1093        int err;
1094        unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095        unsigned int mic_nid = spec->ext_mic.pin;
1096
1097        if (hp_nid) {
1098                err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1099                if (err < 0)
1100                        return err;
1101                alc_report_jack(codec, hp_nid);
1102        }
1103
1104        if (mic_nid) {
1105                err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1106                if (err < 0)
1107                        return err;
1108                alc_report_jack(codec, mic_nid);
1109        }
1110
1111        return 0;
1112}
1113#else
1114static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1115{
1116}
1117
1118static inline int alc_init_jacks(struct hda_codec *codec)
1119{
1120        return 0;
1121}
1122#endif
1123
1124static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1125{
1126        struct alc_spec *spec = codec->spec;
1127        unsigned int mute;
1128        hda_nid_t nid;
1129        int i;
1130
1131        spec->jack_present = 0;
1132        for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1133                nid = spec->autocfg.hp_pins[i];
1134                if (!nid)
1135                        break;
1136                alc_report_jack(codec, nid);
1137                spec->jack_present |= snd_hda_jack_detect(codec, nid);
1138        }
1139
1140        mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1141        /* Toggle internal speakers muting */
1142        for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1143                nid = spec->autocfg.speaker_pins[i];
1144                if (!nid)
1145                        break;
1146                if (pinctl) {
1147                        snd_hda_codec_write(codec, nid, 0,
1148                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
1149                                    spec->jack_present ? 0 : PIN_OUT);
1150                } else {
1151                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1152                                         HDA_AMP_MUTE, mute);
1153                }
1154        }
1155}
1156
1157static void alc_automute_pin(struct hda_codec *codec)
1158{
1159        alc_automute_speaker(codec, 1);
1160}
1161
1162static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1163                                hda_nid_t nid)
1164{
1165        hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1166        int i, nums;
1167
1168        nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1169        for (i = 0; i < nums; i++)
1170                if (conn[i] == nid)
1171                        return i;
1172        return -1;
1173}
1174
1175/* switch the current ADC according to the jack state */
1176static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1177{
1178        struct alc_spec *spec = codec->spec;
1179        unsigned int present;
1180        hda_nid_t new_adc;
1181
1182        present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1183        if (present)
1184                spec->cur_adc_idx = 1;
1185        else
1186                spec->cur_adc_idx = 0;
1187        new_adc = spec->adc_nids[spec->cur_adc_idx];
1188        if (spec->cur_adc && spec->cur_adc != new_adc) {
1189                /* stream is running, let's swap the current ADC */
1190                __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1191                spec->cur_adc = new_adc;
1192                snd_hda_codec_setup_stream(codec, new_adc,
1193                                           spec->cur_adc_stream_tag, 0,
1194                                           spec->cur_adc_format);
1195        }
1196}
1197
1198static void alc_mic_automute(struct hda_codec *codec)
1199{
1200        struct alc_spec *spec = codec->spec;
1201        struct alc_mic_route *dead, *alive;
1202        unsigned int present, type;
1203        hda_nid_t cap_nid;
1204
1205        if (!spec->auto_mic)
1206                return;
1207        if (!spec->int_mic.pin || !spec->ext_mic.pin)
1208                return;
1209        if (snd_BUG_ON(!spec->adc_nids))
1210                return;
1211
1212        if (spec->dual_adc_switch) {
1213                alc_dual_mic_adc_auto_switch(codec);
1214                return;
1215        }
1216
1217        cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1218
1219        present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1220        if (present) {
1221                alive = &spec->ext_mic;
1222                dead = &spec->int_mic;
1223        } else {
1224                alive = &spec->int_mic;
1225                dead = &spec->ext_mic;
1226        }
1227
1228        type = get_wcaps_type(get_wcaps(codec, cap_nid));
1229        if (type == AC_WID_AUD_MIX) {
1230                /* Matrix-mixer style (e.g. ALC882) */
1231                snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1232                                         alive->mux_idx,
1233                                         HDA_AMP_MUTE, 0);
1234                snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1235                                         dead->mux_idx,
1236                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
1237        } else {
1238                /* MUX style (e.g. ALC880) */
1239                snd_hda_codec_write_cache(codec, cap_nid, 0,
1240                                          AC_VERB_SET_CONNECT_SEL,
1241                                          alive->mux_idx);
1242        }
1243        alc_report_jack(codec, spec->ext_mic.pin);
1244
1245        /* FIXME: analog mixer */
1246}
1247
1248/* unsolicited event for HP jack sensing */
1249static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1250{
1251        if (codec->vendor_id == 0x10ec0880)
1252                res >>= 28;
1253        else
1254                res >>= 26;
1255        switch (res) {
1256        case ALC880_HP_EVENT:
1257                alc_automute_pin(codec);
1258                break;
1259        case ALC880_MIC_EVENT:
1260                alc_mic_automute(codec);
1261                break;
1262        }
1263}
1264
1265static void alc_inithook(struct hda_codec *codec)
1266{
1267        alc_automute_pin(codec);
1268        alc_mic_automute(codec);
1269}
1270
1271/* additional initialization for ALC888 variants */
1272static void alc888_coef_init(struct hda_codec *codec)
1273{
1274        unsigned int tmp;
1275
1276        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1277        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1278        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1279        if ((tmp & 0xf0) == 0x20)
1280                /* alc888S-VC */
1281                snd_hda_codec_read(codec, 0x20, 0,
1282                                   AC_VERB_SET_PROC_COEF, 0x830);
1283         else
1284                 /* alc888-VB */
1285                 snd_hda_codec_read(codec, 0x20, 0,
1286                                    AC_VERB_SET_PROC_COEF, 0x3030);
1287}
1288
1289static void alc889_coef_init(struct hda_codec *codec)
1290{
1291        unsigned int tmp;
1292
1293        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1294        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1295        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1296        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1297}
1298
1299/* turn on/off EAPD control (only if available) */
1300static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1301{
1302        if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1303                return;
1304        if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1305                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1306                                    on ? 2 : 0);
1307}
1308
1309static void alc_auto_init_amp(struct hda_codec *codec, int type)
1310{
1311        unsigned int tmp;
1312
1313        switch (type) {
1314        case ALC_INIT_GPIO1:
1315                snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1316                break;
1317        case ALC_INIT_GPIO2:
1318                snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1319                break;
1320        case ALC_INIT_GPIO3:
1321                snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1322                break;
1323        case ALC_INIT_DEFAULT:
1324                switch (codec->vendor_id) {
1325                case 0x10ec0260:
1326                        set_eapd(codec, 0x0f, 1);
1327                        set_eapd(codec, 0x10, 1);
1328                        break;
1329                case 0x10ec0262:
1330                case 0x10ec0267:
1331                case 0x10ec0268:
1332                case 0x10ec0269:
1333                case 0x10ec0270:
1334                case 0x10ec0272:
1335                case 0x10ec0660:
1336                case 0x10ec0662:
1337                case 0x10ec0663:
1338                case 0x10ec0862:
1339                case 0x10ec0889:
1340                        set_eapd(codec, 0x14, 1);
1341                        set_eapd(codec, 0x15, 1);
1342                        break;
1343                }
1344                switch (codec->vendor_id) {
1345                case 0x10ec0260:
1346                        snd_hda_codec_write(codec, 0x1a, 0,
1347                                            AC_VERB_SET_COEF_INDEX, 7);
1348                        tmp = snd_hda_codec_read(codec, 0x1a, 0,
1349                                                 AC_VERB_GET_PROC_COEF, 0);
1350                        snd_hda_codec_write(codec, 0x1a, 0,
1351                                            AC_VERB_SET_COEF_INDEX, 7);
1352                        snd_hda_codec_write(codec, 0x1a, 0,
1353                                            AC_VERB_SET_PROC_COEF,
1354                                            tmp | 0x2010);
1355                        break;
1356                case 0x10ec0262:
1357                case 0x10ec0880:
1358                case 0x10ec0882:
1359                case 0x10ec0883:
1360                case 0x10ec0885:
1361                case 0x10ec0887:
1362                case 0x10ec0889:
1363                        alc889_coef_init(codec);
1364                        break;
1365                case 0x10ec0888:
1366                        alc888_coef_init(codec);
1367                        break;
1368#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1369                case 0x10ec0267:
1370                case 0x10ec0268:
1371                        snd_hda_codec_write(codec, 0x20, 0,
1372                                            AC_VERB_SET_COEF_INDEX, 7);
1373                        tmp = snd_hda_codec_read(codec, 0x20, 0,
1374                                                 AC_VERB_GET_PROC_COEF, 0);
1375                        snd_hda_codec_write(codec, 0x20, 0,
1376                                            AC_VERB_SET_COEF_INDEX, 7);
1377                        snd_hda_codec_write(codec, 0x20, 0,
1378                                            AC_VERB_SET_PROC_COEF,
1379                                            tmp | 0x3000);
1380                        break;
1381#endif /* XXX */
1382                }
1383                break;
1384        }
1385}
1386
1387static void alc_init_auto_hp(struct hda_codec *codec)
1388{
1389        struct alc_spec *spec = codec->spec;
1390        struct auto_pin_cfg *cfg = &spec->autocfg;
1391        int i;
1392
1393        if (!cfg->hp_pins[0]) {
1394                if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1395                        return;
1396        }
1397
1398        if (!cfg->speaker_pins[0]) {
1399                if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1400                        return;
1401                memcpy(cfg->speaker_pins, cfg->line_out_pins,
1402                       sizeof(cfg->speaker_pins));
1403                cfg->speaker_outs = cfg->line_outs;
1404        }
1405
1406        if (!cfg->hp_pins[0]) {
1407                memcpy(cfg->hp_pins, cfg->line_out_pins,
1408                       sizeof(cfg->hp_pins));
1409                cfg->hp_outs = cfg->line_outs;
1410        }
1411
1412        for (i = 0; i < cfg->hp_outs; i++) {
1413                snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1414                            cfg->hp_pins[i]);
1415                snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
1416                                  AC_VERB_SET_UNSOLICITED_ENABLE,
1417                                  AC_USRSP_EN | ALC880_HP_EVENT);
1418        }
1419        spec->unsol_event = alc_sku_unsol_event;
1420}
1421
1422static void alc_init_auto_mic(struct hda_codec *codec)
1423{
1424        struct alc_spec *spec = codec->spec;
1425        struct auto_pin_cfg *cfg = &spec->autocfg;
1426        hda_nid_t fixed, ext;
1427        int i;
1428
1429        /* there must be only two mic inputs exclusively */
1430        for (i = 0; i < cfg->num_inputs; i++)
1431                if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1432                        return;
1433
1434        fixed = ext = 0;
1435        for (i = 0; i < cfg->num_inputs; i++) {
1436                hda_nid_t nid = cfg->inputs[i].pin;
1437                unsigned int defcfg;
1438                defcfg = snd_hda_codec_get_pincfg(codec, nid);
1439                switch (snd_hda_get_input_pin_attr(defcfg)) {
1440                case INPUT_PIN_ATTR_INT:
1441                        if (fixed)
1442                                return; /* already occupied */
1443                        fixed = nid;
1444                        break;
1445                case INPUT_PIN_ATTR_UNUSED:
1446                        return; /* invalid entry */
1447                default:
1448                        if (ext)
1449                                return; /* already occupied */
1450                        ext = nid;
1451                        break;
1452                }
1453        }
1454        if (!ext || !fixed)
1455                return;
1456        if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1457                return; /* no unsol support */
1458        snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1459                    ext, fixed);
1460        spec->ext_mic.pin = ext;
1461        spec->int_mic.pin = fixed;
1462        spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1463        spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1464        spec->auto_mic = 1;
1465        snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1466                                  AC_VERB_SET_UNSOLICITED_ENABLE,
1467                                  AC_USRSP_EN | ALC880_MIC_EVENT);
1468        spec->unsol_event = alc_sku_unsol_event;
1469}
1470
1471/* Could be any non-zero and even value. When used as fixup, tells
1472 * the driver to ignore any present sku defines.
1473 */
1474#define ALC_FIXUP_SKU_IGNORE (2)
1475
1476static int alc_auto_parse_customize_define(struct hda_codec *codec)
1477{
1478        unsigned int ass, tmp, i;
1479        unsigned nid = 0;
1480        struct alc_spec *spec = codec->spec;
1481
1482        spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1483
1484        if (spec->cdefine.fixup) {
1485                ass = spec->cdefine.sku_cfg;
1486                if (ass == ALC_FIXUP_SKU_IGNORE)
1487                        return -1;
1488                goto do_sku;
1489        }
1490
1491        ass = codec->subsystem_id & 0xffff;
1492        if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1493                goto do_sku;
1494
1495        nid = 0x1d;
1496        if (codec->vendor_id == 0x10ec0260)
1497                nid = 0x17;
1498        ass = snd_hda_codec_get_pincfg(codec, nid);
1499
1500        if (!(ass & 1)) {
1501                printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1502                       codec->chip_name, ass);
1503                return -1;
1504        }
1505
1506        /* check sum */
1507        tmp = 0;
1508        for (i = 1; i < 16; i++) {
1509                if ((ass >> i) & 1)
1510                        tmp++;
1511        }
1512        if (((ass >> 16) & 0xf) != tmp)
1513                return -1;
1514
1515        spec->cdefine.port_connectivity = ass >> 30;
1516        spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1517        spec->cdefine.check_sum = (ass >> 16) & 0xf;
1518        spec->cdefine.customization = ass >> 8;
1519do_sku:
1520        spec->cdefine.sku_cfg = ass;
1521        spec->cdefine.external_amp = (ass & 0x38) >> 3;
1522        spec->cdefine.platform_type = (ass & 0x4) >> 2;
1523        spec->cdefine.swap = (ass & 0x2) >> 1;
1524        spec->cdefine.override = ass & 0x1;
1525
1526        snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1527                   nid, spec->cdefine.sku_cfg);
1528        snd_printd("SKU: port_connectivity=0x%x\n",
1529                   spec->cdefine.port_connectivity);
1530        snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1531        snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1532        snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1533        snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1534        snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1535        snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1536        snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1537
1538        return 0;
1539}
1540
1541/* check subsystem ID and set up device-specific initialization;
1542 * return 1 if initialized, 0 if invalid SSID
1543 */
1544/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1545 *      31 ~ 16 :       Manufacture ID
1546 *      15 ~ 8  :       SKU ID
1547 *      7  ~ 0  :       Assembly ID
1548 *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1549 */
1550static int alc_subsystem_id(struct hda_codec *codec,
1551                            hda_nid_t porta, hda_nid_t porte,
1552                            hda_nid_t portd, hda_nid_t porti)
1553{
1554        unsigned int ass, tmp, i;
1555        unsigned nid;
1556        struct alc_spec *spec = codec->spec;
1557
1558        if (spec->cdefine.fixup) {
1559                ass = spec->cdefine.sku_cfg;
1560                if (ass == ALC_FIXUP_SKU_IGNORE)
1561                        return 0;
1562                goto do_sku;
1563        }
1564
1565        ass = codec->subsystem_id & 0xffff;
1566        if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1567                goto do_sku;
1568
1569        /* invalid SSID, check the special NID pin defcfg instead */
1570        /*
1571         * 31~30        : port connectivity
1572         * 29~21        : reserve
1573         * 20           : PCBEEP input
1574         * 19~16        : Check sum (15:1)
1575         * 15~1         : Custom
1576         * 0            : override
1577        */
1578        nid = 0x1d;
1579        if (codec->vendor_id == 0x10ec0260)
1580                nid = 0x17;
1581        ass = snd_hda_codec_get_pincfg(codec, nid);
1582        snd_printd("realtek: No valid SSID, "
1583                   "checking pincfg 0x%08x for NID 0x%x\n",
1584                   ass, nid);
1585        if (!(ass & 1))
1586                return 0;
1587        if ((ass >> 30) != 1)   /* no physical connection */
1588                return 0;
1589
1590        /* check sum */
1591        tmp = 0;
1592        for (i = 1; i < 16; i++) {
1593                if ((ass >> i) & 1)
1594                        tmp++;
1595        }
1596        if (((ass >> 16) & 0xf) != tmp)
1597                return 0;
1598do_sku:
1599        snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1600                   ass & 0xffff, codec->vendor_id);
1601        /*
1602         * 0 : override
1603         * 1 :  Swap Jack
1604         * 2 : 0 --> Desktop, 1 --> Laptop
1605         * 3~5 : External Amplifier control
1606         * 7~6 : Reserved
1607        */
1608        tmp = (ass & 0x38) >> 3;        /* external Amp control */
1609        switch (tmp) {
1610        case 1:
1611                spec->init_amp = ALC_INIT_GPIO1;
1612                break;
1613        case 3:
1614                spec->init_amp = ALC_INIT_GPIO2;
1615                break;
1616        case 7:
1617                spec->init_amp = ALC_INIT_GPIO3;
1618                break;
1619        case 5:
1620        default:
1621                spec->init_amp = ALC_INIT_DEFAULT;
1622                break;
1623        }
1624
1625        /* is laptop or Desktop and enable the function "Mute internal speaker
1626         * when the external headphone out jack is plugged"
1627         */
1628        if (!(ass & 0x8000))
1629                return 1;
1630        /*
1631         * 10~8 : Jack location
1632         * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1633         * 14~13: Resvered
1634         * 15   : 1 --> enable the function "Mute internal speaker
1635         *              when the external headphone out jack is plugged"
1636         */
1637        if (!spec->autocfg.hp_pins[0]) {
1638                hda_nid_t nid;
1639                tmp = (ass >> 11) & 0x3;        /* HP to chassis */
1640                if (tmp == 0)
1641                        nid = porta;
1642                else if (tmp == 1)
1643                        nid = porte;
1644                else if (tmp == 2)
1645                        nid = portd;
1646                else if (tmp == 3)
1647                        nid = porti;
1648                else
1649                        return 1;
1650                for (i = 0; i < spec->autocfg.line_outs; i++)
1651                        if (spec->autocfg.line_out_pins[i] == nid)
1652                                return 1;
1653                spec->autocfg.hp_pins[0] = nid;
1654        }
1655
1656        alc_init_auto_hp(codec);
1657        alc_init_auto_mic(codec);
1658        return 1;
1659}
1660
1661static void alc_ssid_check(struct hda_codec *codec,
1662                           hda_nid_t porta, hda_nid_t porte,
1663                           hda_nid_t portd, hda_nid_t porti)
1664{
1665        if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1666                struct alc_spec *spec = codec->spec;
1667                snd_printd("realtek: "
1668                           "Enable default setup for auto mode as fallback\n");
1669                spec->init_amp = ALC_INIT_DEFAULT;
1670                alc_init_auto_hp(codec);
1671                alc_init_auto_mic(codec);
1672        }
1673}
1674
1675/*
1676 * Fix-up pin default configurations and add default verbs
1677 */
1678
1679struct alc_pincfg {
1680        hda_nid_t nid;
1681        u32 val;
1682};
1683
1684struct alc_model_fixup {
1685        const int id;
1686        const char *name;
1687};
1688
1689struct alc_fixup {
1690        int type;
1691        bool chained;
1692        int chain_id;
1693        union {
1694                unsigned int sku;
1695                const struct alc_pincfg *pins;
1696                const struct hda_verb *verbs;
1697                void (*func)(struct hda_codec *codec,
1698                             const struct alc_fixup *fix,
1699                             int action);
1700        } v;
1701};
1702
1703enum {
1704        ALC_FIXUP_INVALID,
1705        ALC_FIXUP_SKU,
1706        ALC_FIXUP_PINS,
1707        ALC_FIXUP_VERBS,
1708        ALC_FIXUP_FUNC,
1709};
1710
1711enum {
1712        ALC_FIXUP_ACT_PRE_PROBE,
1713        ALC_FIXUP_ACT_PROBE,
1714        ALC_FIXUP_ACT_INIT,
1715};
1716
1717static void alc_apply_fixup(struct hda_codec *codec, int action)
1718{
1719        struct alc_spec *spec = codec->spec;
1720        int id = spec->fixup_id;
1721#ifdef CONFIG_SND_DEBUG_VERBOSE
1722        const char *modelname = spec->fixup_name;
1723#endif
1724        int depth = 0;
1725
1726        if (!spec->fixup_list)
1727                return;
1728
1729        while (id >= 0) {
1730                const struct alc_fixup *fix = spec->fixup_list + id;
1731                const struct alc_pincfg *cfg;
1732
1733                switch (fix->type) {
1734                case ALC_FIXUP_SKU:
1735                        if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1736                                break;;
1737                        snd_printdd(KERN_INFO "hda_codec: %s: "
1738                                    "Apply sku override for %s\n",
1739                                    codec->chip_name, modelname);
1740                        spec->cdefine.sku_cfg = fix->v.sku;
1741                        spec->cdefine.fixup = 1;
1742                        break;
1743                case ALC_FIXUP_PINS:
1744                        cfg = fix->v.pins;
1745                        if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1746                                break;
1747                        snd_printdd(KERN_INFO "hda_codec: %s: "
1748                                    "Apply pincfg for %s\n",
1749                                    codec->chip_name, modelname);
1750                        for (; cfg->nid; cfg++)
1751                                snd_hda_codec_set_pincfg(codec, cfg->nid,
1752                                                         cfg->val);
1753                        break;
1754                case ALC_FIXUP_VERBS:
1755                        if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1756                                break;
1757                        snd_printdd(KERN_INFO "hda_codec: %s: "
1758                                    "Apply fix-verbs for %s\n",
1759                                    codec->chip_name, modelname);
1760                        add_verb(codec->spec, fix->v.verbs);
1761                        break;
1762                case ALC_FIXUP_FUNC:
1763                        if (!fix->v.func)
1764                                break;
1765                        snd_printdd(KERN_INFO "hda_codec: %s: "
1766                                    "Apply fix-func for %s\n",
1767                                    codec->chip_name, modelname);
1768                        fix->v.func(codec, fix, action);
1769                        break;
1770                default:
1771                        snd_printk(KERN_ERR "hda_codec: %s: "
1772                                   "Invalid fixup type %d\n",
1773                                   codec->chip_name, fix->type);
1774                        break;
1775                }
1776                if (!fix[id].chained)
1777                        break;
1778                if (++depth > 10)
1779                        break;
1780                id = fix[id].chain_id;
1781        }
1782}
1783
1784static void alc_pick_fixup(struct hda_codec *codec,
1785                           const struct alc_model_fixup *models,
1786                           const struct snd_pci_quirk *quirk,
1787                           const struct alc_fixup *fixlist)
1788{
1789        struct alc_spec *spec = codec->spec;
1790        int id = -1;
1791        const char *name = NULL;
1792
1793        if (codec->modelname && models) {
1794                while (models->name) {
1795                        if (!strcmp(codec->modelname, models->name)) {
1796                                id = models->id;
1797                                name = models->name;
1798                                break;
1799                        }
1800                        models++;
1801                }
1802        }
1803        if (id < 0) {
1804                quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1805                if (quirk) {
1806                        id = quirk->value;
1807#ifdef CONFIG_SND_DEBUG_VERBOSE
1808                        name = quirk->name;
1809#endif
1810                }
1811        }
1812
1813        spec->fixup_id = id;
1814        if (id >= 0) {
1815                spec->fixup_list = fixlist;
1816                spec->fixup_name = name;
1817        }
1818}
1819
1820static int alc_read_coef_idx(struct hda_codec *codec,
1821                        unsigned int coef_idx)
1822{
1823        unsigned int val;
1824        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1825                                coef_idx);
1826        val = snd_hda_codec_read(codec, 0x20, 0,
1827                                AC_VERB_GET_PROC_COEF, 0);
1828        return val;
1829}
1830
1831static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1832                                                        unsigned int coef_val)
1833{
1834        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1835                            coef_idx);
1836        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1837                            coef_val);
1838}
1839
1840/* set right pin controls for digital I/O */
1841static void alc_auto_init_digital(struct hda_codec *codec)
1842{
1843        struct alc_spec *spec = codec->spec;
1844        int i;
1845        hda_nid_t pin;
1846
1847        for (i = 0; i < spec->autocfg.dig_outs; i++) {
1848                pin = spec->autocfg.dig_out_pins[i];
1849                if (pin) {
1850                        snd_hda_codec_write(codec, pin, 0,
1851                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
1852                                            PIN_OUT);
1853                }
1854        }
1855        pin = spec->autocfg.dig_in_pin;
1856        if (pin)
1857                snd_hda_codec_write(codec, pin, 0,
1858                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
1859                                    PIN_IN);
1860}
1861
1862/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1863static void alc_auto_parse_digital(struct hda_codec *codec)
1864{
1865        struct alc_spec *spec = codec->spec;
1866        int i, err;
1867        hda_nid_t dig_nid;
1868
1869        /* support multiple SPDIFs; the secondary is set up as a slave */
1870        for (i = 0; i < spec->autocfg.dig_outs; i++) {
1871                err = snd_hda_get_connections(codec,
1872                                              spec->autocfg.dig_out_pins[i],
1873                                              &dig_nid, 1);
1874                if (err < 0)
1875                        continue;
1876                if (!i) {
1877                        spec->multiout.dig_out_nid = dig_nid;
1878                        spec->dig_out_type = spec->autocfg.dig_out_type[0];
1879                } else {
1880                        spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1881                        if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1882                                break;
1883                        spec->slave_dig_outs[i - 1] = dig_nid;
1884                }
1885        }
1886
1887        if (spec->autocfg.dig_in_pin) {
1888                dig_nid = codec->start_nid;
1889                for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1890                        unsigned int wcaps = get_wcaps(codec, dig_nid);
1891                        if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1892                                continue;
1893                        if (!(wcaps & AC_WCAP_DIGITAL))
1894                                continue;
1895                        if (!(wcaps & AC_WCAP_CONN_LIST))
1896                                continue;
1897                        err = get_connection_index(codec, dig_nid,
1898                                                   spec->autocfg.dig_in_pin);
1899                        if (err >= 0) {
1900                                spec->dig_in_nid = dig_nid;
1901                                break;
1902                        }
1903                }
1904        }
1905}
1906
1907/*
1908 * ALC888
1909 */
1910
1911/*
1912 * 2ch mode
1913 */
1914static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1915/* Mic-in jack as mic in */
1916        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1917        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1918/* Line-in jack as Line in */
1919        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1920        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1921/* Line-Out as Front */
1922        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1923        { } /* end */
1924};
1925
1926/*
1927 * 4ch mode
1928 */
1929static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1930/* Mic-in jack as mic in */
1931        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1932        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1933/* Line-in jack as Surround */
1934        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1935        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1936/* Line-Out as Front */
1937        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1938        { } /* end */
1939};
1940
1941/*
1942 * 6ch mode
1943 */
1944static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1945/* Mic-in jack as CLFE */
1946        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1947        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1948/* Line-in jack as Surround */
1949        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1950        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1951/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1952        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1953        { } /* end */
1954};
1955
1956/*
1957 * 8ch mode
1958 */
1959static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1960/* Mic-in jack as CLFE */
1961        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1962        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1963/* Line-in jack as Surround */
1964        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1965        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1966/* Line-Out as Side */
1967        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1968        { } /* end */
1969};
1970
1971static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1972        { 2, alc888_4ST_ch2_intel_init },
1973        { 4, alc888_4ST_ch4_intel_init },
1974        { 6, alc888_4ST_ch6_intel_init },
1975        { 8, alc888_4ST_ch8_intel_init },
1976};
1977
1978/*
1979 * ALC888 Fujitsu Siemens Amillo xa3530
1980 */
1981
1982static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1983/* Front Mic: set to PIN_IN (empty by default) */
1984        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1985/* Connect Internal HP to Front */
1986        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1987        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1989/* Connect Bass HP to Front */
1990        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1991        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1992        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1993/* Connect Line-Out side jack (SPDIF) to Side */
1994        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1995        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1996        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1997/* Connect Mic jack to CLFE */
1998        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1999        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2001/* Connect Line-in jack to Surround */
2002        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2003        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2004        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2005/* Connect HP out jack to Front */
2006        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2007        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2009/* Enable unsolicited event for HP jack and Line-out jack */
2010        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2011        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2012        {}
2013};
2014
2015static void alc_automute_amp(struct hda_codec *codec)
2016{
2017        alc_automute_speaker(codec, 0);
2018}
2019
2020static void alc_automute_amp_unsol_event(struct hda_codec *codec,
2021                                         unsigned int res)
2022{
2023        if (codec->vendor_id == 0x10ec0880)
2024                res >>= 28;
2025        else
2026                res >>= 26;
2027        if (res == ALC880_HP_EVENT)
2028                alc_automute_amp(codec);
2029}
2030
2031static void alc889_automute_setup(struct hda_codec *codec)
2032{
2033        struct alc_spec *spec = codec->spec;
2034
2035        spec->autocfg.hp_pins[0] = 0x15;
2036        spec->autocfg.speaker_pins[0] = 0x14;
2037        spec->autocfg.speaker_pins[1] = 0x16;
2038        spec->autocfg.speaker_pins[2] = 0x17;
2039        spec->autocfg.speaker_pins[3] = 0x19;
2040        spec->autocfg.speaker_pins[4] = 0x1a;
2041}
2042
2043static void alc889_intel_init_hook(struct hda_codec *codec)
2044{
2045        alc889_coef_init(codec);
2046        alc_automute_amp(codec);
2047}
2048
2049static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2050{
2051        struct alc_spec *spec = codec->spec;
2052
2053        spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2054        spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2055        spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2056        spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2057}
2058
2059/*
2060 * ALC888 Acer Aspire 4930G model
2061 */
2062
2063static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2064/* Front Mic: set to PIN_IN (empty by default) */
2065        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2066/* Unselect Front Mic by default in input mixer 3 */
2067        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2068/* Enable unsolicited event for HP jack */
2069        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2070/* Connect Internal HP to front */
2071        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2072        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2073        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2074/* Connect HP out to front */
2075        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2076        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2077        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2078        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2079        { }
2080};
2081
2082/*
2083 * ALC888 Acer Aspire 6530G model
2084 */
2085
2086static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2087/* Route to built-in subwoofer as well as speakers */
2088        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2089        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2090        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2091        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2092/* Bias voltage on for external mic port */
2093        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2094/* Front Mic: set to PIN_IN (empty by default) */
2095        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2096/* Unselect Front Mic by default in input mixer 3 */
2097        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2098/* Enable unsolicited event for HP jack */
2099        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2100/* Enable speaker output */
2101        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2102        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2103        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2104/* Enable headphone output */
2105        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2106        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2107        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2108        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2109        { }
2110};
2111
2112/*
2113 *ALC888 Acer Aspire 7730G model
2114 */
2115
2116static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2117/* Bias voltage on for external mic port */
2118        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2119/* Front Mic: set to PIN_IN (empty by default) */
2120        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2121/* Unselect Front Mic by default in input mixer 3 */
2122        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2123/* Enable unsolicited event for HP jack */
2124        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2125/* Enable speaker output */
2126        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2127        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2129/* Enable headphone output */
2130        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2131        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2132        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2133        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2134/*Enable internal subwoofer */
2135        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2136        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2137        {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2138        {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2139        { }
2140};
2141
2142/*
2143 * ALC889 Acer Aspire 8930G model
2144 */
2145
2146static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2147/* Front Mic: set to PIN_IN (empty by default) */
2148        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2149/* Unselect Front Mic by default in input mixer 3 */
2150        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2151/* Enable unsolicited event for HP jack */
2152        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2153/* Connect Internal Front to Front */
2154        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2155        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2157/* Connect Internal Rear to Rear */
2158        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2159        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2160        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2161/* Connect Internal CLFE to CLFE */
2162        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2163        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2164        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2165/* Connect HP out to Front */
2166        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2167        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2168        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2169/* Enable all DACs */
2170/*  DAC DISABLE/MUTE 1? */
2171/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2172        {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2173        {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2174/*  DAC DISABLE/MUTE 2? */
2175/*  some bit here disables the other DACs. Init=0x4900 */
2176        {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2177        {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2178/* DMIC fix
2179 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2180 * which makes the stereo useless. However, either the mic or the ALC889
2181 * makes the signal become a difference/sum signal instead of standard
2182 * stereo, which is annoying. So instead we flip this bit which makes the
2183 * codec replicate the sum signal to both channels, turning it into a
2184 * normal mono mic.
2185 */
2186/*  DMIC_CONTROL? Init value = 0x0001 */
2187        {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2188        {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2189        { }
2190};
2191
2192static struct hda_input_mux alc888_2_capture_sources[2] = {
2193        /* Front mic only available on one ADC */
2194        {
2195                .num_items = 4,
2196                .items = {
2197                        { "Mic", 0x0 },
2198                        { "Line", 0x2 },
2199                        { "CD", 0x4 },
2200                        { "Front Mic", 0xb },
2201                },
2202        },
2203        {
2204                .num_items = 3,
2205                .items = {
2206                        { "Mic", 0x0 },
2207                        { "Line", 0x2 },
2208                        { "CD", 0x4 },
2209                },
2210        }
2211};
2212
2213static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2214        /* Interal mic only available on one ADC */
2215        {
2216                .num_items = 5,
2217                .items = {
2218                        { "Mic", 0x0 },
2219                        { "Line In", 0x2 },
2220                        { "CD", 0x4 },
2221                        { "Input Mix", 0xa },
2222                        { "Internal Mic", 0xb },
2223                },
2224        },
2225        {
2226                .num_items = 4,
2227                .items = {
2228                        { "Mic", 0x0 },
2229                        { "Line In", 0x2 },
2230                        { "CD", 0x4 },
2231                        { "Input Mix", 0xa },
2232                },
2233        }
2234};
2235
2236static struct hda_input_mux alc889_capture_sources[3] = {
2237        /* Digital mic only available on first "ADC" */
2238        {
2239                .num_items = 5,
2240                .items = {
2241                        { "Mic", 0x0 },
2242                        { "Line", 0x2 },
2243                        { "CD", 0x4 },
2244                        { "Front Mic", 0xb },
2245                        { "Input Mix", 0xa },
2246                },
2247        },
2248        {
2249                .num_items = 4,
2250                .items = {
2251                        { "Mic", 0x0 },
2252                        { "Line", 0x2 },
2253                        { "CD", 0x4 },
2254                        { "Input Mix", 0xa },
2255                },
2256        },
2257        {
2258                .num_items = 4,
2259                .items = {
2260                        { "Mic", 0x0 },
2261                        { "Line", 0x2 },
2262                        { "CD", 0x4 },
2263                        { "Input Mix", 0xa },
2264                },
2265        }
2266};
2267
2268static struct snd_kcontrol_new alc888_base_mixer[] = {
2269        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2270        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2271        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2272        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2273        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2274                HDA_OUTPUT),
2275        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2276        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2277        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2278        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2279        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2280        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2281        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2282        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2283        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2284        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2285        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2286        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2287        { } /* end */
2288};
2289
2290static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2291        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2292        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2293        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2294        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2295        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0f, 2, 0x0,
2296                HDA_OUTPUT),
2297        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0f, 2, 2, HDA_INPUT),
2298        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2299        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2300        HDA_CODEC_VOLUME("Side Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2301        HDA_BIND_MUTE("Side Playback Switch", 0x0e, 2, HDA_INPUT),
2302        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2303        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2304        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2305        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2306        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2307        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2308        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2309        { } /* end */
2310};
2311
2312
2313static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2314        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2315        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2316        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2317        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2318        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2319                HDA_OUTPUT),
2320        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2321        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2322        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2323        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2324        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2325        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2326        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2327        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2328        { } /* end */
2329};
2330
2331
2332static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2333{
2334        struct alc_spec *spec = codec->spec;
2335
2336        spec->autocfg.hp_pins[0] = 0x15;
2337        spec->autocfg.speaker_pins[0] = 0x14;
2338        spec->autocfg.speaker_pins[1] = 0x16;
2339        spec->autocfg.speaker_pins[2] = 0x17;
2340}
2341
2342static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2343{
2344        struct alc_spec *spec = codec->spec;
2345
2346        spec->autocfg.hp_pins[0] = 0x15;
2347        spec->autocfg.speaker_pins[0] = 0x14;
2348        spec->autocfg.speaker_pins[1] = 0x16;
2349        spec->autocfg.speaker_pins[2] = 0x17;
2350}
2351
2352static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2353{
2354        struct alc_spec *spec = codec->spec;
2355
2356        spec->autocfg.hp_pins[0] = 0x15;
2357        spec->autocfg.speaker_pins[0] = 0x14;
2358        spec->autocfg.speaker_pins[1] = 0x16;
2359        spec->autocfg.speaker_pins[2] = 0x17;
2360}
2361
2362static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2363{
2364        struct alc_spec *spec = codec->spec;
2365
2366        spec->autocfg.hp_pins[0] = 0x15;
2367        spec->autocfg.speaker_pins[0] = 0x14;
2368        spec->autocfg.speaker_pins[1] = 0x16;
2369        spec->autocfg.speaker_pins[2] = 0x1b;
2370}
2371
2372/*
2373 * ALC880 3-stack model
2374 *
2375 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2376 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2377 *                 F-Mic = 0x1b, HP = 0x19
2378 */
2379
2380static hda_nid_t alc880_dac_nids[4] = {
2381        /* front, rear, clfe, rear_surr */
2382        0x02, 0x05, 0x04, 0x03
2383};
2384
2385static hda_nid_t alc880_adc_nids[3] = {
2386        /* ADC0-2 */
2387        0x07, 0x08, 0x09,
2388};
2389
2390/* The datasheet says the node 0x07 is connected from inputs,
2391 * but it shows zero connection in the real implementation on some devices.
2392 * Note: this is a 915GAV bug, fixed on 915GLV
2393 */
2394static hda_nid_t alc880_adc_nids_alt[2] = {
2395        /* ADC1-2 */
2396        0x08, 0x09,
2397};
2398
2399#define ALC880_DIGOUT_NID       0x06
2400#define ALC880_DIGIN_NID        0x0a
2401
2402static struct hda_input_mux alc880_capture_source = {
2403        .num_items = 4,
2404        .items = {
2405                { "Mic", 0x0 },
2406                { "Front Mic", 0x3 },
2407                { "Line", 0x2 },
2408                { "CD", 0x4 },
2409        },
2410};
2411
2412/* channel source setting (2/6 channel selection for 3-stack) */
2413/* 2ch mode */
2414static struct hda_verb alc880_threestack_ch2_init[] = {
2415        /* set line-in to input, mute it */
2416        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2417        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2418        /* set mic-in to input vref 80%, mute it */
2419        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2420        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2421        { } /* end */
2422};
2423
2424/* 6ch mode */
2425static struct hda_verb alc880_threestack_ch6_init[] = {
2426        /* set line-in to output, unmute it */
2427        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2428        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2429        /* set mic-in to output, unmute it */
2430        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2431        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2432        { } /* end */
2433};
2434
2435static struct hda_channel_mode alc880_threestack_modes[2] = {
2436        { 2, alc880_threestack_ch2_init },
2437        { 6, alc880_threestack_ch6_init },
2438};
2439
2440static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2441        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2442        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2443        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2444        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2445        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2446        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2447        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2448        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2449        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2450        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2451        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2452        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2453        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2454        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2455        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2456        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2457        HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2458        {
2459                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2460                .name = "Channel Mode",
2461                .info = alc_ch_mode_info,
2462                .get = alc_ch_mode_get,
2463                .put = alc_ch_mode_put,
2464        },
2465        { } /* end */
2466};
2467
2468/* capture mixer elements */
2469static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2470                            struct snd_ctl_elem_info *uinfo)
2471{
2472        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2473        struct alc_spec *spec = codec->spec;
2474        int err;
2475
2476        mutex_lock(&codec->control_mutex);
2477        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2478                                                      HDA_INPUT);
2479        err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2480        mutex_unlock(&codec->control_mutex);
2481        return err;
2482}
2483
2484static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2485                           unsigned int size, unsigned int __user *tlv)
2486{
2487        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2488        struct alc_spec *spec = codec->spec;
2489        int err;
2490
2491        mutex_lock(&codec->control_mutex);
2492        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2493                                                      HDA_INPUT);
2494        err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2495        mutex_unlock(&codec->control_mutex);
2496        return err;
2497}
2498
2499typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2500                             struct snd_ctl_elem_value *ucontrol);
2501
2502static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2503                                 struct snd_ctl_elem_value *ucontrol,
2504                                 getput_call_t func)
2505{
2506        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2507        struct alc_spec *spec = codec->spec;
2508        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2509        int err;
2510
2511        mutex_lock(&codec->control_mutex);
2512        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2513                                                      3, 0, HDA_INPUT);
2514        err = func(kcontrol, ucontrol);
2515        mutex_unlock(&codec->control_mutex);
2516        return err;
2517}
2518
2519static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2520                           struct snd_ctl_elem_value *ucontrol)
2521{
2522        return alc_cap_getput_caller(kcontrol, ucontrol,
2523                                     snd_hda_mixer_amp_volume_get);
2524}
2525
2526static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2527                           struct snd_ctl_elem_value *ucontrol)
2528{
2529        return alc_cap_getput_caller(kcontrol, ucontrol,
2530                                     snd_hda_mixer_amp_volume_put);
2531}
2532
2533/* capture mixer elements */
2534#define alc_cap_sw_info         snd_ctl_boolean_stereo_info
2535
2536static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2537                          struct snd_ctl_elem_value *ucontrol)
2538{
2539        return alc_cap_getput_caller(kcontrol, ucontrol,
2540                                     snd_hda_mixer_amp_switch_get);
2541}
2542
2543static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2544                          struct snd_ctl_elem_value *ucontrol)
2545{
2546        return alc_cap_getput_caller(kcontrol, ucontrol,
2547                                     snd_hda_mixer_amp_switch_put);
2548}
2549
2550#define _DEFINE_CAPMIX(num) \
2551        { \
2552                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2553                .name = "Capture Switch", \
2554                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2555                .count = num, \
2556                .info = alc_cap_sw_info, \
2557                .get = alc_cap_sw_get, \
2558                .put = alc_cap_sw_put, \
2559        }, \
2560        { \
2561                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2562                .name = "Capture Volume", \
2563                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2564                           SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2565                           SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2566                .count = num, \
2567                .info = alc_cap_vol_info, \
2568                .get = alc_cap_vol_get, \
2569                .put = alc_cap_vol_put, \
2570                .tlv = { .c = alc_cap_vol_tlv }, \
2571        }
2572
2573#define _DEFINE_CAPSRC(num) \
2574        { \
2575                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2576                /* .name = "Capture Source", */ \
2577                .name = "Input Source", \
2578                .count = num, \
2579                .info = alc_mux_enum_info, \
2580                .get = alc_mux_enum_get, \
2581                .put = alc_mux_enum_put, \
2582        }
2583
2584#define DEFINE_CAPMIX(num) \
2585static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2586        _DEFINE_CAPMIX(num),                                  \
2587        _DEFINE_CAPSRC(num),                                  \
2588        { } /* end */                                         \
2589}
2590
2591#define DEFINE_CAPMIX_NOSRC(num) \
2592static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2593        _DEFINE_CAPMIX(num),                                        \
2594        { } /* end */                                               \
2595}
2596
2597/* up to three ADCs */
2598DEFINE_CAPMIX(1);
2599DEFINE_CAPMIX(2);
2600DEFINE_CAPMIX(3);
2601DEFINE_CAPMIX_NOSRC(1);
2602DEFINE_CAPMIX_NOSRC(2);
2603DEFINE_CAPMIX_NOSRC(3);
2604
2605/*
2606 * ALC880 5-stack model
2607 *
2608 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2609 *      Side = 0x02 (0xd)
2610 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2611 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2612 */
2613
2614/* additional mixers to alc880_three_stack_mixer */
2615static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2616        HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2617        HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2618        { } /* end */
2619};
2620
2621/* channel source setting (6/8 channel selection for 5-stack) */
2622/* 6ch mode */
2623static struct hda_verb alc880_fivestack_ch6_init[] = {
2624        /* set line-in to input, mute it */
2625        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2626        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2627        { } /* end */
2628};
2629
2630/* 8ch mode */
2631static struct hda_verb alc880_fivestack_ch8_init[] = {
2632        /* set line-in to output, unmute it */
2633        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2634        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2635        { } /* end */
2636};
2637
2638static struct hda_channel_mode alc880_fivestack_modes[2] = {
2639        { 6, alc880_fivestack_ch6_init },
2640        { 8, alc880_fivestack_ch8_init },
2641};
2642
2643
2644/*
2645 * ALC880 6-stack model
2646 *
2647 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2648 *      Side = 0x05 (0x0f)
2649 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2650 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2651 */
2652
2653static hda_nid_t alc880_6st_dac_nids[4] = {
2654        /* front, rear, clfe, rear_surr */
2655        0x02, 0x03, 0x04, 0x05
2656};
2657
2658static struct hda_input_mux alc880_6stack_capture_source = {
2659        .num_items = 4,
2660        .items = {
2661                { "Mic", 0x0 },
2662                { "Front Mic", 0x1 },
2663                { "Line", 0x2 },
2664                { "CD", 0x4 },
2665        },
2666};
2667
2668/* fixed 8-channels */
2669static struct hda_channel_mode alc880_sixstack_modes[1] = {
2670        { 8, NULL },
2671};
2672
2673static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2674        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2675        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2676        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2677        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2678        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2679        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2680        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2681        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2682        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2683        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2684        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2685        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2686        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2687        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2688        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2689        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2690        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2691        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2692        {
2693                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2694                .name = "Channel Mode",
2695                .info = alc_ch_mode_info,
2696                .get = alc_ch_mode_get,
2697                .put = alc_ch_mode_put,
2698        },
2699        { } /* end */
2700};
2701
2702
2703/*
2704 * ALC880 W810 model
2705 *
2706 * W810 has rear IO for:
2707 * Front (DAC 02)
2708 * Surround (DAC 03)
2709 * Center/LFE (DAC 04)
2710 * Digital out (06)
2711 *
2712 * The system also has a pair of internal speakers, and a headphone jack.
2713 * These are both connected to Line2 on the codec, hence to DAC 02.
2714 *
2715 * There is a variable resistor to control the speaker or headphone
2716 * volume. This is a hardware-only device without a software API.
2717 *
2718 * Plugging headphones in will disable the internal speakers. This is
2719 * implemented in hardware, not via the driver using jack sense. In
2720 * a similar fashion, plugging into the rear socket marked "front" will
2721 * disable both the speakers and headphones.
2722 *
2723 * For input, there's a microphone jack, and an "audio in" jack.
2724 * These may not do anything useful with this driver yet, because I
2725 * haven't setup any initialization verbs for these yet...
2726 */
2727
2728static hda_nid_t alc880_w810_dac_nids[3] = {
2729        /* front, rear/surround, clfe */
2730        0x02, 0x03, 0x04
2731};
2732
2733/* fixed 6 channels */
2734static struct hda_channel_mode alc880_w810_modes[1] = {
2735        { 6, NULL }
2736};
2737
2738/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2739static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2740        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2741        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2742        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2743        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2744        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2745        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2746        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2747        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2748        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2749        { } /* end */
2750};
2751
2752
2753/*
2754 * Z710V model
2755 *
2756 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2757 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2758 *                 Line = 0x1a
2759 */
2760
2761static hda_nid_t alc880_z71v_dac_nids[1] = {
2762        0x02
2763};
2764#define ALC880_Z71V_HP_DAC      0x03
2765
2766/* fixed 2 channels */
2767static struct hda_channel_mode alc880_2_jack_modes[1] = {
2768        { 2, NULL }
2769};
2770
2771static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2772        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2773        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2774        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2775        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2776        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2777        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2778        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2779        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2780        { } /* end */
2781};
2782
2783
2784/*
2785 * ALC880 F1734 model
2786 *
2787 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2788 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2789 */
2790
2791static hda_nid_t alc880_f1734_dac_nids[1] = {
2792        0x03
2793};
2794#define ALC880_F1734_HP_DAC     0x02
2795
2796static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2797        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2798        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2799        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2800        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2801        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2802        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2803        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2804        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2805        { } /* end */
2806};
2807
2808static struct hda_input_mux alc880_f1734_capture_source = {
2809        .num_items = 2,
2810        .items = {
2811                { "Mic", 0x1 },
2812                { "CD", 0x4 },
2813        },
2814};
2815
2816
2817/*
2818 * ALC880 ASUS model
2819 *
2820 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2821 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2822 *  Mic = 0x18, Line = 0x1a
2823 */
2824
2825#define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
2826#define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
2827
2828static struct snd_kcontrol_new alc880_asus_mixer[] = {
2829        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2830        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2831        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2832        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2833        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2834        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2835        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2836        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2837        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2838        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2839        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2840        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2841        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2842        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2843        {
2844                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2845                .name = "Channel Mode",
2846                .info = alc_ch_mode_info,
2847                .get = alc_ch_mode_get,
2848                .put = alc_ch_mode_put,
2849        },
2850        { } /* end */
2851};
2852
2853/*
2854 * ALC880 ASUS W1V model
2855 *
2856 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2857 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2858 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2859 */
2860
2861/* additional mixers to alc880_asus_mixer */
2862static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2863        HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2864        HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2865        { } /* end */
2866};
2867
2868/* TCL S700 */
2869static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2870        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2871        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2872        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2873        HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2874        HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2875        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2876        HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2877        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2878        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2879        { } /* end */
2880};
2881
2882/* Uniwill */
2883static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2884        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2885        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2886        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2887        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2888        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2889        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2890        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2891        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2892        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2893        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2894        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2895        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2896        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2897        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2898        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2899        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2900        {
2901                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2902                .name = "Channel Mode",
2903                .info = alc_ch_mode_info,
2904                .get = alc_ch_mode_get,
2905                .put = alc_ch_mode_put,
2906        },
2907        { } /* end */
2908};
2909
2910static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2911        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2912        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2913        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2914        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2915        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2916        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2917        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2918        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2919        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2920        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2921        { } /* end */
2922};
2923
2924static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2925        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2926        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2927        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2928        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2929        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2930        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2931        { } /* end */
2932};
2933
2934/*
2935 * virtual master controls
2936 */
2937
2938/*
2939 * slave controls for virtual master
2940 */
2941static const char * const alc_slave_vols[] = {
2942        "Front Playback Volume",
2943        "Surround Playback Volume",
2944        "Center Playback Volume",
2945        "LFE Playback Volume",
2946        "Side Playback Volume",
2947        "Headphone Playback Volume",
2948        "Speaker Playback Volume",
2949        "Mono Playback Volume",
2950        "Line-Out Playback Volume",
2951        "PCM Playback Volume",
2952        NULL,
2953};
2954
2955static const char * const alc_slave_sws[] = {
2956        "Front Playback Switch",
2957        "Surround Playback Switch",
2958        "Center Playback Switch",
2959        "LFE Playback Switch",
2960        "Side Playback Switch",
2961        "Headphone Playback Switch",
2962        "Speaker Playback Switch",
2963        "Mono Playback Switch",
2964        "IEC958 Playback Switch",
2965        "Line-Out Playback Switch",
2966        "PCM Playback Switch",
2967        NULL,
2968};
2969
2970/*
2971 * build control elements
2972 */
2973
2974#define NID_MAPPING             (-1)
2975
2976#define SUBDEV_SPEAKER_         (0 << 6)
2977#define SUBDEV_HP_              (1 << 6)
2978#define SUBDEV_LINE_            (2 << 6)
2979#define SUBDEV_SPEAKER(x)       (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2980#define SUBDEV_HP(x)            (SUBDEV_HP_ | ((x) & 0x3f))
2981#define SUBDEV_LINE(x)          (SUBDEV_LINE_ | ((x) & 0x3f))
2982
2983static void alc_free_kctls(struct hda_codec *codec);
2984
2985#ifdef CONFIG_SND_HDA_INPUT_BEEP
2986/* additional beep mixers; the actual parameters are overwritten at build */
2987static struct snd_kcontrol_new alc_beep_mixer[] = {
2988        HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2989        HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2990        { } /* end */
2991};
2992#endif
2993
2994static int alc_build_controls(struct hda_codec *codec)
2995{
2996        struct alc_spec *spec = codec->spec;
2997        struct snd_kcontrol *kctl = NULL;
2998        struct snd_kcontrol_new *knew;
2999        int i, j, err;
3000        unsigned int u;
3001        hda_nid_t nid;
3002
3003        for (i = 0; i < spec->num_mixers; i++) {
3004                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3005                if (err < 0)
3006                        return err;
3007        }
3008        if (spec->cap_mixer) {
3009                err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3010                if (err < 0)
3011                        return err;
3012        }
3013        if (spec->multiout.dig_out_nid) {
3014                err = snd_hda_create_spdif_out_ctls(codec,
3015                                                    spec->multiout.dig_out_nid);
3016                if (err < 0)
3017                        return err;
3018                if (!spec->no_analog) {
3019                        err = snd_hda_create_spdif_share_sw(codec,
3020                                                            &spec->multiout);
3021                        if (err < 0)
3022                                return err;
3023                        spec->multiout.share_spdif = 1;
3024                }
3025        }
3026        if (spec->dig_in_nid) {
3027                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3028                if (err < 0)
3029                        return err;
3030        }
3031
3032#ifdef CONFIG_SND_HDA_INPUT_BEEP
3033        /* create beep controls if needed */
3034        if (spec->beep_amp) {
3035                struct snd_kcontrol_new *knew;
3036                for (knew = alc_beep_mixer; knew->name; knew++) {
3037                        struct snd_kcontrol *kctl;
3038                        kctl = snd_ctl_new1(knew, codec);
3039                        if (!kctl)
3040                                return -ENOMEM;
3041                        kctl->private_value = spec->beep_amp;
3042                        err = snd_hda_ctl_add(codec, 0, kctl);
3043                        if (err < 0)
3044                                return err;
3045                }
3046        }
3047#endif
3048
3049        /* if we have no master control, let's create it */
3050        if (!spec->no_analog &&
3051            !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3052                unsigned int vmaster_tlv[4];
3053                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3054                                        HDA_OUTPUT, vmaster_tlv);
3055                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3056                                          vmaster_tlv, alc_slave_vols);
3057                if (err < 0)
3058                        return err;
3059        }
3060        if (!spec->no_analog &&
3061            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3062                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3063                                          NULL, alc_slave_sws);
3064                if (err < 0)
3065                        return err;
3066        }
3067
3068        /* assign Capture Source enums to NID */
3069        if (spec->capsrc_nids || spec->adc_nids) {
3070                kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3071                if (!kctl)
3072                        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3073                for (i = 0; kctl && i < kctl->count; i++) {
3074                        hda_nid_t *nids = spec->capsrc_nids;
3075                        if (!nids)
3076                                nids = spec->adc_nids;
3077                        err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3078                        if (err < 0)
3079                                return err;
3080                }
3081        }
3082        if (spec->cap_mixer) {
3083                const char *kname = kctl ? kctl->id.name : NULL;
3084                for (knew = spec->cap_mixer; knew->name; knew++) {
3085                        if (kname && strcmp(knew->name, kname) == 0)
3086                                continue;
3087                        kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3088                        for (i = 0; kctl && i < kctl->count; i++) {
3089                                err = snd_hda_add_nid(codec, kctl, i,
3090                                                      spec->adc_nids[i]);
3091                                if (err < 0)
3092                                        return err;
3093                        }
3094                }
3095        }
3096
3097        /* other nid->control mapping */
3098        for (i = 0; i < spec->num_mixers; i++) {
3099                for (knew = spec->mixers[i]; knew->name; knew++) {
3100                        if (knew->iface != NID_MAPPING)
3101                                continue;
3102                        kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3103                        if (kctl == NULL)
3104                                continue;
3105                        u = knew->subdevice;
3106                        for (j = 0; j < 4; j++, u >>= 8) {
3107                                nid = u & 0x3f;
3108                                if (nid == 0)
3109                                        continue;
3110                                switch (u & 0xc0) {
3111                                case SUBDEV_SPEAKER_:
3112                                        nid = spec->autocfg.speaker_pins[nid];
3113                                        break;
3114                                case SUBDEV_LINE_:
3115                                        nid = spec->autocfg.line_out_pins[nid];
3116                                        break;
3117                                case SUBDEV_HP_:
3118                                        nid = spec->autocfg.hp_pins[nid];
3119                                        break;
3120                                default:
3121                                        continue;
3122                                }
3123                                err = snd_hda_add_nid(codec, kctl, 0, nid);
3124                                if (err < 0)
3125                                        return err;
3126                        }
3127                        u = knew->private_value;
3128                        for (j = 0; j < 4; j++, u >>= 8) {
3129                                nid = u & 0xff;
3130                                if (nid == 0)
3131                                        continue;
3132                                err = snd_hda_add_nid(codec, kctl, 0, nid);
3133                                if (err < 0)
3134                                        return err;
3135                        }
3136                }
3137        }
3138
3139        alc_free_kctls(codec); /* no longer needed */
3140
3141        return 0;
3142}
3143
3144
3145/*
3146 * initialize the codec volumes, etc
3147 */
3148
3149/*
3150 * generic initialization of ADC, input mixers and output mixers
3151 */
3152static struct hda_verb alc880_volume_init_verbs[] = {
3153        /*
3154         * Unmute ADC0-2 and set the default input to mic-in
3155         */
3156        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3157        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3158        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3159        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3160        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3161        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3162
3163        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3164         * mixer widget
3165         * Note: PASD motherboards uses the Line In 2 as the input for front
3166         * panel mic (mic 2)
3167         */
3168        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3169        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3170        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3171        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3172        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3173        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3174        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3175        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3176
3177        /*
3178         * Set up output mixers (0x0c - 0x0f)
3179         */
3180        /* set vol=0 to output mixers */
3181        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3182        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3183        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3184        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3185        /* set up input amps for analog loopback */
3186        /* Amp Indices: DAC = 0, mixer = 1 */
3187        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3188        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3189        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3190        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3191        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3192        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3193        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3194        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3195
3196        { }
3197};
3198
3199/*
3200 * 3-stack pin configuration:
3201 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3202 */
3203static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3204        /*
3205         * preset connection lists of input pins
3206         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3207         */
3208        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3209        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3210        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3211
3212        /*
3213         * Set pin mode and muting
3214         */
3215        /* set front pin widgets 0x14 for output */
3216        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3217        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3218        /* Mic1 (rear panel) pin widget for input and vref at 80% */
3219        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3220        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3221        /* Mic2 (as headphone out) for HP output */
3222        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3223        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3224        /* Line In pin widget for input */
3225        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3226        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3227        /* Line2 (as front mic) pin widget for input and vref at 80% */
3228        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3229        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3230        /* CD pin widget for input */
3231        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3232
3233        { }
3234};
3235
3236/*
3237 * 5-stack pin configuration:
3238 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3239 * line-in/side = 0x1a, f-mic = 0x1b
3240 */
3241static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3242        /*
3243         * preset connection lists of input pins
3244         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3245         */
3246        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3247        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3248
3249        /*
3250         * Set pin mode and muting
3251         */
3252        /* set pin widgets 0x14-0x17 for output */
3253        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3254        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3255        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3256        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3257        /* unmute pins for output (no gain on this amp) */
3258        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3259        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3260        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3261        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3262
3263        /* Mic1 (rear panel) pin widget for input and vref at 80% */
3264        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3265        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3266        /* Mic2 (as headphone out) for HP output */
3267        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3268        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3269        /* Line In pin widget for input */
3270        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3272        /* Line2 (as front mic) pin widget for input and vref at 80% */
3273        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3274        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3275        /* CD pin widget for input */
3276        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3277
3278        { }
3279};
3280
3281/*
3282 * W810 pin configuration:
3283 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3284 */
3285static struct hda_verb alc880_pin_w810_init_verbs[] = {
3286        /* hphone/speaker input selector: front DAC */
3287        {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3288
3289        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3290        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3291        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3292        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3293        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3294        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3295
3296        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3297        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3298
3299        { }
3300};
3301
3302/*
3303 * Z71V pin configuration:
3304 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3305 */
3306static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3307        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3308        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3309        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3310        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3311
3312        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3313        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3314        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3315        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3316
3317        { }
3318};
3319
3320/*
3321 * 6-stack pin configuration:
3322 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3323 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3324 */
3325static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3326        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3327
3328        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3329        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3330        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3331        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3332        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3333        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3334        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3335        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3336
3337        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3338        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3339        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3340        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3341        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3342        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3343        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3344        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3345        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3346
3347        { }
3348};
3349
3350/*
3351 * Uniwill pin configuration:
3352 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3353 * line = 0x1a
3354 */
3355static struct hda_verb alc880_uniwill_init_verbs[] = {
3356        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3357
3358        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3359        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3360        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3361        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3362        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3363        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3364        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3365        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3366        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3367        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3368        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3369        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3370        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3371        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3372
3373        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3374        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3375        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3376        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3377        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3378        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3379        /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3380        /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3381        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3382
3383        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3384        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3385
3386        { }
3387};
3388
3389/*
3390* Uniwill P53
3391* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3392 */
3393static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3394        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3395
3396        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3397        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3398        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3399        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3400        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3401        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3402        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3403        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3404        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3405        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3406        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3407        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3408
3409        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3410        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3411        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3412        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3413        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3414        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3415
3416        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3417        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3418
3419        { }
3420};
3421
3422static struct hda_verb alc880_beep_init_verbs[] = {
3423        { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3424        { }
3425};
3426
3427/* auto-toggle front mic */
3428static void alc88x_simple_mic_automute(struct hda_codec *codec)
3429{
3430        unsigned int present;
3431        unsigned char bits;
3432
3433        present = snd_hda_jack_detect(codec, 0x18);
3434        bits = present ? HDA_AMP_MUTE : 0;
3435        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3436}
3437
3438static void alc880_uniwill_setup(struct hda_codec *codec)
3439{
3440        struct alc_spec *spec = codec->spec;
3441
3442        spec->autocfg.hp_pins[0] = 0x14;
3443        spec->autocfg.speaker_pins[0] = 0x15;
3444        spec->autocfg.speaker_pins[0] = 0x16;
3445}
3446
3447static void alc880_uniwill_init_hook(struct hda_codec *codec)
3448{
3449        alc_automute_amp(codec);
3450        alc88x_simple_mic_automute(codec);
3451}
3452
3453static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3454                                       unsigned int res)
3455{
3456        /* Looks like the unsol event is incompatible with the standard
3457         * definition.  4bit tag is placed at 28 bit!
3458         */
3459        switch (res >> 28) {
3460        case ALC880_MIC_EVENT:
3461                alc88x_simple_mic_automute(codec);
3462                break;
3463        default:
3464                alc_automute_amp_unsol_event(codec, res);
3465                break;
3466        }
3467}
3468
3469static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3470{
3471        struct alc_spec *spec = codec->spec;
3472
3473        spec->autocfg.hp_pins[0] = 0x14;
3474        spec->autocfg.speaker_pins[0] = 0x15;
3475}
3476
3477static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3478{
3479        unsigned int present;
3480
3481        present = snd_hda_codec_read(codec, 0x21, 0,
3482                                     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3483        present &= HDA_AMP_VOLMASK;
3484        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3485                                 HDA_AMP_VOLMASK, present);
3486        snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3487                                 HDA_AMP_VOLMASK, present);
3488}
3489
3490static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3491                                           unsigned int res)
3492{
3493        /* Looks like the unsol event is incompatible with the standard
3494         * definition.  4bit tag is placed at 28 bit!
3495         */
3496        if ((res >> 28) == ALC880_DCVOL_EVENT)
3497                alc880_uniwill_p53_dcvol_automute(codec);
3498        else
3499                alc_automute_amp_unsol_event(codec, res);
3500}
3501
3502/*
3503 * F1734 pin configuration:
3504 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3505 */
3506static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3507        {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3508        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3509        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3510        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3511        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3512
3513        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3514        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3515        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3516        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3517
3518        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3519        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3520        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3521        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3522        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3523        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3524        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3525        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3526        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3527
3528        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3529        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3530
3531        { }
3532};
3533
3534/*
3535 * ASUS pin configuration:
3536 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3537 */
3538static struct hda_verb alc880_pin_asus_init_verbs[] = {
3539        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3540        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3541        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3542        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3543
3544        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3545        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3546        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3547        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3548        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3549        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3550        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3551        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3552
3553        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3554        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3555        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3556        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3558        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3559        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3560        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3562
3563        { }
3564};
3565
3566/* Enable GPIO mask and set output */
3567#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3568#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3569#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3570
3571/* Clevo m520g init */
3572static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3573        /* headphone output */
3574        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3575        /* line-out */
3576        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3577        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3578        /* Line-in */
3579        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3580        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3581        /* CD */
3582        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3584        /* Mic1 (rear panel) */
3585        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3586        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3587        /* Mic2 (front panel) */
3588        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3589        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3590        /* headphone */
3591        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3592        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3593        /* change to EAPD mode */
3594        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3595        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3596
3597        { }
3598};
3599
3600static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3601        /* change to EAPD mode */
3602        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3603        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3604
3605        /* Headphone output */
3606        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3607        /* Front output*/
3608        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3609        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3610
3611        /* Line In pin widget for input */
3612        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3613        /* CD pin widget for input */
3614        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3615        /* Mic1 (rear panel) pin widget for input and vref at 80% */
3616        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617
3618        /* change to EAPD mode */
3619        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3620        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
3621
3622        { }
3623};
3624
3625/*
3626 * LG m1 express dual
3627 *
3628 * Pin assignment:
3629 *   Rear Line-In/Out (blue): 0x14
3630 *   Build-in Mic-In: 0x15
3631 *   Speaker-out: 0x17
3632 *   HP-Out (green): 0x1b
3633 *   Mic-In/Out (red): 0x19
3634 *   SPDIF-Out: 0x1e
3635 */
3636
3637/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3638static hda_nid_t alc880_lg_dac_nids[3] = {
3639        0x05, 0x02, 0x03
3640};
3641
3642/* seems analog CD is not working */
3643static struct hda_input_mux alc880_lg_capture_source = {
3644        .num_items = 3,
3645        .items = {
3646                { "Mic", 0x1 },
3647                { "Line", 0x5 },
3648                { "Internal Mic", 0x6 },
3649        },
3650};
3651
3652/* 2,4,6 channel modes */
3653static struct hda_verb alc880_lg_ch2_init[] = {
3654        /* set line-in and mic-in to input */
3655        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3656        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3657        { }
3658};
3659
3660static struct hda_verb alc880_lg_ch4_init[] = {
3661        /* set line-in to out and mic-in to input */
3662        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3663        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3664        { }
3665};
3666
3667static struct hda_verb alc880_lg_ch6_init[] = {
3668        /* set line-in and mic-in to output */
3669        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3670        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3671        { }
3672};
3673
3674static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3675        { 2, alc880_lg_ch2_init },
3676        { 4, alc880_lg_ch4_init },
3677        { 6, alc880_lg_ch6_init },
3678};
3679
3680static struct snd_kcontrol_new alc880_lg_mixer[] = {
3681        HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3682        HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3683        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3684        HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3685        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3686        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3687        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3688        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3689        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3690        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3691        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3692        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3693        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3694        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3695        {
3696                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3697                .name = "Channel Mode",
3698                .info = alc_ch_mode_info,
3699                .get = alc_ch_mode_get,
3700                .put = alc_ch_mode_put,
3701        },
3702        { } /* end */
3703};
3704
3705static struct hda_verb alc880_lg_init_verbs[] = {
3706        /* set capture source to mic-in */
3707        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3708        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3709        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3710        /* mute all amp mixer inputs */
3711        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3712        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3713        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3714        /* line-in to input */
3715        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3716        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3717        /* built-in mic */
3718        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3719        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3720        /* speaker-out */
3721        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3722        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3723        /* mic-in to input */
3724        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3725        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3726        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3727        /* HP-out */
3728        {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3729        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3730        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731        /* jack sense */
3732        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3733        { }
3734};
3735
3736/* toggle speaker-output according to the hp-jack state */
3737static void alc880_lg_setup(struct hda_codec *codec)
3738{
3739        struct alc_spec *spec = codec->spec;
3740
3741        spec->autocfg.hp_pins[0] = 0x1b;
3742        spec->autocfg.speaker_pins[0] = 0x17;
3743}
3744
3745/*
3746 * LG LW20
3747 *
3748 * Pin assignment:
3749 *   Speaker-out: 0x14
3750 *   Mic-In: 0x18
3751 *   Built-in Mic-In: 0x19
3752 *   Line-In: 0x1b
3753 *   HP-Out: 0x1a
3754 *   SPDIF-Out: 0x1e
3755 */
3756
3757static struct hda_input_mux alc880_lg_lw_capture_source = {
3758        .num_items = 3,
3759        .items = {
3760                { "Mic", 0x0 },
3761                { "Internal Mic", 0x1 },
3762                { "Line In", 0x2 },
3763        },
3764};
3765
3766#define alc880_lg_lw_modes alc880_threestack_modes
3767
3768static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3769        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3770        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3771        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3772        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3773        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3774        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3775        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3776        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3777        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3778        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3779        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3780        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3781        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3782        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3783        {
3784                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3785                .name = "Channel Mode",
3786                .info = alc_ch_mode_info,
3787                .get = alc_ch_mode_get,
3788                .put = alc_ch_mode_put,
3789        },
3790        { } /* end */
3791};
3792
3793static struct hda_verb alc880_lg_lw_init_verbs[] = {
3794        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3795        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3796        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3797
3798        /* set capture source to mic-in */
3799        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3800        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3801        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3802        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3803        /* speaker-out */
3804        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3805        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806        /* HP-out */
3807        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3808        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809        /* mic-in to input */
3810        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3811        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812        /* built-in mic */
3813        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3814        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3815        /* jack sense */
3816        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3817        { }
3818};
3819
3820/* toggle speaker-output according to the hp-jack state */
3821static void alc880_lg_lw_setup(struct hda_codec *codec)
3822{
3823        struct alc_spec *spec = codec->spec;
3824
3825        spec->autocfg.hp_pins[0] = 0x1b;
3826        spec->autocfg.speaker_pins[0] = 0x14;
3827}
3828
3829static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3830        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3831        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3832        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3833        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3834        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3835        HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3836        { } /* end */
3837};
3838
3839static struct hda_input_mux alc880_medion_rim_capture_source = {
3840        .num_items = 2,
3841        .items = {
3842                { "Mic", 0x0 },
3843                { "Internal Mic", 0x1 },
3844        },
3845};
3846
3847static struct hda_verb alc880_medion_rim_init_verbs[] = {
3848        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3849
3850        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3851        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3852
3853        /* Mic1 (rear panel) pin widget for input and vref at 80% */
3854        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3855        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3856        /* Mic2 (as headphone out) for HP output */
3857        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3858        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3859        /* Internal Speaker */
3860        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3861        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862
3863        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3864        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3865
3866        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3867        { }
3868};
3869
3870/* toggle speaker-output according to the hp-jack state */
3871static void alc880_medion_rim_automute(struct hda_codec *codec)
3872{
3873        struct alc_spec *spec = codec->spec;
3874        alc_automute_amp(codec);
3875        /* toggle EAPD */
3876        if (spec->jack_present)
3877                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3878        else
3879                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3880}
3881
3882static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3883                                          unsigned int res)
3884{
3885        /* Looks like the unsol event is incompatible with the standard
3886         * definition.  4bit tag is placed at 28 bit!
3887         */
3888        if ((res >> 28) == ALC880_HP_EVENT)
3889                alc880_medion_rim_automute(codec);
3890}
3891
3892static void alc880_medion_rim_setup(struct hda_codec *codec)
3893{
3894        struct alc_spec *spec = codec->spec;
3895
3896        spec->autocfg.hp_pins[0] = 0x14;
3897        spec->autocfg.speaker_pins[0] = 0x1b;
3898}
3899
3900#ifdef CONFIG_SND_HDA_POWER_SAVE
3901static struct hda_amp_list alc880_loopbacks[] = {
3902        { 0x0b, HDA_INPUT, 0 },
3903        { 0x0b, HDA_INPUT, 1 },
3904        { 0x0b, HDA_INPUT, 2 },
3905        { 0x0b, HDA_INPUT, 3 },
3906        { 0x0b, HDA_INPUT, 4 },
3907        { } /* end */
3908};
3909
3910static struct hda_amp_list alc880_lg_loopbacks[] = {
3911        { 0x0b, HDA_INPUT, 1 },
3912        { 0x0b, HDA_INPUT, 6 },
3913        { 0x0b, HDA_INPUT, 7 },
3914        { } /* end */
3915};
3916#endif
3917
3918/*
3919 * Common callbacks
3920 */
3921
3922static int alc_init(struct hda_codec *codec)
3923{
3924        struct alc_spec *spec = codec->spec;
3925        unsigned int i;
3926
3927        alc_fix_pll(codec);
3928        alc_auto_init_amp(codec, spec->init_amp);
3929
3930        for (i = 0; i < spec->num_init_verbs; i++)
3931                snd_hda_sequence_write(codec, spec->init_verbs[i]);
3932
3933        if (spec->init_hook)
3934                spec->init_hook(codec);
3935
3936        alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3937
3938        hda_call_check_power_status(codec, 0x01);
3939        return 0;
3940}
3941
3942static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3943{
3944        struct alc_spec *spec = codec->spec;
3945
3946        if (spec->unsol_event)
3947                spec->unsol_event(codec, res);
3948}
3949
3950#ifdef CONFIG_SND_HDA_POWER_SAVE
3951static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3952{
3953        struct alc_spec *spec = codec->spec;
3954        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3955}
3956#endif
3957
3958/*
3959 * Analog playback callbacks
3960 */
3961static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3962                                    struct hda_codec *codec,
3963                                    struct snd_pcm_substream *substream)
3964{
3965        struct alc_spec *spec = codec->spec;
3966        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3967                                             hinfo);
3968}
3969
3970static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3971                                       struct hda_codec *codec,
3972                                       unsigned int stream_tag,
3973                                       unsigned int format,
3974                                       struct snd_pcm_substream *substream)
3975{
3976        struct alc_spec *spec = codec->spec;
3977        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3978                                                stream_tag, format, substream);
3979}
3980
3981static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3982                                       struct hda_codec *codec,
3983                                       struct snd_pcm_substream *substream)
3984{
3985        struct alc_spec *spec = codec->spec;
3986        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3987}
3988
3989/*
3990 * Digital out
3991 */
3992static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3993                                        struct hda_codec *codec,
3994                                        struct snd_pcm_substream *substream)
3995{
3996        struct alc_spec *spec = codec->spec;
3997        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3998}
3999
4000static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4001                                           struct hda_codec *codec,
4002                                           unsigned int stream_tag,
4003                                           unsigned int format,
4004                                           struct snd_pcm_substream *substream)
4005{
4006        struct alc_spec *spec = codec->spec;
4007        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4008                                             stream_tag, format, substream);
4009}
4010
4011static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4012                                           struct hda_codec *codec,
4013                                           struct snd_pcm_substream *substream)
4014{
4015        struct alc_spec *spec = codec->spec;
4016        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4017}
4018
4019static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4020                                         struct hda_codec *codec,
4021                                         struct snd_pcm_substream *substream)
4022{
4023        struct alc_spec *spec = codec->spec;
4024        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4025}
4026
4027/*
4028 * Analog capture
4029 */
4030static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4031                                      struct hda_codec *codec,
4032                                      unsigned int stream_tag,
4033                                      unsigned int format,
4034                                      struct snd_pcm_substream *substream)
4035{
4036        struct alc_spec *spec = codec->spec;
4037
4038        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4039                                   stream_tag, 0, format);
4040        return 0;
4041}
4042
4043static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4044                                      struct hda_codec *codec,
4045                                      struct snd_pcm_substream *substream)
4046{
4047        struct alc_spec *spec = codec->spec;
4048
4049        snd_hda_codec_cleanup_stream(codec,
4050                                     spec->adc_nids[substream->number + 1]);
4051        return 0;
4052}
4053
4054/* analog capture with dynamic dual-adc changes */
4055static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4056                                       struct hda_codec *codec,
4057                                       unsigned int stream_tag,
4058                                       unsigned int format,
4059                                       struct snd_pcm_substream *substream)
4060{
4061        struct alc_spec *spec = codec->spec;
4062        spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4063        spec->cur_adc_stream_tag = stream_tag;
4064        spec->cur_adc_format = format;
4065        snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4066        return 0;
4067}
4068
4069static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4070                                       struct hda_codec *codec,
4071                                       struct snd_pcm_substream *substream)
4072{
4073        struct alc_spec *spec = codec->spec;
4074        snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4075        spec->cur_adc = 0;
4076        return 0;
4077}
4078
4079static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4080        .substreams = 1,
4081        .channels_min = 2,
4082        .channels_max = 2,
4083        .nid = 0, /* fill later */
4084        .ops = {
4085                .prepare = dualmic_capture_pcm_prepare,
4086                .cleanup = dualmic_capture_pcm_cleanup
4087        },
4088};
4089
4090/*
4091 */
4092static struct hda_pcm_stream alc880_pcm_analog_playback = {
4093        .substreams = 1,
4094        .channels_min = 2,
4095        .channels_max = 8,
4096        /* NID is set in alc_build_pcms */
4097        .ops = {
4098                .open = alc880_playback_pcm_open,
4099                .prepare = alc880_playback_pcm_prepare,
4100                .cleanup = alc880_playback_pcm_cleanup
4101        },
4102};
4103
4104static struct hda_pcm_stream alc880_pcm_analog_capture = {
4105        .substreams = 1,
4106        .channels_min = 2,
4107        .channels_max = 2,
4108        /* NID is set in alc_build_pcms */
4109};
4110
4111static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4112        .substreams = 1,
4113        .channels_min = 2,
4114        .channels_max = 2,
4115        /* NID is set in alc_build_pcms */
4116};
4117
4118static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4119        .substreams = 2, /* can be overridden */
4120        .channels_min = 2,
4121        .channels_max = 2,
4122        /* NID is set in alc_build_pcms */
4123        .ops = {
4124                .prepare = alc880_alt_capture_pcm_prepare,
4125                .cleanup = alc880_alt_capture_pcm_cleanup
4126        },
4127};
4128
4129static struct hda_pcm_stream alc880_pcm_digital_playback = {
4130        .substreams = 1,
4131        .channels_min = 2,
4132        .channels_max = 2,
4133        /* NID is set in alc_build_pcms */
4134        .ops = {
4135                .open = alc880_dig_playback_pcm_open,
4136                .close = alc880_dig_playback_pcm_close,
4137                .prepare = alc880_dig_playback_pcm_prepare,
4138                .cleanup = alc880_dig_playback_pcm_cleanup
4139        },
4140};
4141
4142static struct hda_pcm_stream alc880_pcm_digital_capture = {
4143        .substreams = 1,
4144        .channels_min = 2,
4145        .channels_max = 2,
4146        /* NID is set in alc_build_pcms */
4147};
4148
4149/* Used by alc_build_pcms to flag that a PCM has no playback stream */
4150static struct hda_pcm_stream alc_pcm_null_stream = {
4151        .substreams = 0,
4152        .channels_min = 0,
4153        .channels_max = 0,
4154};
4155
4156static int alc_build_pcms(struct hda_codec *codec)
4157{
4158        struct alc_spec *spec = codec->spec;
4159        struct hda_pcm *info = spec->pcm_rec;
4160        int i;
4161
4162        codec->num_pcms = 1;
4163        codec->pcm_info = info;
4164
4165        if (spec->no_analog)
4166                goto skip_analog;
4167
4168        snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4169                 "%s Analog", codec->chip_name);
4170        info->name = spec->stream_name_analog;
4171
4172        if (spec->stream_analog_playback) {
4173                if (snd_BUG_ON(!spec->multiout.dac_nids))
4174                        return -EINVAL;
4175                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4176                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4177        }
4178        if (spec->stream_analog_capture) {
4179                if (snd_BUG_ON(!spec->adc_nids))
4180                        return -EINVAL;
4181                info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4182                info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4183        }
4184
4185        if (spec->channel_mode) {
4186                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4187                for (i = 0; i < spec->num_channel_mode; i++) {
4188                        if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4189                                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4190                        }
4191                }
4192        }
4193
4194 skip_analog:
4195        /* SPDIF for stream index #1 */
4196        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4197                snprintf(spec->stream_name_digital,
4198                         sizeof(spec->stream_name_digital),
4199                         "%s Digital", codec->chip_name);
4200                codec->num_pcms = 2;
4201                codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4202                info = spec->pcm_rec + 1;
4203                info->name = spec->stream_name_digital;
4204                if (spec->dig_out_type)
4205                        info->pcm_type = spec->dig_out_type;
4206                else
4207                        info->pcm_type = HDA_PCM_TYPE_SPDIF;
4208                if (spec->multiout.dig_out_nid &&
4209                    spec->stream_digital_playback) {
4210                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4211                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4212                }
4213                if (spec->dig_in_nid &&
4214                    spec->stream_digital_capture) {
4215                        info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4216                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4217                }
4218                /* FIXME: do we need this for all Realtek codec models? */
4219                codec->spdif_status_reset = 1;
4220        }
4221
4222        if (spec->no_analog)
4223                return 0;
4224
4225        /* If the use of more than one ADC is requested for the current
4226         * model, configure a second analog capture-only PCM.
4227         */
4228        /* Additional Analaog capture for index #2 */
4229        if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4230            (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4231                codec->num_pcms = 3;
4232                info = spec->pcm_rec + 2;
4233                info->name = spec->stream_name_analog;
4234                if (spec->alt_dac_nid) {
4235                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4236                                *spec->stream_analog_alt_playback;
4237                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4238                                spec->alt_dac_nid;
4239                } else {
4240                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4241                                alc_pcm_null_stream;
4242                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4243                }
4244                if (spec->num_adc_nids > 1) {
4245                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4246                                *spec->stream_analog_alt_capture;
4247                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4248                                spec->adc_nids[1];
4249                        info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4250                                spec->num_adc_nids - 1;
4251                } else {
4252                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4253                                alc_pcm_null_stream;
4254                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4255                }
4256        }
4257
4258        return 0;
4259}
4260
4261static inline void alc_shutup(struct hda_codec *codec)
4262{
4263        snd_hda_shutup_pins(codec);
4264}
4265
4266static void alc_free_kctls(struct hda_codec *codec)
4267{
4268        struct alc_spec *spec = codec->spec;
4269
4270        if (spec->kctls.list) {
4271                struct snd_kcontrol_new *kctl = spec->kctls.list;
4272                int i;
4273                for (i = 0; i < spec->kctls.used; i++)
4274                        kfree(kctl[i].name);
4275        }
4276        snd_array_free(&spec->kctls);
4277}
4278
4279static void alc_free(struct hda_codec *codec)
4280{
4281        struct alc_spec *spec = codec->spec;
4282
4283        if (!spec)
4284                return;
4285
4286        alc_shutup(codec);
4287        alc_free_kctls(codec);
4288        kfree(spec);
4289        snd_hda_detach_beep_device(codec);
4290}
4291
4292#ifdef CONFIG_SND_HDA_POWER_SAVE
4293static void alc_power_eapd(struct hda_codec *codec)
4294{
4295        /* We currently only handle front, HP */
4296        switch (codec->vendor_id) {
4297        case 0x10ec0260:
4298                set_eapd(codec, 0x0f, 0);
4299                set_eapd(codec, 0x10, 0);
4300                break;
4301        case 0x10ec0262:
4302        case 0x10ec0267:
4303        case 0x10ec0268:
4304        case 0x10ec0269:
4305        case 0x10ec0270:
4306        case 0x10ec0272:
4307        case 0x10ec0660:
4308        case 0x10ec0662:
4309        case 0x10ec0663:
4310        case 0x10ec0862:
4311        case 0x10ec0889:
4312                set_eapd(codec, 0x14, 0);
4313                set_eapd(codec, 0x15, 0);
4314                break;
4315        }
4316}
4317
4318static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4319{
4320        struct alc_spec *spec = codec->spec;
4321        alc_shutup(codec);
4322        if (spec && spec->power_hook)
4323                spec->power_hook(codec);
4324        return 0;
4325}
4326#endif
4327
4328#ifdef SND_HDA_NEEDS_RESUME
4329static int alc_resume(struct hda_codec *codec)
4330{
4331        codec->patch_ops.init(codec);
4332        snd_hda_codec_resume_amp(codec);
4333        snd_hda_codec_resume_cache(codec);
4334        hda_call_check_power_status(codec, 0x01);
4335        return 0;
4336}
4337#endif
4338
4339/*
4340 */
4341static struct hda_codec_ops alc_patch_ops = {
4342        .build_controls = alc_build_controls,
4343        .build_pcms = alc_build_pcms,
4344        .init = alc_init,
4345        .free = alc_free,
4346        .unsol_event = alc_unsol_event,
4347#ifdef SND_HDA_NEEDS_RESUME
4348        .resume = alc_resume,
4349#endif
4350#ifdef CONFIG_SND_HDA_POWER_SAVE
4351        .suspend = alc_suspend,
4352        .check_power_status = alc_check_power_status,
4353#endif
4354        .reboot_notify = alc_shutup,
4355};
4356
4357/* replace the codec chip_name with the given string */
4358static int alc_codec_rename(struct hda_codec *codec, const char *name)
4359{
4360        kfree(codec->chip_name);
4361        codec->chip_name = kstrdup(name, GFP_KERNEL);
4362        if (!codec->chip_name) {
4363                alc_free(codec);
4364                return -ENOMEM;
4365        }
4366        return 0;
4367}
4368
4369/*
4370 * Test configuration for debugging
4371 *
4372 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
4373 * enum controls.
4374 */
4375#ifdef CONFIG_SND_DEBUG
4376static hda_nid_t alc880_test_dac_nids[4] = {
4377        0x02, 0x03, 0x04, 0x05
4378};
4379
4380static struct hda_input_mux alc880_test_capture_source = {
4381        .num_items = 7,
4382        .items = {
4383                { "In-1", 0x0 },
4384                { "In-2", 0x1 },
4385                { "In-3", 0x2 },
4386                { "In-4", 0x3 },
4387                { "CD", 0x4 },
4388                { "Front", 0x5 },
4389                { "Surround", 0x6 },
4390        },
4391};
4392
4393static struct hda_channel_mode alc880_test_modes[4] = {
4394        { 2, NULL },
4395        { 4, NULL },
4396        { 6, NULL },
4397        { 8, NULL },
4398};
4399
4400static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4401                                 struct snd_ctl_elem_info *uinfo)
4402{
4403        static char *texts[] = {
4404                "N/A", "Line Out", "HP Out",
4405                "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4406        };
4407        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4408        uinfo->count = 1;
4409        uinfo->value.enumerated.items = 8;
4410        if (uinfo->value.enumerated.item >= 8)
4411                uinfo->value.enumerated.item = 7;
4412        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4413        return 0;
4414}
4415
4416static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4417                                struct snd_ctl_elem_value *ucontrol)
4418{
4419        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4420        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4421        unsigned int pin_ctl, item = 0;
4422
4423        pin_ctl = snd_hda_codec_read(codec, nid, 0,
4424                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4425        if (pin_ctl & AC_PINCTL_OUT_EN) {
4426                if (pin_ctl & AC_PINCTL_HP_EN)
4427                        item = 2;
4428                else
4429                        item = 1;
4430        } else if (pin_ctl & AC_PINCTL_IN_EN) {
4431                switch (pin_ctl & AC_PINCTL_VREFEN) {
4432                case AC_PINCTL_VREF_HIZ: item = 3; break;
4433                case AC_PINCTL_VREF_50:  item = 4; break;
4434                case AC_PINCTL_VREF_GRD: item = 5; break;
4435                case AC_PINCTL_VREF_80:  item = 6; break;
4436                case AC_PINCTL_VREF_100: item = 7; break;
4437                }
4438        }
4439        ucontrol->value.enumerated.item[0] = item;
4440        return 0;
4441}
4442
4443static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4444                                struct snd_ctl_elem_value *ucontrol)
4445{
4446        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4447        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4448        static unsigned int ctls[] = {
4449                0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4450                AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4451                AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4452                AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4453                AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4454                AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4455        };
4456        unsigned int old_ctl, new_ctl;
4457
4458        old_ctl = snd_hda_codec_read(codec, nid, 0,
4459                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4460        new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4461        if (old_ctl != new_ctl) {
4462                int val;
4463                snd_hda_codec_write_cache(codec, nid, 0,
4464                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
4465                                          new_ctl);
4466                val = ucontrol->value.enumerated.item[0] >= 3 ?
4467                        HDA_AMP_MUTE : 0;
4468                snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4469                                         HDA_AMP_MUTE, val);
4470                return 1;
4471        }
4472        return 0;
4473}
4474
4475static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4476                                 struct snd_ctl_elem_info *uinfo)
4477{
4478        static char *texts[] = {
4479                "Front", "Surround", "CLFE", "Side"
4480        };
4481        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4482        uinfo->count = 1;
4483        uinfo->value.enumerated.items = 4;
4484        if (uinfo->value.enumerated.item >= 4)
4485                uinfo->value.enumerated.item = 3;
4486        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4487        return 0;
4488}
4489
4490static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4491                                struct snd_ctl_elem_value *ucontrol)
4492{
4493        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4494        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4495        unsigned int sel;
4496
4497        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4498        ucontrol->value.enumerated.item[0] = sel & 3;
4499        return 0;
4500}
4501
4502static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4503                                struct snd_ctl_elem_value *ucontrol)
4504{
4505        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4506        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4507        unsigned int sel;
4508
4509        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4510        if (ucontrol->value.enumerated.item[0] != sel) {
4511                sel = ucontrol->value.enumerated.item[0] & 3;
4512                snd_hda_codec_write_cache(codec, nid, 0,
4513                                          AC_VERB_SET_CONNECT_SEL, sel);
4514                return 1;
4515        }
4516        return 0;
4517}
4518
4519#define PIN_CTL_TEST(xname,nid) {                       \
4520                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
4521                        .name = xname,                 \
4522                        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4523                        .info = alc_test_pin_ctl_info, \
4524                        .get = alc_test_pin_ctl_get,   \
4525                        .put = alc_test_pin_ctl_put,   \
4526                        .private_value = nid           \
4527                        }
4528
4529#define PIN_SRC_TEST(xname,nid) {                       \
4530                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
4531                        .name = xname,                 \
4532                        .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4533                        .info = alc_test_pin_src_info, \
4534                        .get = alc_test_pin_src_get,   \
4535                        .put = alc_test_pin_src_put,   \
4536                        .private_value = nid           \
4537                        }
4538
4539static struct snd_kcontrol_new alc880_test_mixer[] = {
4540        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4541        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4542        HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4543        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4544        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4545        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4546        HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4547        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4548        PIN_CTL_TEST("Front Pin Mode", 0x14),
4549        PIN_CTL_TEST("Surround Pin Mode", 0x15),
4550        PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4551        PIN_CTL_TEST("Side Pin Mode", 0x17),
4552        PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4553        PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4554        PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4555        PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4556        PIN_SRC_TEST("In-1 Pin Source", 0x18),
4557        PIN_SRC_TEST("In-2 Pin Source", 0x19),
4558        PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4559        PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4560        HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4561        HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4562        HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4563        HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4564        HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4565        HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4566        HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4567        HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4568        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4569        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4570        {
4571                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4572                .name = "Channel Mode",
4573                .info = alc_ch_mode_info,
4574                .get = alc_ch_mode_get,
4575                .put = alc_ch_mode_put,
4576        },
4577        { } /* end */
4578};
4579
4580static struct hda_verb alc880_test_init_verbs[] = {
4581        /* Unmute inputs of 0x0c - 0x0f */
4582        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4583        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4584        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4585        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4586        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4587        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4588        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4589        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4590        /* Vol output for 0x0c-0x0f */
4591        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4592        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4593        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4594        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4595        /* Set output pins 0x14-0x17 */
4596        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4597        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4598        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4599        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4600        /* Unmute output pins 0x14-0x17 */
4601        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4602        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4603        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4604        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4605        /* Set input pins 0x18-0x1c */
4606        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4607        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4608        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4609        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4610        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4611        /* Mute input pins 0x18-0x1b */
4612        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4613        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4614        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4615        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4616        /* ADC set up */
4617        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4618        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4619        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4620        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4621        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4623        /* Analog input/passthru */
4624        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4625        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4626        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4627        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4628        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4629        { }
4630};
4631#endif
4632
4633/*
4634 */
4635
4636static const char * const alc880_models[ALC880_MODEL_LAST] = {
4637        [ALC880_3ST]            = "3stack",
4638        [ALC880_TCL_S700]       = "tcl",
4639        [ALC880_3ST_DIG]        = "3stack-digout",
4640        [ALC880_CLEVO]          = "clevo",
4641        [ALC880_5ST]            = "5stack",
4642        [ALC880_5ST_DIG]        = "5stack-digout",
4643        [ALC880_W810]           = "w810",
4644        [ALC880_Z71V]           = "z71v",
4645        [ALC880_6ST]            = "6stack",
4646        [ALC880_6ST_DIG]        = "6stack-digout",
4647        [ALC880_ASUS]           = "asus",
4648        [ALC880_ASUS_W1V]       = "asus-w1v",
4649        [ALC880_ASUS_DIG]       = "asus-dig",
4650        [ALC880_ASUS_DIG2]      = "asus-dig2",
4651        [ALC880_UNIWILL_DIG]    = "uniwill",
4652        [ALC880_UNIWILL_P53]    = "uniwill-p53",
4653        [ALC880_FUJITSU]        = "fujitsu",
4654        [ALC880_F1734]          = "F1734",
4655        [ALC880_LG]             = "lg",
4656        [ALC880_LG_LW]          = "lg-lw",
4657        [ALC880_MEDION_RIM]     = "medion",
4658#ifdef CONFIG_SND_DEBUG
4659        [ALC880_TEST]           = "test",
4660#endif
4661        [ALC880_AUTO]           = "auto",
4662};
4663
4664static struct snd_pci_quirk alc880_cfg_tbl[] = {
4665        SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4666        SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4667        SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4668        SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4669        SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4670        SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4671        SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4672        SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4673        SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4674        SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4675        SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4676        SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4677        SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4678        SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4679        SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4680        SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4681        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4682        SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4683        /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4684        SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4685        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4686        SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4687        SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4688        SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4689        SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4690        SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4691        SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4692        SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4693        SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4694        SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4695        SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4696        SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4697        SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4698        SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4699        SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4700        SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4701        SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4702        SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4703        SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4704        SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4705        SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4706        SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4707        SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4708        SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4709        SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4710        SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4711        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4712        SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4713        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4714        SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4715        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4716        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4717        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4718        SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4719        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4720        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4721        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4722        SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4723        SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4724        SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4725        SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4726        SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4727        SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4728        SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4729        SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4730        SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4731        SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4732        SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4733        SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4734        /* default Intel */
4735        SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4736        SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4737        SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4738        {}
4739};
4740
4741/*
4742 * ALC880 codec presets
4743 */
4744static struct alc_config_preset alc880_presets[] = {
4745        [ALC880_3ST] = {
4746                .mixers = { alc880_three_stack_mixer },
4747                .init_verbs = { alc880_volume_init_verbs,
4748                                alc880_pin_3stack_init_verbs },
4749                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4750                .dac_nids = alc880_dac_nids,
4751                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4752                .channel_mode = alc880_threestack_modes,
4753                .need_dac_fix = 1,
4754                .input_mux = &alc880_capture_source,
4755        },
4756        [ALC880_3ST_DIG] = {
4757                .mixers = { alc880_three_stack_mixer },
4758                .init_verbs = { alc880_volume_init_verbs,
4759                                alc880_pin_3stack_init_verbs },
4760                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4761                .dac_nids = alc880_dac_nids,
4762                .dig_out_nid = ALC880_DIGOUT_NID,
4763                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4764                .channel_mode = alc880_threestack_modes,
4765                .need_dac_fix = 1,
4766                .input_mux = &alc880_capture_source,
4767        },
4768        [ALC880_TCL_S700] = {
4769                .mixers = { alc880_tcl_s700_mixer },
4770                .init_verbs = { alc880_volume_init_verbs,
4771                                alc880_pin_tcl_S700_init_verbs,
4772                                alc880_gpio2_init_verbs },
4773                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4774                .dac_nids = alc880_dac_nids,
4775                .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4776                .num_adc_nids = 1, /* single ADC */
4777                .hp_nid = 0x03,
4778                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4779                .channel_mode = alc880_2_jack_modes,
4780                .input_mux = &alc880_capture_source,
4781        },
4782        [ALC880_5ST] = {
4783                .mixers = { alc880_three_stack_mixer,
4784                            alc880_five_stack_mixer},
4785                .init_verbs = { alc880_volume_init_verbs,
4786                                alc880_pin_5stack_init_verbs },
4787                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4788                .dac_nids = alc880_dac_nids,
4789                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4790                .channel_mode = alc880_fivestack_modes,
4791                .input_mux = &alc880_capture_source,
4792        },
4793        [ALC880_5ST_DIG] = {
4794                .mixers = { alc880_three_stack_mixer,
4795                            alc880_five_stack_mixer },
4796                .init_verbs = { alc880_volume_init_verbs,
4797                                alc880_pin_5stack_init_verbs },
4798                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4799                .dac_nids = alc880_dac_nids,
4800                .dig_out_nid = ALC880_DIGOUT_NID,
4801                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4802                .channel_mode = alc880_fivestack_modes,
4803                .input_mux = &alc880_capture_source,
4804        },
4805        [ALC880_6ST] = {
4806                .mixers = { alc880_six_stack_mixer },
4807                .init_verbs = { alc880_volume_init_verbs,
4808                                alc880_pin_6stack_init_verbs },
4809                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4810                .dac_nids = alc880_6st_dac_nids,
4811                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4812                .channel_mode = alc880_sixstack_modes,
4813                .input_mux = &alc880_6stack_capture_source,
4814        },
4815        [ALC880_6ST_DIG] = {
4816                .mixers = { alc880_six_stack_mixer },
4817                .init_verbs = { alc880_volume_init_verbs,
4818                                alc880_pin_6stack_init_verbs },
4819                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4820                .dac_nids = alc880_6st_dac_nids,
4821                .dig_out_nid = ALC880_DIGOUT_NID,
4822                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4823                .channel_mode = alc880_sixstack_modes,
4824                .input_mux = &alc880_6stack_capture_source,
4825        },
4826        [ALC880_W810] = {
4827                .mixers = { alc880_w810_base_mixer },
4828                .init_verbs = { alc880_volume_init_verbs,
4829                                alc880_pin_w810_init_verbs,
4830                                alc880_gpio2_init_verbs },
4831                .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4832                .dac_nids = alc880_w810_dac_nids,
4833                .dig_out_nid = ALC880_DIGOUT_NID,
4834                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4835                .channel_mode = alc880_w810_modes,
4836                .input_mux = &alc880_capture_source,
4837        },
4838        [ALC880_Z71V] = {
4839                .mixers = { alc880_z71v_mixer },
4840                .init_verbs = { alc880_volume_init_verbs,
4841                                alc880_pin_z71v_init_verbs },
4842                .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4843                .dac_nids = alc880_z71v_dac_nids,
4844                .dig_out_nid = ALC880_DIGOUT_NID,
4845                .hp_nid = 0x03,
4846                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4847                .channel_mode = alc880_2_jack_modes,
4848                .input_mux = &alc880_capture_source,
4849        },
4850        [ALC880_F1734] = {
4851                .mixers = { alc880_f1734_mixer },
4852                .init_verbs = { alc880_volume_init_verbs,
4853                                alc880_pin_f1734_init_verbs },
4854                .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4855                .dac_nids = alc880_f1734_dac_nids,
4856                .hp_nid = 0x02,
4857                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4858                .channel_mode = alc880_2_jack_modes,
4859                .input_mux = &alc880_f1734_capture_source,
4860                .unsol_event = alc880_uniwill_p53_unsol_event,
4861                .setup = alc880_uniwill_p53_setup,
4862                .init_hook = alc_automute_amp,
4863        },
4864        [ALC880_ASUS] = {
4865                .mixers = { alc880_asus_mixer },
4866                .init_verbs = { alc880_volume_init_verbs,
4867                                alc880_pin_asus_init_verbs,
4868                                alc880_gpio1_init_verbs },
4869                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4870                .dac_nids = alc880_asus_dac_nids,
4871                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4872                .channel_mode = alc880_asus_modes,
4873                .need_dac_fix = 1,
4874                .input_mux = &alc880_capture_source,
4875        },
4876        [ALC880_ASUS_DIG] = {
4877                .mixers = { alc880_asus_mixer },
4878                .init_verbs = { alc880_volume_init_verbs,
4879                                alc880_pin_asus_init_verbs,
4880                                alc880_gpio1_init_verbs },
4881                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4882                .dac_nids = alc880_asus_dac_nids,
4883                .dig_out_nid = ALC880_DIGOUT_NID,
4884                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4885                .channel_mode = alc880_asus_modes,
4886                .need_dac_fix = 1,
4887                .input_mux = &alc880_capture_source,
4888        },
4889        [ALC880_ASUS_DIG2] = {
4890                .mixers = { alc880_asus_mixer },
4891                .init_verbs = { alc880_volume_init_verbs,
4892                                alc880_pin_asus_init_verbs,
4893                                alc880_gpio2_init_verbs }, /* use GPIO2 */
4894                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4895                .dac_nids = alc880_asus_dac_nids,
4896                .dig_out_nid = ALC880_DIGOUT_NID,
4897                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4898                .channel_mode = alc880_asus_modes,
4899                .need_dac_fix = 1,
4900                .input_mux = &alc880_capture_source,
4901        },
4902        [ALC880_ASUS_W1V] = {
4903                .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4904                .init_verbs = { alc880_volume_init_verbs,
4905                                alc880_pin_asus_init_verbs,
4906                                alc880_gpio1_init_verbs },
4907                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4908                .dac_nids = alc880_asus_dac_nids,
4909                .dig_out_nid = ALC880_DIGOUT_NID,
4910                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4911                .channel_mode = alc880_asus_modes,
4912                .need_dac_fix = 1,
4913                .input_mux = &alc880_capture_source,
4914        },
4915        [ALC880_UNIWILL_DIG] = {
4916                .mixers = { alc880_asus_mixer },
4917                .init_verbs = { alc880_volume_init_verbs,
4918                                alc880_pin_asus_init_verbs },
4919                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4920                .dac_nids = alc880_asus_dac_nids,
4921                .dig_out_nid = ALC880_DIGOUT_NID,
4922                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4923                .channel_mode = alc880_asus_modes,
4924                .need_dac_fix = 1,
4925                .input_mux = &alc880_capture_source,
4926        },
4927        [ALC880_UNIWILL] = {
4928                .mixers = { alc880_uniwill_mixer },
4929                .init_verbs = { alc880_volume_init_verbs,
4930                                alc880_uniwill_init_verbs },
4931                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4932                .dac_nids = alc880_asus_dac_nids,
4933                .dig_out_nid = ALC880_DIGOUT_NID,
4934                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4935                .channel_mode = alc880_threestack_modes,
4936                .need_dac_fix = 1,
4937                .input_mux = &alc880_capture_source,
4938                .unsol_event = alc880_uniwill_unsol_event,
4939                .setup = alc880_uniwill_setup,
4940                .init_hook = alc880_uniwill_init_hook,
4941        },
4942        [ALC880_UNIWILL_P53] = {
4943                .mixers = { alc880_uniwill_p53_mixer },
4944                .init_verbs = { alc880_volume_init_verbs,
4945                                alc880_uniwill_p53_init_verbs },
4946                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4947                .dac_nids = alc880_asus_dac_nids,
4948                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4949                .channel_mode = alc880_threestack_modes,
4950                .input_mux = &alc880_capture_source,
4951                .unsol_event = alc880_uniwill_p53_unsol_event,
4952                .setup = alc880_uniwill_p53_setup,
4953                .init_hook = alc_automute_amp,
4954        },
4955        [ALC880_FUJITSU] = {
4956                .mixers = { alc880_fujitsu_mixer },
4957                .init_verbs = { alc880_volume_init_verbs,
4958                                alc880_uniwill_p53_init_verbs,
4959                                alc880_beep_init_verbs },
4960                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4961                .dac_nids = alc880_dac_nids,
4962                .dig_out_nid = ALC880_DIGOUT_NID,
4963                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4964                .channel_mode = alc880_2_jack_modes,
4965                .input_mux = &alc880_capture_source,
4966                .unsol_event = alc880_uniwill_p53_unsol_event,
4967                .setup = alc880_uniwill_p53_setup,
4968                .init_hook = alc_automute_amp,
4969        },
4970        [ALC880_CLEVO] = {
4971                .mixers = { alc880_three_stack_mixer },
4972                .init_verbs = { alc880_volume_init_verbs,
4973                                alc880_pin_clevo_init_verbs },
4974                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4975                .dac_nids = alc880_dac_nids,
4976                .hp_nid = 0x03,
4977                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4978                .channel_mode = alc880_threestack_modes,
4979                .need_dac_fix = 1,
4980                .input_mux = &alc880_capture_source,
4981        },
4982        [ALC880_LG] = {
4983                .mixers = { alc880_lg_mixer },
4984                .init_verbs = { alc880_volume_init_verbs,
4985                                alc880_lg_init_verbs },
4986                .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4987                .dac_nids = alc880_lg_dac_nids,
4988                .dig_out_nid = ALC880_DIGOUT_NID,
4989                .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4990                .channel_mode = alc880_lg_ch_modes,
4991                .need_dac_fix = 1,
4992                .input_mux = &alc880_lg_capture_source,
4993                .unsol_event = alc_automute_amp_unsol_event,
4994                .setup = alc880_lg_setup,
4995                .init_hook = alc_automute_amp,
4996#ifdef CONFIG_SND_HDA_POWER_SAVE
4997                .loopbacks = alc880_lg_loopbacks,
4998#endif
4999        },
5000        [ALC880_LG_LW] = {
5001                .mixers = { alc880_lg_lw_mixer },
5002                .init_verbs = { alc880_volume_init_verbs,
5003                                alc880_lg_lw_init_verbs },
5004                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5005                .dac_nids = alc880_dac_nids,
5006                .dig_out_nid = ALC880_DIGOUT_NID,
5007                .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5008                .channel_mode = alc880_lg_lw_modes,
5009                .input_mux = &alc880_lg_lw_capture_source,
5010                .unsol_event = alc_automute_amp_unsol_event,
5011                .setup = alc880_lg_lw_setup,
5012                .init_hook = alc_automute_amp,
5013        },
5014        [ALC880_MEDION_RIM] = {
5015                .mixers = { alc880_medion_rim_mixer },
5016                .init_verbs = { alc880_volume_init_verbs,
5017                                alc880_medion_rim_init_verbs,
5018                                alc_gpio2_init_verbs },
5019                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5020                .dac_nids = alc880_dac_nids,
5021                .dig_out_nid = ALC880_DIGOUT_NID,
5022                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5023                .channel_mode = alc880_2_jack_modes,
5024                .input_mux = &alc880_medion_rim_capture_source,
5025                .unsol_event = alc880_medion_rim_unsol_event,
5026                .setup = alc880_medion_rim_setup,
5027                .init_hook = alc880_medion_rim_automute,
5028        },
5029#ifdef CONFIG_SND_DEBUG
5030        [ALC880_TEST] = {
5031                .mixers = { alc880_test_mixer },
5032                .init_verbs = { alc880_test_init_verbs },
5033                .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5034                .dac_nids = alc880_test_dac_nids,
5035                .dig_out_nid = ALC880_DIGOUT_NID,
5036                .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5037                .channel_mode = alc880_test_modes,
5038                .input_mux = &alc880_test_capture_source,
5039        },
5040#endif
5041};
5042
5043/*
5044 * Automatic parse of I/O pins from the BIOS configuration
5045 */
5046
5047enum {
5048        ALC_CTL_WIDGET_VOL,
5049        ALC_CTL_WIDGET_MUTE,
5050        ALC_CTL_BIND_MUTE,
5051};
5052static struct snd_kcontrol_new alc880_control_templates[] = {
5053        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5054        HDA_CODEC_MUTE(NULL, 0, 0, 0),
5055        HDA_BIND_MUTE(NULL, 0, 0, 0),
5056};
5057
5058/* add dynamic controls */
5059static int add_control(struct alc_spec *spec, int type, const char *name,
5060                       int cidx, unsigned long val)
5061{
5062        struct snd_kcontrol_new *knew;
5063
5064        snd_array_init(&spec->kctls, sizeof(*knew), 32);
5065        knew = snd_array_new(&spec->kctls);
5066        if (!knew)
5067                return -ENOMEM;
5068        *knew = alc880_control_templates[type];
5069        knew->name = kstrdup(name, GFP_KERNEL);
5070        if (!knew->name)
5071                return -ENOMEM;
5072        knew->index = cidx;
5073        if (get_amp_nid_(val))
5074                knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5075        knew->private_value = val;
5076        return 0;
5077}
5078
5079static int add_control_with_pfx(struct alc_spec *spec, int type,
5080                                const char *pfx, const char *dir,
5081                                const char *sfx, int cidx, unsigned long val)
5082{
5083        char name[32];
5084        snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5085        return add_control(spec, type, name, cidx, val);
5086}
5087
5088#define add_pb_vol_ctrl(spec, type, pfx, val)                   \
5089        add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5090#define add_pb_sw_ctrl(spec, type, pfx, val)                    \
5091        add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5092#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val)                   \
5093        add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5094#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val)                    \
5095        add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5096
5097#define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
5098#define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
5099#define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
5100#define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
5101#define alc880_idx_to_dac(nid)          ((nid) + 0x02)
5102#define alc880_dac_to_idx(nid)          ((nid) - 0x02)
5103#define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
5104#define alc880_idx_to_selector(nid)     ((nid) + 0x10)
5105#define ALC880_PIN_CD_NID               0x1c
5106
5107/* fill in the dac_nids table from the parsed pin configuration */
5108static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5109                                     const struct auto_pin_cfg *cfg)
5110{
5111        hda_nid_t nid;
5112        int assigned[4];
5113        int i, j;
5114
5115        memset(assigned, 0, sizeof(assigned));
5116        spec->multiout.dac_nids = spec->private_dac_nids;
5117
5118        /* check the pins hardwired to audio widget */
5119        for (i = 0; i < cfg->line_outs; i++) {
5120                nid = cfg->line_out_pins[i];
5121                if (alc880_is_fixed_pin(nid)) {
5122                        int idx = alc880_fixed_pin_idx(nid);
5123                        spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
5124                        assigned[idx] = 1;
5125                }
5126        }
5127        /* left pins can be connect to any audio widget */
5128        for (i = 0; i < cfg->line_outs; i++) {
5129                nid = cfg->line_out_pins[i];
5130                if (alc880_is_fixed_pin(nid))
5131                        continue;
5132                /* search for an empty channel */
5133                for (j = 0; j < cfg->line_outs; j++) {
5134                        if (!assigned[j]) {
5135                                spec->multiout.dac_nids[i] =
5136                                        alc880_idx_to_dac(j);
5137                                assigned[j] = 1;
5138                                break;
5139                        }
5140                }
5141        }
5142        spec->multiout.num_dacs = cfg->line_outs;
5143        return 0;
5144}
5145
5146static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5147                                        bool can_be_master)
5148{
5149        if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5150                return "Master";
5151
5152        switch (cfg->line_out_type) {
5153        case AUTO_PIN_SPEAKER_OUT:
5154                return "Speaker";
5155        case AUTO_PIN_HP_OUT:
5156                return "Headphone";
5157        default:
5158                if (cfg->line_outs == 1)
5159                        return "PCM";
5160                break;
5161        }
5162        return NULL;
5163}
5164
5165/* add playback controls from the parsed DAC table */
5166static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5167                                             const struct auto_pin_cfg *cfg)
5168{
5169        static const char * const chname[4] = {
5170                "Front", "Surround", NULL /*CLFE*/, "Side"
5171        };
5172        const char *pfx = alc_get_line_out_pfx(cfg, false);
5173        hda_nid_t nid;
5174        int i, err;
5175
5176        for (i = 0; i < cfg->line_outs; i++) {
5177                if (!spec->multiout.dac_nids[i])
5178                        continue;
5179                nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5180                if (!pfx && i == 2) {
5181                        /* Center/LFE */
5182                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5183                                              "Center",
5184                                          HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5185                                                              HDA_OUTPUT));
5186                        if (err < 0)
5187                                return err;
5188                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5189                                              "LFE",
5190                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5191                                                              HDA_OUTPUT));
5192                        if (err < 0)
5193                                return err;
5194                        err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5195                                             "Center",
5196                                          HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5197                                                              HDA_INPUT));
5198                        if (err < 0)
5199                                return err;
5200                        err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5201                                             "LFE",
5202                                          HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5203                                                              HDA_INPUT));
5204                        if (err < 0)
5205                                return err;
5206                } else {
5207                        const char *name = pfx;
5208                        if (!name)
5209                                name = chname[i];
5210                        err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5211                                                name, i,
5212                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5213                                                              HDA_OUTPUT));
5214                        if (err < 0)
5215                                return err;
5216                        err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5217                                               name, i,
5218                                          HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5219                                                              HDA_INPUT));
5220                        if (err < 0)
5221                                return err;
5222                }
5223        }
5224        return 0;
5225}
5226
5227/* add playback controls for speaker and HP outputs */
5228static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5229                                        const char *pfx)
5230{
5231        hda_nid_t nid;
5232        int err;
5233
5234        if (!pin)
5235                return 0;
5236
5237        if (alc880_is_fixed_pin(pin)) {
5238                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5239                /* specify the DAC as the extra output */
5240                if (!spec->multiout.hp_nid)
5241                        spec->multiout.hp_nid = nid;
5242                else
5243                        spec->multiout.extra_out_nid[0] = nid;
5244                /* control HP volume/switch on the output mixer amp */
5245                nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5246                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5247                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5248                if (err < 0)
5249                        return err;
5250                err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5251                                  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5252                if (err < 0)
5253                        return err;
5254        } else if (alc880_is_multi_pin(pin)) {
5255                /* set manual connection */
5256                /* we have only a switch on HP-out PIN */
5257                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5258                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5259                if (err < 0)
5260                        return err;
5261        }
5262        return 0;
5263}
5264
5265/* create input playback/capture controls for the given pin */
5266static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5267                            const char *ctlname, int ctlidx,
5268                            int idx, hda_nid_t mix_nid)
5269{
5270        int err;
5271
5272        err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5273                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5274        if (err < 0)
5275                return err;
5276        err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5277                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5278        if (err < 0)
5279                return err;
5280        return 0;
5281}
5282
5283static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5284{
5285        unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5286        return (pincap & AC_PINCAP_IN) != 0;
5287}
5288
5289/* create playback/capture controls for input pins */
5290static int alc_auto_create_input_ctls(struct hda_codec *codec,
5291                                      const struct auto_pin_cfg *cfg,
5292                                      hda_nid_t mixer,
5293                                      hda_nid_t cap1, hda_nid_t cap2)
5294{
5295        struct alc_spec *spec = codec->spec;
5296        struct hda_input_mux *imux = &spec->private_imux[0];
5297        int i, err, idx, type_idx = 0;
5298        const char *prev_label = NULL;
5299
5300        for (i = 0; i < cfg->num_inputs; i++) {
5301                hda_nid_t pin;
5302                const char *label;
5303
5304                pin = cfg->inputs[i].pin;
5305                if (!alc_is_input_pin(codec, pin))
5306                        continue;
5307
5308                label = hda_get_autocfg_input_label(codec, cfg, i);
5309                if (prev_label && !strcmp(label, prev_label))
5310                        type_idx++;
5311                else
5312                        type_idx = 0;
5313                prev_label = label;
5314
5315                if (mixer) {
5316                        idx = get_connection_index(codec, mixer, pin);
5317                        if (idx >= 0) {
5318                                err = new_analog_input(spec, pin,
5319                                                       label, type_idx,
5320                                                       idx, mixer);
5321                                if (err < 0)
5322                                        return err;
5323                        }
5324                }
5325
5326                if (!cap1)
5327                        continue;
5328                idx = get_connection_index(codec, cap1, pin);
5329                if (idx < 0 && cap2)
5330                        idx = get_connection_index(codec, cap2, pin);
5331                if (idx >= 0)
5332                        snd_hda_add_imux_item(imux, label, idx, NULL);
5333        }
5334        return 0;
5335}
5336
5337static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5338                                                const struct auto_pin_cfg *cfg)
5339{
5340        return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5341}
5342
5343static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5344                               unsigned int pin_type)
5345{
5346        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5347                            pin_type);
5348        /* unmute pin */
5349        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5350                            AMP_OUT_UNMUTE);
5351}
5352
5353static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5354                                              hda_nid_t nid, int pin_type,
5355                                              int dac_idx)
5356{
5357        alc_set_pin_output(codec, nid, pin_type);
5358        /* need the manual connection? */
5359        if (alc880_is_multi_pin(nid)) {
5360                struct alc_spec *spec = codec->spec;
5361                int idx = alc880_multi_pin_idx(nid);
5362                snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5363                                    AC_VERB_SET_CONNECT_SEL,
5364                                    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5365        }
5366}
5367
5368static int get_pin_type(int line_out_type)
5369{
5370        if (line_out_type == AUTO_PIN_HP_OUT)
5371                return PIN_HP;
5372        else
5373                return PIN_OUT;
5374}
5375
5376static void alc880_auto_init_multi_out(struct hda_codec *codec)
5377{
5378        struct alc_spec *spec = codec->spec;
5379        int i;
5380
5381        for (i = 0; i < spec->autocfg.line_outs; i++) {
5382                hda_nid_t nid = spec->autocfg.line_out_pins[i];
5383                int pin_type = get_pin_type(spec->autocfg.line_out_type);
5384                alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5385        }
5386}
5387
5388static void alc880_auto_init_extra_out(struct hda_codec *codec)
5389{
5390        struct alc_spec *spec = codec->spec;
5391        hda_nid_t pin;
5392
5393        pin = spec->autocfg.speaker_pins[0];
5394        if (pin) /* connect to front */
5395                alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5396        pin = spec->autocfg.hp_pins[0];
5397        if (pin) /* connect to front */
5398                alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5399}
5400
5401static void alc880_auto_init_analog_input(struct hda_codec *codec)
5402{
5403        struct alc_spec *spec = codec->spec;
5404        struct auto_pin_cfg *cfg = &spec->autocfg;
5405        int i;
5406
5407        for (i = 0; i < cfg->num_inputs; i++) {
5408                hda_nid_t nid = cfg->inputs[i].pin;
5409                if (alc_is_input_pin(codec, nid)) {
5410                        alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5411                        if (nid != ALC880_PIN_CD_NID &&
5412                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5413                                snd_hda_codec_write(codec, nid, 0,
5414                                                    AC_VERB_SET_AMP_GAIN_MUTE,
5415                                                    AMP_OUT_MUTE);
5416                }
5417        }
5418}
5419
5420static void alc880_auto_init_input_src(struct hda_codec *codec)
5421{
5422        struct alc_spec *spec = codec->spec;
5423        int c;
5424
5425        for (c = 0; c < spec->num_adc_nids; c++) {
5426                unsigned int mux_idx;
5427                const struct hda_input_mux *imux;
5428                mux_idx = c >= spec->num_mux_defs ? 0 : c;
5429                imux = &spec->input_mux[mux_idx];
5430                if (!imux->num_items && mux_idx > 0)
5431                        imux = &spec->input_mux[0];
5432                if (imux)
5433                        snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5434                                            AC_VERB_SET_CONNECT_SEL,
5435                                            imux->items[0].index);
5436        }
5437}
5438
5439/* parse the BIOS configuration and set up the alc_spec */
5440/* return 1 if successful, 0 if the proper config is not found,
5441 * or a negative error code
5442 */
5443static int alc880_parse_auto_config(struct hda_codec *codec)
5444{
5445        struct alc_spec *spec = codec->spec;
5446        int err;
5447        static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5448
5449        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5450                                           alc880_ignore);
5451        if (err < 0)
5452                return err;
5453        if (!spec->autocfg.line_outs)
5454                return 0; /* can't find valid BIOS pin config */
5455
5456        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5457        if (err < 0)
5458                return err;
5459        err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5460        if (err < 0)
5461                return err;
5462        err = alc880_auto_create_extra_out(spec,
5463                                           spec->autocfg.speaker_pins[0],
5464                                           "Speaker");
5465        if (err < 0)
5466                return err;
5467        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5468                                           "Headphone");
5469        if (err < 0)
5470                return err;
5471        err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5472        if (err < 0)
5473                return err;
5474
5475        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5476
5477        alc_auto_parse_digital(codec);
5478
5479        if (spec->kctls.list)
5480                add_mixer(spec, spec->kctls.list);
5481
5482        add_verb(spec, alc880_volume_init_verbs);
5483
5484        spec->num_mux_defs = 1;
5485        spec->input_mux = &spec->private_imux[0];
5486
5487        alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5488
5489        return 1;
5490}
5491
5492/* additional initialization for auto-configuration model */
5493static void alc880_auto_init(struct hda_codec *codec)
5494{
5495        struct alc_spec *spec = codec->spec;
5496        alc880_auto_init_multi_out(codec);
5497        alc880_auto_init_extra_out(codec);
5498        alc880_auto_init_analog_input(codec);
5499        alc880_auto_init_input_src(codec);
5500        alc_auto_init_digital(codec);
5501        if (spec->unsol_event)
5502                alc_inithook(codec);
5503}
5504
5505/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5506 * one of two digital mic pins, e.g. on ALC272
5507 */
5508static void fixup_automic_adc(struct hda_codec *codec)
5509{
5510        struct alc_spec *spec = codec->spec;
5511        int i;
5512
5513        for (i = 0; i < spec->num_adc_nids; i++) {
5514                hda_nid_t cap = spec->capsrc_nids ?
5515                        spec->capsrc_nids[i] : spec->adc_nids[i];
5516                int iidx, eidx;
5517
5518                iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5519                if (iidx < 0)
5520                        continue;
5521                eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5522                if (eidx < 0)
5523                        continue;
5524                spec->int_mic.mux_idx = iidx;
5525                spec->ext_mic.mux_idx = eidx;
5526                if (spec->capsrc_nids)
5527                        spec->capsrc_nids += i;
5528                spec->adc_nids += i;
5529                spec->num_adc_nids = 1;
5530                return;
5531        }
5532        snd_printd(KERN_INFO "hda_codec: %s: "
5533                   "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5534                   codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5535        spec->auto_mic = 0; /* disable auto-mic to be sure */
5536}
5537
5538/* select or unmute the given capsrc route */
5539static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5540                                    int idx)
5541{
5542        if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5543                snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5544                                         HDA_AMP_MUTE, 0);
5545        } else {
5546                snd_hda_codec_write_cache(codec, cap, 0,
5547                                          AC_VERB_SET_CONNECT_SEL, idx);
5548        }
5549}
5550
5551/* set the default connection to that pin */
5552static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5553{
5554        struct alc_spec *spec = codec->spec;
5555        int i;
5556
5557        for (i = 0; i < spec->num_adc_nids; i++) {
5558                hda_nid_t cap = spec->capsrc_nids ?
5559                        spec->capsrc_nids[i] : spec->adc_nids[i];
5560                int idx;
5561
5562                idx = get_connection_index(codec, cap, pin);
5563                if (idx < 0)
5564                        continue;
5565                select_or_unmute_capsrc(codec, cap, idx);
5566                return i; /* return the found index */
5567        }
5568        return -1; /* not found */
5569}
5570
5571/* choose the ADC/MUX containing the input pin and initialize the setup */
5572static void fixup_single_adc(struct hda_codec *codec)
5573{
5574        struct alc_spec *spec = codec->spec;
5575        struct auto_pin_cfg *cfg = &spec->autocfg;
5576        int i;
5577
5578        /* search for the input pin; there must be only one */
5579        if (cfg->num_inputs != 1)
5580                return;
5581        i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5582        if (i >= 0) {
5583                /* use only this ADC */
5584                if (spec->capsrc_nids)
5585                        spec->capsrc_nids += i;
5586                spec->adc_nids += i;
5587                spec->num_adc_nids = 1;
5588        }
5589}
5590
5591/* initialize dual adcs */
5592static void fixup_dual_adc_switch(struct hda_codec *codec)
5593{
5594        struct alc_spec *spec = codec->spec;
5595        init_capsrc_for_pin(codec, spec->ext_mic.pin);
5596        init_capsrc_for_pin(codec, spec->int_mic.pin);
5597}
5598
5599static void set_capture_mixer(struct hda_codec *codec)
5600{
5601        struct alc_spec *spec = codec->spec;
5602        static struct snd_kcontrol_new *caps[2][3] = {
5603                { alc_capture_mixer_nosrc1,
5604                  alc_capture_mixer_nosrc2,
5605                  alc_capture_mixer_nosrc3 },
5606                { alc_capture_mixer1,
5607                  alc_capture_mixer2,
5608                  alc_capture_mixer3 },
5609        };
5610        if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5611                int mux = 0;
5612                int num_adcs = spec->num_adc_nids;
5613                if (spec->dual_adc_switch)
5614                        fixup_dual_adc_switch(codec);
5615                else if (spec->auto_mic)
5616                        fixup_automic_adc(codec);
5617                else if (spec->input_mux) {
5618                        if (spec->input_mux->num_items > 1)
5619                                mux = 1;
5620                        else if (spec->input_mux->num_items == 1)
5621                                fixup_single_adc(codec);
5622                }
5623                if (spec->dual_adc_switch)
5624                        num_adcs = 1;
5625                spec->cap_mixer = caps[mux][num_adcs - 1];
5626        }
5627}
5628
5629/* fill adc_nids (and capsrc_nids) containing all active input pins */
5630static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5631                                 int num_nids)
5632{
5633        struct alc_spec *spec = codec->spec;
5634        struct auto_pin_cfg *cfg = &spec->autocfg;
5635        int n;
5636        hda_nid_t fallback_adc = 0, fallback_cap = 0;
5637
5638        for (n = 0; n < num_nids; n++) {
5639                hda_nid_t adc, cap;
5640                hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5641                int nconns, i, j;
5642
5643                adc = nids[n];
5644                if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5645                        continue;
5646                cap = adc;
5647                nconns = snd_hda_get_connections(codec, cap, conn,
5648                                                 ARRAY_SIZE(conn));
5649                if (nconns == 1) {
5650                        cap = conn[0];
5651                        nconns = snd_hda_get_connections(codec, cap, conn,
5652                                                         ARRAY_SIZE(conn));
5653                }
5654                if (nconns <= 0)
5655                        continue;
5656                if (!fallback_adc) {
5657                        fallback_adc = adc;
5658                        fallback_cap = cap;
5659                }
5660                for (i = 0; i < cfg->num_inputs; i++) {
5661                        hda_nid_t nid = cfg->inputs[i].pin;
5662                        for (j = 0; j < nconns; j++) {
5663                                if (conn[j] == nid)
5664                                        break;
5665                        }
5666                        if (j >= nconns)
5667                                break;
5668                }
5669                if (i >= cfg->num_inputs) {
5670                        int num_adcs = spec->num_adc_nids;
5671                        spec->private_adc_nids[num_adcs] = adc;
5672                        spec->private_capsrc_nids[num_adcs] = cap;
5673                        spec->num_adc_nids++;
5674                        spec->adc_nids = spec->private_adc_nids;
5675                        if (adc != cap)
5676                                spec->capsrc_nids = spec->private_capsrc_nids;
5677                }
5678        }
5679        if (!spec->num_adc_nids) {
5680                printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5681                       " using fallback 0x%x\n",
5682                       codec->chip_name, fallback_adc);
5683                spec->private_adc_nids[0] = fallback_adc;
5684                spec->adc_nids = spec->private_adc_nids;
5685                if (fallback_adc != fallback_cap) {
5686                        spec->private_capsrc_nids[0] = fallback_cap;
5687                        spec->capsrc_nids = spec->private_adc_nids;
5688                }
5689        }
5690}
5691
5692#ifdef CONFIG_SND_HDA_INPUT_BEEP
5693#define set_beep_amp(spec, nid, idx, dir) \
5694        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5695
5696static struct snd_pci_quirk beep_white_list[] = {
5697        SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5698        SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5699        SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5700        {}
5701};
5702
5703static inline int has_cdefine_beep(struct hda_codec *codec)
5704{
5705        struct alc_spec *spec = codec->spec;
5706        const struct snd_pci_quirk *q;
5707        q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5708        if (q)
5709                return q->value;
5710        return spec->cdefine.enable_pcbeep;
5711}
5712#else
5713#define set_beep_amp(spec, nid, idx, dir) /* NOP */
5714#define has_cdefine_beep(codec)         0
5715#endif
5716
5717/*
5718 * OK, here we have finally the patch for ALC880
5719 */
5720
5721static int patch_alc880(struct hda_codec *codec)
5722{
5723        struct alc_spec *spec;
5724        int board_config;
5725        int err;
5726
5727        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5728        if (spec == NULL)
5729                return -ENOMEM;
5730
5731        codec->spec = spec;
5732
5733        board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5734                                                  alc880_models,
5735                                                  alc880_cfg_tbl);
5736        if (board_config < 0) {
5737                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5738                       codec->chip_name);
5739                board_config = ALC880_AUTO;
5740        }
5741
5742        if (board_config == ALC880_AUTO) {
5743                /* automatic parse from the BIOS config */
5744                err = alc880_parse_auto_config(codec);
5745                if (err < 0) {
5746                        alc_free(codec);
5747                        return err;
5748                } else if (!err) {
5749                        printk(KERN_INFO
5750                               "hda_codec: Cannot set up configuration "
5751                               "from BIOS.  Using 3-stack mode...\n");
5752                        board_config = ALC880_3ST;
5753                }
5754        }
5755
5756        err = snd_hda_attach_beep_device(codec, 0x1);
5757        if (err < 0) {
5758                alc_free(codec);
5759                return err;
5760        }
5761
5762        if (board_config != ALC880_AUTO)
5763                setup_preset(codec, &alc880_presets[board_config]);
5764
5765        spec->stream_analog_playback = &alc880_pcm_analog_playback;
5766        spec->stream_analog_capture = &alc880_pcm_analog_capture;
5767        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5768
5769        spec->stream_digital_playback = &alc880_pcm_digital_playback;
5770        spec->stream_digital_capture = &alc880_pcm_digital_capture;
5771
5772        if (!spec->adc_nids && spec->input_mux) {
5773                /* check whether NID 0x07 is valid */
5774                unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5775                /* get type */
5776                wcap = get_wcaps_type(wcap);
5777                if (wcap != AC_WID_AUD_IN) {
5778                        spec->adc_nids = alc880_adc_nids_alt;
5779                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5780                } else {
5781                        spec->adc_nids = alc880_adc_nids;
5782                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5783                }
5784        }
5785        set_capture_mixer(codec);
5786        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5787
5788        spec->vmaster_nid = 0x0c;
5789
5790        codec->patch_ops = alc_patch_ops;
5791        if (board_config == ALC880_AUTO)
5792                spec->init_hook = alc880_auto_init;
5793#ifdef CONFIG_SND_HDA_POWER_SAVE
5794        if (!spec->loopback.amplist)
5795                spec->loopback.amplist = alc880_loopbacks;
5796#endif
5797
5798        return 0;
5799}
5800
5801
5802/*
5803 * ALC260 support
5804 */
5805
5806static hda_nid_t alc260_dac_nids[1] = {
5807        /* front */
5808        0x02,
5809};
5810
5811static hda_nid_t alc260_adc_nids[1] = {
5812        /* ADC0 */
5813        0x04,
5814};
5815
5816static hda_nid_t alc260_adc_nids_alt[1] = {
5817        /* ADC1 */
5818        0x05,
5819};
5820
5821/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
5822 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5823 */
5824static hda_nid_t alc260_dual_adc_nids[2] = {
5825        /* ADC0, ADC1 */
5826        0x04, 0x05
5827};
5828
5829#define ALC260_DIGOUT_NID       0x03
5830#define ALC260_DIGIN_NID        0x06
5831
5832static struct hda_input_mux alc260_capture_source = {
5833        .num_items = 4,
5834        .items = {
5835                { "Mic", 0x0 },
5836                { "Front Mic", 0x1 },
5837                { "Line", 0x2 },
5838                { "CD", 0x4 },
5839        },
5840};
5841
5842/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5843 * headphone jack and the internal CD lines since these are the only pins at
5844 * which audio can appear.  For flexibility, also allow the option of
5845 * recording the mixer output on the second ADC (ADC0 doesn't have a
5846 * connection to the mixer output).
5847 */
5848static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5849        {
5850                .num_items = 3,
5851                .items = {
5852                        { "Mic/Line", 0x0 },
5853                        { "CD", 0x4 },
5854                        { "Headphone", 0x2 },
5855                },
5856        },
5857        {
5858                .num_items = 4,
5859                .items = {
5860                        { "Mic/Line", 0x0 },
5861                        { "CD", 0x4 },
5862                        { "Headphone", 0x2 },
5863                        { "Mixer", 0x5 },
5864                },
5865        },
5866
5867};
5868
5869/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5870 * the Fujitsu S702x, but jacks are marked differently.
5871 */
5872static struct hda_input_mux alc260_acer_capture_sources[2] = {
5873        {
5874                .num_items = 4,
5875                .items = {
5876                        { "Mic", 0x0 },
5877                        { "Line", 0x2 },
5878                        { "CD", 0x4 },
5879                        { "Headphone", 0x5 },
5880                },
5881        },
5882        {
5883                .num_items = 5,
5884                .items = {
5885                        { "Mic", 0x0 },
5886                        { "Line", 0x2 },
5887                        { "CD", 0x4 },
5888                        { "Headphone", 0x6 },
5889                        { "Mixer", 0x5 },
5890                },
5891        },
5892};
5893
5894/* Maxdata Favorit 100XS */
5895static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5896        {
5897                .num_items = 2,
5898                .items = {
5899                        { "Line/Mic", 0x0 },
5900                        { "CD", 0x4 },
5901                },
5902        },
5903        {
5904                .num_items = 3,
5905                .items = {
5906                        { "Line/Mic", 0x0 },
5907                        { "CD", 0x4 },
5908                        { "Mixer", 0x5 },
5909                },
5910        },
5911};
5912
5913/*
5914 * This is just place-holder, so there's something for alc_build_pcms to look
5915 * at when it calculates the maximum number of channels. ALC260 has no mixer
5916 * element which allows changing the channel mode, so the verb list is
5917 * never used.
5918 */
5919static struct hda_channel_mode alc260_modes[1] = {
5920        { 2, NULL },
5921};
5922
5923
5924/* Mixer combinations
5925 *
5926 * basic: base_output + input + pc_beep + capture
5927 * HP: base_output + input + capture_alt
5928 * HP_3013: hp_3013 + input + capture
5929 * fujitsu: fujitsu + capture
5930 * acer: acer + capture
5931 */
5932
5933static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5934        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5935        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5936        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5937        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5938        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5939        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5940        { } /* end */
5941};
5942
5943static struct snd_kcontrol_new alc260_input_mixer[] = {
5944        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5945        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5946        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5947        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5948        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5949        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5950        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5951        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5952        { } /* end */
5953};
5954
5955/* update HP, line and mono out pins according to the master switch */
5956static void alc260_hp_master_update(struct hda_codec *codec,
5957                                    hda_nid_t hp, hda_nid_t line,
5958                                    hda_nid_t mono)
5959{
5960        struct alc_spec *spec = codec->spec;
5961        unsigned int val = spec->master_sw ? PIN_HP : 0;
5962        /* change HP and line-out pins */
5963        snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5964                            val);
5965        snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5966                            val);
5967        /* mono (speaker) depending on the HP jack sense */
5968        val = (val && !spec->jack_present) ? PIN_OUT : 0;
5969        snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5970                            val);
5971}
5972
5973static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5974                                   struct snd_ctl_elem_value *ucontrol)
5975{
5976        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5977        struct alc_spec *spec = codec->spec;
5978        *ucontrol->value.integer.value = spec->master_sw;
5979        return 0;
5980}
5981
5982static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5983                                   struct snd_ctl_elem_value *ucontrol)
5984{
5985        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5986        struct alc_spec *spec = codec->spec;
5987        int val = !!*ucontrol->value.integer.value;
5988        hda_nid_t hp, line, mono;
5989
5990        if (val == spec->master_sw)
5991                return 0;
5992        spec->master_sw = val;
5993        hp = (kcontrol->private_value >> 16) & 0xff;
5994        line = (kcontrol->private_value >> 8) & 0xff;
5995        mono = kcontrol->private_value & 0xff;
5996        alc260_hp_master_update(codec, hp, line, mono);
5997        return 1;
5998}
5999
6000static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6001        {
6002                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6003                .name = "Master Playback Switch",
6004                .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6005                .info = snd_ctl_boolean_mono_info,
6006                .get = alc260_hp_master_sw_get,
6007                .put = alc260_hp_master_sw_put,
6008                .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
6009        },
6010        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6011        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6012        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6013        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6014        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6015                              HDA_OUTPUT),
6016        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6017        { } /* end */
6018};
6019
6020static struct hda_verb alc260_hp_unsol_verbs[] = {
6021        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6022        {},
6023};
6024
6025static void alc260_hp_automute(struct hda_codec *codec)
6026{
6027        struct alc_spec *spec = codec->spec;
6028
6029        spec->jack_present = snd_hda_jack_detect(codec, 0x10);
6030        alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
6031}
6032
6033static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
6034{
6035        if ((res >> 26) == ALC880_HP_EVENT)
6036                alc260_hp_automute(codec);
6037}
6038
6039static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6040        {
6041                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6042                .name = "Master Playback Switch",
6043                .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6044                .info = snd_ctl_boolean_mono_info,
6045                .get = alc260_hp_master_sw_get,
6046                .put = alc260_hp_master_sw_put,
6047                .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
6048        },
6049        HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6050        HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6051        HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6052        HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6053        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6054        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6055        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6056        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6057        { } /* end */
6058};
6059
6060static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6061        .ops = &snd_hda_bind_vol,
6062        .values = {
6063                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6064                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6065                HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6066                0
6067        },
6068};
6069
6070static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6071        .ops = &snd_hda_bind_sw,
6072        .values = {
6073                HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6074                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6075                0
6076        },
6077};
6078
6079static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6080        HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6081        HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6082        HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6083        HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6084        { } /* end */
6085};
6086
6087static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6088        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6089        {},
6090};
6091
6092static void alc260_hp_3013_automute(struct hda_codec *codec)
6093{
6094        struct alc_spec *spec = codec->spec;
6095
6096        spec->jack_present = snd_hda_jack_detect(codec, 0x15);
6097        alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
6098}
6099
6100static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6101                                       unsigned int res)
6102{
6103        if ((res >> 26) == ALC880_HP_EVENT)
6104                alc260_hp_3013_automute(codec);
6105}
6106
6107static void alc260_hp_3012_automute(struct hda_codec *codec)
6108{
6109        unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
6110
6111        snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6112                            bits);
6113        snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6114                            bits);
6115        snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6116                            bits);
6117}
6118
6119static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6120                                       unsigned int res)
6121{
6122        if ((res >> 26) == ALC880_HP_EVENT)
6123                alc260_hp_3012_automute(codec);
6124}
6125
6126/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
6127 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
6128 */
6129static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6130        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6131        HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6132        ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6133        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6134        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6135        HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6136        HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6137        ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6138        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6139        HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6140        { } /* end */
6141};
6142
6143/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
6144 * versions of the ALC260 don't act on requests to enable mic bias from NID
6145 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
6146 * datasheet doesn't mention this restriction.  At this stage it's not clear
6147 * whether this behaviour is intentional or is a hardware bug in chip
6148 * revisions available in early 2006.  Therefore for now allow the
6149 * "Headphone Jack Mode" control to span all choices, but if it turns out
6150 * that the lack of mic bias for this NID is intentional we could change the
6151 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6152 *
6153 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6154 * don't appear to make the mic bias available from the "line" jack, even
6155 * though the NID used for this jack (0x14) can supply it.  The theory is
6156 * that perhaps Acer have included blocking capacitors between the ALC260
6157 * and the output jack.  If this turns out to be the case for all such
6158 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6159 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6160 *
6161 * The C20x Tablet series have a mono internal speaker which is controlled
6162 * via the chip's Mono sum widget and pin complex, so include the necessary
6163 * controls for such models.  On models without a "mono speaker" the control
6164 * won't do anything.
6165 */
6166static struct snd_kcontrol_new alc260_acer_mixer[] = {
6167        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6168        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6169        ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6170        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6171                              HDA_OUTPUT),
6172        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6173                           HDA_INPUT),
6174        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6175        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6176        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6177        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6178        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6179        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6180        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6181        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6182        { } /* end */
6183};
6184
6185/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6186 */
6187static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6188        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6189        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6190        ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6191        HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6192        HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6193        ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6194        { } /* end */
6195};
6196
6197/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6198 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
6199 */
6200static struct snd_kcontrol_new alc260_will_mixer[] = {
6201        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6202        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6203        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6204        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6205        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6206        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6207        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6208        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6209        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6210        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6211        { } /* end */
6212};
6213
6214/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6215 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6216 */
6217static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6218        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6219        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6220        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6221        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6222        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6223        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6224        HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6225        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6226        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6227        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6228        { } /* end */
6229};
6230
6231/*
6232 * initialization verbs
6233 */
6234static struct hda_verb alc260_init_verbs[] = {
6235        /* Line In pin widget for input */
6236        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6237        /* CD pin widget for input */
6238        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6239        /* Mic1 (rear panel) pin widget for input and vref at 80% */
6240        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6241        /* Mic2 (front panel) pin widget for input and vref at 80% */
6242        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6243        /* LINE-2 is used for line-out in rear */
6244        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6245        /* select line-out */
6246        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6247        /* LINE-OUT pin */
6248        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6249        /* enable HP */
6250        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6251        /* enable Mono */
6252        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6253        /* mute capture amp left and right */
6254        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6255        /* set connection select to line in (default select for this ADC) */
6256        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6257        /* mute capture amp left and right */
6258        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6259        /* set connection select to line in (default select for this ADC) */
6260        {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6261        /* set vol=0 Line-Out mixer amp left and right */
6262        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6263        /* unmute pin widget amp left and right (no gain on this amp) */
6264        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6265        /* set vol=0 HP mixer amp left and right */
6266        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6267        /* unmute pin widget amp left and right (no gain on this amp) */
6268        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6269        /* set vol=0 Mono mixer amp left and right */
6270        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6271        /* unmute pin widget amp left and right (no gain on this amp) */
6272        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6273        /* unmute LINE-2 out pin */
6274        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6275        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6276         * Line In 2 = 0x03
6277         */
6278        /* mute analog inputs */
6279        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6280        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6281        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6282        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6283        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6284        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6285        /* mute Front out path */
6286        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6287        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6288        /* mute Headphone out path */
6289        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6290        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6291        /* mute Mono out path */
6292        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6293        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6294        { }
6295};
6296
6297#if 0 /* should be identical with alc260_init_verbs? */
6298static struct hda_verb alc260_hp_init_verbs[] = {
6299        /* Headphone and output */
6300        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6301        /* mono output */
6302        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6303        /* Mic1 (rear panel) pin widget for input and vref at 80% */
6304        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6305        /* Mic2 (front panel) pin widget for input and vref at 80% */
6306        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6307        /* Line In pin widget for input */
6308        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6309        /* Line-2 pin widget for output */
6310        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6311        /* CD pin widget for input */
6312        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6313        /* unmute amp left and right */
6314        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6315        /* set connection select to line in (default select for this ADC) */
6316        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6317        /* unmute Line-Out mixer amp left and right (volume = 0) */
6318        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6319        /* mute pin widget amp left and right (no gain on this amp) */
6320        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6321        /* unmute HP mixer amp left and right (volume = 0) */
6322        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6323        /* mute pin widget amp left and right (no gain on this amp) */
6324        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6325        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6326         * Line In 2 = 0x03
6327         */
6328        /* mute analog inputs */
6329        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6331        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6332        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6333        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6334        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6335        /* Unmute Front out path */
6336        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6338        /* Unmute Headphone out path */
6339        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6340        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6341        /* Unmute Mono out path */
6342        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6343        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6344        { }
6345};
6346#endif
6347
6348static struct hda_verb alc260_hp_3013_init_verbs[] = {
6349        /* Line out and output */
6350        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6351        /* mono output */
6352        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6353        /* Mic1 (rear panel) pin widget for input and vref at 80% */
6354        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6355        /* Mic2 (front panel) pin widget for input and vref at 80% */
6356        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6357        /* Line In pin widget for input */
6358        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6359        /* Headphone pin widget for output */
6360        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6361        /* CD pin widget for input */
6362        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6363        /* unmute amp left and right */
6364        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6365        /* set connection select to line in (default select for this ADC) */
6366        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6367        /* unmute Line-Out mixer amp left and right (volume = 0) */
6368        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6369        /* mute pin widget amp left and right (no gain on this amp) */
6370        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6371        /* unmute HP mixer amp left and right (volume = 0) */
6372        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6373        /* mute pin widget amp left and right (no gain on this amp) */
6374        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6375        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6376         * Line In 2 = 0x03
6377         */
6378        /* mute analog inputs */
6379        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6380        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6381        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6382        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6383        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6384        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6385        /* Unmute Front out path */
6386        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6387        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6388        /* Unmute Headphone out path */
6389        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6390        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6391        /* Unmute Mono out path */
6392        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6393        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6394        { }
6395};
6396
6397/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6398 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6399 * audio = 0x16, internal speaker = 0x10.
6400 */
6401static struct hda_verb alc260_fujitsu_init_verbs[] = {
6402        /* Disable all GPIOs */
6403        {0x01, AC_VERB_SET_GPIO_MASK, 0},
6404        /* Internal speaker is connected to headphone pin */
6405        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6406        /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6407        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6408        /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6409        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6410        /* Ensure all other unused pins are disabled and muted. */
6411        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6412        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6413        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6414        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6415        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6416        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6417        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6418        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6419
6420        /* Disable digital (SPDIF) pins */
6421        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6422        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6423
6424        /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6425         * when acting as an output.
6426         */
6427        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6428
6429        /* Start with output sum widgets muted and their output gains at min */
6430        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6431        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6432        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6433        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6434        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6435        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6436        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6437        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6438        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6439
6440        /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6441        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6442        /* Unmute Line1 pin widget output buffer since it starts as an output.
6443         * If the pin mode is changed by the user the pin mode control will
6444         * take care of enabling the pin's input/output buffers as needed.
6445         * Therefore there's no need to enable the input buffer at this
6446         * stage.
6447         */
6448        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6449        /* Unmute input buffer of pin widget used for Line-in (no equiv
6450         * mixer ctrl)
6451         */
6452        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453
6454        /* Mute capture amp left and right */
6455        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6456        /* Set ADC connection select to match default mixer setting - line
6457         * in (on mic1 pin)
6458         */
6459        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6460
6461        /* Do the same for the second ADC: mute capture input amp and
6462         * set ADC connection to line in (on mic1 pin)
6463         */
6464        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6466
6467        /* Mute all inputs to mixer widget (even unconnected ones) */
6468        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6469        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6470        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6471        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6472        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6473        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6474        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6475        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6476
6477        { }
6478};
6479
6480/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6481 * similar laptops (adapted from Fujitsu init verbs).
6482 */
6483static struct hda_verb alc260_acer_init_verbs[] = {
6484        /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6485         * the headphone jack.  Turn this on and rely on the standard mute
6486         * methods whenever the user wants to turn these outputs off.
6487         */
6488        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6489        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6490        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6491        /* Internal speaker/Headphone jack is connected to Line-out pin */
6492        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6493        /* Internal microphone/Mic jack is connected to Mic1 pin */
6494        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6495        /* Line In jack is connected to Line1 pin */
6496        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6497        /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6498        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6499        /* Ensure all other unused pins are disabled and muted. */
6500        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6501        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6502        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6503        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6504        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6505        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506        /* Disable digital (SPDIF) pins */
6507        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6508        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6509
6510        /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6511         * bus when acting as outputs.
6512         */
6513        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6514        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6515
6516        /* Start with output sum widgets muted and their output gains at min */
6517        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6518        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6519        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6520        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6521        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6522        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6523        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6525        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6526
6527        /* Unmute Line-out pin widget amp left and right
6528         * (no equiv mixer ctrl)
6529         */
6530        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6531        /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6532        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6533        /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6534         * inputs. If the pin mode is changed by the user the pin mode control
6535         * will take care of enabling the pin's input/output buffers as needed.
6536         * Therefore there's no need to enable the input buffer at this
6537         * stage.
6538         */
6539        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6540        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6541
6542        /* Mute capture amp left and right */
6543        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6544        /* Set ADC connection select to match default mixer setting - mic
6545         * (on mic1 pin)
6546         */
6547        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6548
6549        /* Do similar with the second ADC: mute capture input amp and
6550         * set ADC connection to mic to match ALSA's default state.
6551         */
6552        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6553        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6554
6555        /* Mute all inputs to mixer widget (even unconnected ones) */
6556        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6557        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6558        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6559        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6560        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6561        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6562        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6563        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6564
6565        { }
6566};
6567
6568/* Initialisation sequence for Maxdata Favorit 100XS
6569 * (adapted from Acer init verbs).
6570 */
6571static struct hda_verb alc260_favorit100_init_verbs[] = {
6572        /* GPIO 0 enables the output jack.
6573         * Turn this on and rely on the standard mute
6574         * methods whenever the user wants to turn these outputs off.
6575         */
6576        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6577        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6578        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6579        /* Line/Mic input jack is connected to Mic1 pin */
6580        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6581        /* Ensure all other unused pins are disabled and muted. */
6582        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6583        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6584        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6585        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6586        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6587        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6588        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6589        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6590        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6591        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6592        /* Disable digital (SPDIF) pins */
6593        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6594        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6595
6596        /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6597         * bus when acting as outputs.
6598         */
6599        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6600        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6601
6602        /* Start with output sum widgets muted and their output gains at min */
6603        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6604        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6605        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6606        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6608        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6609        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6610        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6611        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6612
6613        /* Unmute Line-out pin widget amp left and right
6614         * (no equiv mixer ctrl)
6615         */
6616        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6617        /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6618         * inputs. If the pin mode is changed by the user the pin mode control
6619         * will take care of enabling the pin's input/output buffers as needed.
6620         * Therefore there's no need to enable the input buffer at this
6621         * stage.
6622         */
6623        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6624
6625        /* Mute capture amp left and right */
6626        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6627        /* Set ADC connection select to match default mixer setting - mic
6628         * (on mic1 pin)
6629         */
6630        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6631
6632        /* Do similar with the second ADC: mute capture input amp and
6633         * set ADC connection to mic to match ALSA's default state.
6634         */
6635        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6637
6638        /* Mute all inputs to mixer widget (even unconnected ones) */
6639        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6640        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6641        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6642        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6643        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6644        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6645        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6646        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6647
6648        { }
6649};
6650
6651static struct hda_verb alc260_will_verbs[] = {
6652        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6653        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6654        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6655        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6656        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6657        {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6658        {}
6659};
6660
6661static struct hda_verb alc260_replacer_672v_verbs[] = {
6662        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6663        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6664        {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6665
6666        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6667        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6668        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6669
6670        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6671        {}
6672};
6673
6674/* toggle speaker-output according to the hp-jack state */
6675static void alc260_replacer_672v_automute(struct hda_codec *codec)
6676{
6677        unsigned int present;
6678
6679        /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6680        present = snd_hda_jack_detect(codec, 0x0f);
6681        if (present) {
6682                snd_hda_codec_write_cache(codec, 0x01, 0,
6683                                          AC_VERB_SET_GPIO_DATA, 1);
6684                snd_hda_codec_write_cache(codec, 0x0f, 0,
6685                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
6686                                          PIN_HP);
6687        } else {
6688                snd_hda_codec_write_cache(codec, 0x01, 0,
6689                                          AC_VERB_SET_GPIO_DATA, 0);
6690                snd_hda_codec_write_cache(codec, 0x0f, 0,
6691                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
6692                                          PIN_OUT);
6693        }
6694}
6695
6696static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6697                                       unsigned int res)
6698{
6699        if ((res >> 26) == ALC880_HP_EVENT)
6700                alc260_replacer_672v_automute(codec);
6701}
6702
6703static struct hda_verb alc260_hp_dc7600_verbs[] = {
6704        {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6705        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6706        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6707        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6708        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6709        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6710        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6711        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6712        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6713        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6714        {}
6715};
6716
6717/* Test configuration for debugging, modelled after the ALC880 test
6718 * configuration.
6719 */
6720#ifdef CONFIG_SND_DEBUG
6721static hda_nid_t alc260_test_dac_nids[1] = {
6722        0x02,
6723};
6724static hda_nid_t alc260_test_adc_nids[2] = {
6725        0x04, 0x05,
6726};
6727/* For testing the ALC260, each input MUX needs its own definition since
6728 * the signal assignments are different.  This assumes that the first ADC
6729 * is NID 0x04.
6730 */
6731static struct hda_input_mux alc260_test_capture_sources[2] = {
6732        {
6733                .num_items = 7,
6734                .items = {
6735                        { "MIC1 pin", 0x0 },
6736                        { "MIC2 pin", 0x1 },
6737                        { "LINE1 pin", 0x2 },
6738                        { "LINE2 pin", 0x3 },
6739                        { "CD pin", 0x4 },
6740                        { "LINE-OUT pin", 0x5 },
6741                        { "HP-OUT pin", 0x6 },
6742                },
6743        },
6744        {
6745                .num_items = 8,
6746                .items = {
6747                        { "MIC1 pin", 0x0 },
6748                        { "MIC2 pin", 0x1 },
6749                        { "LINE1 pin", 0x2 },
6750                        { "LINE2 pin", 0x3 },
6751                        { "CD pin", 0x4 },
6752                        { "Mixer", 0x5 },
6753                        { "LINE-OUT pin", 0x6 },
6754                        { "HP-OUT pin", 0x7 },
6755                },
6756        },
6757};
6758static struct snd_kcontrol_new alc260_test_mixer[] = {
6759        /* Output driver widgets */
6760        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6761        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6762        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6763        HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6764        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6765        HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6766
6767        /* Modes for retasking pin widgets
6768         * Note: the ALC260 doesn't seem to act on requests to enable mic
6769         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
6770         * mention this restriction.  At this stage it's not clear whether
6771         * this behaviour is intentional or is a hardware bug in chip
6772         * revisions available at least up until early 2006.  Therefore for
6773         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6774         * choices, but if it turns out that the lack of mic bias for these
6775         * NIDs is intentional we could change their modes from
6776         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6777         */
6778        ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6779        ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6780        ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6781        ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6782        ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6783        ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6784
6785        /* Loopback mixer controls */
6786        HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6787        HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6788        HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6789        HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6790        HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6791        HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6792        HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6793        HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6794        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6795        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6796        HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6797        HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6798        HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6799        HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6800
6801        /* Controls for GPIO pins, assuming they are configured as outputs */
6802        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6803        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6804        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6805        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6806
6807        /* Switches to allow the digital IO pins to be enabled.  The datasheet
6808         * is ambigious as to which NID is which; testing on laptops which
6809         * make this output available should provide clarification.
6810         */
6811        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6812        ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6813
6814        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
6815         * this output to turn on an external amplifier.
6816         */
6817        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6818        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6819
6820        { } /* end */
6821};
6822static struct hda_verb alc260_test_init_verbs[] = {
6823        /* Enable all GPIOs as outputs with an initial value of 0 */
6824        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6825        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6826        {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6827
6828        /* Enable retasking pins as output, initially without power amp */
6829        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6830        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6831        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6832        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6833        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6834        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6835
6836        /* Disable digital (SPDIF) pins initially, but users can enable
6837         * them via a mixer switch.  In the case of SPDIF-out, this initverb
6838         * payload also sets the generation to 0, output to be in "consumer"
6839         * PCM format, copyright asserted, no pre-emphasis and no validity
6840         * control.
6841         */
6842        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6843        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6844
6845        /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6846         * OUT1 sum bus when acting as an output.
6847         */
6848        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6849        {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6850        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6851        {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6852
6853        /* Start with output sum widgets muted and their output gains at min */
6854        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6856        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6857        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6858        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6859        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6860        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6862        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6863
6864        /* Unmute retasking pin widget output buffers since the default
6865         * state appears to be output.  As the pin mode is changed by the
6866         * user the pin mode control will take care of enabling the pin's
6867         * input/output buffers as needed.
6868         */
6869        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6870        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6871        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6872        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6873        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6874        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6875        /* Also unmute the mono-out pin widget */
6876        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6877
6878        /* Mute capture amp left and right */
6879        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6880        /* Set ADC connection select to match default mixer setting (mic1
6881         * pin)
6882         */
6883        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6884
6885        /* Do the same for the second ADC: mute capture input amp and
6886         * set ADC connection to mic1 pin
6887         */
6888        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6889        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6890
6891        /* Mute all inputs to mixer widget (even unconnected ones) */
6892        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6893        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6894        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6895        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6896        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6897        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6898        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6899        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6900
6901        { }
6902};
6903#endif
6904
6905#define alc260_pcm_analog_playback      alc880_pcm_analog_alt_playback
6906#define alc260_pcm_analog_capture       alc880_pcm_analog_capture
6907
6908#define alc260_pcm_digital_playback     alc880_pcm_digital_playback
6909#define alc260_pcm_digital_capture      alc880_pcm_digital_capture
6910
6911/*
6912 * for BIOS auto-configuration
6913 */
6914
6915static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6916                                        const char *pfx, int *vol_bits)
6917{
6918        hda_nid_t nid_vol;
6919        unsigned long vol_val, sw_val;
6920        int err;
6921
6922        if (nid >= 0x0f && nid < 0x11) {
6923                nid_vol = nid - 0x7;
6924                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6925                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6926        } else if (nid == 0x11) {
6927                nid_vol = nid - 0x7;
6928                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6929                sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6930        } else if (nid >= 0x12 && nid <= 0x15) {
6931                nid_vol = 0x08;
6932                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6933                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6934        } else
6935                return 0; /* N/A */
6936
6937        if (!(*vol_bits & (1 << nid_vol))) {
6938                /* first control for the volume widget */
6939                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6940                if (err < 0)
6941                        return err;
6942                *vol_bits |= (1 << nid_vol);
6943        }
6944        err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6945        if (err < 0)
6946                return err;
6947        return 1;
6948}
6949
6950/* add playback controls from the parsed DAC table */
6951static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6952                                             const struct auto_pin_cfg *cfg)
6953{
6954        hda_nid_t nid;
6955        int err;
6956        int vols = 0;
6957
6958        spec->multiout.num_dacs = 1;
6959        spec->multiout.dac_nids = spec->private_dac_nids;
6960        spec->multiout.dac_nids[0] = 0x02;
6961
6962        nid = cfg->line_out_pins[0];
6963        if (nid) {
6964                const char *pfx;
6965                if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6966                        pfx = "Master";
6967                else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6968                        pfx = "Speaker";
6969                else
6970                        pfx = "Front";
6971                err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6972                if (err < 0)
6973                        return err;
6974        }
6975
6976        nid = cfg->speaker_pins[0];
6977        if (nid) {
6978                err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6979                if (err < 0)
6980                        return err;
6981        }
6982
6983        nid = cfg->hp_pins[0];
6984        if (nid) {
6985                err = alc260_add_playback_controls(spec, nid, "Headphone",
6986                                                   &vols);
6987                if (err < 0)
6988                        return err;
6989        }
6990        return 0;
6991}
6992
6993/* create playback/capture controls for input pins */
6994static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6995                                                const struct auto_pin_cfg *cfg)
6996{
6997        return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6998}
6999
7000static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7001                                              hda_nid_t nid, int pin_type,
7002                                              int sel_idx)
7003{
7004        alc_set_pin_output(codec, nid, pin_type);
7005        /* need the manual connection? */
7006        if (nid >= 0x12) {
7007                int idx = nid - 0x12;
7008                snd_hda_codec_write(codec, idx + 0x0b, 0,
7009                                    AC_VERB_SET_CONNECT_SEL, sel_idx);
7010        }
7011}
7012
7013static void alc260_auto_init_multi_out(struct hda_codec *codec)
7014{
7015        struct alc_spec *spec = codec->spec;
7016        hda_nid_t nid;
7017
7018        nid = spec->autocfg.line_out_pins[0];
7019        if (nid) {
7020                int pin_type = get_pin_type(spec->autocfg.line_out_type);
7021                alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7022        }
7023
7024        nid = spec->autocfg.speaker_pins[0];
7025        if (nid)
7026                alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7027
7028        nid = spec->autocfg.hp_pins[0];
7029        if (nid)
7030                alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7031}
7032
7033#define ALC260_PIN_CD_NID               0x16
7034static void alc260_auto_init_analog_input(struct hda_codec *codec)
7035{
7036        struct alc_spec *spec = codec->spec;
7037        struct auto_pin_cfg *cfg = &spec->autocfg;
7038        int i;
7039
7040        for (i = 0; i < cfg->num_inputs; i++) {
7041                hda_nid_t nid = cfg->inputs[i].pin;
7042                if (nid >= 0x12) {
7043                        alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7044                        if (nid != ALC260_PIN_CD_NID &&
7045                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7046                                snd_hda_codec_write(codec, nid, 0,
7047                                                    AC_VERB_SET_AMP_GAIN_MUTE,
7048                                                    AMP_OUT_MUTE);
7049                }
7050        }
7051}
7052
7053#define alc260_auto_init_input_src      alc880_auto_init_input_src
7054
7055/*
7056 * generic initialization of ADC, input mixers and output mixers
7057 */
7058static struct hda_verb alc260_volume_init_verbs[] = {
7059        /*
7060         * Unmute ADC0-1 and set the default input to mic-in
7061         */
7062        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7063        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7064        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7065        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7066
7067        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7068         * mixer widget
7069         * Note: PASD motherboards uses the Line In 2 as the input for
7070         * front panel mic (mic 2)
7071         */
7072        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7073        /* mute analog inputs */
7074        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7075        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7076        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7077        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7078        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7079
7080        /*
7081         * Set up output mixers (0x08 - 0x0a)
7082         */
7083        /* set vol=0 to output mixers */
7084        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7085        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7086        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7087        /* set up input amps for analog loopback */
7088        /* Amp Indices: DAC = 0, mixer = 1 */
7089        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7090        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7091        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7092        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7093        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7094        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7095
7096        { }
7097};
7098
7099static int alc260_parse_auto_config(struct hda_codec *codec)
7100{
7101        struct alc_spec *spec = codec->spec;
7102        int err;
7103        static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7104
7105        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7106                                           alc260_ignore);
7107        if (err < 0)
7108                return err;
7109        err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7110        if (err < 0)
7111                return err;
7112        if (!spec->kctls.list)
7113                return 0; /* can't find valid BIOS pin config */
7114        err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7115        if (err < 0)
7116                return err;
7117
7118        spec->multiout.max_channels = 2;
7119
7120        if (spec->autocfg.dig_outs)
7121                spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7122        if (spec->kctls.list)
7123                add_mixer(spec, spec->kctls.list);
7124
7125        add_verb(spec, alc260_volume_init_verbs);
7126
7127        spec->num_mux_defs = 1;
7128        spec->input_mux = &spec->private_imux[0];
7129
7130        alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7131
7132        return 1;
7133}
7134
7135/* additional initialization for auto-configuration model */
7136static void alc260_auto_init(struct hda_codec *codec)
7137{
7138        struct alc_spec *spec = codec->spec;
7139        alc260_auto_init_multi_out(codec);
7140        alc260_auto_init_analog_input(codec);
7141        alc260_auto_init_input_src(codec);
7142        alc_auto_init_digital(codec);
7143        if (spec->unsol_event)
7144                alc_inithook(codec);
7145}
7146
7147#ifdef CONFIG_SND_HDA_POWER_SAVE
7148static struct hda_amp_list alc260_loopbacks[] = {
7149        { 0x07, HDA_INPUT, 0 },
7150        { 0x07, HDA_INPUT, 1 },
7151        { 0x07, HDA_INPUT, 2 },
7152        { 0x07, HDA_INPUT, 3 },
7153        { 0x07, HDA_INPUT, 4 },
7154        { } /* end */
7155};
7156#endif
7157
7158/*
7159 * Pin config fixes
7160 */
7161enum {
7162        PINFIX_HP_DC5750,
7163};
7164
7165static const struct alc_fixup alc260_fixups[] = {
7166        [PINFIX_HP_DC5750] = {
7167                .type = ALC_FIXUP_PINS,
7168                .v.pins = (const struct alc_pincfg[]) {
7169                        { 0x11, 0x90130110 }, /* speaker */
7170                        { }
7171                }
7172        },
7173};
7174
7175static struct snd_pci_quirk alc260_fixup_tbl[] = {
7176        SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7177        {}
7178};
7179
7180/*
7181 * ALC260 configurations
7182 */
7183static const char * const alc260_models[ALC260_MODEL_LAST] = {
7184        [ALC260_BASIC]          = "basic",
7185        [ALC260_HP]             = "hp",
7186        [ALC260_HP_3013]        = "hp-3013",
7187        [ALC260_HP_DC7600]      = "hp-dc7600",
7188        [ALC260_FUJITSU_S702X]  = "fujitsu",
7189        [ALC260_ACER]           = "acer",
7190        [ALC260_WILL]           = "will",
7191        [ALC260_REPLACER_672V]  = "replacer",
7192        [ALC260_FAVORIT100]     = "favorit100",
7193#ifdef CONFIG_SND_DEBUG
7194        [ALC260_TEST]           = "test",
7195#endif
7196        [ALC260_AUTO]           = "auto",
7197};
7198
7199static struct snd_pci_quirk alc260_cfg_tbl[] = {
7200        SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7201        SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7202        SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7203        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7204        SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7205        SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7206        SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7207        SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7208        SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7209        SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7210        SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7211        SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7212        SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7213        SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7214        SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7215        SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7216        SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7217        SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7218        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7219        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7220        {}
7221};
7222
7223static struct alc_config_preset alc260_presets[] = {
7224        [ALC260_BASIC] = {
7225                .mixers = { alc260_base_output_mixer,
7226                            alc260_input_mixer },
7227                .init_verbs = { alc260_init_verbs },
7228                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7229                .dac_nids = alc260_dac_nids,
7230                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7231                .adc_nids = alc260_dual_adc_nids,
7232                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7233                .channel_mode = alc260_modes,
7234                .input_mux = &alc260_capture_source,
7235        },
7236        [ALC260_HP] = {
7237                .mixers = { alc260_hp_output_mixer,
7238                            alc260_input_mixer },
7239                .init_verbs = { alc260_init_verbs,
7240                                alc260_hp_unsol_verbs },
7241                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7242                .dac_nids = alc260_dac_nids,
7243                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7244                .adc_nids = alc260_adc_nids_alt,
7245                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7246                .channel_mode = alc260_modes,
7247                .input_mux = &alc260_capture_source,
7248                .unsol_event = alc260_hp_unsol_event,
7249                .init_hook = alc260_hp_automute,
7250        },
7251        [ALC260_HP_DC7600] = {
7252                .mixers = { alc260_hp_dc7600_mixer,
7253                            alc260_input_mixer },
7254                .init_verbs = { alc260_init_verbs,
7255                                alc260_hp_dc7600_verbs },
7256                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7257                .dac_nids = alc260_dac_nids,
7258                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7259                .adc_nids = alc260_adc_nids_alt,
7260                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7261                .channel_mode = alc260_modes,
7262                .input_mux = &alc260_capture_source,
7263                .unsol_event = alc260_hp_3012_unsol_event,
7264                .init_hook = alc260_hp_3012_automute,
7265        },
7266        [ALC260_HP_3013] = {
7267                .mixers = { alc260_hp_3013_mixer,
7268                            alc260_input_mixer },
7269                .init_verbs = { alc260_hp_3013_init_verbs,
7270                                alc260_hp_3013_unsol_verbs },
7271                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7272                .dac_nids = alc260_dac_nids,
7273                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7274                .adc_nids = alc260_adc_nids_alt,
7275                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7276                .channel_mode = alc260_modes,
7277                .input_mux = &alc260_capture_source,
7278                .unsol_event = alc260_hp_3013_unsol_event,
7279                .init_hook = alc260_hp_3013_automute,
7280        },
7281        [ALC260_FUJITSU_S702X] = {
7282                .mixers = { alc260_fujitsu_mixer },
7283                .init_verbs = { alc260_fujitsu_init_verbs },
7284                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7285                .dac_nids = alc260_dac_nids,
7286                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7287                .adc_nids = alc260_dual_adc_nids,
7288                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7289                .channel_mode = alc260_modes,
7290                .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7291                .input_mux = alc260_fujitsu_capture_sources,
7292        },
7293        [ALC260_ACER] = {
7294                .mixers = { alc260_acer_mixer },
7295                .init_verbs = { alc260_acer_init_verbs },
7296                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7297                .dac_nids = alc260_dac_nids,
7298                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7299                .adc_nids = alc260_dual_adc_nids,
7300                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7301                .channel_mode = alc260_modes,
7302                .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7303                .input_mux = alc260_acer_capture_sources,
7304        },
7305        [ALC260_FAVORIT100] = {
7306                .mixers = { alc260_favorit100_mixer },
7307                .init_verbs = { alc260_favorit100_init_verbs },
7308                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7309                .dac_nids = alc260_dac_nids,
7310                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7311                .adc_nids = alc260_dual_adc_nids,
7312                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7313                .channel_mode = alc260_modes,
7314                .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7315                .input_mux = alc260_favorit100_capture_sources,
7316        },
7317        [ALC260_WILL] = {
7318                .mixers = { alc260_will_mixer },
7319                .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7320                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7321                .dac_nids = alc260_dac_nids,
7322                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7323                .adc_nids = alc260_adc_nids,
7324                .dig_out_nid = ALC260_DIGOUT_NID,
7325                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7326                .channel_mode = alc260_modes,
7327                .input_mux = &alc260_capture_source,
7328        },
7329        [ALC260_REPLACER_672V] = {
7330                .mixers = { alc260_replacer_672v_mixer },
7331                .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7332                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7333                .dac_nids = alc260_dac_nids,
7334                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7335                .adc_nids = alc260_adc_nids,
7336                .dig_out_nid = ALC260_DIGOUT_NID,
7337                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7338                .channel_mode = alc260_modes,
7339                .input_mux = &alc260_capture_source,
7340                .unsol_event = alc260_replacer_672v_unsol_event,
7341                .init_hook = alc260_replacer_672v_automute,
7342        },
7343#ifdef CONFIG_SND_DEBUG
7344        [ALC260_TEST] = {
7345                .mixers = { alc260_test_mixer },
7346                .init_verbs = { alc260_test_init_verbs },
7347                .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7348                .dac_nids = alc260_test_dac_nids,
7349                .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7350                .adc_nids = alc260_test_adc_nids,
7351                .num_channel_mode = ARRAY_SIZE(alc260_modes),
7352                .channel_mode = alc260_modes,
7353                .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7354                .input_mux = alc260_test_capture_sources,
7355        },
7356#endif
7357};
7358
7359static int patch_alc260(struct hda_codec *codec)
7360{
7361        struct alc_spec *spec;
7362        int err, board_config;
7363
7364        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7365        if (spec == NULL)
7366                return -ENOMEM;
7367
7368        codec->spec = spec;
7369
7370        board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7371                                                  alc260_models,
7372                                                  alc260_cfg_tbl);
7373        if (board_config < 0) {
7374                snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7375                           codec->chip_name);
7376                board_config = ALC260_AUTO;
7377        }
7378
7379        if (board_config == ALC260_AUTO) {
7380                alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7381                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7382        }
7383
7384        if (board_config == ALC260_AUTO) {
7385                /* automatic parse from the BIOS config */
7386                err = alc260_parse_auto_config(codec);
7387                if (err < 0) {
7388                        alc_free(codec);
7389                        return err;
7390                } else if (!err) {
7391                        printk(KERN_INFO
7392                               "hda_codec: Cannot set up configuration "
7393                               "from BIOS.  Using base mode...\n");
7394                        board_config = ALC260_BASIC;
7395                }
7396        }
7397
7398        err = snd_hda_attach_beep_device(codec, 0x1);
7399        if (err < 0) {
7400                alc_free(codec);
7401                return err;
7402        }
7403
7404        if (board_config != ALC260_AUTO)
7405                setup_preset(codec, &alc260_presets[board_config]);
7406
7407        spec->stream_analog_playback = &alc260_pcm_analog_playback;
7408        spec->stream_analog_capture = &alc260_pcm_analog_capture;
7409        spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7410
7411        spec->stream_digital_playback = &alc260_pcm_digital_playback;
7412        spec->stream_digital_capture = &alc260_pcm_digital_capture;
7413
7414        if (!spec->adc_nids && spec->input_mux) {
7415                /* check whether NID 0x04 is valid */
7416                unsigned int wcap = get_wcaps(codec, 0x04);
7417                wcap = get_wcaps_type(wcap);
7418                /* get type */
7419                if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7420                        spec->adc_nids = alc260_adc_nids_alt;
7421                        spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7422                } else {
7423                        spec->adc_nids = alc260_adc_nids;
7424                        spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7425                }
7426        }
7427        set_capture_mixer(codec);
7428        set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7429
7430        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7431
7432        spec->vmaster_nid = 0x08;
7433
7434        codec->patch_ops = alc_patch_ops;
7435        if (board_config == ALC260_AUTO)
7436                spec->init_hook = alc260_auto_init;
7437#ifdef CONFIG_SND_HDA_POWER_SAVE
7438        if (!spec->loopback.amplist)
7439                spec->loopback.amplist = alc260_loopbacks;
7440#endif
7441
7442        return 0;
7443}
7444
7445
7446/*
7447 * ALC882/883/885/888/889 support
7448 *
7449 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7450 * configuration.  Each pin widget can choose any input DACs and a mixer.
7451 * Each ADC is connected from a mixer of all inputs.  This makes possible
7452 * 6-channel independent captures.
7453 *
7454 * In addition, an independent DAC for the multi-playback (not used in this
7455 * driver yet).
7456 */
7457#define ALC882_DIGOUT_NID       0x06
7458#define ALC882_DIGIN_NID        0x0a
7459#define ALC883_DIGOUT_NID       ALC882_DIGOUT_NID
7460#define ALC883_DIGIN_NID        ALC882_DIGIN_NID
7461#define ALC1200_DIGOUT_NID      0x10
7462
7463
7464static struct hda_channel_mode alc882_ch_modes[1] = {
7465        { 8, NULL }
7466};
7467
7468/* DACs */
7469static hda_nid_t alc882_dac_nids[4] = {
7470        /* front, rear, clfe, rear_surr */
7471        0x02, 0x03, 0x04, 0x05
7472};
7473#define alc883_dac_nids         alc882_dac_nids
7474
7475/* ADCs */
7476#define alc882_adc_nids         alc880_adc_nids
7477#define alc882_adc_nids_alt     alc880_adc_nids_alt
7478#define alc883_adc_nids         alc882_adc_nids_alt
7479static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7480static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7481#define alc889_adc_nids         alc880_adc_nids
7482
7483static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7484static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7485#define alc883_capsrc_nids      alc882_capsrc_nids_alt
7486static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7487#define alc889_capsrc_nids      alc882_capsrc_nids
7488
7489/* input MUX */
7490/* FIXME: should be a matrix-type input source selection */
7491
7492static struct hda_input_mux alc882_capture_source = {
7493        .num_items = 4,
7494        .items = {
7495                { "Mic", 0x0 },
7496                { "Front Mic", 0x1 },
7497                { "Line", 0x2 },
7498                { "CD", 0x4 },
7499        },
7500};
7501
7502#define alc883_capture_source   alc882_capture_source
7503
7504static struct hda_input_mux alc889_capture_source = {
7505        .num_items = 3,
7506        .items = {
7507                { "Front Mic", 0x0 },
7508                { "Mic", 0x3 },
7509                { "Line", 0x2 },
7510        },
7511};
7512
7513static struct hda_input_mux mb5_capture_source = {
7514        .num_items = 3,
7515        .items = {
7516                { "Mic", 0x1 },
7517                { "Line", 0x7 },
7518                { "CD", 0x4 },
7519        },
7520};
7521
7522static struct hda_input_mux macmini3_capture_source = {
7523        .num_items = 2,
7524        .items = {
7525                { "Line", 0x2 },
7526                { "CD", 0x4 },
7527        },
7528};
7529
7530static struct hda_input_mux alc883_3stack_6ch_intel = {
7531        .num_items = 4,
7532        .items = {
7533                { "Mic", 0x1 },
7534                { "Front Mic", 0x0 },
7535                { "Line", 0x2 },
7536                { "CD", 0x4 },
7537        },
7538};
7539
7540static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7541        .num_items = 2,
7542        .items = {
7543                { "Mic", 0x1 },
7544                { "Line", 0x2 },
7545        },
7546};
7547
7548static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7549        .num_items = 4,
7550        .items = {
7551                { "Mic", 0x0 },
7552                { "Internal Mic", 0x1 },
7553                { "Line", 0x2 },
7554                { "CD", 0x4 },
7555        },
7556};
7557
7558static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7559        .num_items = 2,
7560        .items = {
7561                { "Mic", 0x0 },
7562                { "Internal Mic", 0x1 },
7563        },
7564};
7565
7566static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7567        .num_items = 3,
7568        .items = {
7569                { "Mic", 0x0 },
7570                { "Front Mic", 0x1 },
7571                { "Line", 0x4 },
7572        },
7573};
7574
7575static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7576        .num_items = 2,
7577        .items = {
7578                { "Mic", 0x0 },
7579                { "Line", 0x2 },
7580        },
7581};
7582
7583static struct hda_input_mux alc889A_mb31_capture_source = {
7584        .num_items = 2,
7585        .items = {
7586                { "Mic", 0x0 },
7587                /* Front Mic (0x01) unused */
7588                { "Line", 0x2 },
7589                /* Line 2 (0x03) unused */
7590                /* CD (0x04) unused? */
7591        },
7592};
7593
7594static struct hda_input_mux alc889A_imac91_capture_source = {
7595        .num_items = 2,
7596        .items = {
7597                { "Mic", 0x01 },
7598                { "Line", 0x2 }, /* Not sure! */
7599        },
7600};
7601
7602/*
7603 * 2ch mode
7604 */
7605static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7606        { 2, NULL }
7607};
7608
7609/*
7610 * 2ch mode
7611 */
7612static struct hda_verb alc882_3ST_ch2_init[] = {
7613        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7614        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7615        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7616        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7617        { } /* end */
7618};
7619
7620/*
7621 * 4ch mode
7622 */
7623static struct hda_verb alc882_3ST_ch4_init[] = {
7624        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7625        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7626        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7627        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7628        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7629        { } /* end */
7630};
7631
7632/*
7633 * 6ch mode
7634 */
7635static struct hda_verb alc882_3ST_ch6_init[] = {
7636        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7637        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7638        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7639        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7640        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7641        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7642        { } /* end */
7643};
7644
7645static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7646        { 2, alc882_3ST_ch2_init },
7647        { 4, alc882_3ST_ch4_init },
7648        { 6, alc882_3ST_ch6_init },
7649};
7650
7651#define alc883_3ST_6ch_modes    alc882_3ST_6ch_modes
7652
7653/*
7654 * 2ch mode
7655 */
7656static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7657        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7658        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7659        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7660        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7661        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7662        { } /* end */
7663};
7664
7665/*
7666 * 4ch mode
7667 */
7668static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7669        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7670        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7671        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7672        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7673        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7674        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7675        { } /* end */
7676};
7677
7678/*
7679 * 6ch mode
7680 */
7681static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7682        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7683        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7684        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7685        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7686        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7687        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7688        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7689        { } /* end */
7690};
7691
7692static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7693        { 2, alc883_3ST_ch2_clevo_init },
7694        { 4, alc883_3ST_ch4_clevo_init },
7695        { 6, alc883_3ST_ch6_clevo_init },
7696};
7697
7698
7699/*
7700 * 6ch mode
7701 */
7702static struct hda_verb alc882_sixstack_ch6_init[] = {
7703        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7704        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7705        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7706        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7707        { } /* end */
7708};
7709
7710/*
7711 * 8ch mode
7712 */
7713static struct hda_verb alc882_sixstack_ch8_init[] = {
7714        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7715        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7716        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7717        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7718        { } /* end */
7719};
7720
7721static struct hda_channel_mode alc882_sixstack_modes[2] = {
7722        { 6, alc882_sixstack_ch6_init },
7723        { 8, alc882_sixstack_ch8_init },
7724};
7725
7726
7727/* Macbook Air 2,1 */
7728
7729static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7730      { 2, NULL },
7731};
7732
7733/*
7734 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7735 */
7736
7737/*
7738 * 2ch mode
7739 */
7740static struct hda_verb alc885_mbp_ch2_init[] = {
7741        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7742        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7743        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7744        { } /* end */
7745};
7746
7747/*
7748 * 4ch mode
7749 */
7750static struct hda_verb alc885_mbp_ch4_init[] = {
7751        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7753        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7754        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7755        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7756        { } /* end */
7757};
7758
7759static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7760        { 2, alc885_mbp_ch2_init },
7761        { 4, alc885_mbp_ch4_init },
7762};
7763
7764/*
7765 * 2ch
7766 * Speakers/Woofer/HP = Front
7767 * LineIn = Input
7768 */
7769static struct hda_verb alc885_mb5_ch2_init[] = {
7770        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7771        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7772        { } /* end */
7773};
7774
7775/*
7776 * 6ch mode
7777 * Speakers/HP = Front
7778 * Woofer = LFE
7779 * LineIn = Surround
7780 */
7781static struct hda_verb alc885_mb5_ch6_init[] = {
7782        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7783        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7784        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7785        { } /* end */
7786};
7787
7788static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7789        { 2, alc885_mb5_ch2_init },
7790        { 6, alc885_mb5_ch6_init },
7791};
7792
7793#define alc885_macmini3_6ch_modes       alc885_mb5_6ch_modes
7794
7795/*
7796 * 2ch mode
7797 */
7798static struct hda_verb alc883_4ST_ch2_init[] = {
7799        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7800        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7801        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7802        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7803        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7804        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7805        { } /* end */
7806};
7807
7808/*
7809 * 4ch mode
7810 */
7811static struct hda_verb alc883_4ST_ch4_init[] = {
7812        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7815        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7816        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7817        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7818        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7819        { } /* end */
7820};
7821
7822/*
7823 * 6ch mode
7824 */
7825static struct hda_verb alc883_4ST_ch6_init[] = {
7826        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7827        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7828        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7829        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7830        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7831        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7832        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7833        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7834        { } /* end */
7835};
7836
7837/*
7838 * 8ch mode
7839 */
7840static struct hda_verb alc883_4ST_ch8_init[] = {
7841        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7842        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7843        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7844        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7845        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7846        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7847        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7848        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7849        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7850        { } /* end */
7851};
7852
7853static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7854        { 2, alc883_4ST_ch2_init },
7855        { 4, alc883_4ST_ch4_init },
7856        { 6, alc883_4ST_ch6_init },
7857        { 8, alc883_4ST_ch8_init },
7858};
7859
7860
7861/*
7862 * 2ch mode
7863 */
7864static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7865        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7868        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7869        { } /* end */
7870};
7871
7872/*
7873 * 4ch mode
7874 */
7875static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7876        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7877        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7878        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7880        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7881        { } /* end */
7882};
7883
7884/*
7885 * 6ch mode
7886 */
7887static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7888        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7890        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7891        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7892        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7893        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7894        { } /* end */
7895};
7896
7897static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7898        { 2, alc883_3ST_ch2_intel_init },
7899        { 4, alc883_3ST_ch4_intel_init },
7900        { 6, alc883_3ST_ch6_intel_init },
7901};
7902
7903/*
7904 * 2ch mode
7905 */
7906static struct hda_verb alc889_ch2_intel_init[] = {
7907        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7908        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7909        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7910        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7911        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7912        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7913        { } /* end */
7914};
7915
7916/*
7917 * 6ch mode
7918 */
7919static struct hda_verb alc889_ch6_intel_init[] = {
7920        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7921        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7923        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7924        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7925        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7926        { } /* end */
7927};
7928
7929/*
7930 * 8ch mode
7931 */
7932static struct hda_verb alc889_ch8_intel_init[] = {
7933        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7934        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7935        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7936        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7937        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7938        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7940        { } /* end */
7941};
7942
7943static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7944        { 2, alc889_ch2_intel_init },
7945        { 6, alc889_ch6_intel_init },
7946        { 8, alc889_ch8_intel_init },
7947};
7948
7949/*
7950 * 6ch mode
7951 */
7952static struct hda_verb alc883_sixstack_ch6_init[] = {
7953        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7954        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7955        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7956        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7957        { } /* end */
7958};
7959
7960/*
7961 * 8ch mode
7962 */
7963static struct hda_verb alc883_sixstack_ch8_init[] = {
7964        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7965        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7966        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7967        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7968        { } /* end */
7969};
7970
7971static struct hda_channel_mode alc883_sixstack_modes[2] = {
7972        { 6, alc883_sixstack_ch6_init },
7973        { 8, alc883_sixstack_ch8_init },
7974};
7975
7976
7977/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7978 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7979 */
7980static struct snd_kcontrol_new alc882_base_mixer[] = {
7981        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7982        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7983        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7984        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7985        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7986        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7987        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7988        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7989        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7990        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7991        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7992        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7993        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7994        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7995        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7996        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7997        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7998        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7999        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8000        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8001        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8002        { } /* end */
8003};
8004
8005/* Macbook Air 2,1 same control for HP and internal Speaker */
8006
8007static struct snd_kcontrol_new alc885_mba21_mixer[] = {
8008      HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8009      HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8010     { }
8011};
8012
8013
8014static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8015        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8016        HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8017        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8018        HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8019        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8020        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8021        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8022        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8023        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8024        HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8025        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8026        { } /* end */
8027};
8028
8029static struct snd_kcontrol_new alc885_mb5_mixer[] = {
8030        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8031        HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8032        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8033        HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8034        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8035        HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8036        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8037        HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8038        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8039        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8040        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8041        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8042        HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8043        HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8044        { } /* end */
8045};
8046
8047static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8048        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8049        HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8050        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8051        HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8052        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8053        HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8054        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8055        HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8056        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8057        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8058        HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8059        { } /* end */
8060};
8061
8062static struct snd_kcontrol_new alc885_imac91_mixer[] = {
8063        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8064        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8065        { } /* end */
8066};
8067
8068
8069static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8070        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8071        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8072        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8073        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8074        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8075        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8076        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8077        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8078        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8079        { } /* end */
8080};
8081
8082static struct snd_kcontrol_new alc882_targa_mixer[] = {
8083        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8084        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8085        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8086        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8087        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8088        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8089        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8090        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8091        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8092        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8093        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8094        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8095        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8096        { } /* end */
8097};
8098
8099/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8100 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8101 */
8102static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8103        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8104        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8105        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8106        HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8107        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8108        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8109        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8110        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8111        HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8112        HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8113        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8114        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8115        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8116        { } /* end */
8117};
8118
8119static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8120        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8121        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8122        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8123        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8124        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8125        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8126        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8127        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8128        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8129        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8130        { } /* end */
8131};
8132
8133static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8134        {
8135                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8136                .name = "Channel Mode",
8137                .info = alc_ch_mode_info,
8138                .get = alc_ch_mode_get,
8139                .put = alc_ch_mode_put,
8140        },
8141        { } /* end */
8142};
8143
8144static struct hda_verb alc882_base_init_verbs[] = {
8145        /* Front mixer: unmute input/output amp left and right (volume = 0) */
8146        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8147        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8148        /* Rear mixer */
8149        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8151        /* CLFE mixer */
8152        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8154        /* Side mixer */
8155        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8157
8158        /* Front Pin: output 0 (0x0c) */
8159        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8160        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8161        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8162        /* Rear Pin: output 1 (0x0d) */
8163        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8164        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8165        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8166        /* CLFE Pin: output 2 (0x0e) */
8167        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8168        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8170        /* Side Pin: output 3 (0x0f) */
8171        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8172        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8173        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8174        /* Mic (rear) pin: input vref at 80% */
8175        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8176        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8177        /* Front Mic pin: input vref at 80% */
8178        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8179        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8180        /* Line In pin: input */
8181        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8182        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8183        /* Line-2 In: Headphone output (output 0 - 0x0c) */
8184        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8185        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8186        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8187        /* CD pin widget for input */
8188        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8189
8190        /* FIXME: use matrix-type input source selection */
8191        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8192        /* Input mixer2 */
8193        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8194        /* Input mixer3 */
8195        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8196        /* ADC2: mute amp left and right */
8197        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8198        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8199        /* ADC3: mute amp left and right */
8200        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8201        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8202
8203        { }
8204};
8205
8206static struct hda_verb alc882_adc1_init_verbs[] = {
8207        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8208        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8209        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8210        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8211        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8212        /* ADC1: mute amp left and right */
8213        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8214        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8215        { }
8216};
8217
8218static struct hda_verb alc882_eapd_verbs[] = {
8219        /* change to EAPD mode */
8220        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8221        {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8222        { }
8223};
8224
8225static struct hda_verb alc889_eapd_verbs[] = {
8226        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8227        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8228        { }
8229};
8230
8231static struct hda_verb alc_hp15_unsol_verbs[] = {
8232        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8233        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8234        {}
8235};
8236
8237static struct hda_verb alc885_init_verbs[] = {
8238        /* Front mixer: unmute input/output amp left and right (volume = 0) */
8239        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8241        /* Rear mixer */
8242        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8244        /* CLFE mixer */
8245        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8247        /* Side mixer */
8248        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8249        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8250
8251        /* Front HP Pin: output 0 (0x0c) */
8252        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8253        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8254        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8255        /* Front Pin: output 0 (0x0c) */
8256        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8257        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8259        /* Rear Pin: output 1 (0x0d) */
8260        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8261        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8262        {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8263        /* CLFE Pin: output 2 (0x0e) */
8264        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8265        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8266        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8267        /* Side Pin: output 3 (0x0f) */
8268        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8269        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8271        /* Mic (rear) pin: input vref at 80% */
8272        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8273        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8274        /* Front Mic pin: input vref at 80% */
8275        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8276        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8277        /* Line In pin: input */
8278        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8279        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8280
8281        /* Mixer elements: 0x18, , 0x1a, 0x1b */
8282        /* Input mixer1 */
8283        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8284        /* Input mixer2 */
8285        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8286        /* Input mixer3 */
8287        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8288        /* ADC2: mute amp left and right */
8289        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8290        /* ADC3: mute amp left and right */
8291        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8292
8293        { }
8294};
8295
8296static struct hda_verb alc885_init_input_verbs[] = {
8297        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8298        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8299        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8300        { }
8301};
8302
8303
8304/* Unmute Selector 24h and set the default input to front mic */
8305static struct hda_verb alc889_init_input_verbs[] = {
8306        {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8307        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308        { }
8309};
8310
8311
8312#define alc883_init_verbs       alc882_base_init_verbs
8313
8314/* Mac Pro test */
8315static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8316        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8317        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8318        HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8319        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8320        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8321        /* FIXME: this looks suspicious...
8322        HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8323        HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8324        */
8325        { } /* end */
8326};
8327
8328static struct hda_verb alc882_macpro_init_verbs[] = {
8329        /* Front mixer: unmute input/output amp left and right (volume = 0) */
8330        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8331        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8332        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8333        /* Front Pin: output 0 (0x0c) */
8334        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8335        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8336        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8337        /* Front Mic pin: input vref at 80% */
8338        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8339        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8340        /* Speaker:  output */
8341        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8342        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8343        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8344        /* Headphone output (output 0 - 0x0c) */
8345        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8347        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8348
8349        /* FIXME: use matrix-type input source selection */
8350        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8351        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8352        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8354        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8355        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8356        /* Input mixer2 */
8357        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8359        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8360        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8361        /* Input mixer3 */
8362        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8363        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8364        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8365        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8366        /* ADC1: mute amp left and right */
8367        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8368        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8369        /* ADC2: mute amp left and right */
8370        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8372        /* ADC3: mute amp left and right */
8373        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8375
8376        { }
8377};
8378
8379/* Macbook 5,1 */
8380static struct hda_verb alc885_mb5_init_verbs[] = {
8381        /* DACs */
8382        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8383        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8386        /* Front mixer */
8387        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8388        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8389        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8390        /* Surround mixer */
8391        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8392        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8393        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8394        /* LFE mixer */
8395        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8396        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8397        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8398        /* HP mixer */
8399        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8400        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8401        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8402        /* Front Pin (0x0c) */
8403        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8404        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8405        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8406        /* LFE Pin (0x0e) */
8407        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8408        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8410        /* HP Pin (0x0f) */
8411        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8412        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413        {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8414        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8415        /* Front Mic pin: input vref at 80% */
8416        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8417        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8418        /* Line In pin */
8419        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8420        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8421
8422        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8423        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8424        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8425        { }
8426};
8427
8428/* Macmini 3,1 */
8429static struct hda_verb alc885_macmini3_init_verbs[] = {
8430        /* DACs */
8431        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8432        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8433        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8435        /* Front mixer */
8436        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8437        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8439        /* Surround mixer */
8440        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8441        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8442        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8443        /* LFE mixer */
8444        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8445        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8447        /* HP mixer */
8448        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8449        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8450        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8451        /* Front Pin (0x0c) */
8452        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8453        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8454        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8455        /* LFE Pin (0x0e) */
8456        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8457        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8458        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8459        /* HP Pin (0x0f) */
8460        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8461        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8462        {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8463        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8464        /* Line In pin */
8465        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8466        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8467
8468        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8469        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8470        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8471        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8472        { }
8473};
8474
8475
8476static struct hda_verb alc885_mba21_init_verbs[] = {
8477        /*Internal and HP Speaker Mixer*/
8478        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8479        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481        /*Internal Speaker Pin (0x0c)*/
8482        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8483        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8484        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8485        /* HP Pin: output 0 (0x0e) */
8486        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8487        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8488        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8489        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8490        /* Line in (is hp when jack connected)*/
8491        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8492        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8493
8494        { }
8495 };
8496
8497
8498/* Macbook Pro rev3 */
8499static struct hda_verb alc885_mbp3_init_verbs[] = {
8500        /* Front mixer: unmute input/output amp left and right (volume = 0) */
8501        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8502        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8503        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8504        /* Rear mixer */
8505        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8507        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8508        /* HP mixer */
8509        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8511        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8512        /* Front Pin: output 0 (0x0c) */
8513        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8514        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8515        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8516        /* HP Pin: output 0 (0x0e) */
8517        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8518        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8519        {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8520        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8521        /* Mic (rear) pin: input vref at 80% */
8522        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8523        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8524        /* Front Mic pin: input vref at 80% */
8525        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8526        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8527        /* Line In pin: use output 1 when in LineOut mode */
8528        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8529        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8530        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8531
8532        /* FIXME: use matrix-type input source selection */
8533        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8534        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8535        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8537        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8538        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8539        /* Input mixer2 */
8540        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8541        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544        /* Input mixer3 */
8545        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8547        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8548        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8549        /* ADC1: mute amp left and right */
8550        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8551        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8552        /* ADC2: mute amp left and right */
8553        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8554        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8555        /* ADC3: mute amp left and right */
8556        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8557        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8558
8559        { }
8560};
8561
8562/* iMac 9,1 */
8563static struct hda_verb alc885_imac91_init_verbs[] = {
8564        /* Internal Speaker Pin (0x0c) */
8565        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8566        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8568        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8569        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8571        /* HP Pin: Rear */
8572        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8573        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8574        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8575        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8576        /* Line in Rear */
8577        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8578        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8579        /* Front Mic pin: input vref at 80% */
8580        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8581        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8582        /* Rear mixer */
8583        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8584        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8585        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8586        /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8587        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8588        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8589        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8590        /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8591        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8592        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8593        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8594        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8595        /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8596        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8597        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8598        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8599        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8600        /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8601        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8602        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8603        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8604        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8605        /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8606        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8607        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8608        /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8609        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8610        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8611        /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8612        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8614        { }
8615};
8616
8617/* iMac 24 mixer. */
8618static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8619        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8620        HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8621        { } /* end */
8622};
8623
8624/* iMac 24 init verbs. */
8625static struct hda_verb alc885_imac24_init_verbs[] = {
8626        /* Internal speakers: output 0 (0x0c) */
8627        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8628        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8629        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630        /* Internal speakers: output 0 (0x0c) */
8631        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8632        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8634        /* Headphone: output 0 (0x0c) */
8635        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8636        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8637        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8638        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8639        /* Front Mic: input vref at 80% */
8640        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642        { }
8643};
8644
8645/* Toggle speaker-output according to the hp-jack state */
8646static void alc885_imac24_setup(struct hda_codec *codec)
8647{
8648        struct alc_spec *spec = codec->spec;
8649
8650        spec->autocfg.hp_pins[0] = 0x14;
8651        spec->autocfg.speaker_pins[0] = 0x18;
8652        spec->autocfg.speaker_pins[1] = 0x1a;
8653}
8654
8655#define alc885_mb5_setup        alc885_imac24_setup
8656#define alc885_macmini3_setup   alc885_imac24_setup
8657
8658/* Macbook Air 2,1 */
8659static void alc885_mba21_setup(struct hda_codec *codec)
8660{
8661       struct alc_spec *spec = codec->spec;
8662
8663       spec->autocfg.hp_pins[0] = 0x14;
8664       spec->autocfg.speaker_pins[0] = 0x18;
8665}
8666
8667
8668
8669static void alc885_mbp3_setup(struct hda_codec *codec)
8670{
8671        struct alc_spec *spec = codec->spec;
8672
8673        spec->autocfg.hp_pins[0] = 0x15;
8674        spec->autocfg.speaker_pins[0] = 0x14;
8675}
8676
8677static void alc885_imac91_setup(struct hda_codec *codec)
8678{
8679        struct alc_spec *spec = codec->spec;
8680
8681        spec->autocfg.hp_pins[0] = 0x14;
8682        spec->autocfg.speaker_pins[0] = 0x18;
8683        spec->autocfg.speaker_pins[1] = 0x1a;
8684}
8685
8686static struct hda_verb alc882_targa_verbs[] = {
8687        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8688        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8689
8690        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8691        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8692
8693        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8694        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8695        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8696
8697        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8698        { } /* end */
8699};
8700
8701/* toggle speaker-output according to the hp-jack state */
8702static void alc882_targa_automute(struct hda_codec *codec)
8703{
8704        struct alc_spec *spec = codec->spec;
8705        alc_automute_amp(codec);
8706        snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8707                                  spec->jack_present ? 1 : 3);
8708}
8709
8710static void alc882_targa_setup(struct hda_codec *codec)
8711{
8712        struct alc_spec *spec = codec->spec;
8713
8714        spec->autocfg.hp_pins[0] = 0x14;
8715        spec->autocfg.speaker_pins[0] = 0x1b;
8716}
8717
8718static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8719{
8720        if ((res >> 26) == ALC880_HP_EVENT)
8721                alc882_targa_automute(codec);
8722}
8723
8724static struct hda_verb alc882_asus_a7j_verbs[] = {
8725        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8726        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8727
8728        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8729        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8730        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8731
8732        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8733        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8734        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8735
8736        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8737        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8738        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8739        { } /* end */
8740};
8741
8742static struct hda_verb alc882_asus_a7m_verbs[] = {
8743        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8744        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8745
8746        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8747        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8748        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8749
8750        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8751        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8752        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8753
8754        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8755        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8756        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8757        { } /* end */
8758};
8759
8760static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8761{
8762        unsigned int gpiostate, gpiomask, gpiodir;
8763
8764        gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8765                                       AC_VERB_GET_GPIO_DATA, 0);
8766
8767        if (!muted)
8768                gpiostate |= (1 << pin);
8769        else
8770                gpiostate &= ~(1 << pin);
8771
8772        gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8773                                      AC_VERB_GET_GPIO_MASK, 0);
8774        gpiomask |= (1 << pin);
8775
8776        gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8777                                     AC_VERB_GET_GPIO_DIRECTION, 0);
8778        gpiodir |= (1 << pin);
8779
8780
8781        snd_hda_codec_write(codec, codec->afg, 0,
8782                            AC_VERB_SET_GPIO_MASK, gpiomask);
8783        snd_hda_codec_write(codec, codec->afg, 0,
8784                            AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8785
8786        msleep(1);
8787
8788        snd_hda_codec_write(codec, codec->afg, 0,
8789                            AC_VERB_SET_GPIO_DATA, gpiostate);
8790}
8791
8792/* set up GPIO at initialization */
8793static void alc885_macpro_init_hook(struct hda_codec *codec)
8794{
8795        alc882_gpio_mute(codec, 0, 0);
8796        alc882_gpio_mute(codec, 1, 0);
8797}
8798
8799/* set up GPIO and update auto-muting at initialization */
8800static void alc885_imac24_init_hook(struct hda_codec *codec)
8801{
8802        alc885_macpro_init_hook(codec);
8803        alc_automute_amp(codec);
8804}
8805
8806/*
8807 * generic initialization of ADC, input mixers and output mixers
8808 */
8809static struct hda_verb alc883_auto_init_verbs[] = {
8810        /*
8811         * Unmute ADC0-2 and set the default input to mic-in
8812         */
8813        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8814        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8816        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8817
8818        /*
8819         * Set up output mixers (0x0c - 0x0f)
8820         */
8821        /* set vol=0 to output mixers */
8822        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8823        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8824        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8825        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8826        /* set up input amps for analog loopback */
8827        /* Amp Indices: DAC = 0, mixer = 1 */
8828        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8829        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8830        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8831        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8832        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8833        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8834        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8835        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8836        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8837        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8838
8839        /* FIXME: use matrix-type input source selection */
8840        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8841        /* Input mixer2 */
8842        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8843        /* Input mixer3 */
8844        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8845        { }
8846};
8847
8848/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8849static struct hda_verb alc889A_mb31_ch2_init[] = {
8850        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
8851        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8852        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
8853        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
8854        { } /* end */
8855};
8856
8857/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8858static struct hda_verb alc889A_mb31_ch4_init[] = {
8859        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
8860        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8861        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
8862        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8863        { } /* end */
8864};
8865
8866/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8867static struct hda_verb alc889A_mb31_ch5_init[] = {
8868        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
8869        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8870        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
8871        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
8872        { } /* end */
8873};
8874
8875/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8876static struct hda_verb alc889A_mb31_ch6_init[] = {
8877        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
8878        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
8879        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
8880        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8881        { } /* end */
8882};
8883
8884static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8885        { 2, alc889A_mb31_ch2_init },
8886        { 4, alc889A_mb31_ch4_init },
8887        { 5, alc889A_mb31_ch5_init },
8888        { 6, alc889A_mb31_ch6_init },
8889};
8890
8891static struct hda_verb alc883_medion_eapd_verbs[] = {
8892        /* eanable EAPD on medion laptop */
8893        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8894        {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8895        { }
8896};
8897
8898#define alc883_base_mixer       alc882_base_mixer
8899
8900static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8901        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8902        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8903        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8904        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8905        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8906        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8907        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8908        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8909        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8910        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8911        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8912        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8913        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8914        { } /* end */
8915};
8916
8917static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8918        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8919        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8920        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8921        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8922        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8923        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8924        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8925        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8926        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8927        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8928        { } /* end */
8929};
8930
8931static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8932        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8933        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8934        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8935        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8936        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8937        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8938        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8939        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8940        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8941        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8942        { } /* end */
8943};
8944
8945static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8946        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8947        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8948        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8949        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8950        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8951        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8952        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8953        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8954        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8955        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8956        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8957        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8958        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8959        { } /* end */
8960};
8961
8962static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8963        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8964        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8965        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8966        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8967        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8968        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8969        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8970        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8971        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8972        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8973        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8974        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8975        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8976        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8977        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8978        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8980        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8981        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8982        { } /* end */
8983};
8984
8985static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8986        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8989        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8990        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8991                              HDA_OUTPUT),
8992        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8993        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8994        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8995        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8996        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8997        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8998        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8999        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9000        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9001        HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9002        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9003        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9004        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9005        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9006        { } /* end */
9007};
9008
9009static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9010        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9011        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9012        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9013        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9014        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9015                              HDA_OUTPUT),
9016        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9017        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9018        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9019        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9020        HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9021        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9022        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9023        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9024        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9025        HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9026        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9027        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9028        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9029        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9030        { } /* end */
9031};
9032
9033static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9034        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9035        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9036        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9037        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9038        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9039        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9040        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9041        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9042        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9043        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9044        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9045        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9046        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9047        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9048        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9049        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9050        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9051        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9052        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9053        { } /* end */
9054};
9055
9056static struct snd_kcontrol_new alc883_targa_mixer[] = {
9057        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9058        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9059        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9060        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9061        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9062        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9063        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9064        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9065        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9066        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9067        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9068        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9069        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9070        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9071        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9072        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9073        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9074        { } /* end */
9075};
9076
9077static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9078        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9079        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9080        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9081        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9082        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9083        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9084        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9085        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9086        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9087        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9088        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9089        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9090        { } /* end */
9091};
9092
9093static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9094        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9095        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9096        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9097        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9098        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9099        { } /* end */
9100};
9101
9102static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9103        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9104        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9105        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9106        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9107        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9108        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9109        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9110        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9111        { } /* end */
9112};
9113
9114static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9115        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9116        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9117        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9118        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9119        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9120        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9121        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9122        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9123        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9124        { } /* end */
9125};
9126
9127static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9128        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9129        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9130        HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9131        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9132        HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9133        HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9134        { } /* end */
9135};
9136
9137static struct hda_verb alc883_medion_wim2160_verbs[] = {
9138        /* Unmute front mixer */
9139        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9140        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9141
9142        /* Set speaker pin to front mixer */
9143        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9144
9145        /* Init headphone pin */
9146        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9147        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9148        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9149        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9150
9151        { } /* end */
9152};
9153
9154/* toggle speaker-output according to the hp-jack state */
9155static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9156{
9157        struct alc_spec *spec = codec->spec;
9158
9159        spec->autocfg.hp_pins[0] = 0x1a;
9160        spec->autocfg.speaker_pins[0] = 0x15;
9161}
9162
9163static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9164        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9165        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9166        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9167        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9168        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9169        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9171        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9172        { } /* end */
9173};
9174
9175static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9176        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9177        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9178        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9179        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9180        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9181        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9182        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9183        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9184        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9185        { } /* end */
9186};
9187
9188static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9189        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9190        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9191        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9192        HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9193        HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9194                                                0x0d, 1, 0x0, HDA_OUTPUT),
9195        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9196        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9197        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9198        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9199        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9200        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9201        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9202        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9203        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9204        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9205        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9206        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9207        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9208        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9209        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9210        { } /* end */
9211};
9212
9213static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9214        /* Output mixers */
9215        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9216        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9217        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9218        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9219        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9220                HDA_OUTPUT),
9221        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9222        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9223        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9224        /* Output switches */
9225        HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9226        HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9227        HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9228        /* Boost mixers */
9229        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9230        HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9231        /* Input mixers */
9232        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9233        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9234        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9235        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9236        { } /* end */
9237};
9238
9239static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9240        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9241        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9242        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9243        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9244        HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9245        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9246        { } /* end */
9247};
9248
9249static struct hda_bind_ctls alc883_bind_cap_vol = {
9250        .ops = &snd_hda_bind_vol,
9251        .values = {
9252                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9253                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9254                0
9255        },
9256};
9257
9258static struct hda_bind_ctls alc883_bind_cap_switch = {
9259        .ops = &snd_hda_bind_sw,
9260        .values = {
9261                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9262                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9263                0
9264        },
9265};
9266
9267static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9268        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9269        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9270        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9271        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9272        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9273        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9274        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9275        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9276        { } /* end */
9277};
9278
9279static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9280        HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9281        HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9282        {
9283                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9284                /* .name = "Capture Source", */
9285                .name = "Input Source",
9286                .count = 1,
9287                .info = alc_mux_enum_info,
9288                .get = alc_mux_enum_get,
9289                .put = alc_mux_enum_put,
9290        },
9291        { } /* end */
9292};
9293
9294static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9295        {
9296                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9297                .name = "Channel Mode",
9298                .info = alc_ch_mode_info,
9299                .get = alc_ch_mode_get,
9300                .put = alc_ch_mode_put,
9301        },
9302        { } /* end */
9303};
9304
9305/* toggle speaker-output according to the hp-jack state */
9306static void alc883_mitac_setup(struct hda_codec *codec)
9307{
9308        struct alc_spec *spec = codec->spec;
9309
9310        spec->autocfg.hp_pins[0] = 0x15;
9311        spec->autocfg.speaker_pins[0] = 0x14;
9312        spec->autocfg.speaker_pins[1] = 0x17;
9313}
9314
9315static struct hda_verb alc883_mitac_verbs[] = {
9316        /* HP */
9317        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9318        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9319        /* Subwoofer */
9320        {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9321        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9322
9323        /* enable unsolicited event */
9324        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9325        /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9326
9327        { } /* end */
9328};
9329
9330static struct hda_verb alc883_clevo_m540r_verbs[] = {
9331        /* HP */
9332        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9333        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9334        /* Int speaker */
9335        /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9336
9337        /* enable unsolicited event */
9338        /*
9339        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9340        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9341        */
9342
9343        { } /* end */
9344};
9345
9346static struct hda_verb alc883_clevo_m720_verbs[] = {
9347        /* HP */
9348        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9349        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9350        /* Int speaker */
9351        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9352        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9353
9354        /* enable unsolicited event */
9355        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9357
9358        { } /* end */
9359};
9360
9361static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9362        /* HP */
9363        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9364        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9365        /* Subwoofer */
9366        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9367        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9368
9369        /* enable unsolicited event */
9370        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9371
9372        { } /* end */
9373};
9374
9375static struct hda_verb alc883_targa_verbs[] = {
9376        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9377        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9378
9379        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9380        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9381
9382/* Connect Line-Out side jack (SPDIF) to Side */
9383        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9384        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9385        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9386/* Connect Mic jack to CLFE */
9387        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9388        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9389        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9390/* Connect Line-in jack to Surround */
9391        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9392        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9393        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9394/* Connect HP out jack to Front */
9395        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9396        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9397        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9398
9399        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9400
9401        { } /* end */
9402};
9403
9404static struct hda_verb alc883_lenovo_101e_verbs[] = {
9405        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9406        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9407        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9408        { } /* end */
9409};
9410
9411static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9412        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9413        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9414        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9415        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9416        { } /* end */
9417};
9418
9419static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9420        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9422        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9423        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9424        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
9425        { } /* end */
9426};
9427
9428static struct hda_verb alc883_haier_w66_verbs[] = {
9429        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9430        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9431
9432        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9433
9434        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9435        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9436        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9437        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9438        { } /* end */
9439};
9440
9441static struct hda_verb alc888_lenovo_sky_verbs[] = {
9442        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9443        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9444        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9445        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9446        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9447        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9448        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9449        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9450        { } /* end */
9451};
9452
9453static struct hda_verb alc888_6st_dell_verbs[] = {
9454        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9455        { }
9456};
9457
9458static struct hda_verb alc883_vaiott_verbs[] = {
9459        /* HP */
9460        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9461        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9462
9463        /* enable unsolicited event */
9464        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9465
9466        { } /* end */
9467};
9468
9469static void alc888_3st_hp_setup(struct hda_codec *codec)
9470{
9471        struct alc_spec *spec = codec->spec;
9472
9473        spec->autocfg.hp_pins[0] = 0x1b;
9474        spec->autocfg.speaker_pins[0] = 0x14;
9475        spec->autocfg.speaker_pins[1] = 0x16;
9476        spec->autocfg.speaker_pins[2] = 0x18;
9477}
9478
9479static struct hda_verb alc888_3st_hp_verbs[] = {
9480        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
9481        {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
9482        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
9483        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9484        { } /* end */
9485};
9486
9487/*
9488 * 2ch mode
9489 */
9490static struct hda_verb alc888_3st_hp_2ch_init[] = {
9491        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9492        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9493        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9494        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9495        { } /* end */
9496};
9497
9498/*
9499 * 4ch mode
9500 */
9501static struct hda_verb alc888_3st_hp_4ch_init[] = {
9502        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9503        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9504        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9505        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9506        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9507        { } /* end */
9508};
9509
9510/*
9511 * 6ch mode
9512 */
9513static struct hda_verb alc888_3st_hp_6ch_init[] = {
9514        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9515        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9516        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9517        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9518        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9519        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9520        { } /* end */
9521};
9522
9523static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9524        { 2, alc888_3st_hp_2ch_init },
9525        { 4, alc888_3st_hp_4ch_init },
9526        { 6, alc888_3st_hp_6ch_init },
9527};
9528
9529/* toggle front-jack and RCA according to the hp-jack state */
9530static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9531{
9532        unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9533
9534        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9535                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9536        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9537                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9538}
9539
9540/* toggle RCA according to the front-jack state */
9541static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9542{
9543        unsigned int present = snd_hda_jack_detect(codec, 0x14);
9544
9545        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9546                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9547}
9548
9549static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9550                                             unsigned int res)
9551{
9552        if ((res >> 26) == ALC880_HP_EVENT)
9553                alc888_lenovo_ms7195_front_automute(codec);
9554        if ((res >> 26) == ALC880_FRONT_EVENT)
9555                alc888_lenovo_ms7195_rca_automute(codec);
9556}
9557
9558/* toggle speaker-output according to the hp-jack state */
9559static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9560{
9561        struct alc_spec *spec = codec->spec;
9562
9563        spec->autocfg.hp_pins[0] = 0x14;
9564        spec->autocfg.speaker_pins[0] = 0x15;
9565}
9566
9567/* toggle speaker-output according to the hp-jack state */
9568#define alc883_targa_init_hook          alc882_targa_init_hook
9569#define alc883_targa_unsol_event        alc882_targa_unsol_event
9570
9571static void alc883_clevo_m720_setup(struct hda_codec *codec)
9572{
9573        struct alc_spec *spec = codec->spec;
9574
9575        spec->autocfg.hp_pins[0] = 0x15;
9576        spec->autocfg.speaker_pins[0] = 0x14;
9577}
9578
9579static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9580{
9581        alc_automute_amp(codec);
9582        alc88x_simple_mic_automute(codec);
9583}
9584
9585static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9586                                           unsigned int res)
9587{
9588        switch (res >> 26) {
9589        case ALC880_MIC_EVENT:
9590                alc88x_simple_mic_automute(codec);
9591                break;
9592        default:
9593                alc_automute_amp_unsol_event(codec, res);
9594                break;
9595        }
9596}
9597
9598/* toggle speaker-output according to the hp-jack state */
9599static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9600{
9601        struct alc_spec *spec = codec->spec;
9602
9603        spec->autocfg.hp_pins[0] = 0x14;
9604        spec->autocfg.speaker_pins[0] = 0x15;
9605}
9606
9607static void alc883_haier_w66_setup(struct hda_codec *codec)
9608{
9609        struct alc_spec *spec = codec->spec;
9610
9611        spec->autocfg.hp_pins[0] = 0x1b;
9612        spec->autocfg.speaker_pins[0] = 0x14;
9613}
9614
9615static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9616{
9617        int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9618
9619        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9620                                 HDA_AMP_MUTE, bits);
9621}
9622
9623static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9624{
9625        int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9626
9627        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9628                                 HDA_AMP_MUTE, bits);
9629        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9630                                 HDA_AMP_MUTE, bits);
9631}
9632
9633static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9634                                           unsigned int res)
9635{
9636        if ((res >> 26) == ALC880_HP_EVENT)
9637                alc883_lenovo_101e_all_automute(codec);
9638        if ((res >> 26) == ALC880_FRONT_EVENT)
9639                alc883_lenovo_101e_ispeaker_automute(codec);
9640}
9641
9642/* toggle speaker-output according to the hp-jack state */
9643static void alc883_acer_aspire_setup(struct hda_codec *codec)
9644{
9645        struct alc_spec *spec = codec->spec;
9646
9647        spec->autocfg.hp_pins[0] = 0x14;
9648        spec->autocfg.speaker_pins[0] = 0x15;
9649        spec->autocfg.speaker_pins[1] = 0x16;
9650}
9651
9652static struct hda_verb alc883_acer_eapd_verbs[] = {
9653        /* HP Pin: output 0 (0x0c) */
9654        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9655        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9656        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9657        /* Front Pin: output 0 (0x0c) */
9658        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9659        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9660        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9661        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9662        /* eanable EAPD on medion laptop */
9663        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9664        {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9665        /* enable unsolicited event */
9666        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9667        { }
9668};
9669
9670static void alc888_6st_dell_setup(struct hda_codec *codec)
9671{
9672        struct alc_spec *spec = codec->spec;
9673
9674        spec->autocfg.hp_pins[0] = 0x1b;
9675        spec->autocfg.speaker_pins[0] = 0x14;
9676        spec->autocfg.speaker_pins[1] = 0x15;
9677        spec->autocfg.speaker_pins[2] = 0x16;
9678        spec->autocfg.speaker_pins[3] = 0x17;
9679}
9680
9681static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9682{
9683        struct alc_spec *spec = codec->spec;
9684
9685        spec->autocfg.hp_pins[0] = 0x1b;
9686        spec->autocfg.speaker_pins[0] = 0x14;
9687        spec->autocfg.speaker_pins[1] = 0x15;
9688        spec->autocfg.speaker_pins[2] = 0x16;
9689        spec->autocfg.speaker_pins[3] = 0x17;
9690        spec->autocfg.speaker_pins[4] = 0x1a;
9691}
9692
9693static void alc883_vaiott_setup(struct hda_codec *codec)
9694{
9695        struct alc_spec *spec = codec->spec;
9696
9697        spec->autocfg.hp_pins[0] = 0x15;
9698        spec->autocfg.speaker_pins[0] = 0x14;
9699        spec->autocfg.speaker_pins[1] = 0x17;
9700}
9701
9702static struct hda_verb alc888_asus_m90v_verbs[] = {
9703        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9704        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9705        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9706        /* enable unsolicited event */
9707        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9708        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9709        { } /* end */
9710};
9711
9712static void alc883_mode2_setup(struct hda_codec *codec)
9713{
9714        struct alc_spec *spec = codec->spec;
9715
9716        spec->autocfg.hp_pins[0] = 0x1b;
9717        spec->autocfg.speaker_pins[0] = 0x14;
9718        spec->autocfg.speaker_pins[1] = 0x15;
9719        spec->autocfg.speaker_pins[2] = 0x16;
9720        spec->ext_mic.pin = 0x18;
9721        spec->int_mic.pin = 0x19;
9722        spec->ext_mic.mux_idx = 0;
9723        spec->int_mic.mux_idx = 1;
9724        spec->auto_mic = 1;
9725}
9726
9727static struct hda_verb alc888_asus_eee1601_verbs[] = {
9728        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9729        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9730        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9731        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9732        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9733        {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9734        {0x20, AC_VERB_SET_PROC_COEF,  0x0838},
9735        /* enable unsolicited event */
9736        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9737        { } /* end */
9738};
9739
9740static void alc883_eee1601_inithook(struct hda_codec *codec)
9741{
9742        struct alc_spec *spec = codec->spec;
9743
9744        spec->autocfg.hp_pins[0] = 0x14;
9745        spec->autocfg.speaker_pins[0] = 0x1b;
9746        alc_automute_pin(codec);
9747}
9748
9749static struct hda_verb alc889A_mb31_verbs[] = {
9750        /* Init rear pin (used as headphone output) */
9751        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
9752        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
9753        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9754        /* Init line pin (used as output in 4ch and 6ch mode) */
9755        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
9756        /* Init line 2 pin (used as headphone out by default) */
9757        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
9758        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9759        { } /* end */
9760};
9761
9762/* Mute speakers according to the headphone jack state */
9763static void alc889A_mb31_automute(struct hda_codec *codec)
9764{
9765        unsigned int present;
9766
9767        /* Mute only in 2ch or 4ch mode */
9768        if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9769            == 0x00) {
9770                present = snd_hda_jack_detect(codec, 0x15);
9771                snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
9772                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9773                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9774                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9775        }
9776}
9777
9778static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9779{
9780        if ((res >> 26) == ALC880_HP_EVENT)
9781                alc889A_mb31_automute(codec);
9782}
9783
9784
9785#ifdef CONFIG_SND_HDA_POWER_SAVE
9786#define alc882_loopbacks        alc880_loopbacks
9787#endif
9788
9789/* pcm configuration: identical with ALC880 */
9790#define alc882_pcm_analog_playback      alc880_pcm_analog_playback
9791#define alc882_pcm_analog_capture       alc880_pcm_analog_capture
9792#define alc882_pcm_digital_playback     alc880_pcm_digital_playback
9793#define alc882_pcm_digital_capture      alc880_pcm_digital_capture
9794
9795static hda_nid_t alc883_slave_dig_outs[] = {
9796        ALC1200_DIGOUT_NID, 0,
9797};
9798
9799static hda_nid_t alc1200_slave_dig_outs[] = {
9800        ALC883_DIGOUT_NID, 0,
9801};
9802
9803/*
9804 * configuration and preset
9805 */
9806static const char * const alc882_models[ALC882_MODEL_LAST] = {
9807        [ALC882_3ST_DIG]        = "3stack-dig",
9808        [ALC882_6ST_DIG]        = "6stack-dig",
9809        [ALC882_ARIMA]          = "arima",
9810        [ALC882_W2JC]           = "w2jc",
9811        [ALC882_TARGA]          = "targa",
9812        [ALC882_ASUS_A7J]       = "asus-a7j",
9813        [ALC882_ASUS_A7M]       = "asus-a7m",
9814        [ALC885_MACPRO]         = "macpro",
9815        [ALC885_MB5]            = "mb5",
9816        [ALC885_MACMINI3]       = "macmini3",
9817        [ALC885_MBA21]          = "mba21",
9818        [ALC885_MBP3]           = "mbp3",
9819        [ALC885_IMAC24]         = "imac24",
9820        [ALC885_IMAC91]         = "imac91",
9821        [ALC883_3ST_2ch_DIG]    = "3stack-2ch-dig",
9822        [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
9823        [ALC883_3ST_6ch]        = "3stack-6ch",
9824        [ALC883_6ST_DIG]        = "alc883-6stack-dig",
9825        [ALC883_TARGA_DIG]      = "targa-dig",
9826        [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
9827        [ALC883_TARGA_8ch_DIG]  = "targa-8ch-dig",
9828        [ALC883_ACER]           = "acer",
9829        [ALC883_ACER_ASPIRE]    = "acer-aspire",
9830        [ALC888_ACER_ASPIRE_4930G]      = "acer-aspire-4930g",
9831        [ALC888_ACER_ASPIRE_6530G]      = "acer-aspire-6530g",
9832        [ALC888_ACER_ASPIRE_8930G]      = "acer-aspire-8930g",
9833        [ALC888_ACER_ASPIRE_7730G]      = "acer-aspire-7730g",
9834        [ALC883_MEDION]         = "medion",
9835        [ALC883_MEDION_WIM2160] = "medion-wim2160",
9836        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
9837        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9838        [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
9839        [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9840        [ALC888_LENOVO_SKY] = "lenovo-sky",
9841        [ALC883_HAIER_W66]      = "haier-w66",
9842        [ALC888_3ST_HP]         = "3stack-hp",
9843        [ALC888_6ST_DELL]       = "6stack-dell",
9844        [ALC883_MITAC]          = "mitac",
9845        [ALC883_CLEVO_M540R]    = "clevo-m540r",
9846        [ALC883_CLEVO_M720]     = "clevo-m720",
9847        [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9848        [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9849        [ALC883_3ST_6ch_INTEL]  = "3stack-6ch-intel",
9850        [ALC889A_INTEL]         = "intel-alc889a",
9851        [ALC889_INTEL]          = "intel-x58",
9852        [ALC1200_ASUS_P5Q]      = "asus-p5q",
9853        [ALC889A_MB31]          = "mb31",
9854        [ALC883_SONY_VAIO_TT]   = "sony-vaio-tt",
9855        [ALC882_AUTO]           = "auto",
9856};
9857
9858static struct snd_pci_quirk alc882_cfg_tbl[] = {
9859        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9860
9861        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9862        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9863        SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9864        SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9865        SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9866        SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9867        SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9868                ALC888_ACER_ASPIRE_4930G),
9869        SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9870                ALC888_ACER_ASPIRE_4930G),
9871        SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9872                ALC888_ACER_ASPIRE_8930G),
9873        SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9874                ALC888_ACER_ASPIRE_8930G),
9875        SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9876        SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9877        SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9878                ALC888_ACER_ASPIRE_6530G),
9879        SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9880                ALC888_ACER_ASPIRE_6530G),
9881        SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9882                ALC888_ACER_ASPIRE_7730G),
9883        /* default Acer -- disabled as it causes more problems.
9884         *    model=auto should work fine now
9885         */
9886        /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9887
9888        SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9889
9890        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9891        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9892        SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9893        SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9894        SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9895        SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9896
9897        SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9898        SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9899        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9900        SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9901        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9902        SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9903        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9904        SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9905        SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9906        SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9907        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9908
9909        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9910        SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9911        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9912        SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9913        SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9914        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9915        SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9916        SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9917        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9918
9919        SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9920        SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9921        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9922        SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
9923        SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9924        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9925        SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9926        SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9927        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9928        SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9929        SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9930        SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9931        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9932        SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9933        SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9934        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9935        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9936        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9937        SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9938        SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9939        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9940        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9941        SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9942        SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9943        SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9944        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9945        SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9946        SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9947        SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9948        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9949        SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9950
9951        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9952        SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9953        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9954        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9955        SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9956        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9957        SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9958        /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9959        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9960        SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9961                      ALC883_FUJITSU_PI2515),
9962        SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9963                ALC888_FUJITSU_XA3530),
9964        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9965        SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9966        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9967        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9968        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9969        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9970        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9971        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9972
9973        SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9974        SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9975        SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9976        SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9977        SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9978        SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9979        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9980
9981        {}
9982};
9983
9984/* codec SSID table for Intel Mac */
9985static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9986        SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9987        SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9988        SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9989        SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9990        SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9991        SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9992        SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9993        SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9994        SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9995        SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9996        SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9997        SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9998        SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9999        SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10000        SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10001        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10002        SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10003        /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10004         * so apparently no perfect solution yet
10005         */
10006        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10007        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10008        SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10009        {} /* terminator */
10010};
10011
10012static struct alc_config_preset alc882_presets[] = {
10013        [ALC882_3ST_DIG] = {
10014                .mixers = { alc882_base_mixer },
10015                .init_verbs = { alc882_base_init_verbs,
10016                                alc882_adc1_init_verbs },
10017                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10018                .dac_nids = alc882_dac_nids,
10019                .dig_out_nid = ALC882_DIGOUT_NID,
10020                .dig_in_nid = ALC882_DIGIN_NID,
10021                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10022                .channel_mode = alc882_ch_modes,
10023                .need_dac_fix = 1,
10024                .input_mux = &alc882_capture_source,
10025        },
10026        [ALC882_6ST_DIG] = {
10027                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10028                .init_verbs = { alc882_base_init_verbs,
10029                                alc882_adc1_init_verbs },
10030                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10031                .dac_nids = alc882_dac_nids,
10032                .dig_out_nid = ALC882_DIGOUT_NID,
10033                .dig_in_nid = ALC882_DIGIN_NID,
10034                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10035                .channel_mode = alc882_sixstack_modes,
10036                .input_mux = &alc882_capture_source,
10037        },
10038        [ALC882_ARIMA] = {
10039                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10040                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10041                                alc882_eapd_verbs },
10042                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10043                .dac_nids = alc882_dac_nids,
10044                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10045                .channel_mode = alc882_sixstack_modes,
10046                .input_mux = &alc882_capture_source,
10047        },
10048        [ALC882_W2JC] = {
10049                .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10050                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10051                                alc882_eapd_verbs, alc880_gpio1_init_verbs },
10052                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10053                .dac_nids = alc882_dac_nids,
10054                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10055                .channel_mode = alc880_threestack_modes,
10056                .need_dac_fix = 1,
10057                .input_mux = &alc882_capture_source,
10058                .dig_out_nid = ALC882_DIGOUT_NID,
10059        },
10060           [ALC885_MBA21] = {
10061                        .mixers = { alc885_mba21_mixer },
10062                        .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10063                        .num_dacs = 2,
10064                        .dac_nids = alc882_dac_nids,
10065                        .channel_mode = alc885_mba21_ch_modes,
10066                        .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10067                        .input_mux = &alc882_capture_source,
10068                        .unsol_event = alc_automute_amp_unsol_event,
10069                        .setup = alc885_mba21_setup,
10070                        .init_hook = alc_automute_amp,
10071       },
10072        [ALC885_MBP3] = {
10073                .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10074                .init_verbs = { alc885_mbp3_init_verbs,
10075                                alc880_gpio1_init_verbs },
10076                .num_dacs = 2,
10077                .dac_nids = alc882_dac_nids,
10078                .hp_nid = 0x04,
10079                .channel_mode = alc885_mbp_4ch_modes,
10080                .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10081                .input_mux = &alc882_capture_source,
10082                .dig_out_nid = ALC882_DIGOUT_NID,
10083                .dig_in_nid = ALC882_DIGIN_NID,
10084                .unsol_event = alc_automute_amp_unsol_event,
10085                .setup = alc885_mbp3_setup,
10086                .init_hook = alc_automute_amp,
10087        },
10088        [ALC885_MB5] = {
10089                .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10090                .init_verbs = { alc885_mb5_init_verbs,
10091                                alc880_gpio1_init_verbs },
10092                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10093                .dac_nids = alc882_dac_nids,
10094                .channel_mode = alc885_mb5_6ch_modes,
10095                .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10096                .input_mux = &mb5_capture_source,
10097                .dig_out_nid = ALC882_DIGOUT_NID,
10098                .dig_in_nid = ALC882_DIGIN_NID,
10099                .unsol_event = alc_automute_amp_unsol_event,
10100                .setup = alc885_mb5_setup,
10101                .init_hook = alc_automute_amp,
10102        },
10103        [ALC885_MACMINI3] = {
10104                .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10105                .init_verbs = { alc885_macmini3_init_verbs,
10106                                alc880_gpio1_init_verbs },
10107                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10108                .dac_nids = alc882_dac_nids,
10109                .channel_mode = alc885_macmini3_6ch_modes,
10110                .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10111                .input_mux = &macmini3_capture_source,
10112                .dig_out_nid = ALC882_DIGOUT_NID,
10113                .dig_in_nid = ALC882_DIGIN_NID,
10114                .unsol_event = alc_automute_amp_unsol_event,
10115                .setup = alc885_macmini3_setup,
10116                .init_hook = alc_automute_amp,
10117        },
10118        [ALC885_MACPRO] = {
10119                .mixers = { alc882_macpro_mixer },
10120                .init_verbs = { alc882_macpro_init_verbs },
10121                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10122                .dac_nids = alc882_dac_nids,
10123                .dig_out_nid = ALC882_DIGOUT_NID,
10124                .dig_in_nid = ALC882_DIGIN_NID,
10125                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10126                .channel_mode = alc882_ch_modes,
10127                .input_mux = &alc882_capture_source,
10128                .init_hook = alc885_macpro_init_hook,
10129        },
10130        [ALC885_IMAC24] = {
10131                .mixers = { alc885_imac24_mixer },
10132                .init_verbs = { alc885_imac24_init_verbs },
10133                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10134                .dac_nids = alc882_dac_nids,
10135                .dig_out_nid = ALC882_DIGOUT_NID,
10136                .dig_in_nid = ALC882_DIGIN_NID,
10137                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10138                .channel_mode = alc882_ch_modes,
10139                .input_mux = &alc882_capture_source,
10140                .unsol_event = alc_automute_amp_unsol_event,
10141                .setup = alc885_imac24_setup,
10142                .init_hook = alc885_imac24_init_hook,
10143        },
10144        [ALC885_IMAC91] = {
10145                .mixers = {alc885_imac91_mixer},
10146                .init_verbs = { alc885_imac91_init_verbs,
10147                                alc880_gpio1_init_verbs },
10148                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10149                .dac_nids = alc882_dac_nids,
10150                .channel_mode = alc885_mba21_ch_modes,
10151                .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10152                .input_mux = &alc889A_imac91_capture_source,
10153                .dig_out_nid = ALC882_DIGOUT_NID,
10154                .dig_in_nid = ALC882_DIGIN_NID,
10155                .unsol_event = alc_automute_amp_unsol_event,
10156                .setup = alc885_imac91_setup,
10157                .init_hook = alc_automute_amp,
10158        },
10159        [ALC882_TARGA] = {
10160                .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10161                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10162                                alc880_gpio3_init_verbs, alc882_targa_verbs},
10163                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10164                .dac_nids = alc882_dac_nids,
10165                .dig_out_nid = ALC882_DIGOUT_NID,
10166                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10167                .adc_nids = alc882_adc_nids,
10168                .capsrc_nids = alc882_capsrc_nids,
10169                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10170                .channel_mode = alc882_3ST_6ch_modes,
10171                .need_dac_fix = 1,
10172                .input_mux = &alc882_capture_source,
10173                .unsol_event = alc882_targa_unsol_event,
10174                .setup = alc882_targa_setup,
10175                .init_hook = alc882_targa_automute,
10176        },
10177        [ALC882_ASUS_A7J] = {
10178                .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10179                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10180                                alc882_asus_a7j_verbs},
10181                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10182                .dac_nids = alc882_dac_nids,
10183                .dig_out_nid = ALC882_DIGOUT_NID,
10184                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10185                .adc_nids = alc882_adc_nids,
10186                .capsrc_nids = alc882_capsrc_nids,
10187                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10188                .channel_mode = alc882_3ST_6ch_modes,
10189                .need_dac_fix = 1,
10190                .input_mux = &alc882_capture_source,
10191        },
10192        [ALC882_ASUS_A7M] = {
10193                .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10194                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10195                                alc882_eapd_verbs, alc880_gpio1_init_verbs,
10196                                alc882_asus_a7m_verbs },
10197                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10198                .dac_nids = alc882_dac_nids,
10199                .dig_out_nid = ALC882_DIGOUT_NID,
10200                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10201                .channel_mode = alc880_threestack_modes,
10202                .need_dac_fix = 1,
10203                .input_mux = &alc882_capture_source,
10204        },
10205        [ALC883_3ST_2ch_DIG] = {
10206                .mixers = { alc883_3ST_2ch_mixer },
10207                .init_verbs = { alc883_init_verbs },
10208                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10209                .dac_nids = alc883_dac_nids,
10210                .dig_out_nid = ALC883_DIGOUT_NID,
10211                .dig_in_nid = ALC883_DIGIN_NID,
10212                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10213                .channel_mode = alc883_3ST_2ch_modes,
10214                .input_mux = &alc883_capture_source,
10215        },
10216        [ALC883_3ST_6ch_DIG] = {
10217                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10218                .init_verbs = { alc883_init_verbs },
10219                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10220                .dac_nids = alc883_dac_nids,
10221                .dig_out_nid = ALC883_DIGOUT_NID,
10222                .dig_in_nid = ALC883_DIGIN_NID,
10223                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10224                .channel_mode = alc883_3ST_6ch_modes,
10225                .need_dac_fix = 1,
10226                .input_mux = &alc883_capture_source,
10227        },
10228        [ALC883_3ST_6ch] = {
10229                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10230                .init_verbs = { alc883_init_verbs },
10231                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10232                .dac_nids = alc883_dac_nids,
10233                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10234                .channel_mode = alc883_3ST_6ch_modes,
10235                .need_dac_fix = 1,
10236                .input_mux = &alc883_capture_source,
10237        },
10238        [ALC883_3ST_6ch_INTEL] = {
10239                .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10240                .init_verbs = { alc883_init_verbs },
10241                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10242                .dac_nids = alc883_dac_nids,
10243                .dig_out_nid = ALC883_DIGOUT_NID,
10244                .dig_in_nid = ALC883_DIGIN_NID,
10245                .slave_dig_outs = alc883_slave_dig_outs,
10246                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10247                .channel_mode = alc883_3ST_6ch_intel_modes,
10248                .need_dac_fix = 1,
10249                .input_mux = &alc883_3stack_6ch_intel,
10250        },
10251        [ALC889A_INTEL] = {
10252                .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10253                .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10254                                alc_hp15_unsol_verbs },
10255                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256                .dac_nids = alc883_dac_nids,
10257                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10258                .adc_nids = alc889_adc_nids,
10259                .dig_out_nid = ALC883_DIGOUT_NID,
10260                .dig_in_nid = ALC883_DIGIN_NID,
10261                .slave_dig_outs = alc883_slave_dig_outs,
10262                .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10263                .channel_mode = alc889_8ch_intel_modes,
10264                .capsrc_nids = alc889_capsrc_nids,
10265                .input_mux = &alc889_capture_source,
10266                .setup = alc889_automute_setup,
10267                .init_hook = alc_automute_amp,
10268                .unsol_event = alc_automute_amp_unsol_event,
10269                .need_dac_fix = 1,
10270        },
10271        [ALC889_INTEL] = {
10272                .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10273                .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10274                                alc889_eapd_verbs, alc_hp15_unsol_verbs},
10275                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10276                .dac_nids = alc883_dac_nids,
10277                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10278                .adc_nids = alc889_adc_nids,
10279                .dig_out_nid = ALC883_DIGOUT_NID,
10280                .dig_in_nid = ALC883_DIGIN_NID,
10281                .slave_dig_outs = alc883_slave_dig_outs,
10282                .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10283                .channel_mode = alc889_8ch_intel_modes,
10284                .capsrc_nids = alc889_capsrc_nids,
10285                .input_mux = &alc889_capture_source,
10286                .setup = alc889_automute_setup,
10287                .init_hook = alc889_intel_init_hook,
10288                .unsol_event = alc_automute_amp_unsol_event,
10289                .need_dac_fix = 1,
10290        },
10291        [ALC883_6ST_DIG] = {
10292                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10293                .init_verbs = { alc883_init_verbs },
10294                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10295                .dac_nids = alc883_dac_nids,
10296                .dig_out_nid = ALC883_DIGOUT_NID,
10297                .dig_in_nid = ALC883_DIGIN_NID,
10298                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10299                .channel_mode = alc883_sixstack_modes,
10300                .input_mux = &alc883_capture_source,
10301        },
10302        [ALC883_TARGA_DIG] = {
10303                .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10304                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10305                                alc883_targa_verbs},
10306                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10307                .dac_nids = alc883_dac_nids,
10308                .dig_out_nid = ALC883_DIGOUT_NID,
10309                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10310                .channel_mode = alc883_3ST_6ch_modes,
10311                .need_dac_fix = 1,
10312                .input_mux = &alc883_capture_source,
10313                .unsol_event = alc883_targa_unsol_event,
10314                .setup = alc882_targa_setup,
10315                .init_hook = alc882_targa_automute,
10316        },
10317        [ALC883_TARGA_2ch_DIG] = {
10318                .mixers = { alc883_targa_2ch_mixer},
10319                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10320                                alc883_targa_verbs},
10321                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10322                .dac_nids = alc883_dac_nids,
10323                .adc_nids = alc883_adc_nids_alt,
10324                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10325                .capsrc_nids = alc883_capsrc_nids,
10326                .dig_out_nid = ALC883_DIGOUT_NID,
10327                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10328                .channel_mode = alc883_3ST_2ch_modes,
10329                .input_mux = &alc883_capture_source,
10330                .unsol_event = alc883_targa_unsol_event,
10331                .setup = alc882_targa_setup,
10332                .init_hook = alc882_targa_automute,
10333        },
10334        [ALC883_TARGA_8ch_DIG] = {
10335                .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10336                            alc883_chmode_mixer },
10337                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10338                                alc883_targa_verbs },
10339                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10340                .dac_nids = alc883_dac_nids,
10341                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10342                .adc_nids = alc883_adc_nids_rev,
10343                .capsrc_nids = alc883_capsrc_nids_rev,
10344                .dig_out_nid = ALC883_DIGOUT_NID,
10345                .dig_in_nid = ALC883_DIGIN_NID,
10346                .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10347                .channel_mode = alc883_4ST_8ch_modes,
10348                .need_dac_fix = 1,
10349                .input_mux = &alc883_capture_source,
10350                .unsol_event = alc883_targa_unsol_event,
10351                .setup = alc882_targa_setup,
10352                .init_hook = alc882_targa_automute,
10353        },
10354        [ALC883_ACER] = {
10355                .mixers = { alc883_base_mixer },
10356                /* On TravelMate laptops, GPIO 0 enables the internal speaker
10357                 * and the headphone jack.  Turn this on and rely on the
10358                 * standard mute methods whenever the user wants to turn
10359                 * these outputs off.
10360                 */
10361                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10362                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10363                .dac_nids = alc883_dac_nids,
10364                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10365                .channel_mode = alc883_3ST_2ch_modes,
10366                .input_mux = &alc883_capture_source,
10367        },
10368        [ALC883_ACER_ASPIRE] = {
10369                .mixers = { alc883_acer_aspire_mixer },
10370                .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10371                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10372                .dac_nids = alc883_dac_nids,
10373                .dig_out_nid = ALC883_DIGOUT_NID,
10374                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10375                .channel_mode = alc883_3ST_2ch_modes,
10376                .input_mux = &alc883_capture_source,
10377                .unsol_event = alc_automute_amp_unsol_event,
10378                .setup = alc883_acer_aspire_setup,
10379                .init_hook = alc_automute_amp,
10380        },
10381        [ALC888_ACER_ASPIRE_4930G] = {
10382                .mixers = { alc888_acer_aspire_4930g_mixer,
10383                                alc883_chmode_mixer },
10384                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10385                                alc888_acer_aspire_4930g_verbs },
10386                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387                .dac_nids = alc883_dac_nids,
10388                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10389                .adc_nids = alc883_adc_nids_rev,
10390                .capsrc_nids = alc883_capsrc_nids_rev,
10391                .dig_out_nid = ALC883_DIGOUT_NID,
10392                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10393                .channel_mode = alc883_3ST_6ch_modes,
10394                .need_dac_fix = 1,
10395                .const_channel_count = 6,
10396                .num_mux_defs =
10397                        ARRAY_SIZE(alc888_2_capture_sources),
10398                .input_mux = alc888_2_capture_sources,
10399                .unsol_event = alc_automute_amp_unsol_event,
10400                .setup = alc888_acer_aspire_4930g_setup,
10401                .init_hook = alc_automute_amp,
10402        },
10403        [ALC888_ACER_ASPIRE_6530G] = {
10404                .mixers = { alc888_acer_aspire_6530_mixer },
10405                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10406                                alc888_acer_aspire_6530g_verbs },
10407                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10408                .dac_nids = alc883_dac_nids,
10409                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10410                .adc_nids = alc883_adc_nids_rev,
10411                .capsrc_nids = alc883_capsrc_nids_rev,
10412                .dig_out_nid = ALC883_DIGOUT_NID,
10413                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10414                .channel_mode = alc883_3ST_2ch_modes,
10415                .num_mux_defs =
10416                        ARRAY_SIZE(alc888_2_capture_sources),
10417                .input_mux = alc888_acer_aspire_6530_sources,
10418                .unsol_event = alc_automute_amp_unsol_event,
10419                .setup = alc888_acer_aspire_6530g_setup,
10420                .init_hook = alc_automute_amp,
10421        },
10422        [ALC888_ACER_ASPIRE_8930G] = {
10423                .mixers = { alc889_acer_aspire_8930g_mixer,
10424                                alc883_chmode_mixer },
10425                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10426                                alc889_acer_aspire_8930g_verbs,
10427                                alc889_eapd_verbs},
10428                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10429                .dac_nids = alc883_dac_nids,
10430                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10431                .adc_nids = alc889_adc_nids,
10432                .capsrc_nids = alc889_capsrc_nids,
10433                .dig_out_nid = ALC883_DIGOUT_NID,
10434                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10435                .channel_mode = alc883_3ST_6ch_modes,
10436                .need_dac_fix = 1,
10437                .const_channel_count = 6,
10438                .num_mux_defs =
10439                        ARRAY_SIZE(alc889_capture_sources),
10440                .input_mux = alc889_capture_sources,
10441                .unsol_event = alc_automute_amp_unsol_event,
10442                .setup = alc889_acer_aspire_8930g_setup,
10443                .init_hook = alc_automute_amp,
10444#ifdef CONFIG_SND_HDA_POWER_SAVE
10445                .power_hook = alc_power_eapd,
10446#endif
10447        },
10448        [ALC888_ACER_ASPIRE_7730G] = {
10449                .mixers = { alc883_3ST_6ch_mixer,
10450                                alc883_chmode_mixer },
10451                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10452                                alc888_acer_aspire_7730G_verbs },
10453                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10454                .dac_nids = alc883_dac_nids,
10455                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10456                .adc_nids = alc883_adc_nids_rev,
10457                .capsrc_nids = alc883_capsrc_nids_rev,
10458                .dig_out_nid = ALC883_DIGOUT_NID,
10459                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10460                .channel_mode = alc883_3ST_6ch_modes,
10461                .need_dac_fix = 1,
10462                .const_channel_count = 6,
10463                .input_mux = &alc883_capture_source,
10464                .unsol_event = alc_automute_amp_unsol_event,
10465                .setup = alc888_acer_aspire_7730g_setup,
10466                .init_hook = alc_automute_amp,
10467        },
10468        [ALC883_MEDION] = {
10469                .mixers = { alc883_fivestack_mixer,
10470                            alc883_chmode_mixer },
10471                .init_verbs = { alc883_init_verbs,
10472                                alc883_medion_eapd_verbs },
10473                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10474                .dac_nids = alc883_dac_nids,
10475                .adc_nids = alc883_adc_nids_alt,
10476                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10477                .capsrc_nids = alc883_capsrc_nids,
10478                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10479                .channel_mode = alc883_sixstack_modes,
10480                .input_mux = &alc883_capture_source,
10481        },
10482        [ALC883_MEDION_WIM2160] = {
10483                .mixers = { alc883_medion_wim2160_mixer },
10484                .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10485                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10486                .dac_nids = alc883_dac_nids,
10487                .dig_out_nid = ALC883_DIGOUT_NID,
10488                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10489                .adc_nids = alc883_adc_nids,
10490                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10491                .channel_mode = alc883_3ST_2ch_modes,
10492                .input_mux = &alc883_capture_source,
10493                .unsol_event = alc_automute_amp_unsol_event,
10494                .setup = alc883_medion_wim2160_setup,
10495                .init_hook = alc_automute_amp,
10496        },
10497        [ALC883_LAPTOP_EAPD] = {
10498                .mixers = { alc883_base_mixer },
10499                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10500                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501                .dac_nids = alc883_dac_nids,
10502                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10503                .channel_mode = alc883_3ST_2ch_modes,
10504                .input_mux = &alc883_capture_source,
10505        },
10506        [ALC883_CLEVO_M540R] = {
10507                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10508                .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10509                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10510                .dac_nids = alc883_dac_nids,
10511                .dig_out_nid = ALC883_DIGOUT_NID,
10512                .dig_in_nid = ALC883_DIGIN_NID,
10513                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10514                .channel_mode = alc883_3ST_6ch_clevo_modes,
10515                .need_dac_fix = 1,
10516                .input_mux = &alc883_capture_source,
10517                /* This machine has the hardware HP auto-muting, thus
10518                 * we need no software mute via unsol event
10519                 */
10520        },
10521        [ALC883_CLEVO_M720] = {
10522                .mixers = { alc883_clevo_m720_mixer },
10523                .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10524                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525                .dac_nids = alc883_dac_nids,
10526                .dig_out_nid = ALC883_DIGOUT_NID,
10527                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10528                .channel_mode = alc883_3ST_2ch_modes,
10529                .input_mux = &alc883_capture_source,
10530                .unsol_event = alc883_clevo_m720_unsol_event,
10531                .setup = alc883_clevo_m720_setup,
10532                .init_hook = alc883_clevo_m720_init_hook,
10533        },
10534        [ALC883_LENOVO_101E_2ch] = {
10535                .mixers = { alc883_lenovo_101e_2ch_mixer},
10536                .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10537                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10538                .dac_nids = alc883_dac_nids,
10539                .adc_nids = alc883_adc_nids_alt,
10540                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10541                .capsrc_nids = alc883_capsrc_nids,
10542                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10543                .channel_mode = alc883_3ST_2ch_modes,
10544                .input_mux = &alc883_lenovo_101e_capture_source,
10545                .unsol_event = alc883_lenovo_101e_unsol_event,
10546                .init_hook = alc883_lenovo_101e_all_automute,
10547        },
10548        [ALC883_LENOVO_NB0763] = {
10549                .mixers = { alc883_lenovo_nb0763_mixer },
10550                .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10551                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552                .dac_nids = alc883_dac_nids,
10553                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554                .channel_mode = alc883_3ST_2ch_modes,
10555                .need_dac_fix = 1,
10556                .input_mux = &alc883_lenovo_nb0763_capture_source,
10557                .unsol_event = alc_automute_amp_unsol_event,
10558                .setup = alc883_lenovo_nb0763_setup,
10559                .init_hook = alc_automute_amp,
10560        },
10561        [ALC888_LENOVO_MS7195_DIG] = {
10562                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10563                .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10564                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565                .dac_nids = alc883_dac_nids,
10566                .dig_out_nid = ALC883_DIGOUT_NID,
10567                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10568                .channel_mode = alc883_3ST_6ch_modes,
10569                .need_dac_fix = 1,
10570                .input_mux = &alc883_capture_source,
10571                .unsol_event = alc883_lenovo_ms7195_unsol_event,
10572                .init_hook = alc888_lenovo_ms7195_front_automute,
10573        },
10574        [ALC883_HAIER_W66] = {
10575                .mixers = { alc883_targa_2ch_mixer},
10576                .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10577                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10578                .dac_nids = alc883_dac_nids,
10579                .dig_out_nid = ALC883_DIGOUT_NID,
10580                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10581                .channel_mode = alc883_3ST_2ch_modes,
10582                .input_mux = &alc883_capture_source,
10583                .unsol_event = alc_automute_amp_unsol_event,
10584                .setup = alc883_haier_w66_setup,
10585                .init_hook = alc_automute_amp,
10586        },
10587        [ALC888_3ST_HP] = {
10588                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10589                .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10590                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10591                .dac_nids = alc883_dac_nids,
10592                .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10593                .channel_mode = alc888_3st_hp_modes,
10594                .need_dac_fix = 1,
10595                .input_mux = &alc883_capture_source,
10596                .unsol_event = alc_automute_amp_unsol_event,
10597                .setup = alc888_3st_hp_setup,
10598                .init_hook = alc_automute_amp,
10599        },
10600        [ALC888_6ST_DELL] = {
10601                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10602                .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10603                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10604                .dac_nids = alc883_dac_nids,
10605                .dig_out_nid = ALC883_DIGOUT_NID,
10606                .dig_in_nid = ALC883_DIGIN_NID,
10607                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10608                .channel_mode = alc883_sixstack_modes,
10609                .input_mux = &alc883_capture_source,
10610                .unsol_event = alc_automute_amp_unsol_event,
10611                .setup = alc888_6st_dell_setup,
10612                .init_hook = alc_automute_amp,
10613        },
10614        [ALC883_MITAC] = {
10615                .mixers = { alc883_mitac_mixer },
10616                .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10617                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10618                .dac_nids = alc883_dac_nids,
10619                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10620                .channel_mode = alc883_3ST_2ch_modes,
10621                .input_mux = &alc883_capture_source,
10622                .unsol_event = alc_automute_amp_unsol_event,
10623                .setup = alc883_mitac_setup,
10624                .init_hook = alc_automute_amp,
10625        },
10626        [ALC883_FUJITSU_PI2515] = {
10627                .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10628                .init_verbs = { alc883_init_verbs,
10629                                alc883_2ch_fujitsu_pi2515_verbs},
10630                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10631                .dac_nids = alc883_dac_nids,
10632                .dig_out_nid = ALC883_DIGOUT_NID,
10633                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10634                .channel_mode = alc883_3ST_2ch_modes,
10635                .input_mux = &alc883_fujitsu_pi2515_capture_source,
10636                .unsol_event = alc_automute_amp_unsol_event,
10637                .setup = alc883_2ch_fujitsu_pi2515_setup,
10638                .init_hook = alc_automute_amp,
10639        },
10640        [ALC888_FUJITSU_XA3530] = {
10641                .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10642                .init_verbs = { alc883_init_verbs,
10643                        alc888_fujitsu_xa3530_verbs },
10644                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10645                .dac_nids = alc883_dac_nids,
10646                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10647                .adc_nids = alc883_adc_nids_rev,
10648                .capsrc_nids = alc883_capsrc_nids_rev,
10649                .dig_out_nid = ALC883_DIGOUT_NID,
10650                .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10651                .channel_mode = alc888_4ST_8ch_intel_modes,
10652                .num_mux_defs =
10653                        ARRAY_SIZE(alc888_2_capture_sources),
10654                .input_mux = alc888_2_capture_sources,
10655                .unsol_event = alc_automute_amp_unsol_event,
10656                .setup = alc888_fujitsu_xa3530_setup,
10657                .init_hook = alc_automute_amp,
10658        },
10659        [ALC888_LENOVO_SKY] = {
10660                .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10661                .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10662                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10663                .dac_nids = alc883_dac_nids,
10664                .dig_out_nid = ALC883_DIGOUT_NID,
10665                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10666                .channel_mode = alc883_sixstack_modes,
10667                .need_dac_fix = 1,
10668                .input_mux = &alc883_lenovo_sky_capture_source,
10669                .unsol_event = alc_automute_amp_unsol_event,
10670                .setup = alc888_lenovo_sky_setup,
10671                .init_hook = alc_automute_amp,
10672        },
10673        [ALC888_ASUS_M90V] = {
10674                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10675                .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10676                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10677                .dac_nids = alc883_dac_nids,
10678                .dig_out_nid = ALC883_DIGOUT_NID,
10679                .dig_in_nid = ALC883_DIGIN_NID,
10680                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10681                .channel_mode = alc883_3ST_6ch_modes,
10682                .need_dac_fix = 1,
10683                .input_mux = &alc883_fujitsu_pi2515_capture_source,
10684                .unsol_event = alc_sku_unsol_event,
10685                .setup = alc883_mode2_setup,
10686                .init_hook = alc_inithook,
10687        },
10688        [ALC888_ASUS_EEE1601] = {
10689                .mixers = { alc883_asus_eee1601_mixer },
10690                .cap_mixer = alc883_asus_eee1601_cap_mixer,
10691                .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10692                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10693                .dac_nids = alc883_dac_nids,
10694                .dig_out_nid = ALC883_DIGOUT_NID,
10695                .dig_in_nid = ALC883_DIGIN_NID,
10696                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10697                .channel_mode = alc883_3ST_2ch_modes,
10698                .need_dac_fix = 1,
10699                .input_mux = &alc883_asus_eee1601_capture_source,
10700                .unsol_event = alc_sku_unsol_event,
10701                .init_hook = alc883_eee1601_inithook,
10702        },
10703        [ALC1200_ASUS_P5Q] = {
10704                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10705                .init_verbs = { alc883_init_verbs },
10706                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10707                .dac_nids = alc883_dac_nids,
10708                .dig_out_nid = ALC1200_DIGOUT_NID,
10709                .dig_in_nid = ALC883_DIGIN_NID,
10710                .slave_dig_outs = alc1200_slave_dig_outs,
10711                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10712                .channel_mode = alc883_sixstack_modes,
10713                .input_mux = &alc883_capture_source,
10714        },
10715        [ALC889A_MB31] = {
10716                .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10717                .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10718                        alc880_gpio1_init_verbs },
10719                .adc_nids = alc883_adc_nids,
10720                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10721                .capsrc_nids = alc883_capsrc_nids,
10722                .dac_nids = alc883_dac_nids,
10723                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10724                .channel_mode = alc889A_mb31_6ch_modes,
10725                .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10726                .input_mux = &alc889A_mb31_capture_source,
10727                .dig_out_nid = ALC883_DIGOUT_NID,
10728                .unsol_event = alc889A_mb31_unsol_event,
10729                .init_hook = alc889A_mb31_automute,
10730        },
10731        [ALC883_SONY_VAIO_TT] = {
10732                .mixers = { alc883_vaiott_mixer },
10733                .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10734                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735                .dac_nids = alc883_dac_nids,
10736                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10737                .channel_mode = alc883_3ST_2ch_modes,
10738                .input_mux = &alc883_capture_source,
10739                .unsol_event = alc_automute_amp_unsol_event,
10740                .setup = alc883_vaiott_setup,
10741                .init_hook = alc_automute_amp,
10742        },
10743};
10744
10745
10746/*
10747 * Pin config fixes
10748 */
10749enum {
10750        PINFIX_ABIT_AW9D_MAX,
10751        PINFIX_PB_M5210,
10752        PINFIX_ACER_ASPIRE_7736,
10753};
10754
10755static const struct alc_fixup alc882_fixups[] = {
10756        [PINFIX_ABIT_AW9D_MAX] = {
10757                .type = ALC_FIXUP_PINS,
10758                .v.pins = (const struct alc_pincfg[]) {
10759                        { 0x15, 0x01080104 }, /* side */
10760                        { 0x16, 0x01011012 }, /* rear */
10761                        { 0x17, 0x01016011 }, /* clfe */
10762                        { }
10763                }
10764        },
10765        [PINFIX_PB_M5210] = {
10766                .type = ALC_FIXUP_VERBS,
10767                .v.verbs = (const struct hda_verb[]) {
10768                        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10769                        {}
10770                }
10771        },
10772        [PINFIX_ACER_ASPIRE_7736] = {
10773                .type = ALC_FIXUP_SKU,
10774                .v.sku = ALC_FIXUP_SKU_IGNORE,
10775        },
10776};
10777
10778static struct snd_pci_quirk alc882_fixup_tbl[] = {
10779        SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10780        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10781        SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10782        {}
10783};
10784
10785/*
10786 * BIOS auto configuration
10787 */
10788static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10789                                                const struct auto_pin_cfg *cfg)
10790{
10791        return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10792}
10793
10794static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10795                                              hda_nid_t nid, int pin_type,
10796                                              hda_nid_t dac)
10797{
10798        int idx;
10799
10800        /* set as output */
10801        alc_set_pin_output(codec, nid, pin_type);
10802
10803        if (dac == 0x25)
10804                idx = 4;
10805        else if (dac >= 0x02 && dac <= 0x05)
10806                idx = dac - 2;
10807        else
10808                return;
10809        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10810}
10811
10812static void alc882_auto_init_multi_out(struct hda_codec *codec)
10813{
10814        struct alc_spec *spec = codec->spec;
10815        int i;
10816
10817        for (i = 0; i <= HDA_SIDE; i++) {
10818                hda_nid_t nid = spec->autocfg.line_out_pins[i];
10819                int pin_type = get_pin_type(spec->autocfg.line_out_type);
10820                if (nid)
10821                        alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10822                                        spec->multiout.dac_nids[i]);
10823        }
10824}
10825
10826static void alc882_auto_init_hp_out(struct hda_codec *codec)
10827{
10828        struct alc_spec *spec = codec->spec;
10829        hda_nid_t pin, dac;
10830        int i;
10831
10832        for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10833                pin = spec->autocfg.hp_pins[i];
10834                if (!pin)
10835                        break;
10836                dac = spec->multiout.hp_nid;
10837                if (!dac)
10838                        dac = spec->multiout.dac_nids[0]; /* to front */
10839                alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10840        }
10841        for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10842                pin = spec->autocfg.speaker_pins[i];
10843                if (!pin)
10844                        break;
10845                dac = spec->multiout.extra_out_nid[0];
10846                if (!dac)
10847                        dac = spec->multiout.dac_nids[0]; /* to front */
10848                alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10849        }
10850}
10851
10852static void alc882_auto_init_analog_input(struct hda_codec *codec)
10853{
10854        struct alc_spec *spec = codec->spec;
10855        struct auto_pin_cfg *cfg = &spec->autocfg;
10856        int i;
10857
10858        for (i = 0; i < cfg->num_inputs; i++) {
10859                hda_nid_t nid = cfg->inputs[i].pin;
10860                alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10861                if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10862                        snd_hda_codec_write(codec, nid, 0,
10863                                            AC_VERB_SET_AMP_GAIN_MUTE,
10864                                            AMP_OUT_MUTE);
10865        }
10866}
10867
10868static void alc882_auto_init_input_src(struct hda_codec *codec)
10869{
10870        struct alc_spec *spec = codec->spec;
10871        int c;
10872
10873        for (c = 0; c < spec->num_adc_nids; c++) {
10874                hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10875                hda_nid_t nid = spec->capsrc_nids[c];
10876                unsigned int mux_idx;
10877                const struct hda_input_mux *imux;
10878                int conns, mute, idx, item;
10879
10880                conns = snd_hda_get_connections(codec, nid, conn_list,
10881                                                ARRAY_SIZE(conn_list));
10882                if (conns < 0)
10883                        continue;
10884                mux_idx = c >= spec->num_mux_defs ? 0 : c;
10885                imux = &spec->input_mux[mux_idx];
10886                if (!imux->num_items && mux_idx > 0)
10887                        imux = &spec->input_mux[0];
10888                for (idx = 0; idx < conns; idx++) {
10889                        /* if the current connection is the selected one,
10890                         * unmute it as default - otherwise mute it
10891                         */
10892                        mute = AMP_IN_MUTE(idx);
10893                        for (item = 0; item < imux->num_items; item++) {
10894                                if (imux->items[item].index == idx) {
10895                                        if (spec->cur_mux[c] == item)
10896                                                mute = AMP_IN_UNMUTE(idx);
10897                                        break;
10898                                }
10899                        }
10900                        /* check if we have a selector or mixer
10901                         * we could check for the widget type instead, but
10902                         * just check for Amp-In presence (in case of mixer
10903                         * without amp-in there is something wrong, this
10904                         * function shouldn't be used or capsrc nid is wrong)
10905                         */
10906                        if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10907                                snd_hda_codec_write(codec, nid, 0,
10908                                                    AC_VERB_SET_AMP_GAIN_MUTE,
10909                                                    mute);
10910                        else if (mute != AMP_IN_MUTE(idx))
10911                                snd_hda_codec_write(codec, nid, 0,
10912                                                    AC_VERB_SET_CONNECT_SEL,
10913                                                    idx);
10914                }
10915        }
10916}
10917
10918/* add mic boosts if needed */
10919static int alc_auto_add_mic_boost(struct hda_codec *codec)
10920{
10921        struct alc_spec *spec = codec->spec;
10922        struct auto_pin_cfg *cfg = &spec->autocfg;
10923        int i, err;
10924        int type_idx = 0;
10925        hda_nid_t nid;
10926        const char *prev_label = NULL;
10927
10928        for (i = 0; i < cfg->num_inputs; i++) {
10929                if (cfg->inputs[i].type > AUTO_PIN_MIC)
10930                        break;
10931                nid = cfg->inputs[i].pin;
10932                if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10933                        const char *label;
10934                        char boost_label[32];
10935
10936                        label = hda_get_autocfg_input_label(codec, cfg, i);
10937                        if (prev_label && !strcmp(label, prev_label))
10938                                type_idx++;
10939                        else
10940                                type_idx = 0;
10941                        prev_label = label;
10942
10943                        snprintf(boost_label, sizeof(boost_label),
10944                                 "%s Boost Volume", label);
10945                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
10946                                          boost_label, type_idx,
10947                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10948                        if (err < 0)
10949                                return err;
10950                }
10951        }
10952        return 0;
10953}
10954
10955/* almost identical with ALC880 parser... */
10956static int alc882_parse_auto_config(struct hda_codec *codec)
10957{
10958        struct alc_spec *spec = codec->spec;
10959        static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10960        int err;
10961
10962        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10963                                           alc882_ignore);
10964        if (err < 0)
10965                return err;
10966        if (!spec->autocfg.line_outs)
10967                return 0; /* can't find valid BIOS pin config */
10968
10969        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10970        if (err < 0)
10971                return err;
10972        err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10973        if (err < 0)
10974                return err;
10975        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10976                                           "Headphone");
10977        if (err < 0)
10978                return err;
10979        err = alc880_auto_create_extra_out(spec,
10980                                           spec->autocfg.speaker_pins[0],
10981                                           "Speaker");
10982        if (err < 0)
10983                return err;
10984        err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10985        if (err < 0)
10986                return err;
10987
10988        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10989
10990        alc_auto_parse_digital(codec);
10991
10992        if (spec->kctls.list)
10993                add_mixer(spec, spec->kctls.list);
10994
10995        add_verb(spec, alc883_auto_init_verbs);
10996        /* if ADC 0x07 is available, initialize it, too */
10997        if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10998                add_verb(spec, alc882_adc1_init_verbs);
10999
11000        spec->num_mux_defs = 1;
11001        spec->input_mux = &spec->private_imux[0];
11002
11003        alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11004
11005        err = alc_auto_add_mic_boost(codec);
11006        if (err < 0)
11007                return err;
11008
11009        return 1; /* config found */
11010}
11011
11012/* additional initialization for auto-configuration model */
11013static void alc882_auto_init(struct hda_codec *codec)
11014{
11015        struct alc_spec *spec = codec->spec;
11016        alc882_auto_init_multi_out(codec);
11017        alc882_auto_init_hp_out(codec);
11018        alc882_auto_init_analog_input(codec);
11019        alc882_auto_init_input_src(codec);
11020        alc_auto_init_digital(codec);
11021        if (spec->unsol_event)
11022                alc_inithook(codec);
11023}
11024
11025static int patch_alc882(struct hda_codec *codec)
11026{
11027        struct alc_spec *spec;
11028        int err, board_config;
11029
11030        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11031        if (spec == NULL)
11032                return -ENOMEM;
11033
11034        codec->spec = spec;
11035
11036        switch (codec->vendor_id) {
11037        case 0x10ec0882:
11038        case 0x10ec0885:
11039                break;
11040        default:
11041                /* ALC883 and variants */
11042                alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11043                break;
11044        }
11045
11046        board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11047                                                  alc882_models,
11048                                                  alc882_cfg_tbl);
11049
11050        if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11051                board_config = snd_hda_check_board_codec_sid_config(codec,
11052                        ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11053
11054        if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11055                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11056                       codec->chip_name);
11057                board_config = ALC882_AUTO;
11058        }
11059
11060        if (board_config == ALC882_AUTO) {
11061                alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11062                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11063        }
11064
11065        alc_auto_parse_customize_define(codec);
11066
11067        if (board_config == ALC882_AUTO) {
11068                /* automatic parse from the BIOS config */
11069                err = alc882_parse_auto_config(codec);
11070                if (err < 0) {
11071                        alc_free(codec);
11072                        return err;
11073                } else if (!err) {
11074                        printk(KERN_INFO
11075                               "hda_codec: Cannot set up configuration "
11076                               "from BIOS.  Using base mode...\n");
11077                        board_config = ALC882_3ST_DIG;
11078                }
11079        }
11080
11081        if (has_cdefine_beep(codec)) {
11082                err = snd_hda_attach_beep_device(codec, 0x1);
11083                if (err < 0) {
11084                        alc_free(codec);
11085                        return err;
11086                }
11087        }
11088
11089        if (board_config != ALC882_AUTO)
11090                setup_preset(codec, &alc882_presets[board_config]);
11091
11092        spec->stream_analog_playback = &alc882_pcm_analog_playback;
11093        spec->stream_analog_capture = &alc882_pcm_analog_capture;
11094        /* FIXME: setup DAC5 */
11095        /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11096        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11097
11098        spec->stream_digital_playback = &alc882_pcm_digital_playback;
11099        spec->stream_digital_capture = &alc882_pcm_digital_capture;
11100
11101        if (!spec->adc_nids && spec->input_mux) {
11102                int i, j;
11103                spec->num_adc_nids = 0;
11104                for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11105                        const struct hda_input_mux *imux = spec->input_mux;
11106                        hda_nid_t cap;
11107                        hda_nid_t items[16];
11108                        hda_nid_t nid = alc882_adc_nids[i];
11109                        unsigned int wcap = get_wcaps(codec, nid);
11110                        /* get type */
11111                        wcap = get_wcaps_type(wcap);
11112                        if (wcap != AC_WID_AUD_IN)
11113                                continue;
11114                        spec->private_adc_nids[spec->num_adc_nids] = nid;
11115                        err = snd_hda_get_connections(codec, nid, &cap, 1);
11116                        if (err < 0)
11117                                continue;
11118                        err = snd_hda_get_connections(codec, cap, items,
11119                                                      ARRAY_SIZE(items));
11120                        if (err < 0)
11121                                continue;
11122                        for (j = 0; j < imux->num_items; j++)
11123                                if (imux->items[j].index >= err)
11124                                        break;
11125                        if (j < imux->num_items)
11126                                continue;
11127                        spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11128                        spec->num_adc_nids++;
11129                }
11130                spec->adc_nids = spec->private_adc_nids;
11131                spec->capsrc_nids = spec->private_capsrc_nids;
11132        }
11133
11134        set_capture_mixer(codec);
11135
11136        if (has_cdefine_beep(codec))
11137                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11138
11139        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11140
11141        spec->vmaster_nid = 0x0c;
11142
11143        codec->patch_ops = alc_patch_ops;
11144        if (board_config == ALC882_AUTO)
11145                spec->init_hook = alc882_auto_init;
11146
11147        alc_init_jacks(codec);
11148#ifdef CONFIG_SND_HDA_POWER_SAVE
11149        if (!spec->loopback.amplist)
11150                spec->loopback.amplist = alc882_loopbacks;
11151#endif
11152
11153        return 0;
11154}
11155
11156
11157/*
11158 * ALC262 support
11159 */
11160
11161#define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
11162#define ALC262_DIGIN_NID        ALC880_DIGIN_NID
11163
11164#define alc262_dac_nids         alc260_dac_nids
11165#define alc262_adc_nids         alc882_adc_nids
11166#define alc262_adc_nids_alt     alc882_adc_nids_alt
11167#define alc262_capsrc_nids      alc882_capsrc_nids
11168#define alc262_capsrc_nids_alt  alc882_capsrc_nids_alt
11169
11170#define alc262_modes            alc260_modes
11171#define alc262_capture_source   alc882_capture_source
11172
11173static hda_nid_t alc262_dmic_adc_nids[1] = {
11174        /* ADC0 */
11175        0x09
11176};
11177
11178static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11179
11180static struct snd_kcontrol_new alc262_base_mixer[] = {
11181        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11182        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11183        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11184        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11185        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11186        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11187        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11188        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11189        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11190        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11191        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11192        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11193        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11194        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11195        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11196        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11197        { } /* end */
11198};
11199
11200/* update HP, line and mono-out pins according to the master switch */
11201static void alc262_hp_master_update(struct hda_codec *codec)
11202{
11203        struct alc_spec *spec = codec->spec;
11204        int val = spec->master_sw;
11205
11206        /* HP & line-out */
11207        snd_hda_codec_write_cache(codec, 0x1b, 0,
11208                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
11209                                  val ? PIN_HP : 0);
11210        snd_hda_codec_write_cache(codec, 0x15, 0,
11211                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
11212                                  val ? PIN_HP : 0);
11213        /* mono (speaker) depending on the HP jack sense */
11214        val = val && !spec->jack_present;
11215        snd_hda_codec_write_cache(codec, 0x16, 0,
11216                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
11217                                  val ? PIN_OUT : 0);
11218}
11219
11220static void alc262_hp_bpc_automute(struct hda_codec *codec)
11221{
11222        struct alc_spec *spec = codec->spec;
11223
11224        spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11225        alc262_hp_master_update(codec);
11226}
11227
11228static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11229{
11230        if ((res >> 26) != ALC880_HP_EVENT)
11231                return;
11232        alc262_hp_bpc_automute(codec);
11233}
11234
11235static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11236{
11237        struct alc_spec *spec = codec->spec;
11238
11239        spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11240        alc262_hp_master_update(codec);
11241}
11242
11243static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11244                                           unsigned int res)
11245{
11246        if ((res >> 26) != ALC880_HP_EVENT)
11247                return;
11248        alc262_hp_wildwest_automute(codec);
11249}
11250
11251#define alc262_hp_master_sw_get         alc260_hp_master_sw_get
11252
11253static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11254                                   struct snd_ctl_elem_value *ucontrol)
11255{
11256        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11257        struct alc_spec *spec = codec->spec;
11258        int val = !!*ucontrol->value.integer.value;
11259
11260        if (val == spec->master_sw)
11261                return 0;
11262        spec->master_sw = val;
11263        alc262_hp_master_update(codec);
11264        return 1;
11265}
11266
11267#define ALC262_HP_MASTER_SWITCH                                 \
11268        {                                                       \
11269                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
11270                .name = "Master Playback Switch",               \
11271                .info = snd_ctl_boolean_mono_info,              \
11272                .get = alc262_hp_master_sw_get,                 \
11273                .put = alc262_hp_master_sw_put,                 \
11274        }, \
11275        {                                                       \
11276                .iface = NID_MAPPING,                           \
11277                .name = "Master Playback Switch",               \
11278                .private_value = 0x15 | (0x16 << 8) | (0x1b << 16),     \
11279        }
11280
11281
11282static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11283        ALC262_HP_MASTER_SWITCH,
11284        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11285        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11286        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11287        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11288                              HDA_OUTPUT),
11289        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11290                            HDA_OUTPUT),
11291        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11292        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11293        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11294        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11295        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11296        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11297        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11298        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11299        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11300        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11301        HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11302        HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11303        { } /* end */
11304};
11305
11306static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11307        ALC262_HP_MASTER_SWITCH,
11308        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11309        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11310        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11311        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11312        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11313                              HDA_OUTPUT),
11314        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11315                            HDA_OUTPUT),
11316        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11317        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11318        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11319        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11320        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11321        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11322        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11323        { } /* end */
11324};
11325
11326static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11327        HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328        HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11329        HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11330        { } /* end */
11331};
11332
11333/* mute/unmute internal speaker according to the hp jack and mute state */
11334static void alc262_hp_t5735_setup(struct hda_codec *codec)
11335{
11336        struct alc_spec *spec = codec->spec;
11337
11338        spec->autocfg.hp_pins[0] = 0x15;
11339        spec->autocfg.speaker_pins[0] = 0x14;
11340}
11341
11342static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11343        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11344        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11345        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11346        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11347        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11348        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11349        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11350        { } /* end */
11351};
11352
11353static struct hda_verb alc262_hp_t5735_verbs[] = {
11354        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11355        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11356
11357        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11358        { }
11359};
11360
11361static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11362        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11363        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11364        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11365        HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11366        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11367        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11368        { } /* end */
11369};
11370
11371static struct hda_verb alc262_hp_rp5700_verbs[] = {
11372        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11373        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11374        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11375        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11376        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11377        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11378        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11379        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11380        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11381        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11382        {}
11383};
11384
11385static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11386        .num_items = 1,
11387        .items = {
11388                { "Line", 0x1 },
11389        },
11390};
11391
11392/* bind hp and internal speaker mute (with plug check) as master switch */
11393static void alc262_hippo_master_update(struct hda_codec *codec)
11394{
11395        struct alc_spec *spec = codec->spec;
11396        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11397        hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11398        hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11399        unsigned int mute;
11400
11401        /* HP */
11402        mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11403        snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11404                                 HDA_AMP_MUTE, mute);
11405        /* mute internal speaker per jack sense */
11406        if (spec->jack_present)
11407                mute = HDA_AMP_MUTE;
11408        if (line_nid)
11409                snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11410                                         HDA_AMP_MUTE, mute);
11411        if (speaker_nid && speaker_nid != line_nid)
11412                snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11413                                         HDA_AMP_MUTE, mute);
11414}
11415
11416#define alc262_hippo_master_sw_get      alc262_hp_master_sw_get
11417
11418static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11419                                      struct snd_ctl_elem_value *ucontrol)
11420{
11421        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11422        struct alc_spec *spec = codec->spec;
11423        int val = !!*ucontrol->value.integer.value;
11424
11425        if (val == spec->master_sw)
11426                return 0;
11427        spec->master_sw = val;
11428        alc262_hippo_master_update(codec);
11429        return 1;
11430}
11431
11432#define ALC262_HIPPO_MASTER_SWITCH                              \
11433        {                                                       \
11434                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
11435                .name = "Master Playback Switch",               \
11436                .info = snd_ctl_boolean_mono_info,              \
11437                .get = alc262_hippo_master_sw_get,              \
11438                .put = alc262_hippo_master_sw_put,              \
11439        },                                                      \
11440        {                                                       \
11441                .iface = NID_MAPPING,                           \
11442                .name = "Master Playback Switch",               \
11443                .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11444                             (SUBDEV_SPEAKER(0) << 16), \
11445        }
11446
11447static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11448        ALC262_HIPPO_MASTER_SWITCH,
11449        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11450        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11451        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11452        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11453        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11454        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11455        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11456        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11457        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11458        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11459        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11460        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11461        { } /* end */
11462};
11463
11464static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11465        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11466        ALC262_HIPPO_MASTER_SWITCH,
11467        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11468        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11469        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11470        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11471        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11472        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11473        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11474        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11475        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11476        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11477        { } /* end */
11478};
11479
11480/* mute/unmute internal speaker according to the hp jack and mute state */
11481static void alc262_hippo_automute(struct hda_codec *codec)
11482{
11483        struct alc_spec *spec = codec->spec;
11484        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11485
11486        spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11487        alc262_hippo_master_update(codec);
11488}
11489
11490static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11491{
11492        if ((res >> 26) != ALC880_HP_EVENT)
11493                return;
11494        alc262_hippo_automute(codec);
11495}
11496
11497static void alc262_hippo_setup(struct hda_codec *codec)
11498{
11499        struct alc_spec *spec = codec->spec;
11500
11501        spec->autocfg.hp_pins[0] = 0x15;
11502        spec->autocfg.speaker_pins[0] = 0x14;
11503}
11504
11505static void alc262_hippo1_setup(struct hda_codec *codec)
11506{
11507        struct alc_spec *spec = codec->spec;
11508
11509        spec->autocfg.hp_pins[0] = 0x1b;
11510        spec->autocfg.speaker_pins[0] = 0x14;
11511}
11512
11513
11514static struct snd_kcontrol_new alc262_sony_mixer[] = {
11515        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11516        ALC262_HIPPO_MASTER_SWITCH,
11517        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11518        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11519        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11520        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11521        { } /* end */
11522};
11523
11524static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11525        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11526        ALC262_HIPPO_MASTER_SWITCH,
11527        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11528        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11529        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11530        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11531        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11532        { } /* end */
11533};
11534
11535static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11536        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11537        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11538        HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11539        HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11540        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11541        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11542        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11543        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11544        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11545        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11546        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11547        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11548        { } /* end */
11549};
11550
11551static struct hda_verb alc262_tyan_verbs[] = {
11552        /* Headphone automute */
11553        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11554        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11555        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11556
11557        /* P11 AUX_IN, white 4-pin connector */
11558        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11559        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11560        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11561        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11562
11563        {}
11564};
11565
11566/* unsolicited event for HP jack sensing */
11567static void alc262_tyan_setup(struct hda_codec *codec)
11568{
11569        struct alc_spec *spec = codec->spec;
11570
11571        spec->autocfg.hp_pins[0] = 0x1b;
11572        spec->autocfg.speaker_pins[0] = 0x15;
11573}
11574
11575
11576#define alc262_capture_mixer            alc882_capture_mixer
11577#define alc262_capture_alt_mixer        alc882_capture_alt_mixer
11578
11579/*
11580 * generic initialization of ADC, input mixers and output mixers
11581 */
11582static struct hda_verb alc262_init_verbs[] = {
11583        /*
11584         * Unmute ADC0-2 and set the default input to mic-in
11585         */
11586        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11587        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11588        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11589        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11590        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11591        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11592
11593        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11594         * mixer widget
11595         * Note: PASD motherboards uses the Line In 2 as the input for
11596         * front panel mic (mic 2)
11597         */
11598        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11599        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11600        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11601        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11602        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11603        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11604
11605        /*
11606         * Set up output mixers (0x0c - 0x0e)
11607         */
11608        /* set vol=0 to output mixers */
11609        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11610        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11611        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11612        /* set up input amps for analog loopback */
11613        /* Amp Indices: DAC = 0, mixer = 1 */
11614        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11615        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11616        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11617        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11618        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11619        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11620
11621        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11622        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11623        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11624        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11625        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11626        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11627
11628        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11629        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11630        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11631        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11632        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11633
11634        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11635        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11636
11637        /* FIXME: use matrix-type input source selection */
11638        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11639        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11640        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11641        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11642        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11643        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11644        /* Input mixer2 */
11645        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11646        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11647        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11648        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11649        /* Input mixer3 */
11650        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11651        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11652        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11653        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11654
11655        { }
11656};
11657
11658static struct hda_verb alc262_eapd_verbs[] = {
11659        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11660        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11661        { }
11662};
11663
11664static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11665        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11666        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11667        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11668
11669        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11670        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11671        {}
11672};
11673
11674static struct hda_verb alc262_sony_unsol_verbs[] = {
11675        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11676        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11677        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
11678
11679        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11680        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11681        {}
11682};
11683
11684static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11685        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11686        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11687        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11688        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11689        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11690        { } /* end */
11691};
11692
11693static struct hda_verb alc262_toshiba_s06_verbs[] = {
11694        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11695        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11696        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11697        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11698        {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11699        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11700        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11701        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11702        {}
11703};
11704
11705static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11706{
11707        struct alc_spec *spec = codec->spec;
11708
11709        spec->autocfg.hp_pins[0] = 0x15;
11710        spec->autocfg.speaker_pins[0] = 0x14;
11711        spec->ext_mic.pin = 0x18;
11712        spec->ext_mic.mux_idx = 0;
11713        spec->int_mic.pin = 0x12;
11714        spec->int_mic.mux_idx = 9;
11715        spec->auto_mic = 1;
11716}
11717
11718/*
11719 * nec model
11720 *  0x15 = headphone
11721 *  0x16 = internal speaker
11722 *  0x18 = external mic
11723 */
11724
11725static struct snd_kcontrol_new alc262_nec_mixer[] = {
11726        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11727        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11728
11729        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11730        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11731        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11732
11733        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11734        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11735        { } /* end */
11736};
11737
11738static struct hda_verb alc262_nec_verbs[] = {
11739        /* Unmute Speaker */
11740        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11741
11742        /* Headphone */
11743        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11744        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11745
11746        /* External mic to headphone */
11747        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11748        /* External mic to speaker */
11749        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11750        {}
11751};
11752
11753/*
11754 * fujitsu model
11755 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
11756 *  0x1b = port replicator headphone out
11757 */
11758
11759#define ALC_HP_EVENT    0x37
11760
11761static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11762        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11763        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11764        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11765        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11766        {}
11767};
11768
11769static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11770        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11771        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11772        {}
11773};
11774
11775static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11776        /* Front Mic pin: input vref at 50% */
11777        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11778        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11779        {}
11780};
11781
11782static struct hda_input_mux alc262_fujitsu_capture_source = {
11783        .num_items = 3,
11784        .items = {
11785                { "Mic", 0x0 },
11786                { "Internal Mic", 0x1 },
11787                { "CD", 0x4 },
11788        },
11789};
11790
11791static struct hda_input_mux alc262_HP_capture_source = {
11792        .num_items = 5,
11793        .items = {
11794                { "Mic", 0x0 },
11795                { "Front Mic", 0x1 },
11796                { "Line", 0x2 },
11797                { "CD", 0x4 },
11798                { "AUX IN", 0x6 },
11799        },
11800};
11801
11802static struct hda_input_mux alc262_HP_D7000_capture_source = {
11803        .num_items = 4,
11804        .items = {
11805                { "Mic", 0x0 },
11806                { "Front Mic", 0x2 },
11807                { "Line", 0x1 },
11808                { "CD", 0x4 },
11809        },
11810};
11811
11812/* mute/unmute internal speaker according to the hp jacks and mute state */
11813static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11814{
11815        struct alc_spec *spec = codec->spec;
11816        unsigned int mute;
11817
11818        if (force || !spec->sense_updated) {
11819                spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11820                                     snd_hda_jack_detect(codec, 0x1b);
11821                spec->sense_updated = 1;
11822        }
11823        /* unmute internal speaker only if both HPs are unplugged and
11824         * master switch is on
11825         */
11826        if (spec->jack_present)
11827                mute = HDA_AMP_MUTE;
11828        else
11829                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11830        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11831                                 HDA_AMP_MUTE, mute);
11832}
11833
11834/* unsolicited event for HP jack sensing */
11835static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11836                                       unsigned int res)
11837{
11838        if ((res >> 26) != ALC_HP_EVENT)
11839                return;
11840        alc262_fujitsu_automute(codec, 1);
11841}
11842
11843static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11844{
11845        alc262_fujitsu_automute(codec, 1);
11846}
11847
11848/* bind volumes of both NID 0x0c and 0x0d */
11849static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11850        .ops = &snd_hda_bind_vol,
11851        .values = {
11852                HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11853                HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11854                0
11855        },
11856};
11857
11858/* mute/unmute internal speaker according to the hp jack and mute state */
11859static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11860{
11861        struct alc_spec *spec = codec->spec;
11862        unsigned int mute;
11863
11864        if (force || !spec->sense_updated) {
11865                spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11866                spec->sense_updated = 1;
11867        }
11868        if (spec->jack_present) {
11869                /* mute internal speaker */
11870                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11871                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
11872                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11873                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
11874        } else {
11875                /* unmute internal speaker if necessary */
11876                mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11877                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11878                                         HDA_AMP_MUTE, mute);
11879                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11880                                         HDA_AMP_MUTE, mute);
11881        }
11882}
11883
11884/* unsolicited event for HP jack sensing */
11885static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11886                                       unsigned int res)
11887{
11888        if ((res >> 26) != ALC_HP_EVENT)
11889                return;
11890        alc262_lenovo_3000_automute(codec, 1);
11891}
11892
11893static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11894                                  int dir, int idx, long *valp)
11895{
11896        int i, change = 0;
11897
11898        for (i = 0; i < 2; i++, valp++)
11899                change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11900                                                   HDA_AMP_MUTE,
11901                                                   *valp ? 0 : HDA_AMP_MUTE);
11902        return change;
11903}
11904
11905/* bind hp and internal speaker mute (with plug check) */
11906static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11907                                         struct snd_ctl_elem_value *ucontrol)
11908{
11909        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11910        long *valp = ucontrol->value.integer.value;
11911        int change;
11912
11913        change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11914        change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11915        if (change)
11916                alc262_fujitsu_automute(codec, 0);
11917        return change;
11918}
11919
11920static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11921        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11922        {
11923                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11924                .name = "Master Playback Switch",
11925                .subdevice = HDA_SUBDEV_AMP_FLAG,
11926                .info = snd_hda_mixer_amp_switch_info,
11927                .get = snd_hda_mixer_amp_switch_get,
11928                .put = alc262_fujitsu_master_sw_put,
11929                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11930        },
11931        {
11932                .iface = NID_MAPPING,
11933                .name = "Master Playback Switch",
11934                .private_value = 0x1b,
11935        },
11936        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11937        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11938        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11939        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11940        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11941        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11942        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11943        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11944        { } /* end */
11945};
11946
11947/* bind hp and internal speaker mute (with plug check) */
11948static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11949                                         struct snd_ctl_elem_value *ucontrol)
11950{
11951        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11952        long *valp = ucontrol->value.integer.value;
11953        int change;
11954
11955        change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11956        if (change)
11957                alc262_lenovo_3000_automute(codec, 0);
11958        return change;
11959}
11960
11961static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11962        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11963        {
11964                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11965                .name = "Master Playback Switch",
11966                .subdevice = HDA_SUBDEV_AMP_FLAG,
11967                .info = snd_hda_mixer_amp_switch_info,
11968                .get = snd_hda_mixer_amp_switch_get,
11969                .put = alc262_lenovo_3000_master_sw_put,
11970                .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11971        },
11972        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11973        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11974        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11975        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11976        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11977        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11978        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11979        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11980        { } /* end */
11981};
11982
11983static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11984        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11985        ALC262_HIPPO_MASTER_SWITCH,
11986        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11987        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11988        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11989        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11990        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11991        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11992        { } /* end */
11993};
11994
11995/* additional init verbs for Benq laptops */
11996static struct hda_verb alc262_EAPD_verbs[] = {
11997        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11998        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
11999        {}
12000};
12001
12002static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12003        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12004        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12005
12006        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12007        {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
12008        {}
12009};
12010
12011/* Samsung Q1 Ultra Vista model setup */
12012static struct snd_kcontrol_new alc262_ultra_mixer[] = {
12013        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12014        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12015        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12016        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12017        HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12018        HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12019        { } /* end */
12020};
12021
12022static struct hda_verb alc262_ultra_verbs[] = {
12023        /* output mixer */
12024        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12025        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12026        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12027        /* speaker */
12028        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12029        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12030        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12031        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12032        /* HP */
12033        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12034        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12035        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12036        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12037        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12038        /* internal mic */
12039        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12040        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12041        /* ADC, choose mic */
12042        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12043        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12044        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12045        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12046        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12047        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12048        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12049        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12050        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12051        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12052        {}
12053};
12054
12055/* mute/unmute internal speaker according to the hp jack and mute state */
12056static void alc262_ultra_automute(struct hda_codec *codec)
12057{
12058        struct alc_spec *spec = codec->spec;
12059        unsigned int mute;
12060
12061        mute = 0;
12062        /* auto-mute only when HP is used as HP */
12063        if (!spec->cur_mux[0]) {
12064                spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12065                if (spec->jack_present)
12066                        mute = HDA_AMP_MUTE;
12067        }
12068        /* mute/unmute internal speaker */
12069        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12070                                 HDA_AMP_MUTE, mute);
12071        /* mute/unmute HP */
12072        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12073                                 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12074}
12075
12076/* unsolicited event for HP jack sensing */
12077static void alc262_ultra_unsol_event(struct hda_codec *codec,
12078                                       unsigned int res)
12079{
12080        if ((res >> 26) != ALC880_HP_EVENT)
12081                return;
12082        alc262_ultra_automute(codec);
12083}
12084
12085static struct hda_input_mux alc262_ultra_capture_source = {
12086        .num_items = 2,
12087        .items = {
12088                { "Mic", 0x1 },
12089                { "Headphone", 0x7 },
12090        },
12091};
12092
12093static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12094                                     struct snd_ctl_elem_value *ucontrol)
12095{
12096        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12097        struct alc_spec *spec = codec->spec;
12098        int ret;
12099
12100        ret = alc_mux_enum_put(kcontrol, ucontrol);
12101        if (!ret)
12102                return 0;
12103        /* reprogram the HP pin as mic or HP according to the input source */
12104        snd_hda_codec_write_cache(codec, 0x15, 0,
12105                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
12106                                  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12107        alc262_ultra_automute(codec); /* mute/unmute HP */
12108        return ret;
12109}
12110
12111static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12112        HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12113        HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12114        {
12115                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12116                .name = "Capture Source",
12117                .info = alc_mux_enum_info,
12118                .get = alc_mux_enum_get,
12119                .put = alc262_ultra_mux_enum_put,
12120        },
12121        {
12122                .iface = NID_MAPPING,
12123                .name = "Capture Source",
12124                .private_value = 0x15,
12125        },
12126        { } /* end */
12127};
12128
12129/* We use two mixers depending on the output pin; 0x16 is a mono output
12130 * and thus it's bound with a different mixer.
12131 * This function returns which mixer amp should be used.
12132 */
12133static int alc262_check_volbit(hda_nid_t nid)
12134{
12135        if (!nid)
12136                return 0;
12137        else if (nid == 0x16)
12138                return 2;
12139        else
12140                return 1;
12141}
12142
12143static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12144                                  const char *pfx, int *vbits, int idx)
12145{
12146        unsigned long val;
12147        int vbit;
12148
12149        vbit = alc262_check_volbit(nid);
12150        if (!vbit)
12151                return 0;
12152        if (*vbits & vbit) /* a volume control for this mixer already there */
12153                return 0;
12154        *vbits |= vbit;
12155        if (vbit == 2)
12156                val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12157        else
12158                val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12159        return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12160}
12161
12162static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12163                                 const char *pfx, int idx)
12164{
12165        unsigned long val;
12166
12167        if (!nid)
12168                return 0;
12169        if (nid == 0x16)
12170                val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12171        else
12172                val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12173        return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12174}
12175
12176/* add playback controls from the parsed DAC table */
12177static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12178                                             const struct auto_pin_cfg *cfg)
12179{
12180        const char *pfx;
12181        int vbits;
12182        int i, err;
12183
12184        spec->multiout.num_dacs = 1;    /* only use one dac */
12185        spec->multiout.dac_nids = spec->private_dac_nids;
12186        spec->multiout.dac_nids[0] = 2;
12187
12188        pfx = alc_get_line_out_pfx(cfg, true);
12189        if (!pfx)
12190                pfx = "Front";
12191        for (i = 0; i < 2; i++) {
12192                err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12193                if (err < 0)
12194                        return err;
12195                if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12196                        err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12197                                                    "Speaker", i);
12198                        if (err < 0)
12199                                return err;
12200                }
12201                if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12202                        err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12203                                                    "Headphone", i);
12204                        if (err < 0)
12205                                return err;
12206                }
12207        }
12208
12209        vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12210                alc262_check_volbit(cfg->speaker_pins[0]) |
12211                alc262_check_volbit(cfg->hp_pins[0]);
12212        if (vbits == 1 || vbits == 2)
12213                pfx = "Master"; /* only one mixer is used */
12214        vbits = 0;
12215        for (i = 0; i < 2; i++) {
12216                err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12217                                             &vbits, i);
12218                if (err < 0)
12219                        return err;
12220                if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12221                        err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12222                                                     "Speaker", &vbits, i);
12223                        if (err < 0)
12224                                return err;
12225                }
12226                if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12227                        err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12228                                                     "Headphone", &vbits, i);
12229                        if (err < 0)
12230                                return err;
12231                }
12232        }
12233        return 0;
12234}
12235
12236#define alc262_auto_create_input_ctls \
12237        alc882_auto_create_input_ctls
12238
12239/*
12240 * generic initialization of ADC, input mixers and output mixers
12241 */
12242static struct hda_verb alc262_volume_init_verbs[] = {
12243        /*
12244         * Unmute ADC0-2 and set the default input to mic-in
12245         */
12246        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12247        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12248        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12249        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12250        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12251        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12252
12253        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12254         * mixer widget
12255         * Note: PASD motherboards uses the Line In 2 as the input for
12256         * front panel mic (mic 2)
12257         */
12258        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12259        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12260        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12261        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12262        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12263        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12264
12265        /*
12266         * Set up output mixers (0x0c - 0x0f)
12267         */
12268        /* set vol=0 to output mixers */
12269        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12270        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12271        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12272
12273        /* set up input amps for analog loopback */
12274        /* Amp Indices: DAC = 0, mixer = 1 */
12275        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12276        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12277        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12278        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12279        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12280        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12281
12282        /* FIXME: use matrix-type input source selection */
12283        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12284        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12285        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12286        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12287        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12288        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12289        /* Input mixer2 */
12290        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12291        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12292        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12293        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12294        /* Input mixer3 */
12295        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12296        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12297        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12298        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12299
12300        { }
12301};
12302
12303static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12304        /*
12305         * Unmute ADC0-2 and set the default input to mic-in
12306         */
12307        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12308        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12309        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12310        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12311        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12312        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12313
12314        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12315         * mixer widget
12316         * Note: PASD motherboards uses the Line In 2 as the input for
12317         * front panel mic (mic 2)
12318         */
12319        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12320        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12321        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12322        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12323        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12324        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12325        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12326        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12327
12328        /*
12329         * Set up output mixers (0x0c - 0x0e)
12330         */
12331        /* set vol=0 to output mixers */
12332        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12333        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12334        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12335
12336        /* set up input amps for analog loopback */
12337        /* Amp Indices: DAC = 0, mixer = 1 */
12338        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12339        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12340        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12341        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12342        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12343        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12344
12345        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12346        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12347        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12348
12349        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12350        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12351
12352        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12353        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12354
12355        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12356        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12357        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12358        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12359        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12360
12361        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12362        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12363        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12364        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12365        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12366        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12367
12368
12369        /* FIXME: use matrix-type input source selection */
12370        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12371        /* Input mixer1: only unmute Mic */
12372        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12373        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12374        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12376        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12377        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12378        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12379        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12380        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12381        /* Input mixer2 */
12382        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12383        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12384        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12385        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12386        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12387        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12388        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12389        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12390        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12391        /* Input mixer3 */
12392        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12393        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12394        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12395        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12396        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12397        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12398        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12399        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12400        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12401
12402        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12403
12404        { }
12405};
12406
12407static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12408        /*
12409         * Unmute ADC0-2 and set the default input to mic-in
12410         */
12411        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12412        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12413        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12414        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12416        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417
12418        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12419         * mixer widget
12420         * Note: PASD motherboards uses the Line In 2 as the input for front
12421         * panel mic (mic 2)
12422         */
12423        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12424        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12425        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12426        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12427        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12428        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12429        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12430        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12431        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12432        /*
12433         * Set up output mixers (0x0c - 0x0e)
12434         */
12435        /* set vol=0 to output mixers */
12436        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12437        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12438        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12439
12440        /* set up input amps for analog loopback */
12441        /* Amp Indices: DAC = 0, mixer = 1 */
12442        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12443        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12444        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12445        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12446        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12447        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12448
12449
12450        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
12451        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
12452        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
12453        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
12454        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
12455        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
12456        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
12457
12458        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12459        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12460
12461        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12462        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12463
12464        /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12465        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12466        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12467        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12468        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12469        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12470
12471        /* FIXME: use matrix-type input source selection */
12472        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12473        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12474        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12475        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12476        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12477        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12478        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12479        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
12480        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12481        /* Input mixer2 */
12482        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12483        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12484        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12485        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12486        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12487        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12488        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12489        /* Input mixer3 */
12490        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12491        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12492        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12493        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12494        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12495        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12496        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12497
12498        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12499
12500        { }
12501};
12502
12503static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12504
12505        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Front Speaker */
12506        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12507        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12508
12509        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* MIC jack */
12510        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
12511        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12512        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12513
12514        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP  jack */
12515        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12516        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12517        {}
12518};
12519
12520/*
12521 * Pin config fixes
12522 */
12523enum {
12524        PINFIX_FSC_H270,
12525};
12526
12527static const struct alc_fixup alc262_fixups[] = {
12528        [PINFIX_FSC_H270] = {
12529                .type = ALC_FIXUP_PINS,
12530                .v.pins = (const struct alc_pincfg[]) {
12531                        { 0x14, 0x99130110 }, /* speaker */
12532                        { 0x15, 0x0221142f }, /* front HP */
12533                        { 0x1b, 0x0121141f }, /* rear HP */
12534                        { }
12535                }
12536        },
12537};
12538
12539static struct snd_pci_quirk alc262_fixup_tbl[] = {
12540        SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12541        {}
12542};
12543
12544
12545#ifdef CONFIG_SND_HDA_POWER_SAVE
12546#define alc262_loopbacks        alc880_loopbacks
12547#endif
12548
12549/* pcm configuration: identical with ALC880 */
12550#define alc262_pcm_analog_playback      alc880_pcm_analog_playback
12551#define alc262_pcm_analog_capture       alc880_pcm_analog_capture
12552#define alc262_pcm_digital_playback     alc880_pcm_digital_playback
12553#define alc262_pcm_digital_capture      alc880_pcm_digital_capture
12554
12555/*
12556 * BIOS auto configuration
12557 */
12558static int alc262_parse_auto_config(struct hda_codec *codec)
12559{
12560        struct alc_spec *spec = codec->spec;
12561        int err;
12562        static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12563
12564        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12565                                           alc262_ignore);
12566        if (err < 0)
12567                return err;
12568        if (!spec->autocfg.line_outs) {
12569                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12570                        spec->multiout.max_channels = 2;
12571                        spec->no_analog = 1;
12572                        goto dig_only;
12573                }
12574                return 0; /* can't find valid BIOS pin config */
12575        }
12576        err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12577        if (err < 0)
12578                return err;
12579        err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12580        if (err < 0)
12581                return err;
12582
12583        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12584
12585 dig_only:
12586        alc_auto_parse_digital(codec);
12587
12588        if (spec->kctls.list)
12589                add_mixer(spec, spec->kctls.list);
12590
12591        add_verb(spec, alc262_volume_init_verbs);
12592        spec->num_mux_defs = 1;
12593        spec->input_mux = &spec->private_imux[0];
12594
12595        err = alc_auto_add_mic_boost(codec);
12596        if (err < 0)
12597                return err;
12598
12599        alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12600
12601        return 1;
12602}
12603
12604#define alc262_auto_init_multi_out      alc882_auto_init_multi_out
12605#define alc262_auto_init_hp_out         alc882_auto_init_hp_out
12606#define alc262_auto_init_analog_input   alc882_auto_init_analog_input
12607#define alc262_auto_init_input_src      alc882_auto_init_input_src
12608
12609
12610/* init callback for auto-configuration model -- overriding the default init */
12611static void alc262_auto_init(struct hda_codec *codec)
12612{
12613        struct alc_spec *spec = codec->spec;
12614        alc262_auto_init_multi_out(codec);
12615        alc262_auto_init_hp_out(codec);
12616        alc262_auto_init_analog_input(codec);
12617        alc262_auto_init_input_src(codec);
12618        alc_auto_init_digital(codec);
12619        if (spec->unsol_event)
12620                alc_inithook(codec);
12621}
12622
12623/*
12624 * configuration and preset
12625 */
12626static const char * const alc262_models[ALC262_MODEL_LAST] = {
12627        [ALC262_BASIC]          = "basic",
12628        [ALC262_HIPPO]          = "hippo",
12629        [ALC262_HIPPO_1]        = "hippo_1",
12630        [ALC262_FUJITSU]        = "fujitsu",
12631        [ALC262_HP_BPC]         = "hp-bpc",
12632        [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12633        [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
12634        [ALC262_HP_RP5700]      = "hp-rp5700",
12635        [ALC262_BENQ_ED8]       = "benq",
12636        [ALC262_BENQ_T31]       = "benq-t31",
12637        [ALC262_SONY_ASSAMD]    = "sony-assamd",
12638        [ALC262_TOSHIBA_S06]    = "toshiba-s06",
12639        [ALC262_TOSHIBA_RX1]    = "toshiba-rx1",
12640        [ALC262_ULTRA]          = "ultra",
12641        [ALC262_LENOVO_3000]    = "lenovo-3000",
12642        [ALC262_NEC]            = "nec",
12643        [ALC262_TYAN]           = "tyan",
12644        [ALC262_AUTO]           = "auto",
12645};
12646
12647static struct snd_pci_quirk alc262_cfg_tbl[] = {
12648        SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12649        SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12650        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12651                           ALC262_HP_BPC),
12652        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12653                           ALC262_HP_BPC),
12654        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12655                           ALC262_HP_BPC),
12656        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12657                           ALC262_HP_BPC),
12658        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12659        SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12660        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12661        SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12662        SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12663        SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12664        SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12665        SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12666        SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12667        SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12668        SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12669        SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12670                      ALC262_HP_TC_T5735),
12671        SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12672        SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12673        SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12674        SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12675        SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12676        SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12677        SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12678        SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12679#if 0 /* disable the quirk since model=auto works better in recent versions */
12680        SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12681                           ALC262_SONY_ASSAMD),
12682#endif
12683        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12684                      ALC262_TOSHIBA_RX1),
12685        SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12686        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12687        SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12688        SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12689        SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12690                           ALC262_ULTRA),
12691        SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12692        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12693        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12694        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12695        SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12696        {}
12697};
12698
12699static struct alc_config_preset alc262_presets[] = {
12700        [ALC262_BASIC] = {
12701                .mixers = { alc262_base_mixer },
12702                .init_verbs = { alc262_init_verbs },
12703                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12704                .dac_nids = alc262_dac_nids,
12705                .hp_nid = 0x03,
12706                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12707                .channel_mode = alc262_modes,
12708                .input_mux = &alc262_capture_source,
12709        },
12710        [ALC262_HIPPO] = {
12711                .mixers = { alc262_hippo_mixer },
12712                .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12713                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12714                .dac_nids = alc262_dac_nids,
12715                .hp_nid = 0x03,
12716                .dig_out_nid = ALC262_DIGOUT_NID,
12717                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12718                .channel_mode = alc262_modes,
12719                .input_mux = &alc262_capture_source,
12720                .unsol_event = alc262_hippo_unsol_event,
12721                .setup = alc262_hippo_setup,
12722                .init_hook = alc262_hippo_automute,
12723        },
12724        [ALC262_HIPPO_1] = {
12725                .mixers = { alc262_hippo1_mixer },
12726                .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12727                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12728                .dac_nids = alc262_dac_nids,
12729                .hp_nid = 0x02,
12730                .dig_out_nid = ALC262_DIGOUT_NID,
12731                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12732                .channel_mode = alc262_modes,
12733                .input_mux = &alc262_capture_source,
12734                .unsol_event = alc262_hippo_unsol_event,
12735                .setup = alc262_hippo1_setup,
12736                .init_hook = alc262_hippo_automute,
12737        },
12738        [ALC262_FUJITSU] = {
12739                .mixers = { alc262_fujitsu_mixer },
12740                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12741                                alc262_fujitsu_unsol_verbs },
12742                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12743                .dac_nids = alc262_dac_nids,
12744                .hp_nid = 0x03,
12745                .dig_out_nid = ALC262_DIGOUT_NID,
12746                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12747                .channel_mode = alc262_modes,
12748                .input_mux = &alc262_fujitsu_capture_source,
12749                .unsol_event = alc262_fujitsu_unsol_event,
12750                .init_hook = alc262_fujitsu_init_hook,
12751        },
12752        [ALC262_HP_BPC] = {
12753                .mixers = { alc262_HP_BPC_mixer },
12754                .init_verbs = { alc262_HP_BPC_init_verbs },
12755                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12756                .dac_nids = alc262_dac_nids,
12757                .hp_nid = 0x03,
12758                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12759                .channel_mode = alc262_modes,
12760                .input_mux = &alc262_HP_capture_source,
12761                .unsol_event = alc262_hp_bpc_unsol_event,
12762                .init_hook = alc262_hp_bpc_automute,
12763        },
12764        [ALC262_HP_BPC_D7000_WF] = {
12765                .mixers = { alc262_HP_BPC_WildWest_mixer },
12766                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12767                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12768                .dac_nids = alc262_dac_nids,
12769                .hp_nid = 0x03,
12770                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12771                .channel_mode = alc262_modes,
12772                .input_mux = &alc262_HP_D7000_capture_source,
12773                .unsol_event = alc262_hp_wildwest_unsol_event,
12774                .init_hook = alc262_hp_wildwest_automute,
12775        },
12776        [ALC262_HP_BPC_D7000_WL] = {
12777                .mixers = { alc262_HP_BPC_WildWest_mixer,
12778                            alc262_HP_BPC_WildWest_option_mixer },
12779                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12780                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12781                .dac_nids = alc262_dac_nids,
12782                .hp_nid = 0x03,
12783                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784                .channel_mode = alc262_modes,
12785                .input_mux = &alc262_HP_D7000_capture_source,
12786                .unsol_event = alc262_hp_wildwest_unsol_event,
12787                .init_hook = alc262_hp_wildwest_automute,
12788        },
12789        [ALC262_HP_TC_T5735] = {
12790                .mixers = { alc262_hp_t5735_mixer },
12791                .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12792                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12793                .dac_nids = alc262_dac_nids,
12794                .hp_nid = 0x03,
12795                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12796                .channel_mode = alc262_modes,
12797                .input_mux = &alc262_capture_source,
12798                .unsol_event = alc_sku_unsol_event,
12799                .setup = alc262_hp_t5735_setup,
12800                .init_hook = alc_inithook,
12801        },
12802        [ALC262_HP_RP5700] = {
12803                .mixers = { alc262_hp_rp5700_mixer },
12804                .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12805                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12806                .dac_nids = alc262_dac_nids,
12807                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808                .channel_mode = alc262_modes,
12809                .input_mux = &alc262_hp_rp5700_capture_source,
12810        },
12811        [ALC262_BENQ_ED8] = {
12812                .mixers = { alc262_base_mixer },
12813                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12814                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815                .dac_nids = alc262_dac_nids,
12816                .hp_nid = 0x03,
12817                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12818                .channel_mode = alc262_modes,
12819                .input_mux = &alc262_capture_source,
12820        },
12821        [ALC262_SONY_ASSAMD] = {
12822                .mixers = { alc262_sony_mixer },
12823                .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12824                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12825                .dac_nids = alc262_dac_nids,
12826                .hp_nid = 0x02,
12827                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12828                .channel_mode = alc262_modes,
12829                .input_mux = &alc262_capture_source,
12830                .unsol_event = alc262_hippo_unsol_event,
12831                .setup = alc262_hippo_setup,
12832                .init_hook = alc262_hippo_automute,
12833        },
12834        [ALC262_BENQ_T31] = {
12835                .mixers = { alc262_benq_t31_mixer },
12836                .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12837                                alc_hp15_unsol_verbs },
12838                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12839                .dac_nids = alc262_dac_nids,
12840                .hp_nid = 0x03,
12841                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12842                .channel_mode = alc262_modes,
12843                .input_mux = &alc262_capture_source,
12844                .unsol_event = alc262_hippo_unsol_event,
12845                .setup = alc262_hippo_setup,
12846                .init_hook = alc262_hippo_automute,
12847        },
12848        [ALC262_ULTRA] = {
12849                .mixers = { alc262_ultra_mixer },
12850                .cap_mixer = alc262_ultra_capture_mixer,
12851                .init_verbs = { alc262_ultra_verbs },
12852                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12853                .dac_nids = alc262_dac_nids,
12854                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12855                .channel_mode = alc262_modes,
12856                .input_mux = &alc262_ultra_capture_source,
12857                .adc_nids = alc262_adc_nids, /* ADC0 */
12858                .capsrc_nids = alc262_capsrc_nids,
12859                .num_adc_nids = 1, /* single ADC */
12860                .unsol_event = alc262_ultra_unsol_event,
12861                .init_hook = alc262_ultra_automute,
12862        },
12863        [ALC262_LENOVO_3000] = {
12864                .mixers = { alc262_lenovo_3000_mixer },
12865                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12866                                alc262_lenovo_3000_unsol_verbs,
12867                                alc262_lenovo_3000_init_verbs },
12868                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12869                .dac_nids = alc262_dac_nids,
12870                .hp_nid = 0x03,
12871                .dig_out_nid = ALC262_DIGOUT_NID,
12872                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12873                .channel_mode = alc262_modes,
12874                .input_mux = &alc262_fujitsu_capture_source,
12875                .unsol_event = alc262_lenovo_3000_unsol_event,
12876        },
12877        [ALC262_NEC] = {
12878                .mixers = { alc262_nec_mixer },
12879                .init_verbs = { alc262_nec_verbs },
12880                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12881                .dac_nids = alc262_dac_nids,
12882                .hp_nid = 0x03,
12883                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12884                .channel_mode = alc262_modes,
12885                .input_mux = &alc262_capture_source,
12886        },
12887        [ALC262_TOSHIBA_S06] = {
12888                .mixers = { alc262_toshiba_s06_mixer },
12889                .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12890                                                        alc262_eapd_verbs },
12891                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12892                .capsrc_nids = alc262_dmic_capsrc_nids,
12893                .dac_nids = alc262_dac_nids,
12894                .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12895                .num_adc_nids = 1, /* single ADC */
12896                .dig_out_nid = ALC262_DIGOUT_NID,
12897                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12898                .channel_mode = alc262_modes,
12899                .unsol_event = alc_sku_unsol_event,
12900                .setup = alc262_toshiba_s06_setup,
12901                .init_hook = alc_inithook,
12902        },
12903        [ALC262_TOSHIBA_RX1] = {
12904                .mixers = { alc262_toshiba_rx1_mixer },
12905                .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12906                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12907                .dac_nids = alc262_dac_nids,
12908                .hp_nid = 0x03,
12909                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12910                .channel_mode = alc262_modes,
12911                .input_mux = &alc262_capture_source,
12912                .unsol_event = alc262_hippo_unsol_event,
12913                .setup = alc262_hippo_setup,
12914                .init_hook = alc262_hippo_automute,
12915        },
12916        [ALC262_TYAN] = {
12917                .mixers = { alc262_tyan_mixer },
12918                .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12919                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12920                .dac_nids = alc262_dac_nids,
12921                .hp_nid = 0x02,
12922                .dig_out_nid = ALC262_DIGOUT_NID,
12923                .num_channel_mode = ARRAY_SIZE(alc262_modes),
12924                .channel_mode = alc262_modes,
12925                .input_mux = &alc262_capture_source,
12926                .unsol_event = alc_automute_amp_unsol_event,
12927                .setup = alc262_tyan_setup,
12928                .init_hook = alc_automute_amp,
12929        },
12930};
12931
12932static int patch_alc262(struct hda_codec *codec)
12933{
12934        struct alc_spec *spec;
12935        int board_config;
12936        int err;
12937
12938        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12939        if (spec == NULL)
12940                return -ENOMEM;
12941
12942        codec->spec = spec;
12943#if 0
12944        /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
12945         * under-run
12946         */
12947        {
12948        int tmp;
12949        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12950        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12951        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12952        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12953        }
12954#endif
12955        alc_auto_parse_customize_define(codec);
12956
12957        alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12958
12959        board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12960                                                  alc262_models,
12961                                                  alc262_cfg_tbl);
12962
12963        if (board_config < 0) {
12964                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12965                       codec->chip_name);
12966                board_config = ALC262_AUTO;
12967        }
12968
12969        if (board_config == ALC262_AUTO) {
12970                alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12971                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12972        }
12973
12974        if (board_config == ALC262_AUTO) {
12975                /* automatic parse from the BIOS config */
12976                err = alc262_parse_auto_config(codec);
12977                if (err < 0) {
12978                        alc_free(codec);
12979                        return err;
12980                } else if (!err) {
12981                        printk(KERN_INFO
12982                               "hda_codec: Cannot set up configuration "
12983                               "from BIOS.  Using base mode...\n");
12984                        board_config = ALC262_BASIC;
12985                }
12986        }
12987
12988        if (!spec->no_analog && has_cdefine_beep(codec)) {
12989                err = snd_hda_attach_beep_device(codec, 0x1);
12990                if (err < 0) {
12991                        alc_free(codec);
12992                        return err;
12993                }
12994        }
12995
12996        if (board_config != ALC262_AUTO)
12997                setup_preset(codec, &alc262_presets[board_config]);
12998
12999        spec->stream_analog_playback = &alc262_pcm_analog_playback;
13000        spec->stream_analog_capture = &alc262_pcm_analog_capture;
13001
13002        spec->stream_digital_playback = &alc262_pcm_digital_playback;
13003        spec->stream_digital_capture = &alc262_pcm_digital_capture;
13004
13005        if (!spec->adc_nids && spec->input_mux) {
13006                int i;
13007                /* check whether the digital-mic has to be supported */
13008                for (i = 0; i < spec->input_mux->num_items; i++) {
13009                        if (spec->input_mux->items[i].index >= 9)
13010                                break;
13011                }
13012                if (i < spec->input_mux->num_items) {
13013                        /* use only ADC0 */
13014                        spec->adc_nids = alc262_dmic_adc_nids;
13015                        spec->num_adc_nids = 1;
13016                        spec->capsrc_nids = alc262_dmic_capsrc_nids;
13017                } else {
13018                        /* all analog inputs */
13019                        /* check whether NID 0x07 is valid */
13020                        unsigned int wcap = get_wcaps(codec, 0x07);
13021
13022                        /* get type */
13023                        wcap = get_wcaps_type(wcap);
13024                        if (wcap != AC_WID_AUD_IN) {
13025                                spec->adc_nids = alc262_adc_nids_alt;
13026                                spec->num_adc_nids =
13027                                        ARRAY_SIZE(alc262_adc_nids_alt);
13028                                spec->capsrc_nids = alc262_capsrc_nids_alt;
13029                        } else {
13030                                spec->adc_nids = alc262_adc_nids;
13031                                spec->num_adc_nids =
13032                                        ARRAY_SIZE(alc262_adc_nids);
13033                                spec->capsrc_nids = alc262_capsrc_nids;
13034                        }
13035                }
13036        }
13037        if (!spec->cap_mixer && !spec->no_analog)
13038                set_capture_mixer(codec);
13039        if (!spec->no_analog && has_cdefine_beep(codec))
13040                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13041
13042        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13043
13044        spec->vmaster_nid = 0x0c;
13045
13046        codec->patch_ops = alc_patch_ops;
13047        if (board_config == ALC262_AUTO)
13048                spec->init_hook = alc262_auto_init;
13049
13050        alc_init_jacks(codec);
13051#ifdef CONFIG_SND_HDA_POWER_SAVE
13052        if (!spec->loopback.amplist)
13053                spec->loopback.amplist = alc262_loopbacks;
13054#endif
13055
13056        return 0;
13057}
13058
13059/*
13060 *  ALC268 channel source setting (2 channel)
13061 */
13062#define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
13063#define alc268_modes            alc260_modes
13064
13065static hda_nid_t alc268_dac_nids[2] = {
13066        /* front, hp */
13067        0x02, 0x03
13068};
13069
13070static hda_nid_t alc268_adc_nids[2] = {
13071        /* ADC0-1 */
13072        0x08, 0x07
13073};
13074
13075static hda_nid_t alc268_adc_nids_alt[1] = {
13076        /* ADC0 */
13077        0x08
13078};
13079
13080static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13081
13082static struct snd_kcontrol_new alc268_base_mixer[] = {
13083        /* output mixer control */
13084        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13085        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13086        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13087        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13088        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13089        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13090        HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13091        { }
13092};
13093
13094static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13095        /* output mixer control */
13096        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13097        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13098        ALC262_HIPPO_MASTER_SWITCH,
13099        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13100        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13101        HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13102        { }
13103};
13104
13105/* bind Beep switches of both NID 0x0f and 0x10 */
13106static struct hda_bind_ctls alc268_bind_beep_sw = {
13107        .ops = &snd_hda_bind_sw,
13108        .values = {
13109                HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13110                HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13111                0
13112        },
13113};
13114
13115static struct snd_kcontrol_new alc268_beep_mixer[] = {
13116        HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13117        HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13118        { }
13119};
13120
13121static struct hda_verb alc268_eapd_verbs[] = {
13122        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13123        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13124        { }
13125};
13126
13127/* Toshiba specific */
13128static struct hda_verb alc268_toshiba_verbs[] = {
13129        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13130        { } /* end */
13131};
13132
13133/* Acer specific */
13134/* bind volumes of both NID 0x02 and 0x03 */
13135static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13136        .ops = &snd_hda_bind_vol,
13137        .values = {
13138                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13139                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13140                0
13141        },
13142};
13143
13144/* mute/unmute internal speaker according to the hp jack and mute state */
13145static void alc268_acer_automute(struct hda_codec *codec, int force)
13146{
13147        struct alc_spec *spec = codec->spec;
13148        unsigned int mute;
13149
13150        if (force || !spec->sense_updated) {
13151                spec->jack_present = snd_hda_jack_detect(codec, 0x14);
13152                spec->sense_updated = 1;
13153        }
13154        if (spec->jack_present)
13155                mute = HDA_AMP_MUTE; /* mute internal speaker */
13156        else /* unmute internal speaker if necessary */
13157                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13158        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13159                                 HDA_AMP_MUTE, mute);
13160}
13161
13162
13163/* bind hp and internal speaker mute (with plug check) */
13164static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13165                                     struct snd_ctl_elem_value *ucontrol)
13166{
13167        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13168        long *valp = ucontrol->value.integer.value;
13169        int change;
13170
13171        change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13172        if (change)
13173                alc268_acer_automute(codec, 0);
13174        return change;
13175}
13176
13177static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13178        /* output mixer control */
13179        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13180        {
13181                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13182                .name = "Master Playback Switch",
13183                .subdevice = HDA_SUBDEV_AMP_FLAG,
13184                .info = snd_hda_mixer_amp_switch_info,
13185                .get = snd_hda_mixer_amp_switch_get,
13186                .put = alc268_acer_master_sw_put,
13187                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13188        },
13189        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13190        { }
13191};
13192
13193static struct snd_kcontrol_new alc268_acer_mixer[] = {
13194        /* output mixer control */
13195        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13196        {
13197                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13198                .name = "Master Playback Switch",
13199                .subdevice = HDA_SUBDEV_AMP_FLAG,
13200                .info = snd_hda_mixer_amp_switch_info,
13201                .get = snd_hda_mixer_amp_switch_get,
13202                .put = alc268_acer_master_sw_put,
13203                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13204        },
13205        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13206        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13207        HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13208        { }
13209};
13210
13211static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13212        /* output mixer control */
13213        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13214        {
13215                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13216                .name = "Master Playback Switch",
13217                .subdevice = HDA_SUBDEV_AMP_FLAG,
13218                .info = snd_hda_mixer_amp_switch_info,
13219                .get = snd_hda_mixer_amp_switch_get,
13220                .put = alc268_acer_master_sw_put,
13221                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13222        },
13223        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13224        HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13225        { }
13226};
13227
13228static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13229        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13230        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13231        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13232        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13233        {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13234        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13235        { }
13236};
13237
13238static struct hda_verb alc268_acer_verbs[] = {
13239        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13240        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13241        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13242        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13243        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13244        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13245        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13246        { }
13247};
13248
13249/* unsolicited event for HP jack sensing */
13250#define alc268_toshiba_unsol_event      alc262_hippo_unsol_event
13251#define alc268_toshiba_setup            alc262_hippo_setup
13252#define alc268_toshiba_automute         alc262_hippo_automute
13253
13254static void alc268_acer_unsol_event(struct hda_codec *codec,
13255                                       unsigned int res)
13256{
13257        if ((res >> 26) != ALC880_HP_EVENT)
13258                return;
13259        alc268_acer_automute(codec, 1);
13260}
13261
13262static void alc268_acer_init_hook(struct hda_codec *codec)
13263{
13264        alc268_acer_automute(codec, 1);
13265}
13266
13267/* toggle speaker-output according to the hp-jack state */
13268static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13269{
13270        unsigned int present;
13271        unsigned char bits;
13272
13273        present = snd_hda_jack_detect(codec, 0x15);
13274        bits = present ? HDA_AMP_MUTE : 0;
13275        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13276                                 HDA_AMP_MUTE, bits);
13277        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13278                                 HDA_AMP_MUTE, bits);
13279}
13280
13281static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13282                                    unsigned int res)
13283{
13284        switch (res >> 26) {
13285        case ALC880_HP_EVENT:
13286                alc268_aspire_one_speaker_automute(codec);
13287                break;
13288        case ALC880_MIC_EVENT:
13289                alc_mic_automute(codec);
13290                break;
13291        }
13292}
13293
13294static void alc268_acer_lc_setup(struct hda_codec *codec)
13295{
13296        struct alc_spec *spec = codec->spec;
13297        spec->ext_mic.pin = 0x18;
13298        spec->ext_mic.mux_idx = 0;
13299        spec->int_mic.pin = 0x12;
13300        spec->int_mic.mux_idx = 6;
13301        spec->auto_mic = 1;
13302}
13303
13304static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13305{
13306        alc268_aspire_one_speaker_automute(codec);
13307        alc_mic_automute(codec);
13308}
13309
13310static struct snd_kcontrol_new alc268_dell_mixer[] = {
13311        /* output mixer control */
13312        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13313        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13314        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13315        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13316        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13317        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13318        { }
13319};
13320
13321static struct hda_verb alc268_dell_verbs[] = {
13322        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13323        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13324        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13325        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13326        { }
13327};
13328
13329/* mute/unmute internal speaker according to the hp jack and mute state */
13330static void alc268_dell_setup(struct hda_codec *codec)
13331{
13332        struct alc_spec *spec = codec->spec;
13333
13334        spec->autocfg.hp_pins[0] = 0x15;
13335        spec->autocfg.speaker_pins[0] = 0x14;
13336        spec->ext_mic.pin = 0x18;
13337        spec->ext_mic.mux_idx = 0;
13338        spec->int_mic.pin = 0x19;
13339        spec->int_mic.mux_idx = 1;
13340        spec->auto_mic = 1;
13341}
13342
13343static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13344        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13345        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13346        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13347        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13348        HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13349        HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13350        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13351        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13352        { }
13353};
13354
13355static struct hda_verb alc267_quanta_il1_verbs[] = {
13356        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13357        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13358        { }
13359};
13360
13361static void alc267_quanta_il1_setup(struct hda_codec *codec)
13362{
13363        struct alc_spec *spec = codec->spec;
13364        spec->autocfg.hp_pins[0] = 0x15;
13365        spec->autocfg.speaker_pins[0] = 0x14;
13366        spec->ext_mic.pin = 0x18;
13367        spec->ext_mic.mux_idx = 0;
13368        spec->int_mic.pin = 0x19;
13369        spec->int_mic.mux_idx = 1;
13370        spec->auto_mic = 1;
13371}
13372
13373/*
13374 * generic initialization of ADC, input mixers and output mixers
13375 */
13376static struct hda_verb alc268_base_init_verbs[] = {
13377        /* Unmute DAC0-1 and set vol = 0 */
13378        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13379        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13380
13381        /*
13382         * Set up output mixers (0x0c - 0x0e)
13383         */
13384        /* set vol=0 to output mixers */
13385        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13386        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13387
13388        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13389        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13390
13391        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13392        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13393        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13394        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13395        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13396        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13397        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13398        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13399
13400        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13401        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13402        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13403        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13404        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13405
13406        /* set PCBEEP vol = 0, mute connections */
13407        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13408        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13409        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13410
13411        /* Unmute Selector 23h,24h and set the default input to mic-in */
13412
13413        {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13414        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13415        {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13416        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13417
13418        { }
13419};
13420
13421/*
13422 * generic initialization of ADC, input mixers and output mixers
13423 */
13424static struct hda_verb alc268_volume_init_verbs[] = {
13425        /* set output DAC */
13426        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13427        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13428
13429        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13430        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13431        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13432        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13433        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13434
13435        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13436        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13437        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13438
13439        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13440        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13441
13442        /* set PCBEEP vol = 0, mute connections */
13443        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13444        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13445        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13446
13447        { }
13448};
13449
13450static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13451        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13452        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13453        { } /* end */
13454};
13455
13456static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13457        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13458        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13459        _DEFINE_CAPSRC(1),
13460        { } /* end */
13461};
13462
13463static struct snd_kcontrol_new alc268_capture_mixer[] = {
13464        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13465        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13466        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13467        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13468        _DEFINE_CAPSRC(2),
13469        { } /* end */
13470};
13471
13472static struct hda_input_mux alc268_capture_source = {
13473        .num_items = 4,
13474        .items = {
13475                { "Mic", 0x0 },
13476                { "Front Mic", 0x1 },
13477                { "Line", 0x2 },
13478                { "CD", 0x3 },
13479        },
13480};
13481
13482static struct hda_input_mux alc268_acer_capture_source = {
13483        .num_items = 3,
13484        .items = {
13485                { "Mic", 0x0 },
13486                { "Internal Mic", 0x1 },
13487                { "Line", 0x2 },
13488        },
13489};
13490
13491static struct hda_input_mux alc268_acer_dmic_capture_source = {
13492        .num_items = 3,
13493        .items = {
13494                { "Mic", 0x0 },
13495                { "Internal Mic", 0x6 },
13496                { "Line", 0x2 },
13497        },
13498};
13499
13500#ifdef CONFIG_SND_DEBUG
13501static struct snd_kcontrol_new alc268_test_mixer[] = {
13502        /* Volume widgets */
13503        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13504        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13505        HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13506        HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13507        HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13508        HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13509        HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13510        HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13511        HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13512        HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13513        HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13514        HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13515        HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13516        /* The below appears problematic on some hardwares */
13517        /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13518        HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13519        HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13520        HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13521        HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13522
13523        /* Modes for retasking pin widgets */
13524        ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13525        ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13526        ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13527        ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13528
13529        /* Controls for GPIO pins, assuming they are configured as outputs */
13530        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13531        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13532        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13533        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13534
13535        /* Switches to allow the digital SPDIF output pin to be enabled.
13536         * The ALC268 does not have an SPDIF input.
13537         */
13538        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13539
13540        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
13541         * this output to turn on an external amplifier.
13542         */
13543        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13544        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13545
13546        { } /* end */
13547};
13548#endif
13549
13550/* create input playback/capture controls for the given pin */
13551static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13552                                    const char *ctlname, int idx)
13553{
13554        hda_nid_t dac;
13555        int err;
13556
13557        switch (nid) {
13558        case 0x14:
13559        case 0x16:
13560                dac = 0x02;
13561                break;
13562        case 0x15:
13563        case 0x1a: /* ALC259/269 only */
13564        case 0x1b: /* ALC259/269 only */
13565        case 0x21: /* ALC269vb has this pin, too */
13566                dac = 0x03;
13567                break;
13568        default:
13569                snd_printd(KERN_WARNING "hda_codec: "
13570                           "ignoring pin 0x%x as unknown\n", nid);
13571                return 0;
13572        }
13573        if (spec->multiout.dac_nids[0] != dac &&
13574            spec->multiout.dac_nids[1] != dac) {
13575                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13576                                  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13577                                                      HDA_OUTPUT));
13578                if (err < 0)
13579                        return err;
13580                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13581        }
13582
13583        if (nid != 0x16)
13584                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13585                          HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13586        else /* mono */
13587                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13588                          HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13589        if (err < 0)
13590                return err;
13591        return 0;
13592}
13593
13594/* add playback controls from the parsed DAC table */
13595static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13596                                             const struct auto_pin_cfg *cfg)
13597{
13598        hda_nid_t nid;
13599        int err;
13600
13601        spec->multiout.dac_nids = spec->private_dac_nids;
13602
13603        nid = cfg->line_out_pins[0];
13604        if (nid) {
13605                const char *name;
13606                if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13607                        name = "Speaker";
13608                else
13609                        name = "Front";
13610                err = alc268_new_analog_output(spec, nid, name, 0);
13611                if (err < 0)
13612                        return err;
13613        }
13614
13615        nid = cfg->speaker_pins[0];
13616        if (nid == 0x1d) {
13617                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13618                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13619                if (err < 0)
13620                        return err;
13621        } else if (nid) {
13622                err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13623                if (err < 0)
13624                        return err;
13625        }
13626        nid = cfg->hp_pins[0];
13627        if (nid) {
13628                err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13629                if (err < 0)
13630                        return err;
13631        }
13632
13633        nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13634        if (nid == 0x16) {
13635                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13636                                  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13637                if (err < 0)
13638                        return err;
13639        }
13640        return 0;
13641}
13642
13643/* create playback/capture controls for input pins */
13644static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13645                                                const struct auto_pin_cfg *cfg)
13646{
13647        return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13648}
13649
13650static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13651                                              hda_nid_t nid, int pin_type)
13652{
13653        int idx;
13654
13655        alc_set_pin_output(codec, nid, pin_type);
13656        if (nid == 0x14 || nid == 0x16)
13657                idx = 0;
13658        else
13659                idx = 1;
13660        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13661}
13662
13663static void alc268_auto_init_multi_out(struct hda_codec *codec)
13664{
13665        struct alc_spec *spec = codec->spec;
13666        int i;
13667
13668        for (i = 0; i < spec->autocfg.line_outs; i++) {
13669                hda_nid_t nid = spec->autocfg.line_out_pins[i];
13670                int pin_type = get_pin_type(spec->autocfg.line_out_type);
13671                alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13672        }
13673}
13674
13675static void alc268_auto_init_hp_out(struct hda_codec *codec)
13676{
13677        struct alc_spec *spec = codec->spec;
13678        hda_nid_t pin;
13679        int i;
13680
13681        for (i = 0; i < spec->autocfg.hp_outs; i++) {
13682                pin = spec->autocfg.hp_pins[i];
13683                alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13684        }
13685        for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13686                pin = spec->autocfg.speaker_pins[i];
13687                alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13688        }
13689        if (spec->autocfg.mono_out_pin)
13690                snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13691                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13692}
13693
13694static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13695{
13696        struct alc_spec *spec = codec->spec;
13697        hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13698        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13699        hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13700        unsigned int    dac_vol1, dac_vol2;
13701
13702        if (line_nid == 0x1d || speaker_nid == 0x1d) {
13703                snd_hda_codec_write(codec, speaker_nid, 0,
13704                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13705                /* mute mixer inputs from 0x1d */
13706                snd_hda_codec_write(codec, 0x0f, 0,
13707                                    AC_VERB_SET_AMP_GAIN_MUTE,
13708                                    AMP_IN_UNMUTE(1));
13709                snd_hda_codec_write(codec, 0x10, 0,
13710                                    AC_VERB_SET_AMP_GAIN_MUTE,
13711                                    AMP_IN_UNMUTE(1));
13712        } else {
13713                /* unmute mixer inputs from 0x1d */
13714                snd_hda_codec_write(codec, 0x0f, 0,
13715                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13716                snd_hda_codec_write(codec, 0x10, 0,
13717                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13718        }
13719
13720        dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
13721        if (line_nid == 0x14)
13722                dac_vol2 = AMP_OUT_ZERO;
13723        else if (line_nid == 0x15)
13724                dac_vol1 = AMP_OUT_ZERO;
13725        if (hp_nid == 0x14)
13726                dac_vol2 = AMP_OUT_ZERO;
13727        else if (hp_nid == 0x15)
13728                dac_vol1 = AMP_OUT_ZERO;
13729        if (line_nid != 0x16 || hp_nid != 0x16 ||
13730            spec->autocfg.line_out_pins[1] != 0x16 ||
13731            spec->autocfg.line_out_pins[2] != 0x16)
13732                dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13733
13734        snd_hda_codec_write(codec, 0x02, 0,
13735                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13736        snd_hda_codec_write(codec, 0x03, 0,
13737                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13738}
13739
13740/* pcm configuration: identical with ALC880 */
13741#define alc268_pcm_analog_playback      alc880_pcm_analog_playback
13742#define alc268_pcm_analog_capture       alc880_pcm_analog_capture
13743#define alc268_pcm_analog_alt_capture   alc880_pcm_analog_alt_capture
13744#define alc268_pcm_digital_playback     alc880_pcm_digital_playback
13745
13746/*
13747 * BIOS auto configuration
13748 */
13749static int alc268_parse_auto_config(struct hda_codec *codec)
13750{
13751        struct alc_spec *spec = codec->spec;
13752        int err;
13753        static hda_nid_t alc268_ignore[] = { 0 };
13754
13755        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13756                                           alc268_ignore);
13757        if (err < 0)
13758                return err;
13759        if (!spec->autocfg.line_outs) {
13760                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13761                        spec->multiout.max_channels = 2;
13762                        spec->no_analog = 1;
13763                        goto dig_only;
13764                }
13765                return 0; /* can't find valid BIOS pin config */
13766        }
13767        err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13768        if (err < 0)
13769                return err;
13770        err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13771        if (err < 0)
13772                return err;
13773
13774        spec->multiout.max_channels = 2;
13775
13776 dig_only:
13777        /* digital only support output */
13778        alc_auto_parse_digital(codec);
13779        if (spec->kctls.list)
13780                add_mixer(spec, spec->kctls.list);
13781
13782        if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13783                add_mixer(spec, alc268_beep_mixer);
13784
13785        add_verb(spec, alc268_volume_init_verbs);
13786        spec->num_mux_defs = 2;
13787        spec->input_mux = &spec->private_imux[0];
13788
13789        err = alc_auto_add_mic_boost(codec);
13790        if (err < 0)
13791                return err;
13792
13793        alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13794
13795        return 1;
13796}
13797
13798#define alc268_auto_init_analog_input   alc882_auto_init_analog_input
13799
13800/* init callback for auto-configuration model -- overriding the default init */
13801static void alc268_auto_init(struct hda_codec *codec)
13802{
13803        struct alc_spec *spec = codec->spec;
13804        alc268_auto_init_multi_out(codec);
13805        alc268_auto_init_hp_out(codec);
13806        alc268_auto_init_mono_speaker_out(codec);
13807        alc268_auto_init_analog_input(codec);
13808        alc_auto_init_digital(codec);
13809        if (spec->unsol_event)
13810                alc_inithook(codec);
13811}
13812
13813/*
13814 * configuration and preset
13815 */
13816static const char * const alc268_models[ALC268_MODEL_LAST] = {
13817        [ALC267_QUANTA_IL1]     = "quanta-il1",
13818        [ALC268_3ST]            = "3stack",
13819        [ALC268_TOSHIBA]        = "toshiba",
13820        [ALC268_ACER]           = "acer",
13821        [ALC268_ACER_DMIC]      = "acer-dmic",
13822        [ALC268_ACER_ASPIRE_ONE]        = "acer-aspire",
13823        [ALC268_DELL]           = "dell",
13824        [ALC268_ZEPTO]          = "zepto",
13825#ifdef CONFIG_SND_DEBUG
13826        [ALC268_TEST]           = "test",
13827#endif
13828        [ALC268_AUTO]           = "auto",
13829};
13830
13831static struct snd_pci_quirk alc268_cfg_tbl[] = {
13832        SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13833        SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13834        SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13835        SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13836        SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13837        SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13838                                                ALC268_ACER_ASPIRE_ONE),
13839        SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13840        SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13841                        "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13842        /* almost compatible with toshiba but with optional digital outs;
13843         * auto-probing seems working fine
13844         */
13845        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13846                           ALC268_AUTO),
13847        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13848        SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13849        SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13850        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13851        SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13852        {}
13853};
13854
13855/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13856static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13857        SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13858        SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13859        SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13860                           ALC268_TOSHIBA),
13861        {}
13862};
13863
13864static struct alc_config_preset alc268_presets[] = {
13865        [ALC267_QUANTA_IL1] = {
13866                .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13867                            alc268_capture_nosrc_mixer },
13868                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13869                                alc267_quanta_il1_verbs },
13870                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13871                .dac_nids = alc268_dac_nids,
13872                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13873                .adc_nids = alc268_adc_nids_alt,
13874                .hp_nid = 0x03,
13875                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13876                .channel_mode = alc268_modes,
13877                .unsol_event = alc_sku_unsol_event,
13878                .setup = alc267_quanta_il1_setup,
13879                .init_hook = alc_inithook,
13880        },
13881        [ALC268_3ST] = {
13882                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13883                            alc268_beep_mixer },
13884                .init_verbs = { alc268_base_init_verbs },
13885                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13886                .dac_nids = alc268_dac_nids,
13887                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13888                .adc_nids = alc268_adc_nids_alt,
13889                .capsrc_nids = alc268_capsrc_nids,
13890                .hp_nid = 0x03,
13891                .dig_out_nid = ALC268_DIGOUT_NID,
13892                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13893                .channel_mode = alc268_modes,
13894                .input_mux = &alc268_capture_source,
13895        },
13896        [ALC268_TOSHIBA] = {
13897                .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13898                            alc268_beep_mixer },
13899                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13900                                alc268_toshiba_verbs },
13901                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13902                .dac_nids = alc268_dac_nids,
13903                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13904                .adc_nids = alc268_adc_nids_alt,
13905                .capsrc_nids = alc268_capsrc_nids,
13906                .hp_nid = 0x03,
13907                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13908                .channel_mode = alc268_modes,
13909                .input_mux = &alc268_capture_source,
13910                .unsol_event = alc268_toshiba_unsol_event,
13911                .setup = alc268_toshiba_setup,
13912                .init_hook = alc268_toshiba_automute,
13913        },
13914        [ALC268_ACER] = {
13915                .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13916                            alc268_beep_mixer },
13917                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13918                                alc268_acer_verbs },
13919                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13920                .dac_nids = alc268_dac_nids,
13921                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13922                .adc_nids = alc268_adc_nids_alt,
13923                .capsrc_nids = alc268_capsrc_nids,
13924                .hp_nid = 0x02,
13925                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13926                .channel_mode = alc268_modes,
13927                .input_mux = &alc268_acer_capture_source,
13928                .unsol_event = alc268_acer_unsol_event,
13929                .init_hook = alc268_acer_init_hook,
13930        },
13931        [ALC268_ACER_DMIC] = {
13932                .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13933                            alc268_beep_mixer },
13934                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13935                                alc268_acer_verbs },
13936                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13937                .dac_nids = alc268_dac_nids,
13938                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13939                .adc_nids = alc268_adc_nids_alt,
13940                .capsrc_nids = alc268_capsrc_nids,
13941                .hp_nid = 0x02,
13942                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13943                .channel_mode = alc268_modes,
13944                .input_mux = &alc268_acer_dmic_capture_source,
13945                .unsol_event = alc268_acer_unsol_event,
13946                .init_hook = alc268_acer_init_hook,
13947        },
13948        [ALC268_ACER_ASPIRE_ONE] = {
13949                .mixers = { alc268_acer_aspire_one_mixer,
13950                            alc268_beep_mixer,
13951                            alc268_capture_nosrc_mixer },
13952                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13953                                alc268_acer_aspire_one_verbs },
13954                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13955                .dac_nids = alc268_dac_nids,
13956                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13957                .adc_nids = alc268_adc_nids_alt,
13958                .capsrc_nids = alc268_capsrc_nids,
13959                .hp_nid = 0x03,
13960                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13961                .channel_mode = alc268_modes,
13962                .unsol_event = alc268_acer_lc_unsol_event,
13963                .setup = alc268_acer_lc_setup,
13964                .init_hook = alc268_acer_lc_init_hook,
13965        },
13966        [ALC268_DELL] = {
13967                .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13968                            alc268_capture_nosrc_mixer },
13969                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13970                                alc268_dell_verbs },
13971                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13972                .dac_nids = alc268_dac_nids,
13973                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13974                .adc_nids = alc268_adc_nids_alt,
13975                .capsrc_nids = alc268_capsrc_nids,
13976                .hp_nid = 0x02,
13977                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13978                .channel_mode = alc268_modes,
13979                .unsol_event = alc_sku_unsol_event,
13980                .setup = alc268_dell_setup,
13981                .init_hook = alc_inithook,
13982        },
13983        [ALC268_ZEPTO] = {
13984                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13985                            alc268_beep_mixer },
13986                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13987                                alc268_toshiba_verbs },
13988                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13989                .dac_nids = alc268_dac_nids,
13990                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13991                .adc_nids = alc268_adc_nids_alt,
13992                .capsrc_nids = alc268_capsrc_nids,
13993                .hp_nid = 0x03,
13994                .dig_out_nid = ALC268_DIGOUT_NID,
13995                .num_channel_mode = ARRAY_SIZE(alc268_modes),
13996                .channel_mode = alc268_modes,
13997                .input_mux = &alc268_capture_source,
13998                .setup = alc268_toshiba_setup,
13999                .init_hook = alc268_toshiba_automute,
14000        },
14001#ifdef CONFIG_SND_DEBUG
14002        [ALC268_TEST] = {
14003                .mixers = { alc268_test_mixer, alc268_capture_mixer },
14004                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14005                                alc268_volume_init_verbs },
14006                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14007                .dac_nids = alc268_dac_nids,
14008                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14009                .adc_nids = alc268_adc_nids_alt,
14010                .capsrc_nids = alc268_capsrc_nids,
14011                .hp_nid = 0x03,
14012                .dig_out_nid = ALC268_DIGOUT_NID,
14013                .num_channel_mode = ARRAY_SIZE(alc268_modes),
14014                .channel_mode = alc268_modes,
14015                .input_mux = &alc268_capture_source,
14016        },
14017#endif
14018};
14019
14020static int patch_alc268(struct hda_codec *codec)
14021{
14022        struct alc_spec *spec;
14023        int board_config;
14024        int i, has_beep, err;
14025
14026        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14027        if (spec == NULL)
14028                return -ENOMEM;
14029
14030        codec->spec = spec;
14031
14032        board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14033                                                  alc268_models,
14034                                                  alc268_cfg_tbl);
14035
14036        if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14037                board_config = snd_hda_check_board_codec_sid_config(codec,
14038                        ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14039
14040        if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14041                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14042                       codec->chip_name);
14043                board_config = ALC268_AUTO;
14044        }
14045
14046        if (board_config == ALC268_AUTO) {
14047                /* automatic parse from the BIOS config */
14048                err = alc268_parse_auto_config(codec);
14049                if (err < 0) {
14050                        alc_free(codec);
14051                        return err;
14052                } else if (!err) {
14053                        printk(KERN_INFO
14054                               "hda_codec: Cannot set up configuration "
14055                               "from BIOS.  Using base mode...\n");
14056                        board_config = ALC268_3ST;
14057                }
14058        }
14059
14060        if (board_config != ALC268_AUTO)
14061                setup_preset(codec, &alc268_presets[board_config]);
14062
14063        spec->stream_analog_playback = &alc268_pcm_analog_playback;
14064        spec->stream_analog_capture = &alc268_pcm_analog_capture;
14065        spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14066
14067        spec->stream_digital_playback = &alc268_pcm_digital_playback;
14068
14069        has_beep = 0;
14070        for (i = 0; i < spec->num_mixers; i++) {
14071                if (spec->mixers[i] == alc268_beep_mixer) {
14072                        has_beep = 1;
14073                        break;
14074                }
14075        }
14076
14077        if (has_beep) {
14078                err = snd_hda_attach_beep_device(codec, 0x1);
14079                if (err < 0) {
14080                        alc_free(codec);
14081                        return err;
14082                }
14083                if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14084                        /* override the amp caps for beep generator */
14085                        snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14086                                          (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14087                                          (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14088                                          (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14089                                          (0 << AC_AMPCAP_MUTE_SHIFT));
14090        }
14091
14092        if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14093                /* check whether NID 0x07 is valid */
14094                unsigned int wcap = get_wcaps(codec, 0x07);
14095                int i;
14096
14097                spec->capsrc_nids = alc268_capsrc_nids;
14098                /* get type */
14099                wcap = get_wcaps_type(wcap);
14100                if (spec->auto_mic ||
14101                    wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14102                        spec->adc_nids = alc268_adc_nids_alt;
14103                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14104                        if (spec->auto_mic)
14105                                fixup_automic_adc(codec);
14106                        if (spec->auto_mic || spec->input_mux->num_items == 1)
14107                                add_mixer(spec, alc268_capture_nosrc_mixer);
14108                        else
14109                                add_mixer(spec, alc268_capture_alt_mixer);
14110                } else {
14111                        spec->adc_nids = alc268_adc_nids;
14112                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14113                        add_mixer(spec, alc268_capture_mixer);
14114                }
14115                /* set default input source */
14116                for (i = 0; i < spec->num_adc_nids; i++)
14117                        snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14118                                0, AC_VERB_SET_CONNECT_SEL,
14119                                i < spec->num_mux_defs ?
14120                                spec->input_mux[i].items[0].index :
14121                                spec->input_mux->items[0].index);
14122        }
14123
14124        spec->vmaster_nid = 0x02;
14125
14126        codec->patch_ops = alc_patch_ops;
14127        if (board_config == ALC268_AUTO)
14128                spec->init_hook = alc268_auto_init;
14129
14130        alc_init_jacks(codec);
14131
14132        return 0;
14133}
14134
14135/*
14136 *  ALC269 channel source setting (2 channel)
14137 */
14138#define ALC269_DIGOUT_NID       ALC880_DIGOUT_NID
14139
14140#define alc269_dac_nids         alc260_dac_nids
14141
14142static hda_nid_t alc269_adc_nids[1] = {
14143        /* ADC1 */
14144        0x08,
14145};
14146
14147static hda_nid_t alc269_capsrc_nids[1] = {
14148        0x23,
14149};
14150
14151static hda_nid_t alc269vb_adc_nids[1] = {
14152        /* ADC1 */
14153        0x09,
14154};
14155
14156static hda_nid_t alc269vb_capsrc_nids[1] = {
14157        0x22,
14158};
14159
14160static hda_nid_t alc269_adc_candidates[] = {
14161        0x08, 0x09, 0x07,
14162};
14163
14164#define alc269_modes            alc260_modes
14165#define alc269_capture_source   alc880_lg_lw_capture_source
14166
14167static struct snd_kcontrol_new alc269_base_mixer[] = {
14168        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14169        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14170        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14171        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14172        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14173        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14174        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14175        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14176        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14177        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14178        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14179        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14180        { } /* end */
14181};
14182
14183static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14184        /* output mixer control */
14185        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14186        {
14187                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14188                .name = "Master Playback Switch",
14189                .subdevice = HDA_SUBDEV_AMP_FLAG,
14190                .info = snd_hda_mixer_amp_switch_info,
14191                .get = snd_hda_mixer_amp_switch_get,
14192                .put = alc268_acer_master_sw_put,
14193                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14194        },
14195        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14196        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14197        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14198        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14199        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14200        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14201        { }
14202};
14203
14204static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14205        /* output mixer control */
14206        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14207        {
14208                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14209                .name = "Master Playback Switch",
14210                .subdevice = HDA_SUBDEV_AMP_FLAG,
14211                .info = snd_hda_mixer_amp_switch_info,
14212                .get = snd_hda_mixer_amp_switch_get,
14213                .put = alc268_acer_master_sw_put,
14214                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14215        },
14216        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14217        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14218        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14219        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14220        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14221        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14222        HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14223        HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14224        HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14225        { }
14226};
14227
14228static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14229        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14230        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14231        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14232        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14233        { } /* end */
14234};
14235
14236static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14237        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14238        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14239        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14240        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14241        { } /* end */
14242};
14243
14244static struct snd_kcontrol_new alc269_asus_mixer[] = {
14245        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14246        HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14247        { } /* end */
14248};
14249
14250/* capture mixer elements */
14251static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14252        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14253        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14254        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14255        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14256        { } /* end */
14257};
14258
14259static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14260        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14261        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14262        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14263        { } /* end */
14264};
14265
14266static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14267        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14268        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14269        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14270        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14271        { } /* end */
14272};
14273
14274static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14275        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14276        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14277        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14278        { } /* end */
14279};
14280
14281/* FSC amilo */
14282#define alc269_fujitsu_mixer    alc269_laptop_mixer
14283
14284static struct hda_verb alc269_quanta_fl1_verbs[] = {
14285        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14286        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14287        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14288        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14289        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14290        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14291        { }
14292};
14293
14294static struct hda_verb alc269_lifebook_verbs[] = {
14295        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14296        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14297        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14298        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14299        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14300        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14301        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14302        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14303        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14304        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14305        { }
14306};
14307
14308/* toggle speaker-output according to the hp-jack state */
14309static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14310{
14311        unsigned int present;
14312        unsigned char bits;
14313
14314        present = snd_hda_jack_detect(codec, 0x15);
14315        bits = present ? HDA_AMP_MUTE : 0;
14316        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14317                                 HDA_AMP_MUTE, bits);
14318        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14319                                 HDA_AMP_MUTE, bits);
14320
14321        snd_hda_codec_write(codec, 0x20, 0,
14322                        AC_VERB_SET_COEF_INDEX, 0x0c);
14323        snd_hda_codec_write(codec, 0x20, 0,
14324                        AC_VERB_SET_PROC_COEF, 0x680);
14325
14326        snd_hda_codec_write(codec, 0x20, 0,
14327                        AC_VERB_SET_COEF_INDEX, 0x0c);
14328        snd_hda_codec_write(codec, 0x20, 0,
14329                        AC_VERB_SET_PROC_COEF, 0x480);
14330}
14331
14332/* toggle speaker-output according to the hp-jacks state */
14333static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14334{
14335        unsigned int present;
14336        unsigned char bits;
14337
14338        /* Check laptop headphone socket */
14339        present = snd_hda_jack_detect(codec, 0x15);
14340
14341        /* Check port replicator headphone socket */
14342        present |= snd_hda_jack_detect(codec, 0x1a);
14343
14344        bits = present ? HDA_AMP_MUTE : 0;
14345        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14346                                 HDA_AMP_MUTE, bits);
14347        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14348                                 HDA_AMP_MUTE, bits);
14349
14350        snd_hda_codec_write(codec, 0x20, 0,
14351                        AC_VERB_SET_COEF_INDEX, 0x0c);
14352        snd_hda_codec_write(codec, 0x20, 0,
14353                        AC_VERB_SET_PROC_COEF, 0x680);
14354
14355        snd_hda_codec_write(codec, 0x20, 0,
14356                        AC_VERB_SET_COEF_INDEX, 0x0c);
14357        snd_hda_codec_write(codec, 0x20, 0,
14358                        AC_VERB_SET_PROC_COEF, 0x480);
14359}
14360
14361static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14362{
14363        unsigned int present_laptop;
14364        unsigned int present_dock;
14365
14366        present_laptop  = snd_hda_jack_detect(codec, 0x18);
14367        present_dock    = snd_hda_jack_detect(codec, 0x1b);
14368
14369        /* Laptop mic port overrides dock mic port, design decision */
14370        if (present_dock)
14371                snd_hda_codec_write(codec, 0x23, 0,
14372                                AC_VERB_SET_CONNECT_SEL, 0x3);
14373        if (present_laptop)
14374                snd_hda_codec_write(codec, 0x23, 0,
14375                                AC_VERB_SET_CONNECT_SEL, 0x0);
14376        if (!present_dock && !present_laptop)
14377                snd_hda_codec_write(codec, 0x23, 0,
14378                                AC_VERB_SET_CONNECT_SEL, 0x1);
14379}
14380
14381static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14382                                    unsigned int res)
14383{
14384        switch (res >> 26) {
14385        case ALC880_HP_EVENT:
14386                alc269_quanta_fl1_speaker_automute(codec);
14387                break;
14388        case ALC880_MIC_EVENT:
14389                alc_mic_automute(codec);
14390                break;
14391        }
14392}
14393
14394static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14395                                        unsigned int res)
14396{
14397        if ((res >> 26) == ALC880_HP_EVENT)
14398                alc269_lifebook_speaker_automute(codec);
14399        if ((res >> 26) == ALC880_MIC_EVENT)
14400                alc269_lifebook_mic_autoswitch(codec);
14401}
14402
14403static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14404{
14405        struct alc_spec *spec = codec->spec;
14406        spec->autocfg.hp_pins[0] = 0x15;
14407        spec->autocfg.speaker_pins[0] = 0x14;
14408        spec->ext_mic.pin = 0x18;
14409        spec->ext_mic.mux_idx = 0;
14410        spec->int_mic.pin = 0x19;
14411        spec->int_mic.mux_idx = 1;
14412        spec->auto_mic = 1;
14413}
14414
14415static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14416{
14417        alc269_quanta_fl1_speaker_automute(codec);
14418        alc_mic_automute(codec);
14419}
14420
14421static void alc269_lifebook_init_hook(struct hda_codec *codec)
14422{
14423        alc269_lifebook_speaker_automute(codec);
14424        alc269_lifebook_mic_autoswitch(codec);
14425}
14426
14427static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14428        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14429        {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14430        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14431        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14432        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14433        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14434        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14435        {}
14436};
14437
14438static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14439        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14440        {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14441        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14442        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14443        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14444        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14445        {}
14446};
14447
14448static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14449        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14450        {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14451        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14452        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14453        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14455        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14456        {}
14457};
14458
14459static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14460        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14461        {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14462        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14463        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14464        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14465        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14466        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14467        {}
14468};
14469
14470static struct hda_verb alc271_acer_dmic_verbs[] = {
14471        {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14472        {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14473        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14474        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14475        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14476        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14477        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14478        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14479        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14480        {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14481        { }
14482};
14483
14484/* toggle speaker-output according to the hp-jack state */
14485static void alc269_speaker_automute(struct hda_codec *codec)
14486{
14487        struct alc_spec *spec = codec->spec;
14488        unsigned int nid = spec->autocfg.hp_pins[0];
14489        unsigned int present;
14490        unsigned char bits;
14491
14492        present = snd_hda_jack_detect(codec, nid);
14493        bits = present ? HDA_AMP_MUTE : 0;
14494        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14495                                 HDA_AMP_MUTE, bits);
14496        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14497                                 HDA_AMP_MUTE, bits);
14498        alc_report_jack(codec, nid);
14499}
14500
14501/* unsolicited event for HP jack sensing */
14502static void alc269_laptop_unsol_event(struct hda_codec *codec,
14503                                     unsigned int res)
14504{
14505        switch (res >> 26) {
14506        case ALC880_HP_EVENT:
14507                alc269_speaker_automute(codec);
14508                break;
14509        case ALC880_MIC_EVENT:
14510                alc_mic_automute(codec);
14511                break;
14512        }
14513}
14514
14515static void alc269_laptop_amic_setup(struct hda_codec *codec)
14516{
14517        struct alc_spec *spec = codec->spec;
14518        spec->autocfg.hp_pins[0] = 0x15;
14519        spec->autocfg.speaker_pins[0] = 0x14;
14520        spec->ext_mic.pin = 0x18;
14521        spec->ext_mic.mux_idx = 0;
14522        spec->int_mic.pin = 0x19;
14523        spec->int_mic.mux_idx = 1;
14524        spec->auto_mic = 1;
14525}
14526
14527static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14528{
14529        struct alc_spec *spec = codec->spec;
14530        spec->autocfg.hp_pins[0] = 0x15;
14531        spec->autocfg.speaker_pins[0] = 0x14;
14532        spec->ext_mic.pin = 0x18;
14533        spec->ext_mic.mux_idx = 0;
14534        spec->int_mic.pin = 0x12;
14535        spec->int_mic.mux_idx = 5;
14536        spec->auto_mic = 1;
14537}
14538
14539static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14540{
14541        struct alc_spec *spec = codec->spec;
14542        spec->autocfg.hp_pins[0] = 0x21;
14543        spec->autocfg.speaker_pins[0] = 0x14;
14544        spec->ext_mic.pin = 0x18;
14545        spec->ext_mic.mux_idx = 0;
14546        spec->int_mic.pin = 0x19;
14547        spec->int_mic.mux_idx = 1;
14548        spec->auto_mic = 1;
14549}
14550
14551static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14552{
14553        struct alc_spec *spec = codec->spec;
14554        spec->autocfg.hp_pins[0] = 0x21;
14555        spec->autocfg.speaker_pins[0] = 0x14;
14556        spec->ext_mic.pin = 0x18;
14557        spec->ext_mic.mux_idx = 0;
14558        spec->int_mic.pin = 0x12;
14559        spec->int_mic.mux_idx = 6;
14560        spec->auto_mic = 1;
14561}
14562
14563static void alc269_laptop_inithook(struct hda_codec *codec)
14564{
14565        alc269_speaker_automute(codec);
14566        alc_mic_automute(codec);
14567}
14568
14569/*
14570 * generic initialization of ADC, input mixers and output mixers
14571 */
14572static struct hda_verb alc269_init_verbs[] = {
14573        /*
14574         * Unmute ADC0 and set the default input to mic-in
14575         */
14576        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14577
14578        /*
14579         * Set up output mixers (0x02 - 0x03)
14580         */
14581        /* set vol=0 to output mixers */
14582        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14583        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14584
14585        /* set up input amps for analog loopback */
14586        /* Amp Indices: DAC = 0, mixer = 1 */
14587        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14588        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14589        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14590        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14591        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14592        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14593
14594        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14595        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14596        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14597        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14598        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14599        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14600        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14601
14602        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14603        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14604
14605        /* FIXME: use Mux-type input source selection */
14606        /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14607        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14608        {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14609
14610        /* set EAPD */
14611        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14612        { }
14613};
14614
14615static struct hda_verb alc269vb_init_verbs[] = {
14616        /*
14617         * Unmute ADC0 and set the default input to mic-in
14618         */
14619        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14620
14621        /*
14622         * Set up output mixers (0x02 - 0x03)
14623         */
14624        /* set vol=0 to output mixers */
14625        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14626        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14627
14628        /* set up input amps for analog loopback */
14629        /* Amp Indices: DAC = 0, mixer = 1 */
14630        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14631        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14632        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14633        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14634        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14635        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14636
14637        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14638        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14639        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14640        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14641        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14642        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14643        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14644
14645        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14646        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14647
14648        /* FIXME: use Mux-type input source selection */
14649        /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14650        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14651        {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14652
14653        /* set EAPD */
14654        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14655        { }
14656};
14657
14658#define alc269_auto_create_multi_out_ctls \
14659        alc268_auto_create_multi_out_ctls
14660#define alc269_auto_create_input_ctls \
14661        alc268_auto_create_input_ctls
14662
14663#ifdef CONFIG_SND_HDA_POWER_SAVE
14664#define alc269_loopbacks        alc880_loopbacks
14665#endif
14666
14667/* pcm configuration: identical with ALC880 */
14668#define alc269_pcm_analog_playback      alc880_pcm_analog_playback
14669#define alc269_pcm_analog_capture       alc880_pcm_analog_capture
14670#define alc269_pcm_digital_playback     alc880_pcm_digital_playback
14671#define alc269_pcm_digital_capture      alc880_pcm_digital_capture
14672
14673static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14674        .substreams = 1,
14675        .channels_min = 2,
14676        .channels_max = 8,
14677        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14678        /* NID is set in alc_build_pcms */
14679        .ops = {
14680                .open = alc880_playback_pcm_open,
14681                .prepare = alc880_playback_pcm_prepare,
14682                .cleanup = alc880_playback_pcm_cleanup
14683        },
14684};
14685
14686static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14687        .substreams = 1,
14688        .channels_min = 2,
14689        .channels_max = 2,
14690        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14691        /* NID is set in alc_build_pcms */
14692};
14693
14694#ifdef CONFIG_SND_HDA_POWER_SAVE
14695static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14696{
14697        switch (codec->subsystem_id) {
14698        case 0x103c1586:
14699                return 1;
14700        }
14701        return 0;
14702}
14703
14704static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14705{
14706        /* update mute-LED according to the speaker mute state */
14707        if (nid == 0x01 || nid == 0x14) {
14708                int pinval;
14709                if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14710                    HDA_AMP_MUTE)
14711                        pinval = 0x24;
14712                else
14713                        pinval = 0x20;
14714                /* mic2 vref pin is used for mute LED control */
14715                snd_hda_codec_update_cache(codec, 0x19, 0,
14716                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
14717                                           pinval);
14718        }
14719        return alc_check_power_status(codec, nid);
14720}
14721#endif /* CONFIG_SND_HDA_POWER_SAVE */
14722
14723static int alc275_setup_dual_adc(struct hda_codec *codec)
14724{
14725        struct alc_spec *spec = codec->spec;
14726
14727        if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14728                return 0;
14729        if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14730            (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14731                if (spec->ext_mic.pin <= 0x12) {
14732                        spec->private_adc_nids[0] = 0x08;
14733                        spec->private_adc_nids[1] = 0x11;
14734                        spec->private_capsrc_nids[0] = 0x23;
14735                        spec->private_capsrc_nids[1] = 0x22;
14736                } else {
14737                        spec->private_adc_nids[0] = 0x11;
14738                        spec->private_adc_nids[1] = 0x08;
14739                        spec->private_capsrc_nids[0] = 0x22;
14740                        spec->private_capsrc_nids[1] = 0x23;
14741                }
14742                spec->adc_nids = spec->private_adc_nids;
14743                spec->capsrc_nids = spec->private_capsrc_nids;
14744                spec->num_adc_nids = 2;
14745                spec->dual_adc_switch = 1;
14746                snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14747                            spec->adc_nids[0], spec->adc_nids[1]);
14748                return 1;
14749        }
14750        return 0;
14751}
14752
14753/* different alc269-variants */
14754enum {
14755        ALC269_TYPE_NORMAL,
14756        ALC269_TYPE_ALC258,
14757        ALC269_TYPE_ALC259,
14758        ALC269_TYPE_ALC269VB,
14759        ALC269_TYPE_ALC270,
14760        ALC269_TYPE_ALC271X,
14761};
14762
14763/*
14764 * BIOS auto configuration
14765 */
14766static int alc269_parse_auto_config(struct hda_codec *codec)
14767{
14768        struct alc_spec *spec = codec->spec;
14769        int err;
14770        static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14771
14772        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14773                                           alc269_ignore);
14774        if (err < 0)
14775                return err;
14776
14777        err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14778        if (err < 0)
14779                return err;
14780        if (spec->codec_variant == ALC269_TYPE_NORMAL)
14781                err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14782        else
14783                err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14784                                                 0x22, 0);
14785        if (err < 0)
14786                return err;
14787
14788        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14789
14790        alc_auto_parse_digital(codec);
14791
14792        if (spec->kctls.list)
14793                add_mixer(spec, spec->kctls.list);
14794
14795        if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14796                add_verb(spec, alc269vb_init_verbs);
14797                alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14798        } else {
14799                add_verb(spec, alc269_init_verbs);
14800                alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14801        }
14802
14803        spec->num_mux_defs = 1;
14804        spec->input_mux = &spec->private_imux[0];
14805
14806        if (!alc275_setup_dual_adc(codec))
14807                fillup_priv_adc_nids(codec, alc269_adc_candidates,
14808                                     sizeof(alc269_adc_candidates));
14809
14810        /* set default input source */
14811        if (!spec->dual_adc_switch)
14812                select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14813                                        spec->input_mux->items[0].index);
14814
14815        err = alc_auto_add_mic_boost(codec);
14816        if (err < 0)
14817                return err;
14818
14819        if (!spec->cap_mixer && !spec->no_analog)
14820                set_capture_mixer(codec);
14821
14822        return 1;
14823}
14824
14825#define alc269_auto_init_multi_out      alc268_auto_init_multi_out
14826#define alc269_auto_init_hp_out         alc268_auto_init_hp_out
14827#define alc269_auto_init_analog_input   alc882_auto_init_analog_input
14828
14829
14830/* init callback for auto-configuration model -- overriding the default init */
14831static void alc269_auto_init(struct hda_codec *codec)
14832{
14833        struct alc_spec *spec = codec->spec;
14834        alc269_auto_init_multi_out(codec);
14835        alc269_auto_init_hp_out(codec);
14836        alc269_auto_init_analog_input(codec);
14837        alc_auto_init_digital(codec);
14838        if (spec->unsol_event)
14839                alc_inithook(codec);
14840}
14841
14842#ifdef SND_HDA_NEEDS_RESUME
14843static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14844{
14845        int val = alc_read_coef_idx(codec, 0x04);
14846        if (power_up)
14847                val |= 1 << 11;
14848        else
14849                val &= ~(1 << 11);
14850        alc_write_coef_idx(codec, 0x04, val);
14851}
14852
14853#ifdef CONFIG_SND_HDA_POWER_SAVE
14854static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14855{
14856        struct alc_spec *spec = codec->spec;
14857
14858        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14859                alc269_toggle_power_output(codec, 0);
14860        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14861                alc269_toggle_power_output(codec, 0);
14862                msleep(150);
14863        }
14864
14865        alc_shutup(codec);
14866        if (spec && spec->power_hook)
14867                spec->power_hook(codec);
14868        return 0;
14869}
14870#endif /* CONFIG_SND_HDA_POWER_SAVE */
14871
14872static int alc269_resume(struct hda_codec *codec)
14873{
14874        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14875                alc269_toggle_power_output(codec, 0);
14876                msleep(150);
14877        }
14878
14879        codec->patch_ops.init(codec);
14880
14881        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14882                alc269_toggle_power_output(codec, 1);
14883                msleep(200);
14884        }
14885
14886        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14887                alc269_toggle_power_output(codec, 1);
14888
14889        snd_hda_codec_resume_amp(codec);
14890        snd_hda_codec_resume_cache(codec);
14891        hda_call_check_power_status(codec, 0x01);
14892        return 0;
14893}
14894#endif /* SND_HDA_NEEDS_RESUME */
14895
14896static void alc269_fixup_hweq(struct hda_codec *codec,
14897                               const struct alc_fixup *fix, int action)
14898{
14899        int coef;
14900
14901        if (action != ALC_FIXUP_ACT_INIT)
14902                return;
14903        coef = alc_read_coef_idx(codec, 0x1e);
14904        alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14905}
14906
14907enum {
14908        ALC269_FIXUP_SONY_VAIO,
14909        ALC275_FIXUP_SONY_VAIO_GPIO2,
14910        ALC269_FIXUP_DELL_M101Z,
14911        ALC269_FIXUP_SKU_IGNORE,
14912        ALC269_FIXUP_ASUS_G73JW,
14913        ALC269_FIXUP_LENOVO_EAPD,
14914        ALC275_FIXUP_SONY_HWEQ,
14915};
14916
14917static const struct alc_fixup alc269_fixups[] = {
14918        [ALC269_FIXUP_SONY_VAIO] = {
14919                .type = ALC_FIXUP_VERBS,
14920                .v.verbs = (const struct hda_verb[]) {
14921                        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14922                        {}
14923                }
14924        },
14925        [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14926                .type = ALC_FIXUP_VERBS,
14927                .v.verbs = (const struct hda_verb[]) {
14928                        {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14929                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14930                        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14931                        { }
14932                },
14933                .chained = true,
14934                .chain_id = ALC269_FIXUP_SONY_VAIO
14935        },
14936        [ALC269_FIXUP_DELL_M101Z] = {
14937                .type = ALC_FIXUP_VERBS,
14938                .v.verbs = (const struct hda_verb[]) {
14939                        /* Enables internal speaker */
14940                        {0x20, AC_VERB_SET_COEF_INDEX, 13},
14941                        {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14942                        {}
14943                }
14944        },
14945        [ALC269_FIXUP_SKU_IGNORE] = {
14946                .type = ALC_FIXUP_SKU,
14947                .v.sku = ALC_FIXUP_SKU_IGNORE,
14948        },
14949        [ALC269_FIXUP_ASUS_G73JW] = {
14950                .type = ALC_FIXUP_PINS,
14951                .v.pins = (const struct alc_pincfg[]) {
14952                        { 0x17, 0x99130111 }, /* subwoofer */
14953                        { }
14954                }
14955        },
14956        [ALC269_FIXUP_LENOVO_EAPD] = {
14957                .type = ALC_FIXUP_VERBS,
14958                .v.verbs = (const struct hda_verb[]) {
14959                        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14960                        {}
14961                }
14962        },
14963        [ALC275_FIXUP_SONY_HWEQ] = {
14964                .type = ALC_FIXUP_FUNC,
14965                .v.func = alc269_fixup_hweq,
14966                .chained = true,
14967                .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14968        }
14969};
14970
14971static struct snd_pci_quirk alc269_fixup_tbl[] = {
14972        SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14973        SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14974        SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14975        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14976        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14977        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14978        SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14979        SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14980        SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14981        SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14982        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14983        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14984        {}
14985};
14986
14987
14988/*
14989 * configuration and preset
14990 */
14991static const char * const alc269_models[ALC269_MODEL_LAST] = {
14992        [ALC269_BASIC]                  = "basic",
14993        [ALC269_QUANTA_FL1]             = "quanta",
14994        [ALC269_AMIC]                   = "laptop-amic",
14995        [ALC269_DMIC]                   = "laptop-dmic",
14996        [ALC269_FUJITSU]                = "fujitsu",
14997        [ALC269_LIFEBOOK]               = "lifebook",
14998        [ALC269_AUTO]                   = "auto",
14999};
15000
15001static struct snd_pci_quirk alc269_cfg_tbl[] = {
15002        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
15003        SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
15004        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
15005                      ALC269_AMIC),
15006        SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15007        SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15008        SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15009        SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15010        SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15011        SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15012        SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15013        SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15014        SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15015        SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15016        SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15017        SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15018        SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15019        SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15020        SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15021        SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15022        SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15023        SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15024        SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15025        SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15026        SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15027        SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15028        SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15029        SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15030        SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15031        SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15032        SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15033        SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15034        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15035        SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15036        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15037        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15038        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15039        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15040        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15041        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15042        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15043                      ALC269_DMIC),
15044        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15045                      ALC269_DMIC),
15046        SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15047        SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15048        SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15049        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15050        SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15051        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15052        SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15053        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15054        SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15055        SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15056        {}
15057};
15058
15059static struct alc_config_preset alc269_presets[] = {
15060        [ALC269_BASIC] = {
15061                .mixers = { alc269_base_mixer },
15062                .init_verbs = { alc269_init_verbs },
15063                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15064                .dac_nids = alc269_dac_nids,
15065                .hp_nid = 0x03,
15066                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15067                .channel_mode = alc269_modes,
15068                .input_mux = &alc269_capture_source,
15069        },
15070        [ALC269_QUANTA_FL1] = {
15071                .mixers = { alc269_quanta_fl1_mixer },
15072                .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15073                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074                .dac_nids = alc269_dac_nids,
15075                .hp_nid = 0x03,
15076                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15077                .channel_mode = alc269_modes,
15078                .input_mux = &alc269_capture_source,
15079                .unsol_event = alc269_quanta_fl1_unsol_event,
15080                .setup = alc269_quanta_fl1_setup,
15081                .init_hook = alc269_quanta_fl1_init_hook,
15082        },
15083        [ALC269_AMIC] = {
15084                .mixers = { alc269_laptop_mixer },
15085                .cap_mixer = alc269_laptop_analog_capture_mixer,
15086                .init_verbs = { alc269_init_verbs,
15087                                alc269_laptop_amic_init_verbs },
15088                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089                .dac_nids = alc269_dac_nids,
15090                .hp_nid = 0x03,
15091                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092                .channel_mode = alc269_modes,
15093                .unsol_event = alc269_laptop_unsol_event,
15094                .setup = alc269_laptop_amic_setup,
15095                .init_hook = alc269_laptop_inithook,
15096        },
15097        [ALC269_DMIC] = {
15098                .mixers = { alc269_laptop_mixer },
15099                .cap_mixer = alc269_laptop_digital_capture_mixer,
15100                .init_verbs = { alc269_init_verbs,
15101                                alc269_laptop_dmic_init_verbs },
15102                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103                .dac_nids = alc269_dac_nids,
15104                .hp_nid = 0x03,
15105                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106                .channel_mode = alc269_modes,
15107                .unsol_event = alc269_laptop_unsol_event,
15108                .setup = alc269_laptop_dmic_setup,
15109                .init_hook = alc269_laptop_inithook,
15110        },
15111        [ALC269VB_AMIC] = {
15112                .mixers = { alc269vb_laptop_mixer },
15113                .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15114                .init_verbs = { alc269vb_init_verbs,
15115                                alc269vb_laptop_amic_init_verbs },
15116                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117                .dac_nids = alc269_dac_nids,
15118                .hp_nid = 0x03,
15119                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120                .channel_mode = alc269_modes,
15121                .unsol_event = alc269_laptop_unsol_event,
15122                .setup = alc269vb_laptop_amic_setup,
15123                .init_hook = alc269_laptop_inithook,
15124        },
15125        [ALC269VB_DMIC] = {
15126                .mixers = { alc269vb_laptop_mixer },
15127                .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15128                .init_verbs = { alc269vb_init_verbs,
15129                                alc269vb_laptop_dmic_init_verbs },
15130                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131                .dac_nids = alc269_dac_nids,
15132                .hp_nid = 0x03,
15133                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134                .channel_mode = alc269_modes,
15135                .unsol_event = alc269_laptop_unsol_event,
15136                .setup = alc269vb_laptop_dmic_setup,
15137                .init_hook = alc269_laptop_inithook,
15138        },
15139        [ALC269_FUJITSU] = {
15140                .mixers = { alc269_fujitsu_mixer },
15141                .cap_mixer = alc269_laptop_digital_capture_mixer,
15142                .init_verbs = { alc269_init_verbs,
15143                                alc269_laptop_dmic_init_verbs },
15144                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15145                .dac_nids = alc269_dac_nids,
15146                .hp_nid = 0x03,
15147                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15148                .channel_mode = alc269_modes,
15149                .unsol_event = alc269_laptop_unsol_event,
15150                .setup = alc269_laptop_dmic_setup,
15151                .init_hook = alc269_laptop_inithook,
15152        },
15153        [ALC269_LIFEBOOK] = {
15154                .mixers = { alc269_lifebook_mixer },
15155                .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15156                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157                .dac_nids = alc269_dac_nids,
15158                .hp_nid = 0x03,
15159                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15160                .channel_mode = alc269_modes,
15161                .input_mux = &alc269_capture_source,
15162                .unsol_event = alc269_lifebook_unsol_event,
15163                .init_hook = alc269_lifebook_init_hook,
15164        },
15165        [ALC271_ACER] = {
15166                .mixers = { alc269_asus_mixer },
15167                .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15168                .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15169                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15170                .dac_nids = alc269_dac_nids,
15171                .adc_nids = alc262_dmic_adc_nids,
15172                .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15173                .capsrc_nids = alc262_dmic_capsrc_nids,
15174                .num_channel_mode = ARRAY_SIZE(alc269_modes),
15175                .channel_mode = alc269_modes,
15176                .input_mux = &alc269_capture_source,
15177                .dig_out_nid = ALC880_DIGOUT_NID,
15178                .unsol_event = alc_sku_unsol_event,
15179                .setup = alc269vb_laptop_dmic_setup,
15180                .init_hook = alc_inithook,
15181        },
15182};
15183
15184static int alc269_fill_coef(struct hda_codec *codec)
15185{
15186        int val;
15187
15188        if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15189                alc_write_coef_idx(codec, 0xf, 0x960b);
15190                alc_write_coef_idx(codec, 0xe, 0x8817);
15191        }
15192
15193        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15194                alc_write_coef_idx(codec, 0xf, 0x960b);
15195                alc_write_coef_idx(codec, 0xe, 0x8814);
15196        }
15197
15198        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15199                val = alc_read_coef_idx(codec, 0x04);
15200                /* Power up output pin */
15201                alc_write_coef_idx(codec, 0x04, val | (1<<11));
15202        }
15203
15204        if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15205                val = alc_read_coef_idx(codec, 0xd);
15206                if ((val & 0x0c00) >> 10 != 0x1) {
15207                        /* Capless ramp up clock control */
15208                        alc_write_coef_idx(codec, 0xd, val | 1<<10);
15209                }
15210                val = alc_read_coef_idx(codec, 0x17);
15211                if ((val & 0x01c0) >> 6 != 0x4) {
15212                        /* Class D power on reset */
15213                        alc_write_coef_idx(codec, 0x17, val | 1<<7);
15214                }
15215        }
15216        return 0;
15217}
15218
15219static int patch_alc269(struct hda_codec *codec)
15220{
15221        struct alc_spec *spec;
15222        int board_config, coef;
15223        int err;
15224
15225        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15226        if (spec == NULL)
15227                return -ENOMEM;
15228
15229        codec->spec = spec;
15230
15231        alc_auto_parse_customize_define(codec);
15232
15233        if (codec->vendor_id == 0x10ec0269) {
15234                coef = alc_read_coef_idx(codec, 0);
15235                if ((coef & 0x00f0) == 0x0010) {
15236                        if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15237                            spec->cdefine.platform_type == 1) {
15238                                alc_codec_rename(codec, "ALC271X");
15239                                spec->codec_variant = ALC269_TYPE_ALC271X;
15240                        } else if ((coef & 0xf000) == 0x1000) {
15241                                spec->codec_variant = ALC269_TYPE_ALC270;
15242                        } else if ((coef & 0xf000) == 0x2000) {
15243                                alc_codec_rename(codec, "ALC259");
15244                                spec->codec_variant = ALC269_TYPE_ALC259;
15245                        } else if ((coef & 0xf000) == 0x3000) {
15246                                alc_codec_rename(codec, "ALC258");
15247                                spec->codec_variant = ALC269_TYPE_ALC258;
15248                        } else {
15249                                alc_codec_rename(codec, "ALC269VB");
15250                                spec->codec_variant = ALC269_TYPE_ALC269VB;
15251                        }
15252                } else
15253                        alc_fix_pll_init(codec, 0x20, 0x04, 15);
15254                alc269_fill_coef(codec);
15255        }
15256
15257        board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15258                                                  alc269_models,
15259                                                  alc269_cfg_tbl);
15260
15261        if (board_config < 0) {
15262                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15263                       codec->chip_name);
15264                board_config = ALC269_AUTO;
15265        }
15266
15267        if (board_config == ALC269_AUTO) {
15268                alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15269                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15270        }
15271
15272        if (board_config == ALC269_AUTO) {
15273                /* automatic parse from the BIOS config */
15274                err = alc269_parse_auto_config(codec);
15275                if (err < 0) {
15276                        alc_free(codec);
15277                        return err;
15278                } else if (!err) {
15279                        printk(KERN_INFO
15280                               "hda_codec: Cannot set up configuration "
15281                               "from BIOS.  Using base mode...\n");
15282                        board_config = ALC269_BASIC;
15283                }
15284        }
15285
15286        if (has_cdefine_beep(codec)) {
15287                err = snd_hda_attach_beep_device(codec, 0x1);
15288                if (err < 0) {
15289                        alc_free(codec);
15290                        return err;
15291                }
15292        }
15293
15294        if (board_config != ALC269_AUTO)
15295                setup_preset(codec, &alc269_presets[board_config]);
15296
15297        if (board_config == ALC269_QUANTA_FL1) {
15298                /* Due to a hardware problem on Lenovo Ideadpad, we need to
15299                 * fix the sample rate of analog I/O to 44.1kHz
15300                 */
15301                spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15302                spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15303        } else if (spec->dual_adc_switch) {
15304                spec->stream_analog_playback = &alc269_pcm_analog_playback;
15305                /* switch ADC dynamically */
15306                spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15307        } else {
15308                spec->stream_analog_playback = &alc269_pcm_analog_playback;
15309                spec->stream_analog_capture = &alc269_pcm_analog_capture;
15310        }
15311        spec->stream_digital_playback = &alc269_pcm_digital_playback;
15312        spec->stream_digital_capture = &alc269_pcm_digital_capture;
15313
15314        if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15315                if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15316                        spec->adc_nids = alc269_adc_nids;
15317                        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15318                        spec->capsrc_nids = alc269_capsrc_nids;
15319                } else {
15320                        spec->adc_nids = alc269vb_adc_nids;
15321                        spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15322                        spec->capsrc_nids = alc269vb_capsrc_nids;
15323                }
15324        }
15325
15326        if (!spec->cap_mixer)
15327                set_capture_mixer(codec);
15328        if (has_cdefine_beep(codec))
15329                set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15330
15331        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15332
15333        spec->vmaster_nid = 0x02;
15334
15335        codec->patch_ops = alc_patch_ops;
15336#ifdef CONFIG_SND_HDA_POWER_SAVE
15337        codec->patch_ops.suspend = alc269_suspend;
15338#endif
15339#ifdef SND_HDA_NEEDS_RESUME
15340        codec->patch_ops.resume = alc269_resume;
15341#endif
15342        if (board_config == ALC269_AUTO)
15343                spec->init_hook = alc269_auto_init;
15344
15345        alc_init_jacks(codec);
15346#ifdef CONFIG_SND_HDA_POWER_SAVE
15347        if (!spec->loopback.amplist)
15348                spec->loopback.amplist = alc269_loopbacks;
15349        if (alc269_mic2_for_mute_led(codec))
15350                codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15351#endif
15352
15353        return 0;
15354}
15355
15356/*
15357 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
15358 */
15359
15360/*
15361 * set the path ways for 2 channel output
15362 * need to set the codec line out and mic 1 pin widgets to inputs
15363 */
15364static struct hda_verb alc861_threestack_ch2_init[] = {
15365        /* set pin widget 1Ah (line in) for input */
15366        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15367        /* set pin widget 18h (mic1/2) for input, for mic also enable
15368         * the vref
15369         */
15370        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15371
15372        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15373#if 0
15374        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15375        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15376#endif
15377        { } /* end */
15378};
15379/*
15380 * 6ch mode
15381 * need to set the codec line out and mic 1 pin widgets to outputs
15382 */
15383static struct hda_verb alc861_threestack_ch6_init[] = {
15384        /* set pin widget 1Ah (line in) for output (Back Surround)*/
15385        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15386        /* set pin widget 18h (mic1) for output (CLFE)*/
15387        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15388
15389        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15390        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15391
15392        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15393#if 0
15394        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15395        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15396#endif
15397        { } /* end */
15398};
15399
15400static struct hda_channel_mode alc861_threestack_modes[2] = {
15401        { 2, alc861_threestack_ch2_init },
15402        { 6, alc861_threestack_ch6_init },
15403};
15404/* Set mic1 as input and unmute the mixer */
15405static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15406        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15407        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15408        { } /* end */
15409};
15410/* Set mic1 as output and mute mixer */
15411static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15412        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15413        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15414        { } /* end */
15415};
15416
15417static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15418        { 2, alc861_uniwill_m31_ch2_init },
15419        { 4, alc861_uniwill_m31_ch4_init },
15420};
15421
15422/* Set mic1 and line-in as input and unmute the mixer */
15423static struct hda_verb alc861_asus_ch2_init[] = {
15424        /* set pin widget 1Ah (line in) for input */
15425        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15426        /* set pin widget 18h (mic1/2) for input, for mic also enable
15427         * the vref
15428         */
15429        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15430
15431        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15432#if 0
15433        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15434        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15435#endif
15436        { } /* end */
15437};
15438/* Set mic1 nad line-in as output and mute mixer */
15439static struct hda_verb alc861_asus_ch6_init[] = {
15440        /* set pin widget 1Ah (line in) for output (Back Surround)*/
15441        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15442        /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15443        /* set pin widget 18h (mic1) for output (CLFE)*/
15444        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15445        /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15446        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15447        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15448
15449        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15450#if 0
15451        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15452        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15453#endif
15454        { } /* end */
15455};
15456
15457static struct hda_channel_mode alc861_asus_modes[2] = {
15458        { 2, alc861_asus_ch2_init },
15459        { 6, alc861_asus_ch6_init },
15460};
15461
15462/* patch-ALC861 */
15463
15464static struct snd_kcontrol_new alc861_base_mixer[] = {
15465        /* output mixer control */
15466        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15467        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15468        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15469        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15470        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15471
15472        /*Input mixer control */
15473        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15474           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15475        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15476        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15477        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15478        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15479        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15480        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15481        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15482        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15483
15484        { } /* end */
15485};
15486
15487static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15488        /* output mixer control */
15489        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15490        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15491        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15492        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15493        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15494
15495        /* Input mixer control */
15496        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15497           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15498        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15499        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15500        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15501        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15502        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15503        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15504        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15505        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15506
15507        {
15508                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15509                .name = "Channel Mode",
15510                .info = alc_ch_mode_info,
15511                .get = alc_ch_mode_get,
15512                .put = alc_ch_mode_put,
15513                .private_value = ARRAY_SIZE(alc861_threestack_modes),
15514        },
15515        { } /* end */
15516};
15517
15518static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15519        /* output mixer control */
15520        HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15521        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15522        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15523
15524        { } /* end */
15525};
15526
15527static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15528        /* output mixer control */
15529        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15530        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15531        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15532        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15533        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15534
15535        /* Input mixer control */
15536        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15537           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15538        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15539        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15540        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15541        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15542        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15543        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15544        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15545        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15546
15547        {
15548                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15549                .name = "Channel Mode",
15550                .info = alc_ch_mode_info,
15551                .get = alc_ch_mode_get,
15552                .put = alc_ch_mode_put,
15553                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15554        },
15555        { } /* end */
15556};
15557
15558static struct snd_kcontrol_new alc861_asus_mixer[] = {
15559        /* output mixer control */
15560        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15561        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15562        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15563        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15564        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15565
15566        /* Input mixer control */
15567        HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15568        HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15569        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15570        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15571        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15572        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15573        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15574        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15575        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15576        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15577
15578        {
15579                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15580                .name = "Channel Mode",
15581                .info = alc_ch_mode_info,
15582                .get = alc_ch_mode_get,
15583                .put = alc_ch_mode_put,
15584                .private_value = ARRAY_SIZE(alc861_asus_modes),
15585        },
15586        { }
15587};
15588
15589/* additional mixer */
15590static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15591        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15592        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15593        { }
15594};
15595
15596/*
15597 * generic initialization of ADC, input mixers and output mixers
15598 */
15599static struct hda_verb alc861_base_init_verbs[] = {
15600        /*
15601         * Unmute ADC0 and set the default input to mic-in
15602         */
15603        /* port-A for surround (rear panel) */
15604        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15605        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15606        /* port-B for mic-in (rear panel) with vref */
15607        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15608        /* port-C for line-in (rear panel) */
15609        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15610        /* port-D for Front */
15611        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15612        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15613        /* port-E for HP out (front panel) */
15614        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15615        /* route front PCM to HP */
15616        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15617        /* port-F for mic-in (front panel) with vref */
15618        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15619        /* port-G for CLFE (rear panel) */
15620        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621        { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622        /* port-H for side (rear panel) */
15623        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15624        { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15625        /* CD-in */
15626        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15627        /* route front mic to ADC1*/
15628        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15629        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15630
15631        /* Unmute DAC0~3 & spdif out*/
15632        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15633        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15634        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15637
15638        /* Unmute Mixer 14 (mic) 1c (Line in)*/
15639        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15640        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15641        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15643
15644        /* Unmute Stereo Mixer 15 */
15645        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15648        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15649
15650        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15651        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15654        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15655        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15656        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15658        /* hp used DAC 3 (Front) */
15659        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15660        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15661
15662        { }
15663};
15664
15665static struct hda_verb alc861_threestack_init_verbs[] = {
15666        /*
15667         * Unmute ADC0 and set the default input to mic-in
15668         */
15669        /* port-A for surround (rear panel) */
15670        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15671        /* port-B for mic-in (rear panel) with vref */
15672        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15673        /* port-C for line-in (rear panel) */
15674        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15675        /* port-D for Front */
15676        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15677        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15678        /* port-E for HP out (front panel) */
15679        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15680        /* route front PCM to HP */
15681        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15682        /* port-F for mic-in (front panel) with vref */
15683        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15684        /* port-G for CLFE (rear panel) */
15685        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15686        /* port-H for side (rear panel) */
15687        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15688        /* CD-in */
15689        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15690        /* route front mic to ADC1*/
15691        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15692        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15693        /* Unmute DAC0~3 & spdif out*/
15694        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15696        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15697        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15699
15700        /* Unmute Mixer 14 (mic) 1c (Line in)*/
15701        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15702        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15703        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705
15706        /* Unmute Stereo Mixer 15 */
15707        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15710        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15711
15712        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15716        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15718        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15720        /* hp used DAC 3 (Front) */
15721        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15722        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15723        { }
15724};
15725
15726static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15727        /*
15728         * Unmute ADC0 and set the default input to mic-in
15729         */
15730        /* port-A for surround (rear panel) */
15731        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15732        /* port-B for mic-in (rear panel) with vref */
15733        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15734        /* port-C for line-in (rear panel) */
15735        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15736        /* port-D for Front */
15737        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15738        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15739        /* port-E for HP out (front panel) */
15740        /* this has to be set to VREF80 */
15741        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15742        /* route front PCM to HP */
15743        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15744        /* port-F for mic-in (front panel) with vref */
15745        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15746        /* port-G for CLFE (rear panel) */
15747        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15748        /* port-H for side (rear panel) */
15749        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15750        /* CD-in */
15751        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15752        /* route front mic to ADC1*/
15753        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15754        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755        /* Unmute DAC0~3 & spdif out*/
15756        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15757        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15758        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15759        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15760        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15761
15762        /* Unmute Mixer 14 (mic) 1c (Line in)*/
15763        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15764        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15765        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15766        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15767
15768        /* Unmute Stereo Mixer 15 */
15769        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15772        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15773
15774        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15776        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15777        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15778        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15779        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15780        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15781        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15782        /* hp used DAC 3 (Front) */
15783        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15784        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15785        { }
15786};
15787
15788static struct hda_verb alc861_asus_init_verbs[] = {
15789        /*
15790         * Unmute ADC0 and set the default input to mic-in
15791         */
15792        /* port-A for surround (rear panel)
15793         * according to codec#0 this is the HP jack
15794         */
15795        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15796        /* route front PCM to HP */
15797        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15798        /* port-B for mic-in (rear panel) with vref */
15799        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15800        /* port-C for line-in (rear panel) */
15801        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15802        /* port-D for Front */
15803        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15804        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15805        /* port-E for HP out (front panel) */
15806        /* this has to be set to VREF80 */
15807        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15808        /* route front PCM to HP */
15809        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15810        /* port-F for mic-in (front panel) with vref */
15811        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15812        /* port-G for CLFE (rear panel) */
15813        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15814        /* port-H for side (rear panel) */
15815        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15816        /* CD-in */
15817        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15818        /* route front mic to ADC1*/
15819        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15820        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821        /* Unmute DAC0~3 & spdif out*/
15822        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15823        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15824        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15825        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15826        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15827        /* Unmute Mixer 14 (mic) 1c (Line in)*/
15828        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15829        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15830        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15831        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15832
15833        /* Unmute Stereo Mixer 15 */
15834        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15835        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15836        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15837        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15838
15839        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15840        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15841        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15842        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15843        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15844        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15845        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15846        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15847        /* hp used DAC 3 (Front) */
15848        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15849        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15850        { }
15851};
15852
15853/* additional init verbs for ASUS laptops */
15854static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15855        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15856        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15857        { }
15858};
15859
15860/*
15861 * generic initialization of ADC, input mixers and output mixers
15862 */
15863static struct hda_verb alc861_auto_init_verbs[] = {
15864        /*
15865         * Unmute ADC0 and set the default input to mic-in
15866         */
15867        /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15868        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15869
15870        /* Unmute DAC0~3 & spdif out*/
15871        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15872        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15873        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15874        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15875        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15876
15877        /* Unmute Mixer 14 (mic) 1c (Line in)*/
15878        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15879        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15880        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15881        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15882
15883        /* Unmute Stereo Mixer 15 */
15884        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15885        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15886        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15887        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15888
15889        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15890        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15891        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15892        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15893        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15894        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15895        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15896        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15897
15898        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15899        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15900        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15901        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15902        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15903        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15904        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15905        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15906
15907        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
15908
15909        { }
15910};
15911
15912static struct hda_verb alc861_toshiba_init_verbs[] = {
15913        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15914
15915        { }
15916};
15917
15918/* toggle speaker-output according to the hp-jack state */
15919static void alc861_toshiba_automute(struct hda_codec *codec)
15920{
15921        unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15922
15923        snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15924                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15925        snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15926                                 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15927}
15928
15929static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15930                                       unsigned int res)
15931{
15932        if ((res >> 26) == ALC880_HP_EVENT)
15933                alc861_toshiba_automute(codec);
15934}
15935
15936/* pcm configuration: identical with ALC880 */
15937#define alc861_pcm_analog_playback      alc880_pcm_analog_playback
15938#define alc861_pcm_analog_capture       alc880_pcm_analog_capture
15939#define alc861_pcm_digital_playback     alc880_pcm_digital_playback
15940#define alc861_pcm_digital_capture      alc880_pcm_digital_capture
15941
15942
15943#define ALC861_DIGOUT_NID       0x07
15944
15945static struct hda_channel_mode alc861_8ch_modes[1] = {
15946        { 8, NULL }
15947};
15948
15949static hda_nid_t alc861_dac_nids[4] = {
15950        /* front, surround, clfe, side */
15951        0x03, 0x06, 0x05, 0x04
15952};
15953
15954static hda_nid_t alc660_dac_nids[3] = {
15955        /* front, clfe, surround */
15956        0x03, 0x05, 0x06
15957};
15958
15959static hda_nid_t alc861_adc_nids[1] = {
15960        /* ADC0-2 */
15961        0x08,
15962};
15963
15964static struct hda_input_mux alc861_capture_source = {
15965        .num_items = 5,
15966        .items = {
15967                { "Mic", 0x0 },
15968                { "Front Mic", 0x3 },
15969                { "Line", 0x1 },
15970                { "CD", 0x4 },
15971                { "Mixer", 0x5 },
15972        },
15973};
15974
15975static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15976{
15977        struct alc_spec *spec = codec->spec;
15978        hda_nid_t mix, srcs[5];
15979        int i, j, num;
15980
15981        if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15982                return 0;
15983        num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15984        if (num < 0)
15985                return 0;
15986        for (i = 0; i < num; i++) {
15987                unsigned int type;
15988                type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15989                if (type != AC_WID_AUD_OUT)
15990                        continue;
15991                for (j = 0; j < spec->multiout.num_dacs; j++)
15992                        if (spec->multiout.dac_nids[j] == srcs[i])
15993                                break;
15994                if (j >= spec->multiout.num_dacs)
15995                        return srcs[i];
15996        }
15997        return 0;
15998}
15999
16000/* fill in the dac_nids table from the parsed pin configuration */
16001static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
16002                                     const struct auto_pin_cfg *cfg)
16003{
16004        struct alc_spec *spec = codec->spec;
16005        int i;
16006        hda_nid_t nid, dac;
16007
16008        spec->multiout.dac_nids = spec->private_dac_nids;
16009        for (i = 0; i < cfg->line_outs; i++) {
16010                nid = cfg->line_out_pins[i];
16011                dac = alc861_look_for_dac(codec, nid);
16012                if (!dac)
16013                        continue;
16014                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
16015        }
16016        return 0;
16017}
16018
16019static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16020                                  hda_nid_t nid, int idx, unsigned int chs)
16021{
16022        return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16023                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16024}
16025
16026#define alc861_create_out_sw(codec, pfx, nid, chs) \
16027        __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16028
16029/* add playback controls from the parsed DAC table */
16030static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16031                                             const struct auto_pin_cfg *cfg)
16032{
16033        struct alc_spec *spec = codec->spec;
16034        static const char * const chname[4] = {
16035                "Front", "Surround", NULL /*CLFE*/, "Side"
16036        };
16037        const char *pfx = alc_get_line_out_pfx(cfg, true);
16038        hda_nid_t nid;
16039        int i, err;
16040
16041        for (i = 0; i < cfg->line_outs; i++) {
16042                nid = spec->multiout.dac_nids[i];
16043                if (!nid)
16044                        continue;
16045                if (!pfx && i == 2) {
16046                        /* Center/LFE */
16047                        err = alc861_create_out_sw(codec, "Center", nid, 1);
16048                        if (err < 0)
16049                                return err;
16050                        err = alc861_create_out_sw(codec, "LFE", nid, 2);
16051                        if (err < 0)
16052                                return err;
16053                } else {
16054                        const char *name = pfx;
16055                        if (!name)
16056                                name = chname[i];
16057                        err = __alc861_create_out_sw(codec, name, nid, i, 3);
16058                        if (err < 0)
16059                                return err;
16060                }
16061        }
16062        return 0;
16063}
16064
16065static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16066{
16067        struct alc_spec *spec = codec->spec;
16068        int err;
16069        hda_nid_t nid;
16070
16071        if (!pin)
16072                return 0;
16073
16074        if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16075                nid = alc861_look_for_dac(codec, pin);
16076                if (nid) {
16077                        err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16078                        if (err < 0)
16079                                return err;
16080                        spec->multiout.hp_nid = nid;
16081                }
16082        }
16083        return 0;
16084}
16085
16086/* create playback/capture controls for input pins */
16087static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16088                                                const struct auto_pin_cfg *cfg)
16089{
16090        return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16091}
16092
16093static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16094                                              hda_nid_t nid,
16095                                              int pin_type, hda_nid_t dac)
16096{
16097        hda_nid_t mix, srcs[5];
16098        int i, num;
16099
16100        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16101                            pin_type);
16102        snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16103                            AMP_OUT_UNMUTE);
16104        if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16105                return;
16106        num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16107        if (num < 0)
16108                return;
16109        for (i = 0; i < num; i++) {
16110                unsigned int mute;
16111                if (srcs[i] == dac || srcs[i] == 0x15)
16112                        mute = AMP_IN_UNMUTE(i);
16113                else
16114                        mute = AMP_IN_MUTE(i);
16115                snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16116                                    mute);
16117        }
16118}
16119
16120static void alc861_auto_init_multi_out(struct hda_codec *codec)
16121{
16122        struct alc_spec *spec = codec->spec;
16123        int i;
16124
16125        for (i = 0; i < spec->autocfg.line_outs; i++) {
16126                hda_nid_t nid = spec->autocfg.line_out_pins[i];
16127                int pin_type = get_pin_type(spec->autocfg.line_out_type);
16128                if (nid)
16129                        alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16130                                                          spec->multiout.dac_nids[i]);
16131        }
16132}
16133
16134static void alc861_auto_init_hp_out(struct hda_codec *codec)
16135{
16136        struct alc_spec *spec = codec->spec;
16137
16138        if (spec->autocfg.hp_outs)
16139                alc861_auto_set_output_and_unmute(codec,
16140                                                  spec->autocfg.hp_pins[0],
16141                                                  PIN_HP,
16142                                                  spec->multiout.hp_nid);
16143        if (spec->autocfg.speaker_outs)
16144                alc861_auto_set_output_and_unmute(codec,
16145                                                  spec->autocfg.speaker_pins[0],
16146                                                  PIN_OUT,
16147                                                  spec->multiout.dac_nids[0]);
16148}
16149
16150static void alc861_auto_init_analog_input(struct hda_codec *codec)
16151{
16152        struct alc_spec *spec = codec->spec;
16153        struct auto_pin_cfg *cfg = &spec->autocfg;
16154        int i;
16155
16156        for (i = 0; i < cfg->num_inputs; i++) {
16157                hda_nid_t nid = cfg->inputs[i].pin;
16158                if (nid >= 0x0c && nid <= 0x11)
16159                        alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16160        }
16161}
16162
16163/* parse the BIOS configuration and set up the alc_spec */
16164/* return 1 if successful, 0 if the proper config is not found,
16165 * or a negative error code
16166 */
16167static int alc861_parse_auto_config(struct hda_codec *codec)
16168{
16169        struct alc_spec *spec = codec->spec;
16170        int err;
16171        static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16172
16173        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16174                                           alc861_ignore);
16175        if (err < 0)
16176                return err;
16177        if (!spec->autocfg.line_outs)
16178                return 0; /* can't find valid BIOS pin config */
16179
16180        err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16181        if (err < 0)
16182                return err;
16183        err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16184        if (err < 0)
16185                return err;
16186        err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16187        if (err < 0)
16188                return err;
16189        err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16190        if (err < 0)
16191                return err;
16192
16193        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16194
16195        alc_auto_parse_digital(codec);
16196
16197        if (spec->kctls.list)
16198                add_mixer(spec, spec->kctls.list);
16199
16200        add_verb(spec, alc861_auto_init_verbs);
16201
16202        spec->num_mux_defs = 1;
16203        spec->input_mux = &spec->private_imux[0];
16204
16205        spec->adc_nids = alc861_adc_nids;
16206        spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16207        set_capture_mixer(codec);
16208
16209        alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16210
16211        return 1;
16212}
16213
16214/* additional initialization for auto-configuration model */
16215static void alc861_auto_init(struct hda_codec *codec)
16216{
16217        struct alc_spec *spec = codec->spec;
16218        alc861_auto_init_multi_out(codec);
16219        alc861_auto_init_hp_out(codec);
16220        alc861_auto_init_analog_input(codec);
16221        alc_auto_init_digital(codec);
16222        if (spec->unsol_event)
16223                alc_inithook(codec);
16224}
16225
16226#ifdef CONFIG_SND_HDA_POWER_SAVE
16227static struct hda_amp_list alc861_loopbacks[] = {
16228        { 0x15, HDA_INPUT, 0 },
16229        { 0x15, HDA_INPUT, 1 },
16230        { 0x15, HDA_INPUT, 2 },
16231        { 0x15, HDA_INPUT, 3 },
16232        { } /* end */
16233};
16234#endif
16235
16236
16237/*
16238 * configuration and preset
16239 */
16240static const char * const alc861_models[ALC861_MODEL_LAST] = {
16241        [ALC861_3ST]            = "3stack",
16242        [ALC660_3ST]            = "3stack-660",
16243        [ALC861_3ST_DIG]        = "3stack-dig",
16244        [ALC861_6ST_DIG]        = "6stack-dig",
16245        [ALC861_UNIWILL_M31]    = "uniwill-m31",
16246        [ALC861_TOSHIBA]        = "toshiba",
16247        [ALC861_ASUS]           = "asus",
16248        [ALC861_ASUS_LAPTOP]    = "asus-laptop",
16249        [ALC861_AUTO]           = "auto",
16250};
16251
16252static struct snd_pci_quirk alc861_cfg_tbl[] = {
16253        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16254        SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16255        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16256        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16257        SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16258        SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16259        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16260        /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16261         *        Any other models that need this preset?
16262         */
16263        /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16264        SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16265        SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16266        SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16267        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16268        SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16269        /* FIXME: the below seems conflict */
16270        /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16271        SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16272        SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16273        {}
16274};
16275
16276static struct alc_config_preset alc861_presets[] = {
16277        [ALC861_3ST] = {
16278                .mixers = { alc861_3ST_mixer },
16279                .init_verbs = { alc861_threestack_init_verbs },
16280                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16281                .dac_nids = alc861_dac_nids,
16282                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16283                .channel_mode = alc861_threestack_modes,
16284                .need_dac_fix = 1,
16285                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16286                .adc_nids = alc861_adc_nids,
16287                .input_mux = &alc861_capture_source,
16288        },
16289        [ALC861_3ST_DIG] = {
16290                .mixers = { alc861_base_mixer },
16291                .init_verbs = { alc861_threestack_init_verbs },
16292                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16293                .dac_nids = alc861_dac_nids,
16294                .dig_out_nid = ALC861_DIGOUT_NID,
16295                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16296                .channel_mode = alc861_threestack_modes,
16297                .need_dac_fix = 1,
16298                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16299                .adc_nids = alc861_adc_nids,
16300                .input_mux = &alc861_capture_source,
16301        },
16302        [ALC861_6ST_DIG] = {
16303                .mixers = { alc861_base_mixer },
16304                .init_verbs = { alc861_base_init_verbs },
16305                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16306                .dac_nids = alc861_dac_nids,
16307                .dig_out_nid = ALC861_DIGOUT_NID,
16308                .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16309                .channel_mode = alc861_8ch_modes,
16310                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16311                .adc_nids = alc861_adc_nids,
16312                .input_mux = &alc861_capture_source,
16313        },
16314        [ALC660_3ST] = {
16315                .mixers = { alc861_3ST_mixer },
16316                .init_verbs = { alc861_threestack_init_verbs },
16317                .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16318                .dac_nids = alc660_dac_nids,
16319                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16320                .channel_mode = alc861_threestack_modes,
16321                .need_dac_fix = 1,
16322                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16323                .adc_nids = alc861_adc_nids,
16324                .input_mux = &alc861_capture_source,
16325        },
16326        [ALC861_UNIWILL_M31] = {
16327                .mixers = { alc861_uniwill_m31_mixer },
16328                .init_verbs = { alc861_uniwill_m31_init_verbs },
16329                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16330                .dac_nids = alc861_dac_nids,
16331                .dig_out_nid = ALC861_DIGOUT_NID,
16332                .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16333                .channel_mode = alc861_uniwill_m31_modes,
16334                .need_dac_fix = 1,
16335                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16336                .adc_nids = alc861_adc_nids,
16337                .input_mux = &alc861_capture_source,
16338        },
16339        [ALC861_TOSHIBA] = {
16340                .mixers = { alc861_toshiba_mixer },
16341                .init_verbs = { alc861_base_init_verbs,
16342                                alc861_toshiba_init_verbs },
16343                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16344                .dac_nids = alc861_dac_nids,
16345                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16346                .channel_mode = alc883_3ST_2ch_modes,
16347                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16348                .adc_nids = alc861_adc_nids,
16349                .input_mux = &alc861_capture_source,
16350                .unsol_event = alc861_toshiba_unsol_event,
16351                .init_hook = alc861_toshiba_automute,
16352        },
16353        [ALC861_ASUS] = {
16354                .mixers = { alc861_asus_mixer },
16355                .init_verbs = { alc861_asus_init_verbs },
16356                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16357                .dac_nids = alc861_dac_nids,
16358                .dig_out_nid = ALC861_DIGOUT_NID,
16359                .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16360                .channel_mode = alc861_asus_modes,
16361                .need_dac_fix = 1,
16362                .hp_nid = 0x06,
16363                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16364                .adc_nids = alc861_adc_nids,
16365                .input_mux = &alc861_capture_source,
16366        },
16367        [ALC861_ASUS_LAPTOP] = {
16368                .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16369                .init_verbs = { alc861_asus_init_verbs,
16370                                alc861_asus_laptop_init_verbs },
16371                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16372                .dac_nids = alc861_dac_nids,
16373                .dig_out_nid = ALC861_DIGOUT_NID,
16374                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16375                .channel_mode = alc883_3ST_2ch_modes,
16376                .need_dac_fix = 1,
16377                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16378                .adc_nids = alc861_adc_nids,
16379                .input_mux = &alc861_capture_source,
16380        },
16381};
16382
16383/* Pin config fixes */
16384enum {
16385        PINFIX_FSC_AMILO_PI1505,
16386};
16387
16388static const struct alc_fixup alc861_fixups[] = {
16389        [PINFIX_FSC_AMILO_PI1505] = {
16390                .type = ALC_FIXUP_PINS,
16391                .v.pins = (const struct alc_pincfg[]) {
16392                        { 0x0b, 0x0221101f }, /* HP */
16393                        { 0x0f, 0x90170310 }, /* speaker */
16394                        { }
16395                }
16396        },
16397};
16398
16399static struct snd_pci_quirk alc861_fixup_tbl[] = {
16400        SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16401        {}
16402};
16403
16404static int patch_alc861(struct hda_codec *codec)
16405{
16406        struct alc_spec *spec;
16407        int board_config;
16408        int err;
16409
16410        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16411        if (spec == NULL)
16412                return -ENOMEM;
16413
16414        codec->spec = spec;
16415
16416        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16417                                                  alc861_models,
16418                                                  alc861_cfg_tbl);
16419
16420        if (board_config < 0) {
16421                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16422                       codec->chip_name);
16423                board_config = ALC861_AUTO;
16424        }
16425
16426        if (board_config == ALC861_AUTO) {
16427                alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16428                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16429        }
16430
16431        if (board_config == ALC861_AUTO) {
16432                /* automatic parse from the BIOS config */
16433                err = alc861_parse_auto_config(codec);
16434                if (err < 0) {
16435                        alc_free(codec);
16436                        return err;
16437                } else if (!err) {
16438                        printk(KERN_INFO
16439                               "hda_codec: Cannot set up configuration "
16440                               "from BIOS.  Using base mode...\n");
16441                   board_config = ALC861_3ST_DIG;
16442                }
16443        }
16444
16445        err = snd_hda_attach_beep_device(codec, 0x23);
16446        if (err < 0) {
16447                alc_free(codec);
16448                return err;
16449        }
16450
16451        if (board_config != ALC861_AUTO)
16452                setup_preset(codec, &alc861_presets[board_config]);
16453
16454        spec->stream_analog_playback = &alc861_pcm_analog_playback;
16455        spec->stream_analog_capture = &alc861_pcm_analog_capture;
16456
16457        spec->stream_digital_playback = &alc861_pcm_digital_playback;
16458        spec->stream_digital_capture = &alc861_pcm_digital_capture;
16459
16460        if (!spec->cap_mixer)
16461                set_capture_mixer(codec);
16462        set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16463
16464        spec->vmaster_nid = 0x03;
16465
16466        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16467
16468        codec->patch_ops = alc_patch_ops;
16469        if (board_config == ALC861_AUTO) {
16470                spec->init_hook = alc861_auto_init;
16471#ifdef CONFIG_SND_HDA_POWER_SAVE
16472                spec->power_hook = alc_power_eapd;
16473#endif
16474        }
16475#ifdef CONFIG_SND_HDA_POWER_SAVE
16476        if (!spec->loopback.amplist)
16477                spec->loopback.amplist = alc861_loopbacks;
16478#endif
16479
16480        return 0;
16481}
16482
16483/*
16484 * ALC861-VD support
16485 *
16486 * Based on ALC882
16487 *
16488 * In addition, an independent DAC
16489 */
16490#define ALC861VD_DIGOUT_NID     0x06
16491
16492static hda_nid_t alc861vd_dac_nids[4] = {
16493        /* front, surr, clfe, side surr */
16494        0x02, 0x03, 0x04, 0x05
16495};
16496
16497/* dac_nids for ALC660vd are in a different order - according to
16498 * Realtek's driver.
16499 * This should probably result in a different mixer for 6stack models
16500 * of ALC660vd codecs, but for now there is only 3stack mixer
16501 * - and it is the same as in 861vd.
16502 * adc_nids in ALC660vd are (is) the same as in 861vd
16503 */
16504static hda_nid_t alc660vd_dac_nids[3] = {
16505        /* front, rear, clfe, rear_surr */
16506        0x02, 0x04, 0x03
16507};
16508
16509static hda_nid_t alc861vd_adc_nids[1] = {
16510        /* ADC0 */
16511        0x09,
16512};
16513
16514static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16515
16516/* input MUX */
16517/* FIXME: should be a matrix-type input source selection */
16518static struct hda_input_mux alc861vd_capture_source = {
16519        .num_items = 4,
16520        .items = {
16521                { "Mic", 0x0 },
16522                { "Front Mic", 0x1 },
16523                { "Line", 0x2 },
16524                { "CD", 0x4 },
16525        },
16526};
16527
16528static struct hda_input_mux alc861vd_dallas_capture_source = {
16529        .num_items = 2,
16530        .items = {
16531                { "Mic", 0x0 },
16532                { "Internal Mic", 0x1 },
16533        },
16534};
16535
16536static struct hda_input_mux alc861vd_hp_capture_source = {
16537        .num_items = 2,
16538        .items = {
16539                { "Front Mic", 0x0 },
16540                { "ATAPI Mic", 0x1 },
16541        },
16542};
16543
16544/*
16545 * 2ch mode
16546 */
16547static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16548        { 2, NULL }
16549};
16550
16551/*
16552 * 6ch mode
16553 */
16554static struct hda_verb alc861vd_6stack_ch6_init[] = {
16555        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16556        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16557        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16558        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559        { } /* end */
16560};
16561
16562/*
16563 * 8ch mode
16564 */
16565static struct hda_verb alc861vd_6stack_ch8_init[] = {
16566        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16567        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16568        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570        { } /* end */
16571};
16572
16573static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16574        { 6, alc861vd_6stack_ch6_init },
16575        { 8, alc861vd_6stack_ch8_init },
16576};
16577
16578static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16579        {
16580                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16581                .name = "Channel Mode",
16582                .info = alc_ch_mode_info,
16583                .get = alc_ch_mode_get,
16584                .put = alc_ch_mode_put,
16585        },
16586        { } /* end */
16587};
16588
16589/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16590 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16591 */
16592static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16593        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16594        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16595
16596        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16597        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16598
16599        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16600                                HDA_OUTPUT),
16601        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16602                                HDA_OUTPUT),
16603        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16604        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16605
16606        HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16607        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16608
16609        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16610
16611        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16612        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16613        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16614
16615        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16616        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16617        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16618
16619        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16620        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16621
16622        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16623        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16624
16625        { } /* end */
16626};
16627
16628static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16629        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16630        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16631
16632        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16633
16634        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16635        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16636        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16637
16638        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16639        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16640        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16641
16642        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16643        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16644
16645        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16646        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16647
16648        { } /* end */
16649};
16650
16651static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16652        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16653        /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16654        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16655
16656        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16657
16658        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16659        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16660        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16661
16662        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16663        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16664        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16665
16666        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16667        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16668
16669        { } /* end */
16670};
16671
16672/* Pin assignment: Speaker=0x14, HP = 0x15,
16673 *                 Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16674 */
16675static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16676        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16677        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16678        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16679        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16680        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16681        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16682        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16683        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16684        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16685        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16686        { } /* end */
16687};
16688
16689/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16690 *                 Front Mic=0x18, ATAPI Mic = 0x19,
16691 */
16692static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16693        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16694        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16695        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16696        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16697        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16698        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16699        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16700        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16701
16702        { } /* end */
16703};
16704
16705/*
16706 * generic initialization of ADC, input mixers and output mixers
16707 */
16708static struct hda_verb alc861vd_volume_init_verbs[] = {
16709        /*
16710         * Unmute ADC0 and set the default input to mic-in
16711         */
16712        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16713        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16714
16715        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16716         * the analog-loopback mixer widget
16717         */
16718        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16719        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16720        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16721        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16722        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16723        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16724
16725        /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16726        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16727        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16728        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16729        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16730
16731        /*
16732         * Set up output mixers (0x02 - 0x05)
16733         */
16734        /* set vol=0 to output mixers */
16735        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16736        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16737        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739
16740        /* set up input amps for analog loopback */
16741        /* Amp Indices: DAC = 0, mixer = 1 */
16742        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16743        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16744        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750
16751        { }
16752};
16753
16754/*
16755 * 3-stack pin configuration:
16756 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16757 */
16758static struct hda_verb alc861vd_3stack_init_verbs[] = {
16759        /*
16760         * Set pin mode and muting
16761         */
16762        /* set front pin widgets 0x14 for output */
16763        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16764        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16765        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16766
16767        /* Mic (rear) pin: input vref at 80% */
16768        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16769        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16770        /* Front Mic pin: input vref at 80% */
16771        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16772        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16773        /* Line In pin: input */
16774        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16775        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16776        /* Line-2 In: Headphone output (output 0 - 0x0c) */
16777        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16778        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16779        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16780        /* CD pin widget for input */
16781        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16782
16783        { }
16784};
16785
16786/*
16787 * 6-stack pin configuration:
16788 */
16789static struct hda_verb alc861vd_6stack_init_verbs[] = {
16790        /*
16791         * Set pin mode and muting
16792         */
16793        /* set front pin widgets 0x14 for output */
16794        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16795        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16796        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16797
16798        /* Rear Pin: output 1 (0x0d) */
16799        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16800        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16801        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16802        /* CLFE Pin: output 2 (0x0e) */
16803        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16804        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16805        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16806        /* Side Pin: output 3 (0x0f) */
16807        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16808        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16809        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16810
16811        /* Mic (rear) pin: input vref at 80% */
16812        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16813        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16814        /* Front Mic pin: input vref at 80% */
16815        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16816        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16817        /* Line In pin: input */
16818        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16819        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16820        /* Line-2 In: Headphone output (output 0 - 0x0c) */
16821        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16822        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16823        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16824        /* CD pin widget for input */
16825        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16826
16827        { }
16828};
16829
16830static struct hda_verb alc861vd_eapd_verbs[] = {
16831        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16832        { }
16833};
16834
16835static struct hda_verb alc660vd_eapd_verbs[] = {
16836        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16837        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16838        { }
16839};
16840
16841static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16842        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16843        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16844        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16845        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16846        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16847        {}
16848};
16849
16850static void alc861vd_lenovo_setup(struct hda_codec *codec)
16851{
16852        struct alc_spec *spec = codec->spec;
16853        spec->autocfg.hp_pins[0] = 0x1b;
16854        spec->autocfg.speaker_pins[0] = 0x14;
16855}
16856
16857static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16858{
16859        alc_automute_amp(codec);
16860        alc88x_simple_mic_automute(codec);
16861}
16862
16863static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16864                                        unsigned int res)
16865{
16866        switch (res >> 26) {
16867        case ALC880_MIC_EVENT:
16868                alc88x_simple_mic_automute(codec);
16869                break;
16870        default:
16871                alc_automute_amp_unsol_event(codec, res);
16872                break;
16873        }
16874}
16875
16876static struct hda_verb alc861vd_dallas_verbs[] = {
16877        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16878        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16879        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16880        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16881
16882        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16883        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16884        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16885        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16886        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16887        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16888        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16890
16891        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16892        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16893        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16894        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16895        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899
16900        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16901        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16902        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16903        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16904        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16905        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16906        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16907        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16908
16909        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16910        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16911        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16912        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16913
16914        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16915        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16916        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16917
16918        { } /* end */
16919};
16920
16921/* toggle speaker-output according to the hp-jack state */
16922static void alc861vd_dallas_setup(struct hda_codec *codec)
16923{
16924        struct alc_spec *spec = codec->spec;
16925
16926        spec->autocfg.hp_pins[0] = 0x15;
16927        spec->autocfg.speaker_pins[0] = 0x14;
16928}
16929
16930#ifdef CONFIG_SND_HDA_POWER_SAVE
16931#define alc861vd_loopbacks      alc880_loopbacks
16932#endif
16933
16934/* pcm configuration: identical with ALC880 */
16935#define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
16936#define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
16937#define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
16938#define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
16939
16940/*
16941 * configuration and preset
16942 */
16943static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16944        [ALC660VD_3ST]          = "3stack-660",
16945        [ALC660VD_3ST_DIG]      = "3stack-660-digout",
16946        [ALC660VD_ASUS_V1S]     = "asus-v1s",
16947        [ALC861VD_3ST]          = "3stack",
16948        [ALC861VD_3ST_DIG]      = "3stack-digout",
16949        [ALC861VD_6ST_DIG]      = "6stack-digout",
16950        [ALC861VD_LENOVO]       = "lenovo",
16951        [ALC861VD_DALLAS]       = "dallas",
16952        [ALC861VD_HP]           = "hp",
16953        [ALC861VD_AUTO]         = "auto",
16954};
16955
16956static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16957        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16958        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16959        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16960        /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16961        SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16962        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16963        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16964        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16965        /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16966        SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16967        SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16968        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16969        SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16970        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16971        SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16972        {}
16973};
16974
16975static struct alc_config_preset alc861vd_presets[] = {
16976        [ALC660VD_3ST] = {
16977                .mixers = { alc861vd_3st_mixer },
16978                .init_verbs = { alc861vd_volume_init_verbs,
16979                                 alc861vd_3stack_init_verbs },
16980                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16981                .dac_nids = alc660vd_dac_nids,
16982                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16983                .channel_mode = alc861vd_3stack_2ch_modes,
16984                .input_mux = &alc861vd_capture_source,
16985        },
16986        [ALC660VD_3ST_DIG] = {
16987                .mixers = { alc861vd_3st_mixer },
16988                .init_verbs = { alc861vd_volume_init_verbs,
16989                                 alc861vd_3stack_init_verbs },
16990                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16991                .dac_nids = alc660vd_dac_nids,
16992                .dig_out_nid = ALC861VD_DIGOUT_NID,
16993                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16994                .channel_mode = alc861vd_3stack_2ch_modes,
16995                .input_mux = &alc861vd_capture_source,
16996        },
16997        [ALC861VD_3ST] = {
16998                .mixers = { alc861vd_3st_mixer },
16999                .init_verbs = { alc861vd_volume_init_verbs,
17000                                 alc861vd_3stack_init_verbs },
17001                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17002                .dac_nids = alc861vd_dac_nids,
17003                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17004                .channel_mode = alc861vd_3stack_2ch_modes,
17005                .input_mux = &alc861vd_capture_source,
17006        },
17007        [ALC861VD_3ST_DIG] = {
17008                .mixers = { alc861vd_3st_mixer },
17009                .init_verbs = { alc861vd_volume_init_verbs,
17010                                 alc861vd_3stack_init_verbs },
17011                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17012                .dac_nids = alc861vd_dac_nids,
17013                .dig_out_nid = ALC861VD_DIGOUT_NID,
17014                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17015                .channel_mode = alc861vd_3stack_2ch_modes,
17016                .input_mux = &alc861vd_capture_source,
17017        },
17018        [ALC861VD_6ST_DIG] = {
17019                .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17020                .init_verbs = { alc861vd_volume_init_verbs,
17021                                alc861vd_6stack_init_verbs },
17022                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17023                .dac_nids = alc861vd_dac_nids,
17024                .dig_out_nid = ALC861VD_DIGOUT_NID,
17025                .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17026                .channel_mode = alc861vd_6stack_modes,
17027                .input_mux = &alc861vd_capture_source,
17028        },
17029        [ALC861VD_LENOVO] = {
17030                .mixers = { alc861vd_lenovo_mixer },
17031                .init_verbs = { alc861vd_volume_init_verbs,
17032                                alc861vd_3stack_init_verbs,
17033                                alc861vd_eapd_verbs,
17034                                alc861vd_lenovo_unsol_verbs },
17035                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17036                .dac_nids = alc660vd_dac_nids,
17037                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17038                .channel_mode = alc861vd_3stack_2ch_modes,
17039                .input_mux = &alc861vd_capture_source,
17040                .unsol_event = alc861vd_lenovo_unsol_event,
17041                .setup = alc861vd_lenovo_setup,
17042                .init_hook = alc861vd_lenovo_init_hook,
17043        },
17044        [ALC861VD_DALLAS] = {
17045                .mixers = { alc861vd_dallas_mixer },
17046                .init_verbs = { alc861vd_dallas_verbs },
17047                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17048                .dac_nids = alc861vd_dac_nids,
17049                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17050                .channel_mode = alc861vd_3stack_2ch_modes,
17051                .input_mux = &alc861vd_dallas_capture_source,
17052                .unsol_event = alc_automute_amp_unsol_event,
17053                .setup = alc861vd_dallas_setup,
17054                .init_hook = alc_automute_amp,
17055        },
17056        [ALC861VD_HP] = {
17057                .mixers = { alc861vd_hp_mixer },
17058                .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17059                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17060                .dac_nids = alc861vd_dac_nids,
17061                .dig_out_nid = ALC861VD_DIGOUT_NID,
17062                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17063                .channel_mode = alc861vd_3stack_2ch_modes,
17064                .input_mux = &alc861vd_hp_capture_source,
17065                .unsol_event = alc_automute_amp_unsol_event,
17066                .setup = alc861vd_dallas_setup,
17067                .init_hook = alc_automute_amp,
17068        },
17069        [ALC660VD_ASUS_V1S] = {
17070                .mixers = { alc861vd_lenovo_mixer },
17071                .init_verbs = { alc861vd_volume_init_verbs,
17072                                alc861vd_3stack_init_verbs,
17073                                alc861vd_eapd_verbs,
17074                                alc861vd_lenovo_unsol_verbs },
17075                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17076                .dac_nids = alc660vd_dac_nids,
17077                .dig_out_nid = ALC861VD_DIGOUT_NID,
17078                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17079                .channel_mode = alc861vd_3stack_2ch_modes,
17080                .input_mux = &alc861vd_capture_source,
17081                .unsol_event = alc861vd_lenovo_unsol_event,
17082                .setup = alc861vd_lenovo_setup,
17083                .init_hook = alc861vd_lenovo_init_hook,
17084        },
17085};
17086
17087/*
17088 * BIOS auto configuration
17089 */
17090static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17091                                                const struct auto_pin_cfg *cfg)
17092{
17093        return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17094}
17095
17096
17097static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17098                                hda_nid_t nid, int pin_type, int dac_idx)
17099{
17100        alc_set_pin_output(codec, nid, pin_type);
17101}
17102
17103static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17104{
17105        struct alc_spec *spec = codec->spec;
17106        int i;
17107
17108        for (i = 0; i <= HDA_SIDE; i++) {
17109                hda_nid_t nid = spec->autocfg.line_out_pins[i];
17110                int pin_type = get_pin_type(spec->autocfg.line_out_type);
17111                if (nid)
17112                        alc861vd_auto_set_output_and_unmute(codec, nid,
17113                                                            pin_type, i);
17114        }
17115}
17116
17117
17118static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17119{
17120        struct alc_spec *spec = codec->spec;
17121        hda_nid_t pin;
17122
17123        pin = spec->autocfg.hp_pins[0];
17124        if (pin) /* connect to front and use dac 0 */
17125                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17126        pin = spec->autocfg.speaker_pins[0];
17127        if (pin)
17128                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17129}
17130
17131#define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
17132
17133static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17134{
17135        struct alc_spec *spec = codec->spec;
17136        struct auto_pin_cfg *cfg = &spec->autocfg;
17137        int i;
17138
17139        for (i = 0; i < cfg->num_inputs; i++) {
17140                hda_nid_t nid = cfg->inputs[i].pin;
17141                if (alc_is_input_pin(codec, nid)) {
17142                        alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17143                        if (nid != ALC861VD_PIN_CD_NID &&
17144                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17145                                snd_hda_codec_write(codec, nid, 0,
17146                                                AC_VERB_SET_AMP_GAIN_MUTE,
17147                                                AMP_OUT_MUTE);
17148                }
17149        }
17150}
17151
17152#define alc861vd_auto_init_input_src    alc882_auto_init_input_src
17153
17154#define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
17155#define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
17156
17157/* add playback controls from the parsed DAC table */
17158/* Based on ALC880 version. But ALC861VD has separate,
17159 * different NIDs for mute/unmute switch and volume control */
17160static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17161                                             const struct auto_pin_cfg *cfg)
17162{
17163        static const char * const chname[4] = {
17164                "Front", "Surround", "CLFE", "Side"
17165        };
17166        const char *pfx = alc_get_line_out_pfx(cfg, true);
17167        hda_nid_t nid_v, nid_s;
17168        int i, err;
17169
17170        for (i = 0; i < cfg->line_outs; i++) {
17171                if (!spec->multiout.dac_nids[i])
17172                        continue;
17173                nid_v = alc861vd_idx_to_mixer_vol(
17174                                alc880_dac_to_idx(
17175                                        spec->multiout.dac_nids[i]));
17176                nid_s = alc861vd_idx_to_mixer_switch(
17177                                alc880_dac_to_idx(
17178                                        spec->multiout.dac_nids[i]));
17179
17180                if (!pfx && i == 2) {
17181                        /* Center/LFE */
17182                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17183                                              "Center",
17184                                          HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17185                                                              HDA_OUTPUT));
17186                        if (err < 0)
17187                                return err;
17188                        err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17189                                              "LFE",
17190                                          HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17191                                                              HDA_OUTPUT));
17192                        if (err < 0)
17193                                return err;
17194                        err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17195                                             "Center",
17196                                          HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17197                                                              HDA_INPUT));
17198                        if (err < 0)
17199                                return err;
17200                        err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17201                                             "LFE",
17202                                          HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17203                                                              HDA_INPUT));
17204                        if (err < 0)
17205                                return err;
17206                } else {
17207                        const char *name = pfx;
17208                        if (!name)
17209                                name = chname[i];
17210                        err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17211                                                name, i,
17212                                          HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17213                                                              HDA_OUTPUT));
17214                        if (err < 0)
17215                                return err;
17216                        err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17217                                               name, i,
17218                                          HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17219                                                              HDA_INPUT));
17220                        if (err < 0)
17221                                return err;
17222                }
17223        }
17224        return 0;
17225}
17226
17227/* add playback controls for speaker and HP outputs */
17228/* Based on ALC880 version. But ALC861VD has separate,
17229 * different NIDs for mute/unmute switch and volume control */
17230static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17231                                        hda_nid_t pin, const char *pfx)
17232{
17233        hda_nid_t nid_v, nid_s;
17234        int err;
17235
17236        if (!pin)
17237                return 0;
17238
17239        if (alc880_is_fixed_pin(pin)) {
17240                nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17241                /* specify the DAC as the extra output */
17242                if (!spec->multiout.hp_nid)
17243                        spec->multiout.hp_nid = nid_v;
17244                else
17245                        spec->multiout.extra_out_nid[0] = nid_v;
17246                /* control HP volume/switch on the output mixer amp */
17247                nid_v = alc861vd_idx_to_mixer_vol(
17248                                alc880_fixed_pin_idx(pin));
17249                nid_s = alc861vd_idx_to_mixer_switch(
17250                                alc880_fixed_pin_idx(pin));
17251
17252                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17253                                  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17254                if (err < 0)
17255                        return err;
17256                err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17257                                  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17258                if (err < 0)
17259                        return err;
17260        } else if (alc880_is_multi_pin(pin)) {
17261                /* set manual connection */
17262                /* we have only a switch on HP-out PIN */
17263                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17264                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17265                if (err < 0)
17266                        return err;
17267        }
17268        return 0;
17269}
17270
17271/* parse the BIOS configuration and set up the alc_spec
17272 * return 1 if successful, 0 if the proper config is not found,
17273 * or a negative error code
17274 * Based on ALC880 version - had to change it to override
17275 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17276static int alc861vd_parse_auto_config(struct hda_codec *codec)
17277{
17278        struct alc_spec *spec = codec->spec;
17279        int err;
17280        static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17281
17282        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17283                                           alc861vd_ignore);
17284        if (err < 0)
17285                return err;
17286        if (!spec->autocfg.line_outs)
17287                return 0; /* can't find valid BIOS pin config */
17288
17289        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17290        if (err < 0)
17291                return err;
17292        err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17293        if (err < 0)
17294                return err;
17295        err = alc861vd_auto_create_extra_out(spec,
17296                                             spec->autocfg.speaker_pins[0],
17297                                             "Speaker");
17298        if (err < 0)
17299                return err;
17300        err = alc861vd_auto_create_extra_out(spec,
17301                                             spec->autocfg.hp_pins[0],
17302                                             "Headphone");
17303        if (err < 0)
17304                return err;
17305        err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17306        if (err < 0)
17307                return err;
17308
17309        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17310
17311        alc_auto_parse_digital(codec);
17312
17313        if (spec->kctls.list)
17314                add_mixer(spec, spec->kctls.list);
17315
17316        add_verb(spec, alc861vd_volume_init_verbs);
17317
17318        spec->num_mux_defs = 1;
17319        spec->input_mux = &spec->private_imux[0];
17320
17321        err = alc_auto_add_mic_boost(codec);
17322        if (err < 0)
17323                return err;
17324
17325        alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17326
17327        return 1;
17328}
17329
17330/* additional initialization for auto-configuration model */
17331static void alc861vd_auto_init(struct hda_codec *codec)
17332{
17333        struct alc_spec *spec = codec->spec;
17334        alc861vd_auto_init_multi_out(codec);
17335        alc861vd_auto_init_hp_out(codec);
17336        alc861vd_auto_init_analog_input(codec);
17337        alc861vd_auto_init_input_src(codec);
17338        alc_auto_init_digital(codec);
17339        if (spec->unsol_event)
17340                alc_inithook(codec);
17341}
17342
17343enum {
17344        ALC660VD_FIX_ASUS_GPIO1
17345};
17346
17347/* reset GPIO1 */
17348static const struct alc_fixup alc861vd_fixups[] = {
17349        [ALC660VD_FIX_ASUS_GPIO1] = {
17350                .type = ALC_FIXUP_VERBS,
17351                .v.verbs = (const struct hda_verb[]) {
17352                        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17353                        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17354                        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17355                        { }
17356                }
17357        },
17358};
17359
17360static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17361        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17362        {}
17363};
17364
17365static int patch_alc861vd(struct hda_codec *codec)
17366{
17367        struct alc_spec *spec;
17368        int err, board_config;
17369
17370        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17371        if (spec == NULL)
17372                return -ENOMEM;
17373
17374        codec->spec = spec;
17375
17376        board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17377                                                  alc861vd_models,
17378                                                  alc861vd_cfg_tbl);
17379
17380        if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17381                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17382                       codec->chip_name);
17383                board_config = ALC861VD_AUTO;
17384        }
17385
17386        if (board_config == ALC861VD_AUTO) {
17387                alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17388                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17389        }
17390
17391        if (board_config == ALC861VD_AUTO) {
17392                /* automatic parse from the BIOS config */
17393                err = alc861vd_parse_auto_config(codec);
17394                if (err < 0) {
17395                        alc_free(codec);
17396                        return err;
17397                } else if (!err) {
17398                        printk(KERN_INFO
17399                               "hda_codec: Cannot set up configuration "
17400                               "from BIOS.  Using base mode...\n");
17401                        board_config = ALC861VD_3ST;
17402                }
17403        }
17404
17405        err = snd_hda_attach_beep_device(codec, 0x23);
17406        if (err < 0) {
17407                alc_free(codec);
17408                return err;
17409        }
17410
17411        if (board_config != ALC861VD_AUTO)
17412                setup_preset(codec, &alc861vd_presets[board_config]);
17413
17414        if (codec->vendor_id == 0x10ec0660) {
17415                /* always turn on EAPD */
17416                add_verb(spec, alc660vd_eapd_verbs);
17417        }
17418
17419        spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17420        spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17421
17422        spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17423        spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17424
17425        if (!spec->adc_nids) {
17426                spec->adc_nids = alc861vd_adc_nids;
17427                spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17428        }
17429        if (!spec->capsrc_nids)
17430                spec->capsrc_nids = alc861vd_capsrc_nids;
17431
17432        set_capture_mixer(codec);
17433        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17434
17435        spec->vmaster_nid = 0x02;
17436
17437        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17438
17439        codec->patch_ops = alc_patch_ops;
17440
17441        if (board_config == ALC861VD_AUTO)
17442                spec->init_hook = alc861vd_auto_init;
17443#ifdef CONFIG_SND_HDA_POWER_SAVE
17444        if (!spec->loopback.amplist)
17445                spec->loopback.amplist = alc861vd_loopbacks;
17446#endif
17447
17448        return 0;
17449}
17450
17451/*
17452 * ALC662 support
17453 *
17454 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17455 * configuration.  Each pin widget can choose any input DACs and a mixer.
17456 * Each ADC is connected from a mixer of all inputs.  This makes possible
17457 * 6-channel independent captures.
17458 *
17459 * In addition, an independent DAC for the multi-playback (not used in this
17460 * driver yet).
17461 */
17462#define ALC662_DIGOUT_NID       0x06
17463#define ALC662_DIGIN_NID        0x0a
17464
17465static hda_nid_t alc662_dac_nids[4] = {
17466        /* front, rear, clfe, rear_surr */
17467        0x02, 0x03, 0x04
17468};
17469
17470static hda_nid_t alc272_dac_nids[2] = {
17471        0x02, 0x03
17472};
17473
17474static hda_nid_t alc662_adc_nids[2] = {
17475        /* ADC1-2 */
17476        0x09, 0x08
17477};
17478
17479static hda_nid_t alc272_adc_nids[1] = {
17480        /* ADC1-2 */
17481        0x08,
17482};
17483
17484static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17485static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17486
17487
17488/* input MUX */
17489/* FIXME: should be a matrix-type input source selection */
17490static struct hda_input_mux alc662_capture_source = {
17491        .num_items = 4,
17492        .items = {
17493                { "Mic", 0x0 },
17494                { "Front Mic", 0x1 },
17495                { "Line", 0x2 },
17496                { "CD", 0x4 },
17497        },
17498};
17499
17500static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17501        .num_items = 2,
17502        .items = {
17503                { "Mic", 0x1 },
17504                { "Line", 0x2 },
17505        },
17506};
17507
17508static struct hda_input_mux alc663_capture_source = {
17509        .num_items = 3,
17510        .items = {
17511                { "Mic", 0x0 },
17512                { "Front Mic", 0x1 },
17513                { "Line", 0x2 },
17514        },
17515};
17516
17517#if 0 /* set to 1 for testing other input sources below */
17518static struct hda_input_mux alc272_nc10_capture_source = {
17519        .num_items = 16,
17520        .items = {
17521                { "Autoselect Mic", 0x0 },
17522                { "Internal Mic", 0x1 },
17523                { "In-0x02", 0x2 },
17524                { "In-0x03", 0x3 },
17525                { "In-0x04", 0x4 },
17526                { "In-0x05", 0x5 },
17527                { "In-0x06", 0x6 },
17528                { "In-0x07", 0x7 },
17529                { "In-0x08", 0x8 },
17530                { "In-0x09", 0x9 },
17531                { "In-0x0a", 0x0a },
17532                { "In-0x0b", 0x0b },
17533                { "In-0x0c", 0x0c },
17534                { "In-0x0d", 0x0d },
17535                { "In-0x0e", 0x0e },
17536                { "In-0x0f", 0x0f },
17537        },
17538};
17539#endif
17540
17541/*
17542 * 2ch mode
17543 */
17544static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17545        { 2, NULL }
17546};
17547
17548/*
17549 * 2ch mode
17550 */
17551static struct hda_verb alc662_3ST_ch2_init[] = {
17552        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17553        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17554        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17555        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17556        { } /* end */
17557};
17558
17559/*
17560 * 6ch mode
17561 */
17562static struct hda_verb alc662_3ST_ch6_init[] = {
17563        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17564        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17565        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17566        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17567        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17568        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17569        { } /* end */
17570};
17571
17572static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17573        { 2, alc662_3ST_ch2_init },
17574        { 6, alc662_3ST_ch6_init },
17575};
17576
17577/*
17578 * 2ch mode
17579 */
17580static struct hda_verb alc662_sixstack_ch6_init[] = {
17581        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17582        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17583        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584        { } /* end */
17585};
17586
17587/*
17588 * 6ch mode
17589 */
17590static struct hda_verb alc662_sixstack_ch8_init[] = {
17591        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17592        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17593        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17594        { } /* end */
17595};
17596
17597static struct hda_channel_mode alc662_5stack_modes[2] = {
17598        { 2, alc662_sixstack_ch6_init },
17599        { 6, alc662_sixstack_ch8_init },
17600};
17601
17602/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17603 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17604 */
17605
17606static struct snd_kcontrol_new alc662_base_mixer[] = {
17607        /* output mixer control */
17608        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17609        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17610        HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17611        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17612        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17613        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17614        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17615        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17616        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17617
17618        /*Input mixer control */
17619        HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17620        HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17621        HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17622        HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17623        HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17624        HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17625        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17626        HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17627        { } /* end */
17628};
17629
17630static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17631        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17632        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17633        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17635        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17636        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17637        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17638        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17639        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17640        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17641        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17642        { } /* end */
17643};
17644
17645static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17646        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17647        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17648        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17649        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17650        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17651        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17652        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17653        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17654        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17655        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17656        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17657        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17658        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17659        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17660        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17661        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17662        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17663        { } /* end */
17664};
17665
17666static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17667        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17668        HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17669        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17670        HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17671        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17673        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17674        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17675        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17676        { } /* end */
17677};
17678
17679static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17680        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17681        ALC262_HIPPO_MASTER_SWITCH,
17682
17683        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17684        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17685        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17686
17687        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17688        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17689        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17690        { } /* end */
17691};
17692
17693static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17694        ALC262_HIPPO_MASTER_SWITCH,
17695        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17696        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17697        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17698        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17699        HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17700        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17701        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17702        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17703        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17704        { } /* end */
17705};
17706
17707static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17708        .ops = &snd_hda_bind_vol,
17709        .values = {
17710                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17711                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17712                0
17713        },
17714};
17715
17716static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17717        .ops = &snd_hda_bind_sw,
17718        .values = {
17719                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17720                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17721                0
17722        },
17723};
17724
17725static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17726        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17727        HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17728        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17729        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17730        { } /* end */
17731};
17732
17733static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17734        .ops = &snd_hda_bind_sw,
17735        .values = {
17736                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17738                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17739                0
17740        },
17741};
17742
17743static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17744        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17745        HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17746        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17749        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17750
17751        { } /* end */
17752};
17753
17754static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17755        .ops = &snd_hda_bind_sw,
17756        .values = {
17757                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17758                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17759                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17760                0
17761        },
17762};
17763
17764static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17765        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17766        HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17767        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17768        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17769        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17770        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17771        { } /* end */
17772};
17773
17774static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17775        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17776        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17777        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17778        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17779        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17780        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17781        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17782        { } /* end */
17783};
17784
17785static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17786        .ops = &snd_hda_bind_vol,
17787        .values = {
17788                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17789                HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17790                0
17791        },
17792};
17793
17794static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17795        .ops = &snd_hda_bind_sw,
17796        .values = {
17797                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17798                HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17799                0
17800        },
17801};
17802
17803static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17804        HDA_BIND_VOL("Master Playback Volume",
17805                                &alc663_asus_two_bind_master_vol),
17806        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17807        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17808        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17809        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17810        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17811        { } /* end */
17812};
17813
17814static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17815        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17816        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17817        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17818        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17819        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17820        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17821        { } /* end */
17822};
17823
17824static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17825        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17826        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17827        HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17828        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17829        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17830
17831        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17832        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17833        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17834        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17835        { } /* end */
17836};
17837
17838static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17839        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17840        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17841        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17842
17843        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17844        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17845        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17846        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17847        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17848        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17849        { } /* end */
17850};
17851
17852static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17853        .ops = &snd_hda_bind_sw,
17854        .values = {
17855                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17856                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17857                HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17858                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17859                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17860                0
17861        },
17862};
17863
17864static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17865        .ops = &snd_hda_bind_sw,
17866        .values = {
17867                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17868                HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17869                0
17870        },
17871};
17872
17873static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17874        HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17875        HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17876        HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17877        HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17878        HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17879        HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17880        HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17881        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17882        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17883        { } /* end */
17884};
17885
17886static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17887        HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17888        HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17889        HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17890        HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17891        HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17892        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17893        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17894        { } /* end */
17895};
17896
17897
17898static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17899        {
17900                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17901                .name = "Channel Mode",
17902                .info = alc_ch_mode_info,
17903                .get = alc_ch_mode_get,
17904                .put = alc_ch_mode_put,
17905        },
17906        { } /* end */
17907};
17908
17909static struct hda_verb alc662_init_verbs[] = {
17910        /* ADC: mute amp left and right */
17911        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17912        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17913
17914        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17915        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17916        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17917        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17918        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17919        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17920
17921        /* Front Pin: output 0 (0x0c) */
17922        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17923        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17924
17925        /* Rear Pin: output 1 (0x0d) */
17926        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17927        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17928
17929        /* CLFE Pin: output 2 (0x0e) */
17930        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17931        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17932
17933        /* Mic (rear) pin: input vref at 80% */
17934        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17935        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17936        /* Front Mic pin: input vref at 80% */
17937        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17938        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17939        /* Line In pin: input */
17940        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17941        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17942        /* Line-2 In: Headphone output (output 0 - 0x0c) */
17943        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17944        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17946        /* CD pin widget for input */
17947        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17948
17949        /* FIXME: use matrix-type input source selection */
17950        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17951        /* Input mixer */
17952        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17953        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17954
17955        /* always trun on EAPD */
17956        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17957        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17958
17959        { }
17960};
17961
17962static struct hda_verb alc663_init_verbs[] = {
17963        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17964        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17966        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17967        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17968        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17969        { }
17970};
17971
17972static struct hda_verb alc272_init_verbs[] = {
17973        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17974        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17975        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17976        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17977        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17978        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17979        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17980        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17981        { }
17982};
17983
17984static struct hda_verb alc662_sue_init_verbs[] = {
17985        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17986        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17987        {}
17988};
17989
17990static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17991        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17992        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17993        {}
17994};
17995
17996/* Set Unsolicited Event*/
17997static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17998        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17999        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18000        {}
18001};
18002
18003static struct hda_verb alc663_m51va_init_verbs[] = {
18004        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18005        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18006        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18007        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18008        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18009        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18010        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18011        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18012        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18013        {}
18014};
18015
18016static struct hda_verb alc663_21jd_amic_init_verbs[] = {
18017        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18020        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18021        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18022        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18023        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18024        {}
18025};
18026
18027static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18028        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18029        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18030        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18031        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
18032        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18033        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18034        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18035        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18036        {}
18037};
18038
18039static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18040        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18041        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18042        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18043        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18044        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18045        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18046        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18047        {}
18048};
18049
18050static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18051        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18052        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18053        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18054        {0x21, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
18055        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18056        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18057        {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
18058        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18059        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18060        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18061        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18062        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18063        {}
18064};
18065
18066static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18067        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18068        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18069        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18070        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18071        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18072        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18073        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18074        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18075        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18076        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18077        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18078        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18079        {}
18080};
18081
18082static struct hda_verb alc663_g71v_init_verbs[] = {
18083        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18084        /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18085        /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18086
18087        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18088        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18089        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
18090
18091        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18092        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18093        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18094        {}
18095};
18096
18097static struct hda_verb alc663_g50v_init_verbs[] = {
18098        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18099        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18100        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
18101
18102        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104        {}
18105};
18106
18107static struct hda_verb alc662_ecs_init_verbs[] = {
18108        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18109        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18110        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18111        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18112        {}
18113};
18114
18115static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18116        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18120        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18121        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18122        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18123        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18124        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18125        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18126        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18127        {}
18128};
18129
18130static struct hda_verb alc272_dell_init_verbs[] = {
18131        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18134        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18135        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18136        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18137        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18138        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18139        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18140        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18141        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18142        {}
18143};
18144
18145static struct hda_verb alc663_mode7_init_verbs[] = {
18146        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18147        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18148        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18149        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18151        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18152        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18153        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18154        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18155        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18156        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18157        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18158        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18159        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18160        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18161        {}
18162};
18163
18164static struct hda_verb alc663_mode8_init_verbs[] = {
18165        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18166        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18167        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18168        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18169        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18170        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18171        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18172        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18173        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18174        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18175        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
18176        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18177        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18178        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18180        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18181        {}
18182};
18183
18184static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18185        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18186        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18187        { } /* end */
18188};
18189
18190static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18191        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18192        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18193        { } /* end */
18194};
18195
18196static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18197{
18198        unsigned int present;
18199        unsigned char bits;
18200
18201        present = snd_hda_jack_detect(codec, 0x14);
18202        bits = present ? HDA_AMP_MUTE : 0;
18203
18204        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18205                                 HDA_AMP_MUTE, bits);
18206}
18207
18208static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18209{
18210        unsigned int present;
18211        unsigned char bits;
18212
18213        present = snd_hda_jack_detect(codec, 0x1b);
18214        bits = present ? HDA_AMP_MUTE : 0;
18215
18216        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18217                                 HDA_AMP_MUTE, bits);
18218        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18219                                 HDA_AMP_MUTE, bits);
18220}
18221
18222static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18223                                           unsigned int res)
18224{
18225        if ((res >> 26) == ALC880_HP_EVENT)
18226                alc662_lenovo_101e_all_automute(codec);
18227        if ((res >> 26) == ALC880_FRONT_EVENT)
18228                alc662_lenovo_101e_ispeaker_automute(codec);
18229}
18230
18231/* unsolicited event for HP jack sensing */
18232static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18233                                     unsigned int res)
18234{
18235        if ((res >> 26) == ALC880_MIC_EVENT)
18236                alc_mic_automute(codec);
18237        else
18238                alc262_hippo_unsol_event(codec, res);
18239}
18240
18241static void alc662_eeepc_setup(struct hda_codec *codec)
18242{
18243        struct alc_spec *spec = codec->spec;
18244
18245        alc262_hippo1_setup(codec);
18246        spec->ext_mic.pin = 0x18;
18247        spec->ext_mic.mux_idx = 0;
18248        spec->int_mic.pin = 0x19;
18249        spec->int_mic.mux_idx = 1;
18250        spec->auto_mic = 1;
18251}
18252
18253static void alc662_eeepc_inithook(struct hda_codec *codec)
18254{
18255        alc262_hippo_automute(codec);
18256        alc_mic_automute(codec);
18257}
18258
18259static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18260{
18261        struct alc_spec *spec = codec->spec;
18262
18263        spec->autocfg.hp_pins[0] = 0x14;
18264        spec->autocfg.speaker_pins[0] = 0x1b;
18265}
18266
18267#define alc662_eeepc_ep20_inithook      alc262_hippo_master_update
18268
18269static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18270{
18271        unsigned int present;
18272        unsigned char bits;
18273
18274        present = snd_hda_jack_detect(codec, 0x21);
18275        bits = present ? HDA_AMP_MUTE : 0;
18276        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18277                                 HDA_AMP_MUTE, bits);
18278        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18279                                 HDA_AMP_MUTE, bits);
18280}
18281
18282static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18283{
18284        unsigned int present;
18285        unsigned char bits;
18286
18287        present = snd_hda_jack_detect(codec, 0x21);
18288        bits = present ? HDA_AMP_MUTE : 0;
18289        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18290                                 HDA_AMP_MUTE, bits);
18291        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18292                                 HDA_AMP_MUTE, bits);
18293        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18294                                 HDA_AMP_MUTE, bits);
18295        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18296                                 HDA_AMP_MUTE, bits);
18297}
18298
18299static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18300{
18301        unsigned int present;
18302        unsigned char bits;
18303
18304        present = snd_hda_jack_detect(codec, 0x15);
18305        bits = present ? HDA_AMP_MUTE : 0;
18306        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18307                                 HDA_AMP_MUTE, bits);
18308        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18309                                 HDA_AMP_MUTE, bits);
18310        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18311                                 HDA_AMP_MUTE, bits);
18312        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18313                                 HDA_AMP_MUTE, bits);
18314}
18315
18316static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18317{
18318        unsigned int present;
18319        unsigned char bits;
18320
18321        present = snd_hda_jack_detect(codec, 0x1b);
18322        bits = present ? 0 : PIN_OUT;
18323        snd_hda_codec_write(codec, 0x14, 0,
18324                         AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18325}
18326
18327static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18328{
18329        unsigned int present1, present2;
18330
18331        present1 = snd_hda_jack_detect(codec, 0x21);
18332        present2 = snd_hda_jack_detect(codec, 0x15);
18333
18334        if (present1 || present2) {
18335                snd_hda_codec_write_cache(codec, 0x14, 0,
18336                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18337        } else {
18338                snd_hda_codec_write_cache(codec, 0x14, 0,
18339                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18340        }
18341}
18342
18343static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18344{
18345        unsigned int present1, present2;
18346
18347        present1 = snd_hda_jack_detect(codec, 0x1b);
18348        present2 = snd_hda_jack_detect(codec, 0x15);
18349
18350        if (present1 || present2) {
18351                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18352                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
18353                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18354                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
18355        } else {
18356                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18357                                         HDA_AMP_MUTE, 0);
18358                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18359                                         HDA_AMP_MUTE, 0);
18360        }
18361}
18362
18363static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18364{
18365        unsigned int present1, present2;
18366
18367        present1 = snd_hda_codec_read(codec, 0x1b, 0,
18368                        AC_VERB_GET_PIN_SENSE, 0)
18369                        & AC_PINSENSE_PRESENCE;
18370        present2 = snd_hda_codec_read(codec, 0x21, 0,
18371                        AC_VERB_GET_PIN_SENSE, 0)
18372                        & AC_PINSENSE_PRESENCE;
18373
18374        if (present1 || present2) {
18375                snd_hda_codec_write_cache(codec, 0x14, 0,
18376                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18377                snd_hda_codec_write_cache(codec, 0x17, 0,
18378                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18379        } else {
18380                snd_hda_codec_write_cache(codec, 0x14, 0,
18381                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18382                snd_hda_codec_write_cache(codec, 0x17, 0,
18383                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18384        }
18385}
18386
18387static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18388{
18389        unsigned int present1, present2;
18390
18391        present1 = snd_hda_codec_read(codec, 0x21, 0,
18392                        AC_VERB_GET_PIN_SENSE, 0)
18393                        & AC_PINSENSE_PRESENCE;
18394        present2 = snd_hda_codec_read(codec, 0x15, 0,
18395                        AC_VERB_GET_PIN_SENSE, 0)
18396                        & AC_PINSENSE_PRESENCE;
18397
18398        if (present1 || present2) {
18399                snd_hda_codec_write_cache(codec, 0x14, 0,
18400                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18401                snd_hda_codec_write_cache(codec, 0x17, 0,
18402                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18403        } else {
18404                snd_hda_codec_write_cache(codec, 0x14, 0,
18405                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18406                snd_hda_codec_write_cache(codec, 0x17, 0,
18407                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18408        }
18409}
18410
18411static void alc663_m51va_unsol_event(struct hda_codec *codec,
18412                                           unsigned int res)
18413{
18414        switch (res >> 26) {
18415        case ALC880_HP_EVENT:
18416                alc663_m51va_speaker_automute(codec);
18417                break;
18418        case ALC880_MIC_EVENT:
18419                alc_mic_automute(codec);
18420                break;
18421        }
18422}
18423
18424static void alc663_m51va_setup(struct hda_codec *codec)
18425{
18426        struct alc_spec *spec = codec->spec;
18427        spec->ext_mic.pin = 0x18;
18428        spec->ext_mic.mux_idx = 0;
18429        spec->int_mic.pin = 0x12;
18430        spec->int_mic.mux_idx = 9;
18431        spec->auto_mic = 1;
18432}
18433
18434static void alc663_m51va_inithook(struct hda_codec *codec)
18435{
18436        alc663_m51va_speaker_automute(codec);
18437        alc_mic_automute(codec);
18438}
18439
18440/* ***************** Mode1 ******************************/
18441#define alc663_mode1_unsol_event        alc663_m51va_unsol_event
18442
18443static void alc663_mode1_setup(struct hda_codec *codec)
18444{
18445        struct alc_spec *spec = codec->spec;
18446        spec->ext_mic.pin = 0x18;
18447        spec->ext_mic.mux_idx = 0;
18448        spec->int_mic.pin = 0x19;
18449        spec->int_mic.mux_idx = 1;
18450        spec->auto_mic = 1;
18451}
18452
18453#define alc663_mode1_inithook           alc663_m51va_inithook
18454
18455/* ***************** Mode2 ******************************/
18456static void alc662_mode2_unsol_event(struct hda_codec *codec,
18457                                           unsigned int res)
18458{
18459        switch (res >> 26) {
18460        case ALC880_HP_EVENT:
18461                alc662_f5z_speaker_automute(codec);
18462                break;
18463        case ALC880_MIC_EVENT:
18464                alc_mic_automute(codec);
18465                break;
18466        }
18467}
18468
18469#define alc662_mode2_setup      alc663_mode1_setup
18470
18471static void alc662_mode2_inithook(struct hda_codec *codec)
18472{
18473        alc662_f5z_speaker_automute(codec);
18474        alc_mic_automute(codec);
18475}
18476/* ***************** Mode3 ******************************/
18477static void alc663_mode3_unsol_event(struct hda_codec *codec,
18478                                           unsigned int res)
18479{
18480        switch (res >> 26) {
18481        case ALC880_HP_EVENT:
18482                alc663_two_hp_m1_speaker_automute(codec);
18483                break;
18484        case ALC880_MIC_EVENT:
18485                alc_mic_automute(codec);
18486                break;
18487        }
18488}
18489
18490#define alc663_mode3_setup      alc663_mode1_setup
18491
18492static void alc663_mode3_inithook(struct hda_codec *codec)
18493{
18494        alc663_two_hp_m1_speaker_automute(codec);
18495        alc_mic_automute(codec);
18496}
18497/* ***************** Mode4 ******************************/
18498static void alc663_mode4_unsol_event(struct hda_codec *codec,
18499                                           unsigned int res)
18500{
18501        switch (res >> 26) {
18502        case ALC880_HP_EVENT:
18503                alc663_21jd_two_speaker_automute(codec);
18504                break;
18505        case ALC880_MIC_EVENT:
18506                alc_mic_automute(codec);
18507                break;
18508        }
18509}
18510
18511#define alc663_mode4_setup      alc663_mode1_setup
18512
18513static void alc663_mode4_inithook(struct hda_codec *codec)
18514{
18515        alc663_21jd_two_speaker_automute(codec);
18516        alc_mic_automute(codec);
18517}
18518/* ***************** Mode5 ******************************/
18519static void alc663_mode5_unsol_event(struct hda_codec *codec,
18520                                           unsigned int res)
18521{
18522        switch (res >> 26) {
18523        case ALC880_HP_EVENT:
18524                alc663_15jd_two_speaker_automute(codec);
18525                break;
18526        case ALC880_MIC_EVENT:
18527                alc_mic_automute(codec);
18528                break;
18529        }
18530}
18531
18532#define alc663_mode5_setup      alc663_mode1_setup
18533
18534static void alc663_mode5_inithook(struct hda_codec *codec)
18535{
18536        alc663_15jd_two_speaker_automute(codec);
18537        alc_mic_automute(codec);
18538}
18539/* ***************** Mode6 ******************************/
18540static void alc663_mode6_unsol_event(struct hda_codec *codec,
18541                                           unsigned int res)
18542{
18543        switch (res >> 26) {
18544        case ALC880_HP_EVENT:
18545                alc663_two_hp_m2_speaker_automute(codec);
18546                break;
18547        case ALC880_MIC_EVENT:
18548                alc_mic_automute(codec);
18549                break;
18550        }
18551}
18552
18553#define alc663_mode6_setup      alc663_mode1_setup
18554
18555static void alc663_mode6_inithook(struct hda_codec *codec)
18556{
18557        alc663_two_hp_m2_speaker_automute(codec);
18558        alc_mic_automute(codec);
18559}
18560
18561/* ***************** Mode7 ******************************/
18562static void alc663_mode7_unsol_event(struct hda_codec *codec,
18563                                           unsigned int res)
18564{
18565        switch (res >> 26) {
18566        case ALC880_HP_EVENT:
18567                alc663_two_hp_m7_speaker_automute(codec);
18568                break;
18569        case ALC880_MIC_EVENT:
18570                alc_mic_automute(codec);
18571                break;
18572        }
18573}
18574
18575#define alc663_mode7_setup      alc663_mode1_setup
18576
18577static void alc663_mode7_inithook(struct hda_codec *codec)
18578{
18579        alc663_two_hp_m7_speaker_automute(codec);
18580        alc_mic_automute(codec);
18581}
18582
18583/* ***************** Mode8 ******************************/
18584static void alc663_mode8_unsol_event(struct hda_codec *codec,
18585                                           unsigned int res)
18586{
18587        switch (res >> 26) {
18588        case ALC880_HP_EVENT:
18589                alc663_two_hp_m8_speaker_automute(codec);
18590                break;
18591        case ALC880_MIC_EVENT:
18592                alc_mic_automute(codec);
18593                break;
18594        }
18595}
18596
18597#define alc663_mode8_setup      alc663_m51va_setup
18598
18599static void alc663_mode8_inithook(struct hda_codec *codec)
18600{
18601        alc663_two_hp_m8_speaker_automute(codec);
18602        alc_mic_automute(codec);
18603}
18604
18605static void alc663_g71v_hp_automute(struct hda_codec *codec)
18606{
18607        unsigned int present;
18608        unsigned char bits;
18609
18610        present = snd_hda_jack_detect(codec, 0x21);
18611        bits = present ? HDA_AMP_MUTE : 0;
18612        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18613                                 HDA_AMP_MUTE, bits);
18614        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18615                                 HDA_AMP_MUTE, bits);
18616}
18617
18618static void alc663_g71v_front_automute(struct hda_codec *codec)
18619{
18620        unsigned int present;
18621        unsigned char bits;
18622
18623        present = snd_hda_jack_detect(codec, 0x15);
18624        bits = present ? HDA_AMP_MUTE : 0;
18625        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18626                                 HDA_AMP_MUTE, bits);
18627}
18628
18629static void alc663_g71v_unsol_event(struct hda_codec *codec,
18630                                           unsigned int res)
18631{
18632        switch (res >> 26) {
18633        case ALC880_HP_EVENT:
18634                alc663_g71v_hp_automute(codec);
18635                break;
18636        case ALC880_FRONT_EVENT:
18637                alc663_g71v_front_automute(codec);
18638                break;
18639        case ALC880_MIC_EVENT:
18640                alc_mic_automute(codec);
18641                break;
18642        }
18643}
18644
18645#define alc663_g71v_setup       alc663_m51va_setup
18646
18647static void alc663_g71v_inithook(struct hda_codec *codec)
18648{
18649        alc663_g71v_front_automute(codec);
18650        alc663_g71v_hp_automute(codec);
18651        alc_mic_automute(codec);
18652}
18653
18654static void alc663_g50v_unsol_event(struct hda_codec *codec,
18655                                           unsigned int res)
18656{
18657        switch (res >> 26) {
18658        case ALC880_HP_EVENT:
18659                alc663_m51va_speaker_automute(codec);
18660                break;
18661        case ALC880_MIC_EVENT:
18662                alc_mic_automute(codec);
18663                break;
18664        }
18665}
18666
18667#define alc663_g50v_setup       alc663_m51va_setup
18668
18669static void alc663_g50v_inithook(struct hda_codec *codec)
18670{
18671        alc663_m51va_speaker_automute(codec);
18672        alc_mic_automute(codec);
18673}
18674
18675static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18676        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18677        ALC262_HIPPO_MASTER_SWITCH,
18678
18679        HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18680        HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18681        HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18682
18683        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18684        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18685        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18686        { } /* end */
18687};
18688
18689static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18690        /* Master Playback automatically created from Speaker and Headphone */
18691        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18692        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18693        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18694        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18695
18696        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18697        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18698        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18699
18700        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18701        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18702        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18703        { } /* end */
18704};
18705
18706#ifdef CONFIG_SND_HDA_POWER_SAVE
18707#define alc662_loopbacks        alc880_loopbacks
18708#endif
18709
18710
18711/* pcm configuration: identical with ALC880 */
18712#define alc662_pcm_analog_playback      alc880_pcm_analog_playback
18713#define alc662_pcm_analog_capture       alc880_pcm_analog_capture
18714#define alc662_pcm_digital_playback     alc880_pcm_digital_playback
18715#define alc662_pcm_digital_capture      alc880_pcm_digital_capture
18716
18717/*
18718 * configuration and preset
18719 */
18720static const char * const alc662_models[ALC662_MODEL_LAST] = {
18721        [ALC662_3ST_2ch_DIG]    = "3stack-dig",
18722        [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
18723        [ALC662_3ST_6ch]        = "3stack-6ch",
18724        [ALC662_5ST_DIG]        = "6stack-dig",
18725        [ALC662_LENOVO_101E]    = "lenovo-101e",
18726        [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18727        [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18728        [ALC662_ECS] = "ecs",
18729        [ALC663_ASUS_M51VA] = "m51va",
18730        [ALC663_ASUS_G71V] = "g71v",
18731        [ALC663_ASUS_H13] = "h13",
18732        [ALC663_ASUS_G50V] = "g50v",
18733        [ALC663_ASUS_MODE1] = "asus-mode1",
18734        [ALC662_ASUS_MODE2] = "asus-mode2",
18735        [ALC663_ASUS_MODE3] = "asus-mode3",
18736        [ALC663_ASUS_MODE4] = "asus-mode4",
18737        [ALC663_ASUS_MODE5] = "asus-mode5",
18738        [ALC663_ASUS_MODE6] = "asus-mode6",
18739        [ALC663_ASUS_MODE7] = "asus-mode7",
18740        [ALC663_ASUS_MODE8] = "asus-mode8",
18741        [ALC272_DELL]           = "dell",
18742        [ALC272_DELL_ZM1]       = "dell-zm1",
18743        [ALC272_SAMSUNG_NC10]   = "samsung-nc10",
18744        [ALC662_AUTO]           = "auto",
18745};
18746
18747static struct snd_pci_quirk alc662_cfg_tbl[] = {
18748        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18749        SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18750        SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18751        SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18752        SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18753        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18754        SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18755        SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18756        SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18757        SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18758        SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18759        SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18760        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18761        SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18762        SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18763        SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18764        SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18765        SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18766        SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18767        SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18768        SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18769        SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18770        SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18771        SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18772        SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18773        SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18774        SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18775        SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18776        SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18777        SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18778        SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18779        SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18780        SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18781        SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18782        SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18783        SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18784        SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18785        /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18786        SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18787        SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18788        SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18789        SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18790        SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18791        SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18792        SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18793        SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18794        SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18795        SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18796        SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18797        SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18798        SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18799        SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18800        SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18801        /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18802        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18803        SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18804        SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18805        SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18806        SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18807        SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18808        SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18809        SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18810        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18811        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18812                      ALC662_3ST_6ch_DIG),
18813        SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18814        SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18815        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18816                      ALC662_3ST_6ch_DIG),
18817        SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18818        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18819        SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18820        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18821        SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18822                                        ALC662_3ST_6ch_DIG),
18823        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18824                           ALC663_ASUS_H13),
18825        SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18826        {}
18827};
18828
18829static struct alc_config_preset alc662_presets[] = {
18830        [ALC662_3ST_2ch_DIG] = {
18831                .mixers = { alc662_3ST_2ch_mixer },
18832                .init_verbs = { alc662_init_verbs },
18833                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18834                .dac_nids = alc662_dac_nids,
18835                .dig_out_nid = ALC662_DIGOUT_NID,
18836                .dig_in_nid = ALC662_DIGIN_NID,
18837                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18838                .channel_mode = alc662_3ST_2ch_modes,
18839                .input_mux = &alc662_capture_source,
18840        },
18841        [ALC662_3ST_6ch_DIG] = {
18842                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18843                .init_verbs = { alc662_init_verbs },
18844                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18845                .dac_nids = alc662_dac_nids,
18846                .dig_out_nid = ALC662_DIGOUT_NID,
18847                .dig_in_nid = ALC662_DIGIN_NID,
18848                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18849                .channel_mode = alc662_3ST_6ch_modes,
18850                .need_dac_fix = 1,
18851                .input_mux = &alc662_capture_source,
18852        },
18853        [ALC662_3ST_6ch] = {
18854                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18855                .init_verbs = { alc662_init_verbs },
18856                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18857                .dac_nids = alc662_dac_nids,
18858                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18859                .channel_mode = alc662_3ST_6ch_modes,
18860                .need_dac_fix = 1,
18861                .input_mux = &alc662_capture_source,
18862        },
18863        [ALC662_5ST_DIG] = {
18864                .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18865                .init_verbs = { alc662_init_verbs },
18866                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18867                .dac_nids = alc662_dac_nids,
18868                .dig_out_nid = ALC662_DIGOUT_NID,
18869                .dig_in_nid = ALC662_DIGIN_NID,
18870                .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18871                .channel_mode = alc662_5stack_modes,
18872                .input_mux = &alc662_capture_source,
18873        },
18874        [ALC662_LENOVO_101E] = {
18875                .mixers = { alc662_lenovo_101e_mixer },
18876                .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18877                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18878                .dac_nids = alc662_dac_nids,
18879                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18880                .channel_mode = alc662_3ST_2ch_modes,
18881                .input_mux = &alc662_lenovo_101e_capture_source,
18882                .unsol_event = alc662_lenovo_101e_unsol_event,
18883                .init_hook = alc662_lenovo_101e_all_automute,
18884        },
18885        [ALC662_ASUS_EEEPC_P701] = {
18886                .mixers = { alc662_eeepc_p701_mixer },
18887                .init_verbs = { alc662_init_verbs,
18888                                alc662_eeepc_sue_init_verbs },
18889                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18890                .dac_nids = alc662_dac_nids,
18891                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18892                .channel_mode = alc662_3ST_2ch_modes,
18893                .unsol_event = alc662_eeepc_unsol_event,
18894                .setup = alc662_eeepc_setup,
18895                .init_hook = alc662_eeepc_inithook,
18896        },
18897        [ALC662_ASUS_EEEPC_EP20] = {
18898                .mixers = { alc662_eeepc_ep20_mixer,
18899                            alc662_chmode_mixer },
18900                .init_verbs = { alc662_init_verbs,
18901                                alc662_eeepc_ep20_sue_init_verbs },
18902                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18903                .dac_nids = alc662_dac_nids,
18904                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18905                .channel_mode = alc662_3ST_6ch_modes,
18906                .input_mux = &alc662_lenovo_101e_capture_source,
18907                .unsol_event = alc662_eeepc_unsol_event,
18908                .setup = alc662_eeepc_ep20_setup,
18909                .init_hook = alc662_eeepc_ep20_inithook,
18910        },
18911        [ALC662_ECS] = {
18912                .mixers = { alc662_ecs_mixer },
18913                .init_verbs = { alc662_init_verbs,
18914                                alc662_ecs_init_verbs },
18915                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18916                .dac_nids = alc662_dac_nids,
18917                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18918                .channel_mode = alc662_3ST_2ch_modes,
18919                .unsol_event = alc662_eeepc_unsol_event,
18920                .setup = alc662_eeepc_setup,
18921                .init_hook = alc662_eeepc_inithook,
18922        },
18923        [ALC663_ASUS_M51VA] = {
18924                .mixers = { alc663_m51va_mixer },
18925                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18926                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18927                .dac_nids = alc662_dac_nids,
18928                .dig_out_nid = ALC662_DIGOUT_NID,
18929                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18930                .channel_mode = alc662_3ST_2ch_modes,
18931                .unsol_event = alc663_m51va_unsol_event,
18932                .setup = alc663_m51va_setup,
18933                .init_hook = alc663_m51va_inithook,
18934        },
18935        [ALC663_ASUS_G71V] = {
18936                .mixers = { alc663_g71v_mixer },
18937                .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18938                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18939                .dac_nids = alc662_dac_nids,
18940                .dig_out_nid = ALC662_DIGOUT_NID,
18941                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18942                .channel_mode = alc662_3ST_2ch_modes,
18943                .unsol_event = alc663_g71v_unsol_event,
18944                .setup = alc663_g71v_setup,
18945                .init_hook = alc663_g71v_inithook,
18946        },
18947        [ALC663_ASUS_H13] = {
18948                .mixers = { alc663_m51va_mixer },
18949                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18950                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18951                .dac_nids = alc662_dac_nids,
18952                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18953                .channel_mode = alc662_3ST_2ch_modes,
18954                .unsol_event = alc663_m51va_unsol_event,
18955                .init_hook = alc663_m51va_inithook,
18956        },
18957        [ALC663_ASUS_G50V] = {
18958                .mixers = { alc663_g50v_mixer },
18959                .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18960                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18961                .dac_nids = alc662_dac_nids,
18962                .dig_out_nid = ALC662_DIGOUT_NID,
18963                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18964                .channel_mode = alc662_3ST_6ch_modes,
18965                .input_mux = &alc663_capture_source,
18966                .unsol_event = alc663_g50v_unsol_event,
18967                .setup = alc663_g50v_setup,
18968                .init_hook = alc663_g50v_inithook,
18969        },
18970        [ALC663_ASUS_MODE1] = {
18971                .mixers = { alc663_m51va_mixer },
18972                .cap_mixer = alc662_auto_capture_mixer,
18973                .init_verbs = { alc662_init_verbs,
18974                                alc663_21jd_amic_init_verbs },
18975                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18976                .hp_nid = 0x03,
18977                .dac_nids = alc662_dac_nids,
18978                .dig_out_nid = ALC662_DIGOUT_NID,
18979                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18980                .channel_mode = alc662_3ST_2ch_modes,
18981                .unsol_event = alc663_mode1_unsol_event,
18982                .setup = alc663_mode1_setup,
18983                .init_hook = alc663_mode1_inithook,
18984        },
18985        [ALC662_ASUS_MODE2] = {
18986                .mixers = { alc662_1bjd_mixer },
18987                .cap_mixer = alc662_auto_capture_mixer,
18988                .init_verbs = { alc662_init_verbs,
18989                                alc662_1bjd_amic_init_verbs },
18990                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18991                .dac_nids = alc662_dac_nids,
18992                .dig_out_nid = ALC662_DIGOUT_NID,
18993                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18994                .channel_mode = alc662_3ST_2ch_modes,
18995                .unsol_event = alc662_mode2_unsol_event,
18996                .setup = alc662_mode2_setup,
18997                .init_hook = alc662_mode2_inithook,
18998        },
18999        [ALC663_ASUS_MODE3] = {
19000                .mixers = { alc663_two_hp_m1_mixer },
19001                .cap_mixer = alc662_auto_capture_mixer,
19002                .init_verbs = { alc662_init_verbs,
19003                                alc663_two_hp_amic_m1_init_verbs },
19004                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19005                .hp_nid = 0x03,
19006                .dac_nids = alc662_dac_nids,
19007                .dig_out_nid = ALC662_DIGOUT_NID,
19008                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19009                .channel_mode = alc662_3ST_2ch_modes,
19010                .unsol_event = alc663_mode3_unsol_event,
19011                .setup = alc663_mode3_setup,
19012                .init_hook = alc663_mode3_inithook,
19013        },
19014        [ALC663_ASUS_MODE4] = {
19015                .mixers = { alc663_asus_21jd_clfe_mixer },
19016                .cap_mixer = alc662_auto_capture_mixer,
19017                .init_verbs = { alc662_init_verbs,
19018                                alc663_21jd_amic_init_verbs},
19019                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19020                .hp_nid = 0x03,
19021                .dac_nids = alc662_dac_nids,
19022                .dig_out_nid = ALC662_DIGOUT_NID,
19023                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19024                .channel_mode = alc662_3ST_2ch_modes,
19025                .unsol_event = alc663_mode4_unsol_event,
19026                .setup = alc663_mode4_setup,
19027                .init_hook = alc663_mode4_inithook,
19028        },
19029        [ALC663_ASUS_MODE5] = {
19030                .mixers = { alc663_asus_15jd_clfe_mixer },
19031                .cap_mixer = alc662_auto_capture_mixer,
19032                .init_verbs = { alc662_init_verbs,
19033                                alc663_15jd_amic_init_verbs },
19034                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19035                .hp_nid = 0x03,
19036                .dac_nids = alc662_dac_nids,
19037                .dig_out_nid = ALC662_DIGOUT_NID,
19038                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19039                .channel_mode = alc662_3ST_2ch_modes,
19040                .unsol_event = alc663_mode5_unsol_event,
19041                .setup = alc663_mode5_setup,
19042                .init_hook = alc663_mode5_inithook,
19043        },
19044        [ALC663_ASUS_MODE6] = {
19045                .mixers = { alc663_two_hp_m2_mixer },
19046                .cap_mixer = alc662_auto_capture_mixer,
19047                .init_verbs = { alc662_init_verbs,
19048                                alc663_two_hp_amic_m2_init_verbs },
19049                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19050                .hp_nid = 0x03,
19051                .dac_nids = alc662_dac_nids,
19052                .dig_out_nid = ALC662_DIGOUT_NID,
19053                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19054                .channel_mode = alc662_3ST_2ch_modes,
19055                .unsol_event = alc663_mode6_unsol_event,
19056                .setup = alc663_mode6_setup,
19057                .init_hook = alc663_mode6_inithook,
19058        },
19059        [ALC663_ASUS_MODE7] = {
19060                .mixers = { alc663_mode7_mixer },
19061                .cap_mixer = alc662_auto_capture_mixer,
19062                .init_verbs = { alc662_init_verbs,
19063                                alc663_mode7_init_verbs },
19064                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19065                .hp_nid = 0x03,
19066                .dac_nids = alc662_dac_nids,
19067                .dig_out_nid = ALC662_DIGOUT_NID,
19068                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19069                .channel_mode = alc662_3ST_2ch_modes,
19070                .unsol_event = alc663_mode7_unsol_event,
19071                .setup = alc663_mode7_setup,
19072                .init_hook = alc663_mode7_inithook,
19073        },
19074        [ALC663_ASUS_MODE8] = {
19075                .mixers = { alc663_mode8_mixer },
19076                .cap_mixer = alc662_auto_capture_mixer,
19077                .init_verbs = { alc662_init_verbs,
19078                                alc663_mode8_init_verbs },
19079                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19080                .hp_nid = 0x03,
19081                .dac_nids = alc662_dac_nids,
19082                .dig_out_nid = ALC662_DIGOUT_NID,
19083                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19084                .channel_mode = alc662_3ST_2ch_modes,
19085                .unsol_event = alc663_mode8_unsol_event,
19086                .setup = alc663_mode8_setup,
19087                .init_hook = alc663_mode8_inithook,
19088        },
19089        [ALC272_DELL] = {
19090                .mixers = { alc663_m51va_mixer },
19091                .cap_mixer = alc272_auto_capture_mixer,
19092                .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19093                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19094                .dac_nids = alc662_dac_nids,
19095                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19096                .adc_nids = alc272_adc_nids,
19097                .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19098                .capsrc_nids = alc272_capsrc_nids,
19099                .channel_mode = alc662_3ST_2ch_modes,
19100                .unsol_event = alc663_m51va_unsol_event,
19101                .setup = alc663_m51va_setup,
19102                .init_hook = alc663_m51va_inithook,
19103        },
19104        [ALC272_DELL_ZM1] = {
19105                .mixers = { alc663_m51va_mixer },
19106                .cap_mixer = alc662_auto_capture_mixer,
19107                .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19108                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19109                .dac_nids = alc662_dac_nids,
19110                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19111                .adc_nids = alc662_adc_nids,
19112                .num_adc_nids = 1,
19113                .capsrc_nids = alc662_capsrc_nids,
19114                .channel_mode = alc662_3ST_2ch_modes,
19115                .unsol_event = alc663_m51va_unsol_event,
19116                .setup = alc663_m51va_setup,
19117                .init_hook = alc663_m51va_inithook,
19118        },
19119        [ALC272_SAMSUNG_NC10] = {
19120                .mixers = { alc272_nc10_mixer },
19121                .init_verbs = { alc662_init_verbs,
19122                                alc663_21jd_amic_init_verbs },
19123                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19124                .dac_nids = alc272_dac_nids,
19125                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19126                .channel_mode = alc662_3ST_2ch_modes,
19127                /*.input_mux = &alc272_nc10_capture_source,*/
19128                .unsol_event = alc663_mode4_unsol_event,
19129                .setup = alc663_mode4_setup,
19130                .init_hook = alc663_mode4_inithook,
19131        },
19132};
19133
19134
19135/*
19136 * BIOS auto configuration
19137 */
19138
19139/* convert from MIX nid to DAC */
19140static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19141{
19142        if (nid == 0x0f)
19143                return 0x02;
19144        else if (nid >= 0x0c && nid <= 0x0e)
19145                return nid - 0x0c + 0x02;
19146        else if (nid == 0x26) /* ALC887-VD has this DAC too */
19147                return 0x25;
19148        else
19149                return 0;
19150}
19151
19152/* get MIX nid connected to the given pin targeted to DAC */
19153static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19154                                   hda_nid_t dac)
19155{
19156        hda_nid_t mix[5];
19157        int i, num;
19158
19159        num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19160        for (i = 0; i < num; i++) {
19161                if (alc662_mix_to_dac(mix[i]) == dac)
19162                        return mix[i];
19163        }
19164        return 0;
19165}
19166
19167/* look for an empty DAC slot */
19168static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19169{
19170        struct alc_spec *spec = codec->spec;
19171        hda_nid_t srcs[5];
19172        int i, j, num;
19173
19174        num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19175        if (num < 0)
19176                return 0;
19177        for (i = 0; i < num; i++) {
19178                hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19179                if (!nid)
19180                        continue;
19181                for (j = 0; j < spec->multiout.num_dacs; j++)
19182                        if (spec->multiout.dac_nids[j] == nid)
19183                                break;
19184                if (j >= spec->multiout.num_dacs)
19185                        return nid;
19186        }
19187        return 0;
19188}
19189
19190/* fill in the dac_nids table from the parsed pin configuration */
19191static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19192                                     const struct auto_pin_cfg *cfg)
19193{
19194        struct alc_spec *spec = codec->spec;
19195        int i;
19196        hda_nid_t dac;
19197
19198        spec->multiout.dac_nids = spec->private_dac_nids;
19199        for (i = 0; i < cfg->line_outs; i++) {
19200                dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19201                if (!dac)
19202                        continue;
19203                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19204        }
19205        return 0;
19206}
19207
19208static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19209                                       hda_nid_t nid, int idx, unsigned int chs)
19210{
19211        return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19212                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19213}
19214
19215static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19216                                      hda_nid_t nid, int idx, unsigned int chs)
19217{
19218        return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19219                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19220}
19221
19222#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19223        __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19224#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19225        __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19226#define alc662_add_stereo_vol(spec, pfx, nid) \
19227        alc662_add_vol_ctl(spec, pfx, nid, 3)
19228#define alc662_add_stereo_sw(spec, pfx, nid) \
19229        alc662_add_sw_ctl(spec, pfx, nid, 3)
19230
19231/* add playback controls from the parsed DAC table */
19232static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19233                                             const struct auto_pin_cfg *cfg)
19234{
19235        struct alc_spec *spec = codec->spec;
19236        static const char * const chname[4] = {
19237                "Front", "Surround", NULL /*CLFE*/, "Side"
19238        };
19239        const char *pfx = alc_get_line_out_pfx(cfg, true);
19240        hda_nid_t nid, mix;
19241        int i, err;
19242
19243        for (i = 0; i < cfg->line_outs; i++) {
19244                nid = spec->multiout.dac_nids[i];
19245                if (!nid)
19246                        continue;
19247                mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19248                if (!mix)
19249                        continue;
19250                if (!pfx && i == 2) {
19251                        /* Center/LFE */
19252                        err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19253                        if (err < 0)
19254                                return err;
19255                        err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19256                        if (err < 0)
19257                                return err;
19258                        err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19259                        if (err < 0)
19260                                return err;
19261                        err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19262                        if (err < 0)
19263                                return err;
19264                } else {
19265                        const char *name = pfx;
19266                        if (!name)
19267                                name = chname[i];
19268                        err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
19269                        if (err < 0)
19270                                return err;
19271                        err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
19272                        if (err < 0)
19273                                return err;
19274                }
19275        }
19276        return 0;
19277}
19278
19279/* add playback controls for speaker and HP outputs */
19280/* return DAC nid if any new DAC is assigned */
19281static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19282                                        const char *pfx)
19283{
19284        struct alc_spec *spec = codec->spec;
19285        hda_nid_t nid, mix;
19286        int err;
19287
19288        if (!pin)
19289                return 0;
19290        nid = alc662_look_for_dac(codec, pin);
19291        if (!nid) {
19292                /* the corresponding DAC is already occupied */
19293                if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19294                        return 0; /* no way */
19295                /* create a switch only */
19296                return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19297                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19298        }
19299
19300        mix = alc662_dac_to_mix(codec, pin, nid);
19301        if (!mix)
19302                return 0;
19303        err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19304        if (err < 0)
19305                return err;
19306        err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19307        if (err < 0)
19308                return err;
19309        return nid;
19310}
19311
19312/* create playback/capture controls for input pins */
19313#define alc662_auto_create_input_ctls \
19314        alc882_auto_create_input_ctls
19315
19316static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19317                                              hda_nid_t nid, int pin_type,
19318                                              hda_nid_t dac)
19319{
19320        int i, num;
19321        hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19322
19323        alc_set_pin_output(codec, nid, pin_type);
19324        /* need the manual connection? */
19325        num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19326        if (num <= 1)
19327                return;
19328        for (i = 0; i < num; i++) {
19329                if (alc662_mix_to_dac(srcs[i]) != dac)
19330                        continue;
19331                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19332                return;
19333        }
19334}
19335
19336static void alc662_auto_init_multi_out(struct hda_codec *codec)
19337{
19338        struct alc_spec *spec = codec->spec;
19339        int pin_type = get_pin_type(spec->autocfg.line_out_type);
19340        int i;
19341
19342        for (i = 0; i <= HDA_SIDE; i++) {
19343                hda_nid_t nid = spec->autocfg.line_out_pins[i];
19344                if (nid)
19345                        alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19346                                        spec->multiout.dac_nids[i]);
19347        }
19348}
19349
19350static void alc662_auto_init_hp_out(struct hda_codec *codec)
19351{
19352        struct alc_spec *spec = codec->spec;
19353        hda_nid_t pin;
19354
19355        pin = spec->autocfg.hp_pins[0];
19356        if (pin)
19357                alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19358                                                  spec->multiout.hp_nid);
19359        pin = spec->autocfg.speaker_pins[0];
19360        if (pin)
19361                alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19362                                        spec->multiout.extra_out_nid[0]);
19363}
19364
19365#define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
19366
19367static void alc662_auto_init_analog_input(struct hda_codec *codec)
19368{
19369        struct alc_spec *spec = codec->spec;
19370        struct auto_pin_cfg *cfg = &spec->autocfg;
19371        int i;
19372
19373        for (i = 0; i < cfg->num_inputs; i++) {
19374                hda_nid_t nid = cfg->inputs[i].pin;
19375                if (alc_is_input_pin(codec, nid)) {
19376                        alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19377                        if (nid != ALC662_PIN_CD_NID &&
19378                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19379                                snd_hda_codec_write(codec, nid, 0,
19380                                                    AC_VERB_SET_AMP_GAIN_MUTE,
19381                                                    AMP_OUT_MUTE);
19382                }
19383        }
19384}
19385
19386#define alc662_auto_init_input_src      alc882_auto_init_input_src
19387
19388static int alc662_parse_auto_config(struct hda_codec *codec)
19389{
19390        struct alc_spec *spec = codec->spec;
19391        int err;
19392        static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19393
19394        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19395                                           alc662_ignore);
19396        if (err < 0)
19397                return err;
19398        if (!spec->autocfg.line_outs)
19399                return 0; /* can't find valid BIOS pin config */
19400
19401        err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19402        if (err < 0)
19403                return err;
19404        err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19405        if (err < 0)
19406                return err;
19407        err = alc662_auto_create_extra_out(codec,
19408                                           spec->autocfg.speaker_pins[0],
19409                                           "Speaker");
19410        if (err < 0)
19411                return err;
19412        if (err)
19413                spec->multiout.extra_out_nid[0] = err;
19414        err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19415                                           "Headphone");
19416        if (err < 0)
19417                return err;
19418        if (err)
19419                spec->multiout.hp_nid = err;
19420        err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19421        if (err < 0)
19422                return err;
19423
19424        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19425
19426        alc_auto_parse_digital(codec);
19427
19428        if (spec->kctls.list)
19429                add_mixer(spec, spec->kctls.list);
19430
19431        spec->num_mux_defs = 1;
19432        spec->input_mux = &spec->private_imux[0];
19433
19434        add_verb(spec, alc662_init_verbs);
19435        if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19436            codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19437                add_verb(spec, alc663_init_verbs);
19438
19439        if (codec->vendor_id == 0x10ec0272)
19440                add_verb(spec, alc272_init_verbs);
19441
19442        err = alc_auto_add_mic_boost(codec);
19443        if (err < 0)
19444                return err;
19445
19446        if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19447            codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19448            alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19449        else
19450            alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19451
19452        return 1;
19453}
19454
19455/* additional initialization for auto-configuration model */
19456static void alc662_auto_init(struct hda_codec *codec)
19457{
19458        struct alc_spec *spec = codec->spec;
19459        alc662_auto_init_multi_out(codec);
19460        alc662_auto_init_hp_out(codec);
19461        alc662_auto_init_analog_input(codec);
19462        alc662_auto_init_input_src(codec);
19463        alc_auto_init_digital(codec);
19464        if (spec->unsol_event)
19465                alc_inithook(codec);
19466}
19467
19468static void alc272_fixup_mario(struct hda_codec *codec,
19469                               const struct alc_fixup *fix, int action)
19470{
19471        if (action != ALC_FIXUP_ACT_PROBE)
19472                return;
19473        if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19474                                      (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19475                                      (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19476                                      (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19477                                      (0 << AC_AMPCAP_MUTE_SHIFT)))
19478                printk(KERN_WARNING
19479                       "hda_codec: failed to override amp caps for NID 0x2\n");
19480}
19481
19482enum {
19483        ALC662_FIXUP_ASPIRE,
19484        ALC662_FIXUP_IDEAPAD,
19485        ALC272_FIXUP_MARIO,
19486        ALC662_FIXUP_CZC_P10T,
19487};
19488
19489static const struct alc_fixup alc662_fixups[] = {
19490        [ALC662_FIXUP_ASPIRE] = {
19491                .type = ALC_FIXUP_PINS,
19492                .v.pins = (const struct alc_pincfg[]) {
19493                        { 0x15, 0x99130112 }, /* subwoofer */
19494                        { }
19495                }
19496        },
19497        [ALC662_FIXUP_IDEAPAD] = {
19498                .type = ALC_FIXUP_PINS,
19499                .v.pins = (const struct alc_pincfg[]) {
19500                        { 0x17, 0x99130112 }, /* subwoofer */
19501                        { }
19502                }
19503        },
19504        [ALC272_FIXUP_MARIO] = {
19505                .type = ALC_FIXUP_FUNC,
19506                .v.func = alc272_fixup_mario,
19507        },
19508        [ALC662_FIXUP_CZC_P10T] = {
19509                .type = ALC_FIXUP_VERBS,
19510                .v.verbs = (const struct hda_verb[]) {
19511                        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19512                        {}
19513                }
19514        },
19515};
19516
19517static struct snd_pci_quirk alc662_fixup_tbl[] = {
19518        SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19519        SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19520        SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19521        SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19522        SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19523        SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19524        {}
19525};
19526
19527static const struct alc_model_fixup alc662_fixup_models[] = {
19528        {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19529        {}
19530};
19531
19532
19533static int patch_alc662(struct hda_codec *codec)
19534{
19535        struct alc_spec *spec;
19536        int err, board_config;
19537        int coef;
19538
19539        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19540        if (!spec)
19541                return -ENOMEM;
19542
19543        codec->spec = spec;
19544
19545        alc_auto_parse_customize_define(codec);
19546
19547        alc_fix_pll_init(codec, 0x20, 0x04, 15);
19548
19549        coef = alc_read_coef_idx(codec, 0);
19550        if (coef == 0x8020 || coef == 0x8011)
19551                alc_codec_rename(codec, "ALC661");
19552        else if (coef & (1 << 14) &&
19553                codec->bus->pci->subsystem_vendor == 0x1025 &&
19554                spec->cdefine.platform_type == 1)
19555                alc_codec_rename(codec, "ALC272X");
19556        else if (coef == 0x4011)
19557                alc_codec_rename(codec, "ALC656");
19558
19559        board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19560                                                  alc662_models,
19561                                                  alc662_cfg_tbl);
19562        if (board_config < 0) {
19563                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19564                       codec->chip_name);
19565                board_config = ALC662_AUTO;
19566        }
19567
19568        if (board_config == ALC662_AUTO) {
19569                alc_pick_fixup(codec, alc662_fixup_models,
19570                               alc662_fixup_tbl, alc662_fixups);
19571                alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19572                /* automatic parse from the BIOS config */
19573                err = alc662_parse_auto_config(codec);
19574                if (err < 0) {
19575                        alc_free(codec);
19576                        return err;
19577                } else if (!err) {
19578                        printk(KERN_INFO
19579                               "hda_codec: Cannot set up configuration "
19580                               "from BIOS.  Using base mode...\n");
19581                        board_config = ALC662_3ST_2ch_DIG;
19582                }
19583        }
19584
19585        if (has_cdefine_beep(codec)) {
19586                err = snd_hda_attach_beep_device(codec, 0x1);
19587                if (err < 0) {
19588                        alc_free(codec);
19589                        return err;
19590                }
19591        }
19592
19593        if (board_config != ALC662_AUTO)
19594                setup_preset(codec, &alc662_presets[board_config]);
19595
19596        spec->stream_analog_playback = &alc662_pcm_analog_playback;
19597        spec->stream_analog_capture = &alc662_pcm_analog_capture;
19598
19599        spec->stream_digital_playback = &alc662_pcm_digital_playback;
19600        spec->stream_digital_capture = &alc662_pcm_digital_capture;
19601
19602        if (!spec->adc_nids) {
19603                spec->adc_nids = alc662_adc_nids;
19604                spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19605        }
19606        if (!spec->capsrc_nids)
19607                spec->capsrc_nids = alc662_capsrc_nids;
19608
19609        if (!spec->cap_mixer)
19610                set_capture_mixer(codec);
19611
19612        if (has_cdefine_beep(codec)) {
19613                switch (codec->vendor_id) {
19614                case 0x10ec0662:
19615                        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19616                        break;
19617                case 0x10ec0272:
19618                case 0x10ec0663:
19619                case 0x10ec0665:
19620                        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19621                        break;
19622                case 0x10ec0273:
19623                        set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19624                        break;
19625                }
19626        }
19627        spec->vmaster_nid = 0x02;
19628
19629        alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19630
19631        codec->patch_ops = alc_patch_ops;
19632        if (board_config == ALC662_AUTO)
19633                spec->init_hook = alc662_auto_init;
19634
19635        alc_init_jacks(codec);
19636
19637#ifdef CONFIG_SND_HDA_POWER_SAVE
19638        if (!spec->loopback.amplist)
19639                spec->loopback.amplist = alc662_loopbacks;
19640#endif
19641
19642        return 0;
19643}
19644
19645static int patch_alc888(struct hda_codec *codec)
19646{
19647        if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19648                kfree(codec->chip_name);
19649                if (codec->vendor_id == 0x10ec0887)
19650                        codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19651                else
19652                        codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19653                if (!codec->chip_name) {
19654                        alc_free(codec);
19655                        return -ENOMEM;
19656                }
19657                return patch_alc662(codec);
19658        }
19659        return patch_alc882(codec);
19660}
19661
19662/*
19663 * ALC680 support
19664 */
19665#define ALC680_DIGIN_NID        ALC880_DIGIN_NID
19666#define ALC680_DIGOUT_NID       ALC880_DIGOUT_NID
19667#define alc680_modes            alc260_modes
19668
19669static hda_nid_t alc680_dac_nids[3] = {
19670        /* Lout1, Lout2, hp */
19671        0x02, 0x03, 0x04
19672};
19673
19674static hda_nid_t alc680_adc_nids[3] = {
19675        /* ADC0-2 */
19676        /* DMIC, MIC, Line-in*/
19677        0x07, 0x08, 0x09
19678};
19679
19680/*
19681 * Analog capture ADC cgange
19682 */
19683static void alc680_rec_autoswitch(struct hda_codec *codec)
19684{
19685        struct alc_spec *spec = codec->spec;
19686        struct auto_pin_cfg *cfg = &spec->autocfg;
19687        int pin_found = 0;
19688        int type_found = AUTO_PIN_LAST;
19689        hda_nid_t nid;
19690        int i;
19691
19692        for (i = 0; i < cfg->num_inputs; i++) {
19693                nid = cfg->inputs[i].pin;
19694                if (!(snd_hda_query_pin_caps(codec, nid) &
19695                      AC_PINCAP_PRES_DETECT))
19696                        continue;
19697                if (snd_hda_jack_detect(codec, nid)) {
19698                        if (cfg->inputs[i].type < type_found) {
19699                                type_found = cfg->inputs[i].type;
19700                                pin_found = nid;
19701                        }
19702                }
19703        }
19704
19705        nid = 0x07;
19706        if (pin_found)
19707                snd_hda_get_connections(codec, pin_found, &nid, 1);
19708
19709        if (nid != spec->cur_adc)
19710                __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19711        spec->cur_adc = nid;
19712        snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19713                                   spec->cur_adc_format);
19714}
19715
19716static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19717                                      struct hda_codec *codec,
19718                                      unsigned int stream_tag,
19719                                      unsigned int format,
19720                                      struct snd_pcm_substream *substream)
19721{
19722        struct alc_spec *spec = codec->spec;
19723
19724        spec->cur_adc = 0x07;
19725        spec->cur_adc_stream_tag = stream_tag;
19726        spec->cur_adc_format = format;
19727
19728        alc680_rec_autoswitch(codec);
19729        return 0;
19730}
19731
19732static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19733                                      struct hda_codec *codec,
19734                                      struct snd_pcm_substream *substream)
19735{
19736        snd_hda_codec_cleanup_stream(codec, 0x07);
19737        snd_hda_codec_cleanup_stream(codec, 0x08);
19738        snd_hda_codec_cleanup_stream(codec, 0x09);
19739        return 0;
19740}
19741
19742static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19743        .substreams = 1, /* can be overridden */
19744        .channels_min = 2,
19745        .channels_max = 2,
19746        /* NID is set in alc_build_pcms */
19747        .ops = {
19748                .prepare = alc680_capture_pcm_prepare,
19749                .cleanup = alc680_capture_pcm_cleanup
19750        },
19751};
19752
19753static struct snd_kcontrol_new alc680_base_mixer[] = {
19754        /* output mixer control */
19755        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19756        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19757        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19758        HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19759        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19760        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19761        HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19762        { }
19763};
19764
19765static struct hda_bind_ctls alc680_bind_cap_vol = {
19766        .ops = &snd_hda_bind_vol,
19767        .values = {
19768                HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19769                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19770                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19771                0
19772        },
19773};
19774
19775static struct hda_bind_ctls alc680_bind_cap_switch = {
19776        .ops = &snd_hda_bind_sw,
19777        .values = {
19778                HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19779                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19780                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19781                0
19782        },
19783};
19784
19785static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19786        HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19787        HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19788        { } /* end */
19789};
19790
19791/*
19792 * generic initialization of ADC, input mixers and output mixers
19793 */
19794static struct hda_verb alc680_init_verbs[] = {
19795        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19796        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19797        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19798
19799        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19800        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19801        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19802        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19803        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19804        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19805
19806        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19807        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19808        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19809        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19810        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19811
19812        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT   | AC_USRSP_EN},
19813        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19814        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT  | AC_USRSP_EN},
19815
19816        { }
19817};
19818
19819/* toggle speaker-output according to the hp-jack state */
19820static void alc680_base_setup(struct hda_codec *codec)
19821{
19822        struct alc_spec *spec = codec->spec;
19823
19824        spec->autocfg.hp_pins[0] = 0x16;
19825        spec->autocfg.speaker_pins[0] = 0x14;
19826        spec->autocfg.speaker_pins[1] = 0x15;
19827        spec->autocfg.num_inputs = 2;
19828        spec->autocfg.inputs[0].pin = 0x18;
19829        spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19830        spec->autocfg.inputs[1].pin = 0x19;
19831        spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19832}
19833
19834static void alc680_unsol_event(struct hda_codec *codec,
19835                                           unsigned int res)
19836{
19837        if ((res >> 26) == ALC880_HP_EVENT)
19838                alc_automute_amp(codec);
19839        if ((res >> 26) == ALC880_MIC_EVENT)
19840                alc680_rec_autoswitch(codec);
19841}
19842
19843static void alc680_inithook(struct hda_codec *codec)
19844{
19845        alc_automute_amp(codec);
19846        alc680_rec_autoswitch(codec);
19847}
19848
19849/* create input playback/capture controls for the given pin */
19850static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19851                                    const char *ctlname, int idx)
19852{
19853        hda_nid_t dac;
19854        int err;
19855
19856        switch (nid) {
19857        case 0x14:
19858                dac = 0x02;
19859                break;
19860        case 0x15:
19861                dac = 0x03;
19862                break;
19863        case 0x16:
19864                dac = 0x04;
19865                break;
19866        default:
19867                return 0;
19868        }
19869        if (spec->multiout.dac_nids[0] != dac &&
19870            spec->multiout.dac_nids[1] != dac) {
19871                err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19872                                  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19873                                                      HDA_OUTPUT));
19874                if (err < 0)
19875                        return err;
19876
19877                err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19878                          HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19879
19880                if (err < 0)
19881                        return err;
19882                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19883        }
19884
19885        return 0;
19886}
19887
19888/* add playback controls from the parsed DAC table */
19889static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19890                                             const struct auto_pin_cfg *cfg)
19891{
19892        hda_nid_t nid;
19893        int err;
19894
19895        spec->multiout.dac_nids = spec->private_dac_nids;
19896
19897        nid = cfg->line_out_pins[0];
19898        if (nid) {
19899                const char *name;
19900                if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19901                        name = "Speaker";
19902                else
19903                        name = "Front";
19904                err = alc680_new_analog_output(spec, nid, name, 0);
19905                if (err < 0)
19906                        return err;
19907        }
19908
19909        nid = cfg->speaker_pins[0];
19910        if (nid) {
19911                err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19912                if (err < 0)
19913                        return err;
19914        }
19915        nid = cfg->hp_pins[0];
19916        if (nid) {
19917                err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19918                if (err < 0)
19919                        return err;
19920        }
19921
19922        return 0;
19923}
19924
19925static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19926                                              hda_nid_t nid, int pin_type)
19927{
19928        alc_set_pin_output(codec, nid, pin_type);
19929}
19930
19931static void alc680_auto_init_multi_out(struct hda_codec *codec)
19932{
19933        struct alc_spec *spec = codec->spec;
19934        hda_nid_t nid = spec->autocfg.line_out_pins[0];
19935        if (nid) {
19936                int pin_type = get_pin_type(spec->autocfg.line_out_type);
19937                alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19938        }
19939}
19940
19941static void alc680_auto_init_hp_out(struct hda_codec *codec)
19942{
19943        struct alc_spec *spec = codec->spec;
19944        hda_nid_t pin;
19945
19946        pin = spec->autocfg.hp_pins[0];
19947        if (pin)
19948                alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19949        pin = spec->autocfg.speaker_pins[0];
19950        if (pin)
19951                alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19952}
19953
19954/* pcm configuration: identical with ALC880 */
19955#define alc680_pcm_analog_playback      alc880_pcm_analog_playback
19956#define alc680_pcm_analog_capture       alc880_pcm_analog_capture
19957#define alc680_pcm_analog_alt_capture   alc880_pcm_analog_alt_capture
19958#define alc680_pcm_digital_playback     alc880_pcm_digital_playback
19959#define alc680_pcm_digital_capture      alc880_pcm_digital_capture
19960
19961/*
19962 * BIOS auto configuration
19963 */
19964static int alc680_parse_auto_config(struct hda_codec *codec)
19965{
19966        struct alc_spec *spec = codec->spec;
19967        int err;
19968        static hda_nid_t alc680_ignore[] = { 0 };
19969
19970        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19971                                           alc680_ignore);
19972        if (err < 0)
19973                return err;
19974
19975        if (!spec->autocfg.line_outs) {
19976                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19977                        spec->multiout.max_channels = 2;
19978                        spec->no_analog = 1;
19979                        goto dig_only;
19980                }
19981                return 0; /* can't find valid BIOS pin config */
19982        }
19983        err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19984        if (err < 0)
19985                return err;
19986
19987        spec->multiout.max_channels = 2;
19988
19989 dig_only:
19990        /* digital only support output */
19991        alc_auto_parse_digital(codec);
19992        if (spec->kctls.list)
19993                add_mixer(spec, spec->kctls.list);
19994
19995        add_verb(spec, alc680_init_verbs);
19996
19997        err = alc_auto_add_mic_boost(codec);
19998        if (err < 0)
19999                return err;
20000
20001        return 1;
20002}
20003
20004#define alc680_auto_init_analog_input   alc882_auto_init_analog_input
20005
20006/* init callback for auto-configuration model -- overriding the default init */
20007static void alc680_auto_init(struct hda_codec *codec)
20008{
20009        struct alc_spec *spec = codec->spec;
20010        alc680_auto_init_multi_out(codec);
20011        alc680_auto_init_hp_out(codec);
20012        alc680_auto_init_analog_input(codec);
20013        alc_auto_init_digital(codec);
20014        if (spec->unsol_event)
20015                alc_inithook(codec);
20016}
20017
20018/*
20019 * configuration and preset
20020 */
20021static const char * const alc680_models[ALC680_MODEL_LAST] = {
20022        [ALC680_BASE]           = "base",
20023        [ALC680_AUTO]           = "auto",
20024};
20025
20026static struct snd_pci_quirk alc680_cfg_tbl[] = {
20027        SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20028        {}
20029};
20030
20031static struct alc_config_preset alc680_presets[] = {
20032        [ALC680_BASE] = {
20033                .mixers = { alc680_base_mixer },
20034                .cap_mixer =  alc680_master_capture_mixer,
20035                .init_verbs = { alc680_init_verbs },
20036                .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20037                .dac_nids = alc680_dac_nids,
20038                .dig_out_nid = ALC680_DIGOUT_NID,
20039                .num_channel_mode = ARRAY_SIZE(alc680_modes),
20040                .channel_mode = alc680_modes,
20041                .unsol_event = alc680_unsol_event,
20042                .setup = alc680_base_setup,
20043                .init_hook = alc680_inithook,
20044
20045        },
20046};
20047
20048static int patch_alc680(struct hda_codec *codec)
20049{
20050        struct alc_spec *spec;
20051        int board_config;
20052        int err;
20053
20054        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20055        if (spec == NULL)
20056                return -ENOMEM;
20057
20058        codec->spec = spec;
20059
20060        board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20061                                                  alc680_models,
20062                                                  alc680_cfg_tbl);
20063
20064        if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20065                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20066                       codec->chip_name);
20067                board_config = ALC680_AUTO;
20068        }
20069
20070        if (board_config == ALC680_AUTO) {
20071                /* automatic parse from the BIOS config */
20072                err = alc680_parse_auto_config(codec);
20073                if (err < 0) {
20074                        alc_free(codec);
20075                        return err;
20076                } else if (!err) {
20077                        printk(KERN_INFO
20078                               "hda_codec: Cannot set up configuration "
20079                               "from BIOS.  Using base mode...\n");
20080                        board_config = ALC680_BASE;
20081                }
20082        }
20083
20084        if (board_config != ALC680_AUTO)
20085                setup_preset(codec, &alc680_presets[board_config]);
20086
20087        spec->stream_analog_playback = &alc680_pcm_analog_playback;
20088        spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20089        spec->stream_digital_playback = &alc680_pcm_digital_playback;
20090        spec->stream_digital_capture = &alc680_pcm_digital_capture;
20091
20092        if (!spec->adc_nids) {
20093                spec->adc_nids = alc680_adc_nids;
20094                spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20095        }
20096
20097        if (!spec->cap_mixer)
20098                set_capture_mixer(codec);
20099
20100        spec->vmaster_nid = 0x02;
20101
20102        codec->patch_ops = alc_patch_ops;
20103        if (board_config == ALC680_AUTO)
20104                spec->init_hook = alc680_auto_init;
20105
20106        return 0;
20107}
20108
20109/*
20110 * patch entries
20111 */
20112static struct hda_codec_preset snd_hda_preset_realtek[] = {
20113        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20114        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20115        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20116        { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20117        { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20118        { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20119        { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20120        { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20121        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20122          .patch = patch_alc861 },
20123        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20124        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20125        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20126        { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20127          .patch = patch_alc882 },
20128        { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20129          .patch = patch_alc662 },
20130        { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20131        { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20132        { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20133        { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20134        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20135        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20136        { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20137        { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20138          .patch = patch_alc882 },
20139        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20140          .patch = patch_alc882 },
20141        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20142        { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20143        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20144          .patch = patch_alc882 },
20145        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20146        { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20147        { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20148        {} /* terminator */
20149};
20150
20151MODULE_ALIAS("snd-hda-codec-id:10ec*");
20152
20153MODULE_LICENSE("GPL");
20154MODULE_DESCRIPTION("Realtek HD-audio codec");
20155
20156static struct hda_codec_preset_list realtek_list = {
20157        .preset = snd_hda_preset_realtek,
20158        .owner = THIS_MODULE,
20159};
20160
20161static int __init patch_realtek_init(void)
20162{
20163        return snd_hda_add_codec_preset(&realtek_list);
20164}
20165
20166static void __exit patch_realtek_exit(void)
20167{
20168        snd_hda_delete_codec_preset(&realtek_list);
20169}
20170
20171module_init(patch_realtek_init)
20172module_exit(patch_realtek_exit)
20173