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 "hda_codec.h"
  32#include "hda_local.h"
  33#include "hda_beep.h"
  34
  35#define ALC880_FRONT_EVENT              0x01
  36#define ALC880_DCVOL_EVENT              0x02
  37#define ALC880_HP_EVENT                 0x04
  38#define ALC880_MIC_EVENT                0x08
  39
  40/* ALC880 board config type */
  41enum {
  42        ALC880_3ST,
  43        ALC880_3ST_DIG,
  44        ALC880_5ST,
  45        ALC880_5ST_DIG,
  46        ALC880_W810,
  47        ALC880_Z71V,
  48        ALC880_6ST,
  49        ALC880_6ST_DIG,
  50        ALC880_F1734,
  51        ALC880_ASUS,
  52        ALC880_ASUS_DIG,
  53        ALC880_ASUS_W1V,
  54        ALC880_ASUS_DIG2,
  55        ALC880_FUJITSU,
  56        ALC880_UNIWILL_DIG,
  57        ALC880_UNIWILL,
  58        ALC880_UNIWILL_P53,
  59        ALC880_CLEVO,
  60        ALC880_TCL_S700,
  61        ALC880_LG,
  62        ALC880_LG_LW,
  63        ALC880_MEDION_RIM,
  64#ifdef CONFIG_SND_DEBUG
  65        ALC880_TEST,
  66#endif
  67        ALC880_AUTO,
  68        ALC880_MODEL_LAST /* last tag */
  69};
  70
  71/* ALC260 models */
  72enum {
  73        ALC260_BASIC,
  74        ALC260_HP,
  75        ALC260_HP_DC7600,
  76        ALC260_HP_3013,
  77        ALC260_FUJITSU_S702X,
  78        ALC260_ACER,
  79        ALC260_WILL,
  80        ALC260_REPLACER_672V,
  81        ALC260_FAVORIT100,
  82#ifdef CONFIG_SND_DEBUG
  83        ALC260_TEST,
  84#endif
  85        ALC260_AUTO,
  86        ALC260_MODEL_LAST /* last tag */
  87};
  88
  89/* ALC262 models */
  90enum {
  91        ALC262_BASIC,
  92        ALC262_HIPPO,
  93        ALC262_HIPPO_1,
  94        ALC262_FUJITSU,
  95        ALC262_HP_BPC,
  96        ALC262_HP_BPC_D7000_WL,
  97        ALC262_HP_BPC_D7000_WF,
  98        ALC262_HP_TC_T5735,
  99        ALC262_HP_RP5700,
 100        ALC262_BENQ_ED8,
 101        ALC262_SONY_ASSAMD,
 102        ALC262_BENQ_T31,
 103        ALC262_ULTRA,
 104        ALC262_LENOVO_3000,
 105        ALC262_NEC,
 106        ALC262_TOSHIBA_S06,
 107        ALC262_TOSHIBA_RX1,
 108        ALC262_TYAN,
 109        ALC262_AUTO,
 110        ALC262_MODEL_LAST /* last tag */
 111};
 112
 113/* ALC268 models */
 114enum {
 115        ALC267_QUANTA_IL1,
 116        ALC268_3ST,
 117        ALC268_TOSHIBA,
 118        ALC268_ACER,
 119        ALC268_ACER_DMIC,
 120        ALC268_ACER_ASPIRE_ONE,
 121        ALC268_DELL,
 122        ALC268_ZEPTO,
 123#ifdef CONFIG_SND_DEBUG
 124        ALC268_TEST,
 125#endif
 126        ALC268_AUTO,
 127        ALC268_MODEL_LAST /* last tag */
 128};
 129
 130/* ALC269 models */
 131enum {
 132        ALC269_BASIC,
 133        ALC269_QUANTA_FL1,
 134        ALC269_ASUS_EEEPC_P703,
 135        ALC269_ASUS_EEEPC_P901,
 136        ALC269_FUJITSU,
 137        ALC269_LIFEBOOK,
 138        ALC269_AUTO,
 139        ALC269_MODEL_LAST /* last tag */
 140};
 141
 142/* ALC861 models */
 143enum {
 144        ALC861_3ST,
 145        ALC660_3ST,
 146        ALC861_3ST_DIG,
 147        ALC861_6ST_DIG,
 148        ALC861_UNIWILL_M31,
 149        ALC861_TOSHIBA,
 150        ALC861_ASUS,
 151        ALC861_ASUS_LAPTOP,
 152        ALC861_AUTO,
 153        ALC861_MODEL_LAST,
 154};
 155
 156/* ALC861-VD models */
 157enum {
 158        ALC660VD_3ST,
 159        ALC660VD_3ST_DIG,
 160        ALC660VD_ASUS_V1S,
 161        ALC861VD_3ST,
 162        ALC861VD_3ST_DIG,
 163        ALC861VD_6ST_DIG,
 164        ALC861VD_LENOVO,
 165        ALC861VD_DALLAS,
 166        ALC861VD_HP,
 167        ALC861VD_AUTO,
 168        ALC861VD_MODEL_LAST,
 169};
 170
 171/* ALC662 models */
 172enum {
 173        ALC662_3ST_2ch_DIG,
 174        ALC662_3ST_6ch_DIG,
 175        ALC662_3ST_6ch,
 176        ALC662_5ST_DIG,
 177        ALC662_LENOVO_101E,
 178        ALC662_ASUS_EEEPC_P701,
 179        ALC662_ASUS_EEEPC_EP20,
 180        ALC663_ASUS_M51VA,
 181        ALC663_ASUS_G71V,
 182        ALC663_ASUS_H13,
 183        ALC663_ASUS_G50V,
 184        ALC662_ECS,
 185        ALC663_ASUS_MODE1,
 186        ALC662_ASUS_MODE2,
 187        ALC663_ASUS_MODE3,
 188        ALC663_ASUS_MODE4,
 189        ALC663_ASUS_MODE5,
 190        ALC663_ASUS_MODE6,
 191        ALC272_DELL,
 192        ALC272_DELL_ZM1,
 193        ALC272_SAMSUNG_NC10,
 194        ALC662_AUTO,
 195        ALC662_MODEL_LAST,
 196};
 197
 198/* ALC882 models */
 199enum {
 200        ALC882_3ST_DIG,
 201        ALC882_6ST_DIG,
 202        ALC882_ARIMA,
 203        ALC882_W2JC,
 204        ALC882_TARGA,
 205        ALC882_ASUS_A7J,
 206        ALC882_ASUS_A7M,
 207        ALC885_MACPRO,
 208        ALC885_MBP3,
 209        ALC885_MB5,
 210        ALC885_IMAC24,
 211        ALC883_3ST_2ch_DIG,
 212        ALC883_3ST_6ch_DIG,
 213        ALC883_3ST_6ch,
 214        ALC883_6ST_DIG,
 215        ALC883_TARGA_DIG,
 216        ALC883_TARGA_2ch_DIG,
 217        ALC883_TARGA_8ch_DIG,
 218        ALC883_ACER,
 219        ALC883_ACER_ASPIRE,
 220        ALC888_ACER_ASPIRE_4930G,
 221        ALC888_ACER_ASPIRE_6530G,
 222        ALC888_ACER_ASPIRE_8930G,
 223        ALC888_ACER_ASPIRE_7730G,
 224        ALC883_MEDION,
 225        ALC883_MEDION_MD2,
 226        ALC883_LAPTOP_EAPD,
 227        ALC883_LENOVO_101E_2ch,
 228        ALC883_LENOVO_NB0763,
 229        ALC888_LENOVO_MS7195_DIG,
 230        ALC888_LENOVO_SKY,
 231        ALC883_HAIER_W66,
 232        ALC888_3ST_HP,
 233        ALC888_6ST_DELL,
 234        ALC883_MITAC,
 235        ALC883_CLEVO_M540R,
 236        ALC883_CLEVO_M720,
 237        ALC883_FUJITSU_PI2515,
 238        ALC888_FUJITSU_XA3530,
 239        ALC883_3ST_6ch_INTEL,
 240        ALC889A_INTEL,
 241        ALC889_INTEL,
 242        ALC888_ASUS_M90V,
 243        ALC888_ASUS_EEE1601,
 244        ALC889A_MB31,
 245        ALC1200_ASUS_P5Q,
 246        ALC883_SONY_VAIO_TT,
 247        ALC882_AUTO,
 248        ALC882_MODEL_LAST,
 249};
 250
 251/* for GPIO Poll */
 252#define GPIO_MASK       0x03
 253
 254/* extra amp-initialization sequence types */
 255enum {
 256        ALC_INIT_NONE,
 257        ALC_INIT_DEFAULT,
 258        ALC_INIT_GPIO1,
 259        ALC_INIT_GPIO2,
 260        ALC_INIT_GPIO3,
 261};
 262
 263struct alc_mic_route {
 264        hda_nid_t pin;
 265        unsigned char mux_idx;
 266        unsigned char amix_idx;
 267};
 268
 269#define MUX_IDX_UNDEF   ((unsigned char)-1)
 270
 271struct alc_spec {
 272        /* codec parameterization */
 273        struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
 274        unsigned int num_mixers;
 275        struct snd_kcontrol_new *cap_mixer;     /* capture mixer */
 276        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
 277
 278        const struct hda_verb *init_verbs[10];  /* initialization verbs
 279                                                 * don't forget NULL
 280                                                 * termination!
 281                                                 */
 282        unsigned int num_init_verbs;
 283
 284        char stream_name_analog[32];    /* analog PCM stream */
 285        struct hda_pcm_stream *stream_analog_playback;
 286        struct hda_pcm_stream *stream_analog_capture;
 287        struct hda_pcm_stream *stream_analog_alt_playback;
 288        struct hda_pcm_stream *stream_analog_alt_capture;
 289
 290        char stream_name_digital[32];   /* digital PCM stream */
 291        struct hda_pcm_stream *stream_digital_playback;
 292        struct hda_pcm_stream *stream_digital_capture;
 293
 294        /* playback */
 295        struct hda_multi_out multiout;  /* playback set-up
 296                                         * max_channels, dacs must be set
 297                                         * dig_out_nid and hp_nid are optional
 298                                         */
 299        hda_nid_t alt_dac_nid;
 300        hda_nid_t slave_dig_outs[3];    /* optional - for auto-parsing */
 301        int dig_out_type;
 302
 303        /* capture */
 304        unsigned int num_adc_nids;
 305        hda_nid_t *adc_nids;
 306        hda_nid_t *capsrc_nids;
 307        hda_nid_t dig_in_nid;           /* digital-in NID; optional */
 308
 309        /* capture source */
 310        unsigned int num_mux_defs;
 311        const struct hda_input_mux *input_mux;
 312        unsigned int cur_mux[3];
 313        struct alc_mic_route ext_mic;
 314        struct alc_mic_route int_mic;
 315
 316        /* channel model */
 317        const struct hda_channel_mode *channel_mode;
 318        int num_channel_mode;
 319        int need_dac_fix;
 320        int const_channel_count;
 321        int ext_channel_count;
 322
 323        /* PCM information */
 324        struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
 325
 326        /* dynamic controls, init_verbs and input_mux */
 327        struct auto_pin_cfg autocfg;
 328        struct snd_array kctls;
 329        struct hda_input_mux private_imux[3];
 330        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 331        hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
 332        hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
 333
 334        /* hooks */
 335        void (*init_hook)(struct hda_codec *codec);
 336        void (*unsol_event)(struct hda_codec *codec, unsigned int res);
 337
 338        /* for pin sensing */
 339        unsigned int sense_updated: 1;
 340        unsigned int jack_present: 1;
 341        unsigned int master_sw: 1;
 342        unsigned int auto_mic:1;
 343
 344        /* other flags */
 345        unsigned int no_analog :1; /* digital I/O only */
 346        int init_amp;
 347
 348        /* for virtual master */
 349        hda_nid_t vmaster_nid;
 350#ifdef CONFIG_SND_HDA_POWER_SAVE
 351        struct hda_loopback_check loopback;
 352#endif
 353
 354        /* for PLL fix */
 355        hda_nid_t pll_nid;
 356        unsigned int pll_coef_idx, pll_coef_bit;
 357};
 358
 359/*
 360 * configuration template - to be copied to the spec instance
 361 */
 362struct alc_config_preset {
 363        struct snd_kcontrol_new *mixers[5]; /* should be identical size
 364                                             * with spec
 365                                             */
 366        struct snd_kcontrol_new *cap_mixer; /* capture mixer */
 367        const struct hda_verb *init_verbs[5];
 368        unsigned int num_dacs;
 369        hda_nid_t *dac_nids;
 370        hda_nid_t dig_out_nid;          /* optional */
 371        hda_nid_t hp_nid;               /* optional */
 372        hda_nid_t *slave_dig_outs;
 373        unsigned int num_adc_nids;
 374        hda_nid_t *adc_nids;
 375        hda_nid_t *capsrc_nids;
 376        hda_nid_t dig_in_nid;
 377        unsigned int num_channel_mode;
 378        const struct hda_channel_mode *channel_mode;
 379        int need_dac_fix;
 380        int const_channel_count;
 381        unsigned int num_mux_defs;
 382        const struct hda_input_mux *input_mux;
 383        void (*unsol_event)(struct hda_codec *, unsigned int);
 384        void (*setup)(struct hda_codec *);
 385        void (*init_hook)(struct hda_codec *);
 386#ifdef CONFIG_SND_HDA_POWER_SAVE
 387        struct hda_amp_list *loopbacks;
 388#endif
 389};
 390
 391
 392/*
 393 * input MUX handling
 394 */
 395static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
 396                             struct snd_ctl_elem_info *uinfo)
 397{
 398        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 399        struct alc_spec *spec = codec->spec;
 400        unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
 401        if (mux_idx >= spec->num_mux_defs)
 402                mux_idx = 0;
 403        return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
 404}
 405
 406static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
 407                            struct snd_ctl_elem_value *ucontrol)
 408{
 409        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 410        struct alc_spec *spec = codec->spec;
 411        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 412
 413        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 414        return 0;
 415}
 416
 417static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
 418                            struct snd_ctl_elem_value *ucontrol)
 419{
 420        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 421        struct alc_spec *spec = codec->spec;
 422        const struct hda_input_mux *imux;
 423        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 424        unsigned int mux_idx;
 425        hda_nid_t nid = spec->capsrc_nids ?
 426                spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
 427        unsigned int type;
 428
 429        mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
 430        imux = &spec->input_mux[mux_idx];
 431
 432        type = get_wcaps_type(get_wcaps(codec, nid));
 433        if (type == AC_WID_AUD_MIX) {
 434                /* Matrix-mixer style (e.g. ALC882) */
 435                unsigned int *cur_val = &spec->cur_mux[adc_idx];
 436                unsigned int i, idx;
 437
 438                idx = ucontrol->value.enumerated.item[0];
 439                if (idx >= imux->num_items)
 440                        idx = imux->num_items - 1;
 441                if (*cur_val == idx)
 442                        return 0;
 443                for (i = 0; i < imux->num_items; i++) {
 444                        unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
 445                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
 446                                                 imux->items[i].index,
 447                                                 HDA_AMP_MUTE, v);
 448                }
 449                *cur_val = idx;
 450                return 1;
 451        } else {
 452                /* MUX style (e.g. ALC880) */
 453                return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
 454                                             &spec->cur_mux[adc_idx]);
 455        }
 456}
 457
 458/*
 459 * channel mode setting
 460 */
 461static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
 462                            struct snd_ctl_elem_info *uinfo)
 463{
 464        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 465        struct alc_spec *spec = codec->spec;
 466        return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
 467                                    spec->num_channel_mode);
 468}
 469
 470static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
 471                           struct snd_ctl_elem_value *ucontrol)
 472{
 473        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 474        struct alc_spec *spec = codec->spec;
 475        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
 476                                   spec->num_channel_mode,
 477                                   spec->ext_channel_count);
 478}
 479
 480static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
 481                           struct snd_ctl_elem_value *ucontrol)
 482{
 483        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 484        struct alc_spec *spec = codec->spec;
 485        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
 486                                      spec->num_channel_mode,
 487                                      &spec->ext_channel_count);
 488        if (err >= 0 && !spec->const_channel_count) {
 489                spec->multiout.max_channels = spec->ext_channel_count;
 490                if (spec->need_dac_fix)
 491                        spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 492        }
 493        return err;
 494}
 495
 496/*
 497 * Control the mode of pin widget settings via the mixer.  "pc" is used
 498 * instead of "%" to avoid consequences of accidently treating the % as
 499 * being part of a format specifier.  Maximum allowed length of a value is
 500 * 63 characters plus NULL terminator.
 501 *
 502 * Note: some retasking pin complexes seem to ignore requests for input
 503 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
 504 * are requested.  Therefore order this list so that this behaviour will not
 505 * cause problems when mixer clients move through the enum sequentially.
 506 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
 507 * March 2006.
 508 */
 509static char *alc_pin_mode_names[] = {
 510        "Mic 50pc bias", "Mic 80pc bias",
 511        "Line in", "Line out", "Headphone out",
 512};
 513static unsigned char alc_pin_mode_values[] = {
 514        PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
 515};
 516/* The control can present all 5 options, or it can limit the options based
 517 * in the pin being assumed to be exclusively an input or an output pin.  In
 518 * addition, "input" pins may or may not process the mic bias option
 519 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
 520 * accept requests for bias as of chip versions up to March 2006) and/or
 521 * wiring in the computer.
 522 */
 523#define ALC_PIN_DIR_IN              0x00
 524#define ALC_PIN_DIR_OUT             0x01
 525#define ALC_PIN_DIR_INOUT           0x02
 526#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
 527#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
 528
 529/* Info about the pin modes supported by the different pin direction modes.
 530 * For each direction the minimum and maximum values are given.
 531 */
 532static signed char alc_pin_mode_dir_info[5][2] = {
 533        { 0, 2 },    /* ALC_PIN_DIR_IN */
 534        { 3, 4 },    /* ALC_PIN_DIR_OUT */
 535        { 0, 4 },    /* ALC_PIN_DIR_INOUT */
 536        { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
 537        { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
 538};
 539#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
 540#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
 541#define alc_pin_mode_n_items(_dir) \
 542        (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
 543
 544static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
 545                             struct snd_ctl_elem_info *uinfo)
 546{
 547        unsigned int item_num = uinfo->value.enumerated.item;
 548        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 549
 550        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 551        uinfo->count = 1;
 552        uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
 553
 554        if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
 555                item_num = alc_pin_mode_min(dir);
 556        strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
 557        return 0;
 558}
 559
 560static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
 561                            struct snd_ctl_elem_value *ucontrol)
 562{
 563        unsigned int i;
 564        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 565        hda_nid_t nid = kcontrol->private_value & 0xffff;
 566        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 567        long *valp = ucontrol->value.integer.value;
 568        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
 569                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
 570                                                 0x00);
 571
 572        /* Find enumerated value for current pinctl setting */
 573        i = alc_pin_mode_min(dir);
 574        while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
 575                i++;
 576        *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
 577        return 0;
 578}
 579
 580static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
 581                            struct snd_ctl_elem_value *ucontrol)
 582{
 583        signed int change;
 584        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 585        hda_nid_t nid = kcontrol->private_value & 0xffff;
 586        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
 587        long val = *ucontrol->value.integer.value;
 588        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
 589                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
 590                                                 0x00);
 591
 592        if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
 593                val = alc_pin_mode_min(dir);
 594
 595        change = pinctl != alc_pin_mode_values[val];
 596        if (change) {
 597                /* Set pin mode to that requested */
 598                snd_hda_codec_write_cache(codec, nid, 0,
 599                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
 600                                          alc_pin_mode_values[val]);
 601
 602                /* Also enable the retasking pin's input/output as required
 603                 * for the requested pin mode.  Enum values of 2 or less are
 604                 * input modes.
 605                 *
 606                 * Dynamically switching the input/output buffers probably
 607                 * reduces noise slightly (particularly on input) so we'll
 608                 * do it.  However, having both input and output buffers
 609                 * enabled simultaneously doesn't seem to be problematic if
 610                 * this turns out to be necessary in the future.
 611                 */
 612                if (val <= 2) {
 613                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 614                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
 615                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
 616                                                 HDA_AMP_MUTE, 0);
 617                } else {
 618                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
 619                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
 620                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 621                                                 HDA_AMP_MUTE, 0);
 622                }
 623        }
 624        return change;
 625}
 626
 627#define ALC_PIN_MODE(xname, nid, dir) \
 628        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 629          .info = alc_pin_mode_info, \
 630          .get = alc_pin_mode_get, \
 631          .put = alc_pin_mode_put, \
 632          .private_value = nid | (dir<<16) }
 633
 634/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
 635 * together using a mask with more than one bit set.  This control is
 636 * currently used only by the ALC260 test model.  At this stage they are not
 637 * needed for any "production" models.
 638 */
 639#ifdef CONFIG_SND_DEBUG
 640#define alc_gpio_data_info      snd_ctl_boolean_mono_info
 641
 642static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
 643                             struct snd_ctl_elem_value *ucontrol)
 644{
 645        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 646        hda_nid_t nid = kcontrol->private_value & 0xffff;
 647        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 648        long *valp = ucontrol->value.integer.value;
 649        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 650                                              AC_VERB_GET_GPIO_DATA, 0x00);
 651
 652        *valp = (val & mask) != 0;
 653        return 0;
 654}
 655static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
 656                             struct snd_ctl_elem_value *ucontrol)
 657{
 658        signed int change;
 659        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 660        hda_nid_t nid = kcontrol->private_value & 0xffff;
 661        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 662        long val = *ucontrol->value.integer.value;
 663        unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
 664                                                    AC_VERB_GET_GPIO_DATA,
 665                                                    0x00);
 666
 667        /* Set/unset the masked GPIO bit(s) as needed */
 668        change = (val == 0 ? 0 : mask) != (gpio_data & mask);
 669        if (val == 0)
 670                gpio_data &= ~mask;
 671        else
 672                gpio_data |= mask;
 673        snd_hda_codec_write_cache(codec, nid, 0,
 674                                  AC_VERB_SET_GPIO_DATA, gpio_data);
 675
 676        return change;
 677}
 678#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
 679        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 680          .info = alc_gpio_data_info, \
 681          .get = alc_gpio_data_get, \
 682          .put = alc_gpio_data_put, \
 683          .private_value = nid | (mask<<16) }
 684#endif   /* CONFIG_SND_DEBUG */
 685
 686/* A switch control to allow the enabling of the digital IO pins on the
 687 * ALC260.  This is incredibly simplistic; the intention of this control is
 688 * to provide something in the test model allowing digital outputs to be
 689 * identified if present.  If models are found which can utilise these
 690 * outputs a more complete mixer control can be devised for those models if
 691 * necessary.
 692 */
 693#ifdef CONFIG_SND_DEBUG
 694#define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
 695
 696static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
 697                              struct snd_ctl_elem_value *ucontrol)
 698{
 699        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 700        hda_nid_t nid = kcontrol->private_value & 0xffff;
 701        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 702        long *valp = ucontrol->value.integer.value;
 703        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 704                                              AC_VERB_GET_DIGI_CONVERT_1, 0x00);
 705
 706        *valp = (val & mask) != 0;
 707        return 0;
 708}
 709static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
 710                              struct snd_ctl_elem_value *ucontrol)
 711{
 712        signed int change;
 713        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 714        hda_nid_t nid = kcontrol->private_value & 0xffff;
 715        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 716        long val = *ucontrol->value.integer.value;
 717        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
 718                                                    AC_VERB_GET_DIGI_CONVERT_1,
 719                                                    0x00);
 720
 721        /* Set/unset the masked control bit(s) as needed */
 722        change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
 723        if (val==0)
 724                ctrl_data &= ~mask;
 725        else
 726                ctrl_data |= mask;
 727        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
 728                                  ctrl_data);
 729
 730        return change;
 731}
 732#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
 733        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 734          .info = alc_spdif_ctrl_info, \
 735          .get = alc_spdif_ctrl_get, \
 736          .put = alc_spdif_ctrl_put, \
 737          .private_value = nid | (mask<<16) }
 738#endif   /* CONFIG_SND_DEBUG */
 739
 740/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
 741 * Again, this is only used in the ALC26x test models to help identify when
 742 * the EAPD line must be asserted for features to work.
 743 */
 744#ifdef CONFIG_SND_DEBUG
 745#define alc_eapd_ctrl_info      snd_ctl_boolean_mono_info
 746
 747static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
 748                              struct snd_ctl_elem_value *ucontrol)
 749{
 750        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 751        hda_nid_t nid = kcontrol->private_value & 0xffff;
 752        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 753        long *valp = ucontrol->value.integer.value;
 754        unsigned int val = snd_hda_codec_read(codec, nid, 0,
 755                                              AC_VERB_GET_EAPD_BTLENABLE, 0x00);
 756
 757        *valp = (val & mask) != 0;
 758        return 0;
 759}
 760
 761static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
 762                              struct snd_ctl_elem_value *ucontrol)
 763{
 764        int change;
 765        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 766        hda_nid_t nid = kcontrol->private_value & 0xffff;
 767        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
 768        long val = *ucontrol->value.integer.value;
 769        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
 770                                                    AC_VERB_GET_EAPD_BTLENABLE,
 771                                                    0x00);
 772
 773        /* Set/unset the masked control bit(s) as needed */
 774        change = (!val ? 0 : mask) != (ctrl_data & mask);
 775        if (!val)
 776                ctrl_data &= ~mask;
 777        else
 778                ctrl_data |= mask;
 779        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
 780                                  ctrl_data);
 781
 782        return change;
 783}
 784
 785#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
 786        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 787          .info = alc_eapd_ctrl_info, \
 788          .get = alc_eapd_ctrl_get, \
 789          .put = alc_eapd_ctrl_put, \
 790          .private_value = nid | (mask<<16) }
 791#endif   /* CONFIG_SND_DEBUG */
 792
 793/*
 794 * set up the input pin config (depending on the given auto-pin type)
 795 */
 796static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
 797                              int auto_pin_type)
 798{
 799        unsigned int val = PIN_IN;
 800
 801        if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
 802                unsigned int pincap;
 803                pincap = snd_hda_query_pin_caps(codec, nid);
 804                pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
 805                if (pincap & AC_PINCAP_VREF_80)
 806                        val = PIN_VREF80;
 807                else if (pincap & AC_PINCAP_VREF_50)
 808                        val = PIN_VREF50;
 809                else if (pincap & AC_PINCAP_VREF_100)
 810                        val = PIN_VREF100;
 811                else if (pincap & AC_PINCAP_VREF_GRD)
 812                        val = PIN_VREFGRD;
 813        }
 814        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
 815}
 816
 817/*
 818 */
 819static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
 820{
 821        if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
 822                return;
 823        spec->mixers[spec->num_mixers++] = mix;
 824}
 825
 826static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
 827{
 828        if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
 829                return;
 830        spec->init_verbs[spec->num_init_verbs++] = verb;
 831}
 832
 833#ifdef CONFIG_PROC_FS
 834/*
 835 * hook for proc
 836 */
 837static void print_realtek_coef(struct snd_info_buffer *buffer,
 838                               struct hda_codec *codec, hda_nid_t nid)
 839{
 840        int coeff;
 841
 842        if (nid != 0x20)
 843                return;
 844        coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
 845        snd_iprintf(buffer, "  Processing Coefficient: 0x%02x\n", coeff);
 846        coeff = snd_hda_codec_read(codec, nid, 0,
 847                                   AC_VERB_GET_COEF_INDEX, 0);
 848        snd_iprintf(buffer, "  Coefficient Index: 0x%02x\n", coeff);
 849}
 850#else
 851#define print_realtek_coef      NULL
 852#endif
 853
 854/*
 855 * set up from the preset table
 856 */
 857static void setup_preset(struct hda_codec *codec,
 858                         const struct alc_config_preset *preset)
 859{
 860        struct alc_spec *spec = codec->spec;
 861        int i;
 862
 863        for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
 864                add_mixer(spec, preset->mixers[i]);
 865        spec->cap_mixer = preset->cap_mixer;
 866        for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
 867             i++)
 868                add_verb(spec, preset->init_verbs[i]);
 869
 870        spec->channel_mode = preset->channel_mode;
 871        spec->num_channel_mode = preset->num_channel_mode;
 872        spec->need_dac_fix = preset->need_dac_fix;
 873        spec->const_channel_count = preset->const_channel_count;
 874
 875        if (preset->const_channel_count)
 876                spec->multiout.max_channels = preset->const_channel_count;
 877        else
 878                spec->multiout.max_channels = spec->channel_mode[0].channels;
 879        spec->ext_channel_count = spec->channel_mode[0].channels;
 880
 881        spec->multiout.num_dacs = preset->num_dacs;
 882        spec->multiout.dac_nids = preset->dac_nids;
 883        spec->multiout.dig_out_nid = preset->dig_out_nid;
 884        spec->multiout.slave_dig_outs = preset->slave_dig_outs;
 885        spec->multiout.hp_nid = preset->hp_nid;
 886
 887        spec->num_mux_defs = preset->num_mux_defs;
 888        if (!spec->num_mux_defs)
 889                spec->num_mux_defs = 1;
 890        spec->input_mux = preset->input_mux;
 891
 892        spec->num_adc_nids = preset->num_adc_nids;
 893        spec->adc_nids = preset->adc_nids;
 894        spec->capsrc_nids = preset->capsrc_nids;
 895        spec->dig_in_nid = preset->dig_in_nid;
 896
 897        spec->unsol_event = preset->unsol_event;
 898        spec->init_hook = preset->init_hook;
 899#ifdef CONFIG_SND_HDA_POWER_SAVE
 900        spec->loopback.amplist = preset->loopbacks;
 901#endif
 902
 903        if (preset->setup)
 904                preset->setup(codec);
 905}
 906
 907/* Enable GPIO mask and set output */
 908static struct hda_verb alc_gpio1_init_verbs[] = {
 909        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 910        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 911        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 912        { }
 913};
 914
 915static struct hda_verb alc_gpio2_init_verbs[] = {
 916        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 917        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 918        {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
 919        { }
 920};
 921
 922static struct hda_verb alc_gpio3_init_verbs[] = {
 923        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 924        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 925        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 926        { }
 927};
 928
 929/*
 930 * Fix hardware PLL issue
 931 * On some codecs, the analog PLL gating control must be off while
 932 * the default value is 1.
 933 */
 934static void alc_fix_pll(struct hda_codec *codec)
 935{
 936        struct alc_spec *spec = codec->spec;
 937        unsigned int val;
 938
 939        if (!spec->pll_nid)
 940                return;
 941        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 942                            spec->pll_coef_idx);
 943        val = snd_hda_codec_read(codec, spec->pll_nid, 0,
 944                                 AC_VERB_GET_PROC_COEF, 0);
 945        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
 946                            spec->pll_coef_idx);
 947        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
 948                            val & ~(1 << spec->pll_coef_bit));
 949}
 950
 951static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
 952                             unsigned int coef_idx, unsigned int coef_bit)
 953{
 954        struct alc_spec *spec = codec->spec;
 955        spec->pll_nid = nid;
 956        spec->pll_coef_idx = coef_idx;
 957        spec->pll_coef_bit = coef_bit;
 958        alc_fix_pll(codec);
 959}
 960
 961static void alc_automute_pin(struct hda_codec *codec)
 962{
 963        struct alc_spec *spec = codec->spec;
 964        unsigned int present, pincap;
 965        unsigned int nid = spec->autocfg.hp_pins[0];
 966        int i;
 967
 968        if (!nid)
 969                return;
 970        pincap = snd_hda_query_pin_caps(codec, nid);
 971        if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
 972                snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
 973        present = snd_hda_codec_read(codec, nid, 0,
 974                                     AC_VERB_GET_PIN_SENSE, 0);
 975        spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
 976        for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
 977                nid = spec->autocfg.speaker_pins[i];
 978                if (!nid)
 979                        break;
 980                snd_hda_codec_write(codec, nid, 0,
 981                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
 982                                    spec->jack_present ? 0 : PIN_OUT);
 983        }
 984}
 985
 986static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
 987                                hda_nid_t nid)
 988{
 989        hda_nid_t conn[HDA_MAX_NUM_INPUTS];
 990        int i, nums;
 991
 992        nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
 993        for (i = 0; i < nums; i++)
 994                if (conn[i] == nid)
 995                        return i;
 996        return -1;
 997}
 998
 999static void alc_mic_automute(struct hda_codec *codec)
1000{
1001        struct alc_spec *spec = codec->spec;
1002        struct alc_mic_route *dead, *alive;
1003        unsigned int present, type;
1004        hda_nid_t cap_nid;
1005
1006        if (!spec->auto_mic)
1007                return;
1008        if (!spec->int_mic.pin || !spec->ext_mic.pin)
1009                return;
1010        if (snd_BUG_ON(!spec->adc_nids))
1011                return;
1012
1013        cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1014
1015        present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0,
1016                                     AC_VERB_GET_PIN_SENSE, 0);
1017        present &= AC_PINSENSE_PRESENCE;
1018        if (present) {
1019                alive = &spec->ext_mic;
1020                dead = &spec->int_mic;
1021        } else {
1022                alive = &spec->int_mic;
1023                dead = &spec->ext_mic;
1024        }
1025
1026        type = get_wcaps_type(get_wcaps(codec, cap_nid));
1027        if (type == AC_WID_AUD_MIX) {
1028                /* Matrix-mixer style (e.g. ALC882) */
1029                snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1030                                         alive->mux_idx,
1031                                         HDA_AMP_MUTE, 0);
1032                snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1033                                         dead->mux_idx,
1034                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
1035        } else {
1036                /* MUX style (e.g. ALC880) */
1037                snd_hda_codec_write_cache(codec, cap_nid, 0,
1038                                          AC_VERB_SET_CONNECT_SEL,
1039                                          alive->mux_idx);
1040        }
1041
1042        /* FIXME: analog mixer */
1043}
1044
1045/* unsolicited event for HP jack sensing */
1046static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1047{
1048        if (codec->vendor_id == 0x10ec0880)
1049                res >>= 28;
1050        else
1051                res >>= 26;
1052        switch (res) {
1053        case ALC880_HP_EVENT:
1054                alc_automute_pin(codec);
1055                break;
1056        case ALC880_MIC_EVENT:
1057                alc_mic_automute(codec);
1058                break;
1059        }
1060}
1061
1062static void alc_inithook(struct hda_codec *codec)
1063{
1064        alc_automute_pin(codec);
1065        alc_mic_automute(codec);
1066}
1067
1068/* additional initialization for ALC888 variants */
1069static void alc888_coef_init(struct hda_codec *codec)
1070{
1071        unsigned int tmp;
1072
1073        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1074        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1075        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1076        if ((tmp & 0xf0) == 0x20)
1077                /* alc888S-VC */
1078                snd_hda_codec_read(codec, 0x20, 0,
1079                                   AC_VERB_SET_PROC_COEF, 0x830);
1080         else
1081                 /* alc888-VB */
1082                 snd_hda_codec_read(codec, 0x20, 0,
1083                                    AC_VERB_SET_PROC_COEF, 0x3030);
1084}
1085
1086static void alc889_coef_init(struct hda_codec *codec)
1087{
1088        unsigned int tmp;
1089
1090        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1091        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1092        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1093        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1094}
1095
1096static void alc_auto_init_amp(struct hda_codec *codec, int type)
1097{
1098        unsigned int tmp;
1099
1100        switch (type) {
1101        case ALC_INIT_GPIO1:
1102                snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1103                break;
1104        case ALC_INIT_GPIO2:
1105                snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1106                break;
1107        case ALC_INIT_GPIO3:
1108                snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1109                break;
1110        case ALC_INIT_DEFAULT:
1111                switch (codec->vendor_id) {
1112                case 0x10ec0260:
1113                        snd_hda_codec_write(codec, 0x0f, 0,
1114                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
1115                        snd_hda_codec_write(codec, 0x10, 0,
1116                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
1117                        break;
1118                case 0x10ec0262:
1119                case 0x10ec0267:
1120                case 0x10ec0268:
1121                case 0x10ec0269:
1122                case 0x10ec0272:
1123                case 0x10ec0660:
1124                case 0x10ec0662:
1125                case 0x10ec0663:
1126                case 0x10ec0862:
1127                case 0x10ec0889:
1128                        snd_hda_codec_write(codec, 0x14, 0,
1129                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
1130                        snd_hda_codec_write(codec, 0x15, 0,
1131                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
1132                        break;
1133                }
1134                switch (codec->vendor_id) {
1135                case 0x10ec0260:
1136                        snd_hda_codec_write(codec, 0x1a, 0,
1137                                            AC_VERB_SET_COEF_INDEX, 7);
1138                        tmp = snd_hda_codec_read(codec, 0x1a, 0,
1139                                                 AC_VERB_GET_PROC_COEF, 0);
1140                        snd_hda_codec_write(codec, 0x1a, 0,
1141                                            AC_VERB_SET_COEF_INDEX, 7);
1142                        snd_hda_codec_write(codec, 0x1a, 0,
1143                                            AC_VERB_SET_PROC_COEF,
1144                                            tmp | 0x2010);
1145                        break;
1146                case 0x10ec0262:
1147                case 0x10ec0880:
1148                case 0x10ec0882:
1149                case 0x10ec0883:
1150                case 0x10ec0885:
1151                case 0x10ec0887:
1152                case 0x10ec0889:
1153                        alc889_coef_init(codec);
1154                        break;
1155                case 0x10ec0888:
1156                        alc888_coef_init(codec);
1157                        break;
1158                case 0x10ec0267:
1159                case 0x10ec0268:
1160                        snd_hda_codec_write(codec, 0x20, 0,
1161                                            AC_VERB_SET_COEF_INDEX, 7);
1162                        tmp = snd_hda_codec_read(codec, 0x20, 0,
1163                                                 AC_VERB_GET_PROC_COEF, 0);
1164                        snd_hda_codec_write(codec, 0x20, 0,
1165                                            AC_VERB_SET_COEF_INDEX, 7);
1166                        snd_hda_codec_write(codec, 0x20, 0,
1167                                            AC_VERB_SET_PROC_COEF,
1168                                            tmp | 0x3000);
1169                        break;
1170                }
1171                break;
1172        }
1173}
1174
1175static void alc_init_auto_hp(struct hda_codec *codec)
1176{
1177        struct alc_spec *spec = codec->spec;
1178
1179        if (!spec->autocfg.hp_pins[0])
1180                return;
1181
1182        if (!spec->autocfg.speaker_pins[0]) {
1183                if (spec->autocfg.line_out_pins[0] &&
1184                    spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1185                        spec->autocfg.speaker_pins[0] =
1186                                spec->autocfg.line_out_pins[0];
1187                else
1188                        return;
1189        }
1190
1191        snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1192                    spec->autocfg.hp_pins[0]);
1193        snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1194                                  AC_VERB_SET_UNSOLICITED_ENABLE,
1195                                  AC_USRSP_EN | ALC880_HP_EVENT);
1196        spec->unsol_event = alc_sku_unsol_event;
1197}
1198
1199static void alc_init_auto_mic(struct hda_codec *codec)
1200{
1201        struct alc_spec *spec = codec->spec;
1202        struct auto_pin_cfg *cfg = &spec->autocfg;
1203        hda_nid_t fixed, ext;
1204        int i;
1205
1206        /* there must be only two mic inputs exclusively */
1207        for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1208                if (cfg->input_pins[i])
1209                        return;
1210
1211        fixed = ext = 0;
1212        for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1213                hda_nid_t nid = cfg->input_pins[i];
1214                unsigned int defcfg;
1215                if (!nid)
1216                        return;
1217                defcfg = snd_hda_codec_get_pincfg(codec, nid);
1218                switch (get_defcfg_connect(defcfg)) {
1219                case AC_JACK_PORT_FIXED:
1220                        if (fixed)
1221                                return; /* already occupied */
1222                        fixed = nid;
1223                        break;
1224                case AC_JACK_PORT_COMPLEX:
1225                        if (ext)
1226                                return; /* already occupied */
1227                        ext = nid;
1228                        break;
1229                default:
1230                        return; /* invalid entry */
1231                }
1232        }
1233        if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1234                return; /* no unsol support */
1235        snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1236                    ext, fixed);
1237        spec->ext_mic.pin = ext;
1238        spec->int_mic.pin = fixed;
1239        spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1240        spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1241        spec->auto_mic = 1;
1242        snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1243                                  AC_VERB_SET_UNSOLICITED_ENABLE,
1244                                  AC_USRSP_EN | ALC880_MIC_EVENT);
1245        spec->unsol_event = alc_sku_unsol_event;
1246}
1247
1248/* check subsystem ID and set up device-specific initialization;
1249 * return 1 if initialized, 0 if invalid SSID
1250 */
1251/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1252 *      31 ~ 16 :       Manufacture ID
1253 *      15 ~ 8  :       SKU ID
1254 *      7  ~ 0  :       Assembly ID
1255 *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1256 */
1257static int alc_subsystem_id(struct hda_codec *codec,
1258                            hda_nid_t porta, hda_nid_t porte,
1259                            hda_nid_t portd)
1260{
1261        unsigned int ass, tmp, i;
1262        unsigned nid;
1263        struct alc_spec *spec = codec->spec;
1264
1265        ass = codec->subsystem_id & 0xffff;
1266        if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1267                goto do_sku;
1268
1269        /* invalid SSID, check the special NID pin defcfg instead */
1270        /*
1271         * 31~30        : port connectivity
1272         * 29~21        : reserve
1273         * 20           : PCBEEP input
1274         * 19~16        : Check sum (15:1)
1275         * 15~1         : Custom
1276         * 0            : override
1277        */
1278        nid = 0x1d;
1279        if (codec->vendor_id == 0x10ec0260)
1280                nid = 0x17;
1281        ass = snd_hda_codec_get_pincfg(codec, nid);
1282        snd_printd("realtek: No valid SSID, "
1283                   "checking pincfg 0x%08x for NID 0x%x\n",
1284                   ass, nid);
1285        if (!(ass & 1) && !(ass & 0x100000))
1286                return 0;
1287        if ((ass >> 30) != 1)   /* no physical connection */
1288                return 0;
1289
1290        /* check sum */
1291        tmp = 0;
1292        for (i = 1; i < 16; i++) {
1293                if ((ass >> i) & 1)
1294                        tmp++;
1295        }
1296        if (((ass >> 16) & 0xf) != tmp)
1297                return 0;
1298do_sku:
1299        snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1300                   ass & 0xffff, codec->vendor_id);
1301        /*
1302         * 0 : override
1303         * 1 :  Swap Jack
1304         * 2 : 0 --> Desktop, 1 --> Laptop
1305         * 3~5 : External Amplifier control
1306         * 7~6 : Reserved
1307        */
1308        tmp = (ass & 0x38) >> 3;        /* external Amp control */
1309        switch (tmp) {
1310        case 1:
1311                spec->init_amp = ALC_INIT_GPIO1;
1312                break;
1313        case 3:
1314                spec->init_amp = ALC_INIT_GPIO2;
1315                break;
1316        case 7:
1317                spec->init_amp = ALC_INIT_GPIO3;
1318                break;
1319        case 5:
1320                spec->init_amp = ALC_INIT_DEFAULT;
1321                break;
1322        }
1323
1324        /* is laptop or Desktop and enable the function "Mute internal speaker
1325         * when the external headphone out jack is plugged"
1326         */
1327        if (!(ass & 0x8000))
1328                return 1;
1329        /*
1330         * 10~8 : Jack location
1331         * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1332         * 14~13: Resvered
1333         * 15   : 1 --> enable the function "Mute internal speaker
1334         *              when the external headphone out jack is plugged"
1335         */
1336        if (!spec->autocfg.hp_pins[0]) {
1337                hda_nid_t nid;
1338                tmp = (ass >> 11) & 0x3;        /* HP to chassis */
1339                if (tmp == 0)
1340                        nid = porta;
1341                else if (tmp == 1)
1342                        nid = porte;
1343                else if (tmp == 2)
1344                        nid = portd;
1345                else
1346                        return 1;
1347                for (i = 0; i < spec->autocfg.line_outs; i++)
1348                        if (spec->autocfg.line_out_pins[i] == nid)
1349                                return 1;
1350                spec->autocfg.hp_pins[0] = nid;
1351        }
1352
1353        alc_init_auto_hp(codec);
1354        alc_init_auto_mic(codec);
1355        return 1;
1356}
1357
1358static void alc_ssid_check(struct hda_codec *codec,
1359                           hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1360{
1361        if (!alc_subsystem_id(codec, porta, porte, portd)) {
1362                struct alc_spec *spec = codec->spec;
1363                snd_printd("realtek: "
1364                           "Enable default setup for auto mode as fallback\n");
1365                spec->init_amp = ALC_INIT_DEFAULT;
1366                alc_init_auto_hp(codec);
1367                alc_init_auto_mic(codec);
1368        }
1369}
1370
1371/*
1372 * Fix-up pin default configurations and add default verbs
1373 */
1374
1375struct alc_pincfg {
1376        hda_nid_t nid;
1377        u32 val;
1378};
1379
1380struct alc_fixup {
1381        const struct alc_pincfg *pins;
1382        const struct hda_verb *verbs;
1383};
1384
1385static void alc_pick_fixup(struct hda_codec *codec,
1386                           const struct snd_pci_quirk *quirk,
1387                           const struct alc_fixup *fix)
1388{
1389        const struct alc_pincfg *cfg;
1390
1391        quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1392        if (!quirk)
1393                return;
1394
1395        fix += quirk->value;
1396        cfg = fix->pins;
1397        if (cfg) {
1398                for (; cfg->nid; cfg++)
1399                        snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1400        }
1401        if (fix->verbs)
1402                add_verb(codec->spec, fix->verbs);
1403}
1404
1405/*
1406 * ALC888
1407 */
1408
1409/*
1410 * 2ch mode
1411 */
1412static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1413/* Mic-in jack as mic in */
1414        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1415        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1416/* Line-in jack as Line in */
1417        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1418        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1419/* Line-Out as Front */
1420        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1421        { } /* end */
1422};
1423
1424/*
1425 * 4ch mode
1426 */
1427static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1428/* Mic-in jack as mic in */
1429        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1430        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1431/* Line-in jack as Surround */
1432        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1433        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1434/* Line-Out as Front */
1435        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1436        { } /* end */
1437};
1438
1439/*
1440 * 6ch mode
1441 */
1442static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1443/* Mic-in jack as CLFE */
1444        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1445        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1446/* Line-in jack as Surround */
1447        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1448        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1449/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1450        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1451        { } /* end */
1452};
1453
1454/*
1455 * 8ch mode
1456 */
1457static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1458/* Mic-in jack as CLFE */
1459        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1460        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1461/* Line-in jack as Surround */
1462        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1463        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1464/* Line-Out as Side */
1465        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1466        { } /* end */
1467};
1468
1469static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1470        { 2, alc888_4ST_ch2_intel_init },
1471        { 4, alc888_4ST_ch4_intel_init },
1472        { 6, alc888_4ST_ch6_intel_init },
1473        { 8, alc888_4ST_ch8_intel_init },
1474};
1475
1476/*
1477 * ALC888 Fujitsu Siemens Amillo xa3530
1478 */
1479
1480static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1481/* Front Mic: set to PIN_IN (empty by default) */
1482        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1483/* Connect Internal HP to Front */
1484        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1485        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1486        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1487/* Connect Bass HP to Front */
1488        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1489        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1490        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1491/* Connect Line-Out side jack (SPDIF) to Side */
1492        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1493        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1495/* Connect Mic jack to CLFE */
1496        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1499/* Connect Line-in jack to Surround */
1500        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1502        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1503/* Connect HP out jack to Front */
1504        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1505        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1506        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1507/* Enable unsolicited event for HP jack and Line-out jack */
1508        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1509        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1510        {}
1511};
1512
1513static void alc_automute_amp(struct hda_codec *codec)
1514{
1515        struct alc_spec *spec = codec->spec;
1516        unsigned int val, mute, pincap;
1517        hda_nid_t nid;
1518        int i;
1519
1520        spec->jack_present = 0;
1521        for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1522                nid = spec->autocfg.hp_pins[i];
1523                if (!nid)
1524                        break;
1525                pincap = snd_hda_query_pin_caps(codec, nid);
1526                if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1527                        snd_hda_codec_read(codec, nid, 0,
1528                                           AC_VERB_SET_PIN_SENSE, 0);
1529                val = snd_hda_codec_read(codec, nid, 0,
1530                                         AC_VERB_GET_PIN_SENSE, 0);
1531                if (val & AC_PINSENSE_PRESENCE) {
1532                        spec->jack_present = 1;
1533                        break;
1534                }
1535        }
1536
1537        mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1538        /* Toggle internal speakers muting */
1539        for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1540                nid = spec->autocfg.speaker_pins[i];
1541                if (!nid)
1542                        break;
1543                snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1544                                         HDA_AMP_MUTE, mute);
1545        }
1546}
1547
1548static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1549                                         unsigned int res)
1550{
1551        if (codec->vendor_id == 0x10ec0880)
1552                res >>= 28;
1553        else
1554                res >>= 26;
1555        if (res == ALC880_HP_EVENT)
1556                alc_automute_amp(codec);
1557}
1558
1559static void alc889_automute_setup(struct hda_codec *codec)
1560{
1561        struct alc_spec *spec = codec->spec;
1562
1563        spec->autocfg.hp_pins[0] = 0x15;
1564        spec->autocfg.speaker_pins[0] = 0x14;
1565        spec->autocfg.speaker_pins[1] = 0x16;
1566        spec->autocfg.speaker_pins[2] = 0x17;
1567        spec->autocfg.speaker_pins[3] = 0x19;
1568        spec->autocfg.speaker_pins[4] = 0x1a;
1569}
1570
1571static void alc889_intel_init_hook(struct hda_codec *codec)
1572{
1573        alc889_coef_init(codec);
1574        alc_automute_amp(codec);
1575}
1576
1577static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1578{
1579        struct alc_spec *spec = codec->spec;
1580
1581        spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1582        spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1583        spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1584        spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1585}
1586
1587/*
1588 * ALC888 Acer Aspire 4930G model
1589 */
1590
1591static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1592/* Front Mic: set to PIN_IN (empty by default) */
1593        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1594/* Unselect Front Mic by default in input mixer 3 */
1595        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1596/* Enable unsolicited event for HP jack */
1597        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1598/* Connect Internal HP to front */
1599        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1600        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1601        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1602/* Connect HP out to front */
1603        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1604        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1606        { }
1607};
1608
1609/*
1610 * ALC888 Acer Aspire 6530G model
1611 */
1612
1613static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1614/* Bias voltage on for external mic port */
1615        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1616/* Front Mic: set to PIN_IN (empty by default) */
1617        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1618/* Unselect Front Mic by default in input mixer 3 */
1619        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1620/* Enable unsolicited event for HP jack */
1621        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1622/* Enable speaker output */
1623        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1624        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1625/* Enable headphone output */
1626        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1627        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1629        { }
1630};
1631
1632/*
1633 * ALC889 Acer Aspire 8930G model
1634 */
1635
1636static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1637/* Front Mic: set to PIN_IN (empty by default) */
1638        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1639/* Unselect Front Mic by default in input mixer 3 */
1640        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1641/* Enable unsolicited event for HP jack */
1642        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1643/* Connect Internal Front to Front */
1644        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1645        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1646        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1647/* Connect Internal Rear to Rear */
1648        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1649        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1651/* Connect Internal CLFE to CLFE */
1652        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1653        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1654        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1655/* Connect HP out to Front */
1656        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1657        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1658        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1659/* Enable all DACs */
1660/*  DAC DISABLE/MUTE 1? */
1661/*  setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1662        {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1663        {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1664/*  DAC DISABLE/MUTE 2? */
1665/*  some bit here disables the other DACs. Init=0x4900 */
1666        {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1667        {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1668/* Enable amplifiers */
1669        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1670        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1671/* DMIC fix
1672 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1673 * which makes the stereo useless. However, either the mic or the ALC889
1674 * makes the signal become a difference/sum signal instead of standard
1675 * stereo, which is annoying. So instead we flip this bit which makes the
1676 * codec replicate the sum signal to both channels, turning it into a
1677 * normal mono mic.
1678 */
1679/*  DMIC_CONTROL? Init value = 0x0001 */
1680        {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1681        {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1682        { }
1683};
1684
1685static struct hda_input_mux alc888_2_capture_sources[2] = {
1686        /* Front mic only available on one ADC */
1687        {
1688                .num_items = 4,
1689                .items = {
1690                        { "Mic", 0x0 },
1691                        { "Line", 0x2 },
1692                        { "CD", 0x4 },
1693                        { "Front Mic", 0xb },
1694                },
1695        },
1696        {
1697                .num_items = 3,
1698                .items = {
1699                        { "Mic", 0x0 },
1700                        { "Line", 0x2 },
1701                        { "CD", 0x4 },
1702                },
1703        }
1704};
1705
1706static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1707        /* Interal mic only available on one ADC */
1708        {
1709                .num_items = 5,
1710                .items = {
1711                        { "Ext Mic", 0x0 },
1712                        { "Line In", 0x2 },
1713                        { "CD", 0x4 },
1714                        { "Input Mix", 0xa },
1715                        { "Int Mic", 0xb },
1716                },
1717        },
1718        {
1719                .num_items = 4,
1720                .items = {
1721                        { "Ext Mic", 0x0 },
1722                        { "Line In", 0x2 },
1723                        { "CD", 0x4 },
1724                        { "Input Mix", 0xa },
1725                },
1726        }
1727};
1728
1729static struct hda_input_mux alc889_capture_sources[3] = {
1730        /* Digital mic only available on first "ADC" */
1731        {
1732                .num_items = 5,
1733                .items = {
1734                        { "Mic", 0x0 },
1735                        { "Line", 0x2 },
1736                        { "CD", 0x4 },
1737                        { "Front Mic", 0xb },
1738                        { "Input Mix", 0xa },
1739                },
1740        },
1741        {
1742                .num_items = 4,
1743                .items = {
1744                        { "Mic", 0x0 },
1745                        { "Line", 0x2 },
1746                        { "CD", 0x4 },
1747                        { "Input Mix", 0xa },
1748                },
1749        },
1750        {
1751                .num_items = 4,
1752                .items = {
1753                        { "Mic", 0x0 },
1754                        { "Line", 0x2 },
1755                        { "CD", 0x4 },
1756                        { "Input Mix", 0xa },
1757                },
1758        }
1759};
1760
1761static struct snd_kcontrol_new alc888_base_mixer[] = {
1762        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1763        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1764        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1765        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1766        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1767                HDA_OUTPUT),
1768        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1769        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1770        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1771        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1772        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1773        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1774        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1775        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1776        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1777        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1778        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1779        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1780        { } /* end */
1781};
1782
1783static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1784{
1785        struct alc_spec *spec = codec->spec;
1786
1787        spec->autocfg.hp_pins[0] = 0x15;
1788        spec->autocfg.speaker_pins[0] = 0x14;
1789}
1790
1791static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1792{
1793        struct alc_spec *spec = codec->spec;
1794
1795        spec->autocfg.hp_pins[0] = 0x15;
1796        spec->autocfg.speaker_pins[0] = 0x14;
1797        spec->autocfg.speaker_pins[1] = 0x16;
1798        spec->autocfg.speaker_pins[2] = 0x17;
1799}
1800
1801static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1802{
1803        struct alc_spec *spec = codec->spec;
1804
1805        spec->autocfg.hp_pins[0] = 0x15;
1806        spec->autocfg.speaker_pins[0] = 0x14;
1807        spec->autocfg.speaker_pins[1] = 0x16;
1808        spec->autocfg.speaker_pins[2] = 0x1b;
1809}
1810
1811/*
1812 * ALC880 3-stack model
1813 *
1814 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1815 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1816 *                 F-Mic = 0x1b, HP = 0x19
1817 */
1818
1819static hda_nid_t alc880_dac_nids[4] = {
1820        /* front, rear, clfe, rear_surr */
1821        0x02, 0x05, 0x04, 0x03
1822};
1823
1824static hda_nid_t alc880_adc_nids[3] = {
1825        /* ADC0-2 */
1826        0x07, 0x08, 0x09,
1827};
1828
1829/* The datasheet says the node 0x07 is connected from inputs,
1830 * but it shows zero connection in the real implementation on some devices.
1831 * Note: this is a 915GAV bug, fixed on 915GLV
1832 */
1833static hda_nid_t alc880_adc_nids_alt[2] = {
1834        /* ADC1-2 */
1835        0x08, 0x09,
1836};
1837
1838#define ALC880_DIGOUT_NID       0x06
1839#define ALC880_DIGIN_NID        0x0a
1840
1841static struct hda_input_mux alc880_capture_source = {
1842        .num_items = 4,
1843        .items = {
1844                { "Mic", 0x0 },
1845                { "Front Mic", 0x3 },
1846                { "Line", 0x2 },
1847                { "CD", 0x4 },
1848        },
1849};
1850
1851/* channel source setting (2/6 channel selection for 3-stack) */
1852/* 2ch mode */
1853static struct hda_verb alc880_threestack_ch2_init[] = {
1854        /* set line-in to input, mute it */
1855        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1856        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1857        /* set mic-in to input vref 80%, mute it */
1858        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1859        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1860        { } /* end */
1861};
1862
1863/* 6ch mode */
1864static struct hda_verb alc880_threestack_ch6_init[] = {
1865        /* set line-in to output, unmute it */
1866        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1867        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1868        /* set mic-in to output, unmute it */
1869        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1870        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1871        { } /* end */
1872};
1873
1874static struct hda_channel_mode alc880_threestack_modes[2] = {
1875        { 2, alc880_threestack_ch2_init },
1876        { 6, alc880_threestack_ch6_init },
1877};
1878
1879static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1880        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1881        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1882        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1883        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1884        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1885        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1886        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1887        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1888        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1889        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1890        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1891        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1892        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1893        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1894        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1895        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1896        HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1897        {
1898                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1899                .name = "Channel Mode",
1900                .info = alc_ch_mode_info,
1901                .get = alc_ch_mode_get,
1902                .put = alc_ch_mode_put,
1903        },
1904        { } /* end */
1905};
1906
1907/* capture mixer elements */
1908static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1909                            struct snd_ctl_elem_info *uinfo)
1910{
1911        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1912        struct alc_spec *spec = codec->spec;
1913        int err;
1914
1915        mutex_lock(&codec->control_mutex);
1916        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1917                                                      HDA_INPUT);
1918        err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1919        mutex_unlock(&codec->control_mutex);
1920        return err;
1921}
1922
1923static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1924                           unsigned int size, unsigned int __user *tlv)
1925{
1926        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1927        struct alc_spec *spec = codec->spec;
1928        int err;
1929
1930        mutex_lock(&codec->control_mutex);
1931        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1932                                                      HDA_INPUT);
1933        err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1934        mutex_unlock(&codec->control_mutex);
1935        return err;
1936}
1937
1938typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1939                             struct snd_ctl_elem_value *ucontrol);
1940
1941static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1942                                 struct snd_ctl_elem_value *ucontrol,
1943                                 getput_call_t func)
1944{
1945        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1946        struct alc_spec *spec = codec->spec;
1947        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1948        int err;
1949
1950        mutex_lock(&codec->control_mutex);
1951        kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1952                                                      3, 0, HDA_INPUT);
1953        err = func(kcontrol, ucontrol);
1954        mutex_unlock(&codec->control_mutex);
1955        return err;
1956}
1957
1958static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1959                           struct snd_ctl_elem_value *ucontrol)
1960{
1961        return alc_cap_getput_caller(kcontrol, ucontrol,
1962                                     snd_hda_mixer_amp_volume_get);
1963}
1964
1965static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1966                           struct snd_ctl_elem_value *ucontrol)
1967{
1968        return alc_cap_getput_caller(kcontrol, ucontrol,
1969                                     snd_hda_mixer_amp_volume_put);
1970}
1971
1972/* capture mixer elements */
1973#define alc_cap_sw_info         snd_ctl_boolean_stereo_info
1974
1975static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1976                          struct snd_ctl_elem_value *ucontrol)
1977{
1978        return alc_cap_getput_caller(kcontrol, ucontrol,
1979                                     snd_hda_mixer_amp_switch_get);
1980}
1981
1982static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1983                          struct snd_ctl_elem_value *ucontrol)
1984{
1985        return alc_cap_getput_caller(kcontrol, ucontrol,
1986                                     snd_hda_mixer_amp_switch_put);
1987}
1988
1989#define _DEFINE_CAPMIX(num) \
1990        { \
1991                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1992                .name = "Capture Switch", \
1993                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1994                .count = num, \
1995                .info = alc_cap_sw_info, \
1996                .get = alc_cap_sw_get, \
1997                .put = alc_cap_sw_put, \
1998        }, \
1999        { \
2000                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2001                .name = "Capture Volume", \
2002                .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2003                           SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2004                           SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2005                .count = num, \
2006                .info = alc_cap_vol_info, \
2007                .get = alc_cap_vol_get, \
2008                .put = alc_cap_vol_put, \
2009                .tlv = { .c = alc_cap_vol_tlv }, \
2010        }
2011
2012#define _DEFINE_CAPSRC(num) \
2013        { \
2014                .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2015                /* .name = "Capture Source", */ \
2016                .name = "Input Source", \
2017                .count = num, \
2018                .info = alc_mux_enum_info, \
2019                .get = alc_mux_enum_get, \
2020                .put = alc_mux_enum_put, \
2021        }
2022
2023#define DEFINE_CAPMIX(num) \
2024static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2025        _DEFINE_CAPMIX(num),                                  \
2026        _DEFINE_CAPSRC(num),                                  \
2027        { } /* end */                                         \
2028}
2029
2030#define DEFINE_CAPMIX_NOSRC(num) \
2031static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2032        _DEFINE_CAPMIX(num),                                        \
2033        { } /* end */                                               \
2034}
2035
2036/* up to three ADCs */
2037DEFINE_CAPMIX(1);
2038DEFINE_CAPMIX(2);
2039DEFINE_CAPMIX(3);
2040DEFINE_CAPMIX_NOSRC(1);
2041DEFINE_CAPMIX_NOSRC(2);
2042DEFINE_CAPMIX_NOSRC(3);
2043
2044/*
2045 * ALC880 5-stack model
2046 *
2047 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2048 *      Side = 0x02 (0xd)
2049 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2050 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2051 */
2052
2053/* additional mixers to alc880_three_stack_mixer */
2054static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2055        HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2056        HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2057        { } /* end */
2058};
2059
2060/* channel source setting (6/8 channel selection for 5-stack) */
2061/* 6ch mode */
2062static struct hda_verb alc880_fivestack_ch6_init[] = {
2063        /* set line-in to input, mute it */
2064        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2065        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2066        { } /* end */
2067};
2068
2069/* 8ch mode */
2070static struct hda_verb alc880_fivestack_ch8_init[] = {
2071        /* set line-in to output, unmute it */
2072        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2073        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2074        { } /* end */
2075};
2076
2077static struct hda_channel_mode alc880_fivestack_modes[2] = {
2078        { 6, alc880_fivestack_ch6_init },
2079        { 8, alc880_fivestack_ch8_init },
2080};
2081
2082
2083/*
2084 * ALC880 6-stack model
2085 *
2086 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2087 *      Side = 0x05 (0x0f)
2088 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2089 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2090 */
2091
2092static hda_nid_t alc880_6st_dac_nids[4] = {
2093        /* front, rear, clfe, rear_surr */
2094        0x02, 0x03, 0x04, 0x05
2095};
2096
2097static struct hda_input_mux alc880_6stack_capture_source = {
2098        .num_items = 4,
2099        .items = {
2100                { "Mic", 0x0 },
2101                { "Front Mic", 0x1 },
2102                { "Line", 0x2 },
2103                { "CD", 0x4 },
2104        },
2105};
2106
2107/* fixed 8-channels */
2108static struct hda_channel_mode alc880_sixstack_modes[1] = {
2109        { 8, NULL },
2110};
2111
2112static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2113        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2114        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2115        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2116        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2117        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2118        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2119        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2120        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2121        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2122        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2123        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2124        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2125        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2126        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2127        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2128        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2129        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2130        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2131        {
2132                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2133                .name = "Channel Mode",
2134                .info = alc_ch_mode_info,
2135                .get = alc_ch_mode_get,
2136                .put = alc_ch_mode_put,
2137        },
2138        { } /* end */
2139};
2140
2141
2142/*
2143 * ALC880 W810 model
2144 *
2145 * W810 has rear IO for:
2146 * Front (DAC 02)
2147 * Surround (DAC 03)
2148 * Center/LFE (DAC 04)
2149 * Digital out (06)
2150 *
2151 * The system also has a pair of internal speakers, and a headphone jack.
2152 * These are both connected to Line2 on the codec, hence to DAC 02.
2153 *
2154 * There is a variable resistor to control the speaker or headphone
2155 * volume. This is a hardware-only device without a software API.
2156 *
2157 * Plugging headphones in will disable the internal speakers. This is
2158 * implemented in hardware, not via the driver using jack sense. In
2159 * a similar fashion, plugging into the rear socket marked "front" will
2160 * disable both the speakers and headphones.
2161 *
2162 * For input, there's a microphone jack, and an "audio in" jack.
2163 * These may not do anything useful with this driver yet, because I
2164 * haven't setup any initialization verbs for these yet...
2165 */
2166
2167static hda_nid_t alc880_w810_dac_nids[3] = {
2168        /* front, rear/surround, clfe */
2169        0x02, 0x03, 0x04
2170};
2171
2172/* fixed 6 channels */
2173static struct hda_channel_mode alc880_w810_modes[1] = {
2174        { 6, NULL }
2175};
2176
2177/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2178static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2179        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2180        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2181        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2182        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2183        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2184        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2185        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2186        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2187        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2188        { } /* end */
2189};
2190
2191
2192/*
2193 * Z710V model
2194 *
2195 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2196 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2197 *                 Line = 0x1a
2198 */
2199
2200static hda_nid_t alc880_z71v_dac_nids[1] = {
2201        0x02
2202};
2203#define ALC880_Z71V_HP_DAC      0x03
2204
2205/* fixed 2 channels */
2206static struct hda_channel_mode alc880_2_jack_modes[1] = {
2207        { 2, NULL }
2208};
2209
2210static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2211        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2212        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2213        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2214        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2215        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2216        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2217        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2218        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2219        { } /* end */
2220};
2221
2222
2223/*
2224 * ALC880 F1734 model
2225 *
2226 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2227 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2228 */
2229
2230static hda_nid_t alc880_f1734_dac_nids[1] = {
2231        0x03
2232};
2233#define ALC880_F1734_HP_DAC     0x02
2234
2235static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2236        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2237        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2238        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2239        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2240        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2241        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2242        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2243        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2244        { } /* end */
2245};
2246
2247static struct hda_input_mux alc880_f1734_capture_source = {
2248        .num_items = 2,
2249        .items = {
2250                { "Mic", 0x1 },
2251                { "CD", 0x4 },
2252        },
2253};
2254
2255
2256/*
2257 * ALC880 ASUS model
2258 *
2259 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2260 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2261 *  Mic = 0x18, Line = 0x1a
2262 */
2263
2264#define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
2265#define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
2266
2267static struct snd_kcontrol_new alc880_asus_mixer[] = {
2268        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2269        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2270        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2271        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2272        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2273        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2274        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2275        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2276        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2277        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2278        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2279        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2280        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2281        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2282        {
2283                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2284                .name = "Channel Mode",
2285                .info = alc_ch_mode_info,
2286                .get = alc_ch_mode_get,
2287                .put = alc_ch_mode_put,
2288        },
2289        { } /* end */
2290};
2291
2292/*
2293 * ALC880 ASUS W1V model
2294 *
2295 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2296 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2297 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2298 */
2299
2300/* additional mixers to alc880_asus_mixer */
2301static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2302        HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2303        HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2304        { } /* end */
2305};
2306
2307/* TCL S700 */
2308static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2309        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2310        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2311        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2312        HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2313        HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2314        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2315        HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2316        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2317        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2318        { } /* end */
2319};
2320
2321/* Uniwill */
2322static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2323        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2324        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2325        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2326        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2327        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2328        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2329        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2330        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2331        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2332        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2333        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2334        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2335        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2336        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2337        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2338        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2339        {
2340                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2341                .name = "Channel Mode",
2342                .info = alc_ch_mode_info,
2343                .get = alc_ch_mode_get,
2344                .put = alc_ch_mode_put,
2345        },
2346        { } /* end */
2347};
2348
2349static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2350        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2351        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2352        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2353        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2354        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2355        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2356        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2357        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2358        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2359        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2360        { } /* end */
2361};
2362
2363static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2364        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2365        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2366        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2367        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2368        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2369        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2370        { } /* end */
2371};
2372
2373/*
2374 * virtual master controls
2375 */
2376
2377/*
2378 * slave controls for virtual master
2379 */
2380static const char *alc_slave_vols[] = {
2381        "Front Playback Volume",
2382        "Surround Playback Volume",
2383        "Center Playback Volume",
2384        "LFE Playback Volume",
2385        "Side Playback Volume",
2386        "Headphone Playback Volume",
2387        "Speaker Playback Volume",
2388        "Mono Playback Volume",
2389        "Line-Out Playback Volume",
2390        "PCM Playback Volume",
2391        NULL,
2392};
2393
2394static const char *alc_slave_sws[] = {
2395        "Front Playback Switch",
2396        "Surround Playback Switch",
2397        "Center Playback Switch",
2398        "LFE Playback Switch",
2399        "Side Playback Switch",
2400        "Headphone Playback Switch",
2401        "Speaker Playback Switch",
2402        "Mono Playback Switch",
2403        "IEC958 Playback Switch",
2404        NULL,
2405};
2406
2407/*
2408 * build control elements
2409 */
2410
2411static void alc_free_kctls(struct hda_codec *codec);
2412
2413/* additional beep mixers; the actual parameters are overwritten at build */
2414static struct snd_kcontrol_new alc_beep_mixer[] = {
2415        HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2416        HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2417        { } /* end */
2418};
2419
2420static int alc_build_controls(struct hda_codec *codec)
2421{
2422        struct alc_spec *spec = codec->spec;
2423        int err;
2424        int i;
2425
2426        for (i = 0; i < spec->num_mixers; i++) {
2427                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2428                if (err < 0)
2429                        return err;
2430        }
2431        if (spec->cap_mixer) {
2432                err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2433                if (err < 0)
2434                        return err;
2435        }
2436        if (spec->multiout.dig_out_nid) {
2437                err = snd_hda_create_spdif_out_ctls(codec,
2438                                                    spec->multiout.dig_out_nid);
2439                if (err < 0)
2440                        return err;
2441                if (!spec->no_analog) {
2442                        err = snd_hda_create_spdif_share_sw(codec,
2443                                                            &spec->multiout);
2444                        if (err < 0)
2445                                return err;
2446                        spec->multiout.share_spdif = 1;
2447                }
2448        }
2449        if (spec->dig_in_nid) {
2450                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2451                if (err < 0)
2452                        return err;
2453        }
2454
2455        /* create beep controls if needed */
2456        if (spec->beep_amp) {
2457                struct snd_kcontrol_new *knew;
2458                for (knew = alc_beep_mixer; knew->name; knew++) {
2459                        struct snd_kcontrol *kctl;
2460                        kctl = snd_ctl_new1(knew, codec);
2461                        if (!kctl)
2462                                return -ENOMEM;
2463                        kctl->private_value = spec->beep_amp;
2464                        err = snd_hda_ctl_add(codec, kctl);
2465                        if (err < 0)
2466                                return err;
2467                }
2468        }
2469
2470        /* if we have no master control, let's create it */
2471        if (!spec->no_analog &&
2472            !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2473                unsigned int vmaster_tlv[4];
2474                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2475                                        HDA_OUTPUT, vmaster_tlv);
2476                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2477                                          vmaster_tlv, alc_slave_vols);
2478                if (err < 0)
2479                        return err;
2480        }
2481        if (!spec->no_analog &&
2482            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2483                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2484                                          NULL, alc_slave_sws);
2485                if (err < 0)
2486                        return err;
2487        }
2488
2489        alc_free_kctls(codec); /* no longer needed */
2490        return 0;
2491}
2492
2493
2494/*
2495 * initialize the codec volumes, etc
2496 */
2497
2498/*
2499 * generic initialization of ADC, input mixers and output mixers
2500 */
2501static struct hda_verb alc880_volume_init_verbs[] = {
2502        /*
2503         * Unmute ADC0-2 and set the default input to mic-in
2504         */
2505        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2506        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2507        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2508        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2509        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2510        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2511
2512        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2513         * mixer widget
2514         * Note: PASD motherboards uses the Line In 2 as the input for front
2515         * panel mic (mic 2)
2516         */
2517        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2518        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2519        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2520        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2521        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2522        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2523        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2524        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2525
2526        /*
2527         * Set up output mixers (0x0c - 0x0f)
2528         */
2529        /* set vol=0 to output mixers */
2530        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2531        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2532        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2533        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2534        /* set up input amps for analog loopback */
2535        /* Amp Indices: DAC = 0, mixer = 1 */
2536        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2537        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2538        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2539        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2540        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2541        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2542        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2543        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2544
2545        { }
2546};
2547
2548/*
2549 * 3-stack pin configuration:
2550 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2551 */
2552static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2553        /*
2554         * preset connection lists of input pins
2555         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2556         */
2557        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2558        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2559        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2560
2561        /*
2562         * Set pin mode and muting
2563         */
2564        /* set front pin widgets 0x14 for output */
2565        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2566        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2567        /* Mic1 (rear panel) pin widget for input and vref at 80% */
2568        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2569        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2570        /* Mic2 (as headphone out) for HP output */
2571        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2572        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573        /* Line In pin widget for input */
2574        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2575        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2576        /* Line2 (as front mic) pin widget for input and vref at 80% */
2577        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2578        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2579        /* CD pin widget for input */
2580        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2581
2582        { }
2583};
2584
2585/*
2586 * 5-stack pin configuration:
2587 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2588 * line-in/side = 0x1a, f-mic = 0x1b
2589 */
2590static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2591        /*
2592         * preset connection lists of input pins
2593         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2594         */
2595        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2596        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2597
2598        /*
2599         * Set pin mode and muting
2600         */
2601        /* set pin widgets 0x14-0x17 for output */
2602        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2603        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2604        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2605        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2606        /* unmute pins for output (no gain on this amp) */
2607        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2608        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2609        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2610        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2611
2612        /* Mic1 (rear panel) pin widget for input and vref at 80% */
2613        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2614        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2615        /* Mic2 (as headphone out) for HP output */
2616        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2617        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2618        /* Line In pin widget for input */
2619        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2620        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2621        /* Line2 (as front mic) pin widget for input and vref at 80% */
2622        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2623        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2624        /* CD pin widget for input */
2625        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2626
2627        { }
2628};
2629
2630/*
2631 * W810 pin configuration:
2632 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2633 */
2634static struct hda_verb alc880_pin_w810_init_verbs[] = {
2635        /* hphone/speaker input selector: front DAC */
2636        {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2637
2638        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2639        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2640        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2641        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2642        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2643        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2644
2645        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2646        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2647
2648        { }
2649};
2650
2651/*
2652 * Z71V pin configuration:
2653 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2654 */
2655static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2656        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2657        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2658        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2659        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2660
2661        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2662        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2663        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2664        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2665
2666        { }
2667};
2668
2669/*
2670 * 6-stack pin configuration:
2671 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2672 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2673 */
2674static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2675        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2676
2677        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2678        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2679        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2680        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2681        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2682        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2683        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2684        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2685
2686        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2687        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2688        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2689        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2690        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2691        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2692        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2693        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2694        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2695
2696        { }
2697};
2698
2699/*
2700 * Uniwill pin configuration:
2701 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2702 * line = 0x1a
2703 */
2704static struct hda_verb alc880_uniwill_init_verbs[] = {
2705        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2706
2707        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2708        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2709        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2710        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2711        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2712        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2713        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2714        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2715        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2716        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2717        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2718        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2719        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2720        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2721
2722        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2723        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2724        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2725        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2726        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2727        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2728        /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2729        /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2730        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2731
2732        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2733        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2734
2735        { }
2736};
2737
2738/*
2739* Uniwill P53
2740* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2741 */
2742static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2743        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2744
2745        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2746        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2747        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2748        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2749        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2750        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2751        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2752        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2753        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2754        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2755        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2756        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2757
2758        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2759        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2760        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2761        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2762        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2763        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2764
2765        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2766        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2767
2768        { }
2769};
2770
2771static struct hda_verb alc880_beep_init_verbs[] = {
2772        { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2773        { }
2774};
2775
2776/* auto-toggle front mic */
2777static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2778{
2779        unsigned int present;
2780        unsigned char bits;
2781
2782        present = snd_hda_codec_read(codec, 0x18, 0,
2783                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2784        bits = present ? HDA_AMP_MUTE : 0;
2785        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2786}
2787
2788static void alc880_uniwill_setup(struct hda_codec *codec)
2789{
2790        struct alc_spec *spec = codec->spec;
2791
2792        spec->autocfg.hp_pins[0] = 0x14;
2793        spec->autocfg.speaker_pins[0] = 0x15;
2794        spec->autocfg.speaker_pins[0] = 0x16;
2795}
2796
2797static void alc880_uniwill_init_hook(struct hda_codec *codec)
2798{
2799        alc_automute_amp(codec);
2800        alc880_uniwill_mic_automute(codec);
2801}
2802
2803static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2804                                       unsigned int res)
2805{
2806        /* Looks like the unsol event is incompatible with the standard
2807         * definition.  4bit tag is placed at 28 bit!
2808         */
2809        switch (res >> 28) {
2810        case ALC880_MIC_EVENT:
2811                alc880_uniwill_mic_automute(codec);
2812                break;
2813        default:
2814                alc_automute_amp_unsol_event(codec, res);
2815                break;
2816        }
2817}
2818
2819static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2820{
2821        struct alc_spec *spec = codec->spec;
2822
2823        spec->autocfg.hp_pins[0] = 0x14;
2824        spec->autocfg.speaker_pins[0] = 0x15;
2825}
2826
2827static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2828{
2829        unsigned int present;
2830
2831        present = snd_hda_codec_read(codec, 0x21, 0,
2832                                     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2833        present &= HDA_AMP_VOLMASK;
2834        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2835                                 HDA_AMP_VOLMASK, present);
2836        snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2837                                 HDA_AMP_VOLMASK, present);
2838}
2839
2840static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2841                                           unsigned int res)
2842{
2843        /* Looks like the unsol event is incompatible with the standard
2844         * definition.  4bit tag is placed at 28 bit!
2845         */
2846        if ((res >> 28) == ALC880_DCVOL_EVENT)
2847                alc880_uniwill_p53_dcvol_automute(codec);
2848        else
2849                alc_automute_amp_unsol_event(codec, res);
2850}
2851
2852/*
2853 * F1734 pin configuration:
2854 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2855 */
2856static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2857        {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2858        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2859        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2860        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2861        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2862
2863        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2864        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2865        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2866        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2867
2868        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2869        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2870        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2871        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2872        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2873        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2874        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2875        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2876        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2877
2878        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2879        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2880
2881        { }
2882};
2883
2884/*
2885 * ASUS pin configuration:
2886 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2887 */
2888static struct hda_verb alc880_pin_asus_init_verbs[] = {
2889        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2890        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2891        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2892        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2893
2894        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2895        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2896        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2897        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2898        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2899        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2900        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2901        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2902
2903        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2904        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2905        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2906        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2907        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2908        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2909        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2910        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2911        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2912
2913        { }
2914};
2915
2916/* Enable GPIO mask and set output */
2917#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2918#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2919#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2920
2921/* Clevo m520g init */
2922static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2923        /* headphone output */
2924        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2925        /* line-out */
2926        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2927        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2928        /* Line-in */
2929        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2930        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2931        /* CD */
2932        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2933        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934        /* Mic1 (rear panel) */
2935        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2936        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2937        /* Mic2 (front panel) */
2938        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2939        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2940        /* headphone */
2941        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2942        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2943        /* change to EAPD mode */
2944        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2945        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2946
2947        { }
2948};
2949
2950static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2951        /* change to EAPD mode */
2952        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2953        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
2954
2955        /* Headphone output */
2956        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2957        /* Front output*/
2958        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2959        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2960
2961        /* Line In pin widget for input */
2962        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2963        /* CD pin widget for input */
2964        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2965        /* Mic1 (rear panel) pin widget for input and vref at 80% */
2966        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2967
2968        /* change to EAPD mode */
2969        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2970        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
2971
2972        { }
2973};
2974
2975/*
2976 * LG m1 express dual
2977 *
2978 * Pin assignment:
2979 *   Rear Line-In/Out (blue): 0x14
2980 *   Build-in Mic-In: 0x15
2981 *   Speaker-out: 0x17
2982 *   HP-Out (green): 0x1b
2983 *   Mic-In/Out (red): 0x19
2984 *   SPDIF-Out: 0x1e
2985 */
2986
2987/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2988static hda_nid_t alc880_lg_dac_nids[3] = {
2989        0x05, 0x02, 0x03
2990};
2991
2992/* seems analog CD is not working */
2993static struct hda_input_mux alc880_lg_capture_source = {
2994        .num_items = 3,
2995        .items = {
2996                { "Mic", 0x1 },
2997                { "Line", 0x5 },
2998                { "Internal Mic", 0x6 },
2999        },
3000};
3001
3002/* 2,4,6 channel modes */
3003static struct hda_verb alc880_lg_ch2_init[] = {
3004        /* set line-in and mic-in to input */
3005        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3006        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3007        { }
3008};
3009
3010static struct hda_verb alc880_lg_ch4_init[] = {
3011        /* set line-in to out and mic-in to input */
3012        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3013        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3014        { }
3015};
3016
3017static struct hda_verb alc880_lg_ch6_init[] = {
3018        /* set line-in and mic-in to output */
3019        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3020        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3021        { }
3022};
3023
3024static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3025        { 2, alc880_lg_ch2_init },
3026        { 4, alc880_lg_ch4_init },
3027        { 6, alc880_lg_ch6_init },
3028};
3029
3030static struct snd_kcontrol_new alc880_lg_mixer[] = {
3031        HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3032        HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3033        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3034        HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3035        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3036        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3037        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3038        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3039        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3040        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3041        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3042        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3043        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3044        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3045        {
3046                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3047                .name = "Channel Mode",
3048                .info = alc_ch_mode_info,
3049                .get = alc_ch_mode_get,
3050                .put = alc_ch_mode_put,
3051        },
3052        { } /* end */
3053};
3054
3055static struct hda_verb alc880_lg_init_verbs[] = {
3056        /* set capture source to mic-in */
3057        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3058        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3059        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3060        /* mute all amp mixer inputs */
3061        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3062        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3063        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3064        /* line-in to input */
3065        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3066        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3067        /* built-in mic */
3068        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3069        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3070        /* speaker-out */
3071        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3072        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3073        /* mic-in to input */
3074        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3075        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3076        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3077        /* HP-out */
3078        {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3079        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3080        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3081        /* jack sense */
3082        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3083        { }
3084};
3085
3086/* toggle speaker-output according to the hp-jack state */
3087static void alc880_lg_setup(struct hda_codec *codec)
3088{
3089        struct alc_spec *spec = codec->spec;
3090
3091        spec->autocfg.hp_pins[0] = 0x1b;
3092        spec->autocfg.speaker_pins[0] = 0x17;
3093}
3094
3095/*
3096 * LG LW20
3097 *
3098 * Pin assignment:
3099 *   Speaker-out: 0x14
3100 *   Mic-In: 0x18
3101 *   Built-in Mic-In: 0x19
3102 *   Line-In: 0x1b
3103 *   HP-Out: 0x1a
3104 *   SPDIF-Out: 0x1e
3105 */
3106
3107static struct hda_input_mux alc880_lg_lw_capture_source = {
3108        .num_items = 3,
3109        .items = {
3110                { "Mic", 0x0 },
3111                { "Internal Mic", 0x1 },
3112                { "Line In", 0x2 },
3113        },
3114};
3115
3116#define alc880_lg_lw_modes alc880_threestack_modes
3117
3118static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3119        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3120        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3121        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3122        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3123        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3124        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3125        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3126        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3127        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3128        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3129        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3130        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3131        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3132        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3133        {
3134                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3135                .name = "Channel Mode",
3136                .info = alc_ch_mode_info,
3137                .get = alc_ch_mode_get,
3138                .put = alc_ch_mode_put,
3139        },
3140        { } /* end */
3141};
3142
3143static struct hda_verb alc880_lg_lw_init_verbs[] = {
3144        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3145        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3146        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3147
3148        /* set capture source to mic-in */
3149        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3150        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3151        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3152        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3153        /* speaker-out */
3154        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3155        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3156        /* HP-out */
3157        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3158        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3159        /* mic-in to input */
3160        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3161        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3162        /* built-in mic */
3163        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3164        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3165        /* jack sense */
3166        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3167        { }
3168};
3169
3170/* toggle speaker-output according to the hp-jack state */
3171static void alc880_lg_lw_setup(struct hda_codec *codec)
3172{
3173        struct alc_spec *spec = codec->spec;
3174
3175        spec->autocfg.hp_pins[0] = 0x1b;
3176        spec->autocfg.speaker_pins[0] = 0x14;
3177}
3178
3179static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3180        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3181        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3182        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3183        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3184        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3185        HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3186        { } /* end */
3187};
3188
3189static struct hda_input_mux alc880_medion_rim_capture_source = {
3190        .num_items = 2,
3191        .items = {
3192                { "Mic", 0x0 },
3193                { "Internal Mic", 0x1 },
3194        },
3195};
3196
3197static struct hda_verb alc880_medion_rim_init_verbs[] = {
3198        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3199
3200        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3201        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3202
3203        /* Mic1 (rear panel) pin widget for input and vref at 80% */
3204        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3205        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3206        /* Mic2 (as headphone out) for HP output */
3207        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3208        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3209        /* Internal Speaker */
3210        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3211        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3212
3213        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3214        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
3215
3216        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3217        { }
3218};
3219
3220/* toggle speaker-output according to the hp-jack state */
3221static void alc880_medion_rim_automute(struct hda_codec *codec)
3222{
3223        struct alc_spec *spec = codec->spec;
3224        alc_automute_amp(codec);
3225        /* toggle EAPD */
3226        if (spec->jack_present)
3227                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3228        else
3229                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3230}
3231
3232static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3233                                          unsigned int res)
3234{
3235        /* Looks like the unsol event is incompatible with the standard
3236         * definition.  4bit tag is placed at 28 bit!
3237         */
3238        if ((res >> 28) == ALC880_HP_EVENT)
3239                alc880_medion_rim_automute(codec);
3240}
3241
3242static void alc880_medion_rim_setup(struct hda_codec *codec)
3243{
3244        struct alc_spec *spec = codec->spec;
3245
3246        spec->autocfg.hp_pins[0] = 0x14;
3247        spec->autocfg.speaker_pins[0] = 0x1b;
3248}
3249
3250#ifdef CONFIG_SND_HDA_POWER_SAVE
3251static struct hda_amp_list alc880_loopbacks[] = {
3252        { 0x0b, HDA_INPUT, 0 },
3253        { 0x0b, HDA_INPUT, 1 },
3254        { 0x0b, HDA_INPUT, 2 },
3255        { 0x0b, HDA_INPUT, 3 },
3256        { 0x0b, HDA_INPUT, 4 },
3257        { } /* end */
3258};
3259
3260static struct hda_amp_list alc880_lg_loopbacks[] = {
3261        { 0x0b, HDA_INPUT, 1 },
3262        { 0x0b, HDA_INPUT, 6 },
3263        { 0x0b, HDA_INPUT, 7 },
3264        { } /* end */
3265};
3266#endif
3267
3268/*
3269 * Common callbacks
3270 */
3271
3272static int alc_init(struct hda_codec *codec)
3273{
3274        struct alc_spec *spec = codec->spec;
3275        unsigned int i;
3276
3277        alc_fix_pll(codec);
3278        alc_auto_init_amp(codec, spec->init_amp);
3279
3280        for (i = 0; i < spec->num_init_verbs; i++)
3281                snd_hda_sequence_write(codec, spec->init_verbs[i]);
3282
3283        if (spec->init_hook)
3284                spec->init_hook(codec);
3285
3286        return 0;
3287}
3288
3289static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3290{
3291        struct alc_spec *spec = codec->spec;
3292
3293        if (spec->unsol_event)
3294                spec->unsol_event(codec, res);
3295}
3296
3297#ifdef CONFIG_SND_HDA_POWER_SAVE
3298static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3299{
3300        struct alc_spec *spec = codec->spec;
3301        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3302}
3303#endif
3304
3305/*
3306 * Analog playback callbacks
3307 */
3308static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3309                                    struct hda_codec *codec,
3310                                    struct snd_pcm_substream *substream)
3311{
3312        struct alc_spec *spec = codec->spec;
3313        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3314                                             hinfo);
3315}
3316
3317static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3318                                       struct hda_codec *codec,
3319                                       unsigned int stream_tag,
3320                                       unsigned int format,
3321                                       struct snd_pcm_substream *substream)
3322{
3323        struct alc_spec *spec = codec->spec;
3324        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3325                                                stream_tag, format, substream);
3326}
3327
3328static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3329                                       struct hda_codec *codec,
3330                                       struct snd_pcm_substream *substream)
3331{
3332        struct alc_spec *spec = codec->spec;
3333        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3334}
3335
3336/*
3337 * Digital out
3338 */
3339static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3340                                        struct hda_codec *codec,
3341                                        struct snd_pcm_substream *substream)
3342{
3343        struct alc_spec *spec = codec->spec;
3344        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3345}
3346
3347static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3348                                           struct hda_codec *codec,
3349                                           unsigned int stream_tag,
3350                                           unsigned int format,
3351                                           struct snd_pcm_substream *substream)
3352{
3353        struct alc_spec *spec = codec->spec;
3354        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3355                                             stream_tag, format, substream);
3356}
3357
3358static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3359                                           struct hda_codec *codec,
3360                                           struct snd_pcm_substream *substream)
3361{
3362        struct alc_spec *spec = codec->spec;
3363        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3364}
3365
3366static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3367                                         struct hda_codec *codec,
3368                                         struct snd_pcm_substream *substream)
3369{
3370        struct alc_spec *spec = codec->spec;
3371        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3372}
3373
3374/*
3375 * Analog capture
3376 */
3377static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3378                                      struct hda_codec *codec,
3379                                      unsigned int stream_tag,
3380                                      unsigned int format,
3381                                      struct snd_pcm_substream *substream)
3382{
3383        struct alc_spec *spec = codec->spec;
3384
3385        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3386                                   stream_tag, 0, format);
3387        return 0;
3388}
3389
3390static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3391                                      struct hda_codec *codec,
3392                                      struct snd_pcm_substream *substream)
3393{
3394        struct alc_spec *spec = codec->spec;
3395
3396        snd_hda_codec_cleanup_stream(codec,
3397                                     spec->adc_nids[substream->number + 1]);
3398        return 0;
3399}
3400
3401
3402/*
3403 */
3404static struct hda_pcm_stream alc880_pcm_analog_playback = {
3405        .substreams = 1,
3406        .channels_min = 2,
3407        .channels_max = 8,
3408        /* NID is set in alc_build_pcms */
3409        .ops = {
3410                .open = alc880_playback_pcm_open,
3411                .prepare = alc880_playback_pcm_prepare,
3412                .cleanup = alc880_playback_pcm_cleanup
3413        },
3414};
3415
3416static struct hda_pcm_stream alc880_pcm_analog_capture = {
3417        .substreams = 1,
3418        .channels_min = 2,
3419        .channels_max = 2,
3420        /* NID is set in alc_build_pcms */
3421};
3422
3423static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3424        .substreams = 1,
3425        .channels_min = 2,
3426        .channels_max = 2,
3427        /* NID is set in alc_build_pcms */
3428};
3429
3430static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3431        .substreams = 2, /* can be overridden */
3432        .channels_min = 2,
3433        .channels_max = 2,
3434        /* NID is set in alc_build_pcms */
3435        .ops = {
3436                .prepare = alc880_alt_capture_pcm_prepare,
3437                .cleanup = alc880_alt_capture_pcm_cleanup
3438        },
3439};
3440
3441static struct hda_pcm_stream alc880_pcm_digital_playback = {
3442        .substreams = 1,
3443        .channels_min = 2,
3444        .channels_max = 2,
3445        /* NID is set in alc_build_pcms */
3446        .ops = {
3447                .open = alc880_dig_playback_pcm_open,
3448                .close = alc880_dig_playback_pcm_close,
3449                .prepare = alc880_dig_playback_pcm_prepare,
3450                .cleanup = alc880_dig_playback_pcm_cleanup
3451        },
3452};
3453
3454static struct hda_pcm_stream alc880_pcm_digital_capture = {
3455        .substreams = 1,
3456        .channels_min = 2,
3457        .channels_max = 2,
3458        /* NID is set in alc_build_pcms */
3459};
3460
3461/* Used by alc_build_pcms to flag that a PCM has no playback stream */
3462static struct hda_pcm_stream alc_pcm_null_stream = {
3463        .substreams = 0,
3464        .channels_min = 0,
3465        .channels_max = 0,
3466};
3467
3468static int alc_build_pcms(struct hda_codec *codec)
3469{
3470        struct alc_spec *spec = codec->spec;
3471        struct hda_pcm *info = spec->pcm_rec;
3472        int i;
3473
3474        codec->num_pcms = 1;
3475        codec->pcm_info = info;
3476
3477        if (spec->no_analog)
3478                goto skip_analog;
3479
3480        snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3481                 "%s Analog", codec->chip_name);
3482        info->name = spec->stream_name_analog;
3483        
3484        if (spec->stream_analog_playback) {
3485                if (snd_BUG_ON(!spec->multiout.dac_nids))
3486                        return -EINVAL;
3487                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3488                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3489        }
3490        if (spec->stream_analog_capture) {
3491                if (snd_BUG_ON(!spec->adc_nids))
3492                        return -EINVAL;
3493                info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3494                info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3495        }
3496
3497        if (spec->channel_mode) {
3498                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3499                for (i = 0; i < spec->num_channel_mode; i++) {
3500                        if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3501                                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3502                        }
3503                }
3504        }
3505
3506 skip_analog:
3507        /* SPDIF for stream index #1 */
3508        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3509                snprintf(spec->stream_name_digital,
3510                         sizeof(spec->stream_name_digital),
3511                         "%s Digital", codec->chip_name);
3512                codec->num_pcms = 2;
3513                codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3514                info = spec->pcm_rec + 1;
3515                info->name = spec->stream_name_digital;
3516                if (spec->dig_out_type)
3517                        info->pcm_type = spec->dig_out_type;
3518                else
3519                        info->pcm_type = HDA_PCM_TYPE_SPDIF;
3520                if (spec->multiout.dig_out_nid &&
3521                    spec->stream_digital_playback) {
3522                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3523                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3524                }
3525                if (spec->dig_in_nid &&
3526                    spec->stream_digital_capture) {
3527                        info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3528                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3529                }
3530                /* FIXME: do we need this for all Realtek codec models? */
3531                codec->spdif_status_reset = 1;
3532        }
3533
3534        if (spec->no_analog)
3535                return 0;
3536
3537        /* If the use of more than one ADC is requested for the current
3538         * model, configure a second analog capture-only PCM.
3539         */
3540        /* Additional Analaog capture for index #2 */
3541        if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3542            (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3543                codec->num_pcms = 3;
3544                info = spec->pcm_rec + 2;
3545                info->name = spec->stream_name_analog;
3546                if (spec->alt_dac_nid) {
3547                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3548                                *spec->stream_analog_alt_playback;
3549                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3550                                spec->alt_dac_nid;
3551                } else {
3552                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3553                                alc_pcm_null_stream;
3554                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3555                }
3556                if (spec->num_adc_nids > 1) {
3557                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3558                                *spec->stream_analog_alt_capture;
3559                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3560                                spec->adc_nids[1];
3561                        info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3562                                spec->num_adc_nids - 1;
3563                } else {
3564                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3565                                alc_pcm_null_stream;
3566                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3567                }
3568        }
3569
3570        return 0;
3571}
3572
3573static void alc_free_kctls(struct hda_codec *codec)
3574{
3575        struct alc_spec *spec = codec->spec;
3576
3577        if (spec->kctls.list) {
3578                struct snd_kcontrol_new *kctl = spec->kctls.list;
3579                int i;
3580                for (i = 0; i < spec->kctls.used; i++)
3581                        kfree(kctl[i].name);
3582        }
3583        snd_array_free(&spec->kctls);
3584}
3585
3586static void alc_free(struct hda_codec *codec)
3587{
3588        struct alc_spec *spec = codec->spec;
3589
3590        if (!spec)
3591                return;
3592
3593        alc_free_kctls(codec);
3594        kfree(spec);
3595        snd_hda_detach_beep_device(codec);
3596}
3597
3598#ifdef SND_HDA_NEEDS_RESUME
3599static int alc_resume(struct hda_codec *codec)
3600{
3601        codec->patch_ops.init(codec);
3602        snd_hda_codec_resume_amp(codec);
3603        snd_hda_codec_resume_cache(codec);
3604        return 0;
3605}
3606#endif
3607
3608/*
3609 */
3610static struct hda_codec_ops alc_patch_ops = {
3611        .build_controls = alc_build_controls,
3612        .build_pcms = alc_build_pcms,
3613        .init = alc_init,
3614        .free = alc_free,
3615        .unsol_event = alc_unsol_event,
3616#ifdef SND_HDA_NEEDS_RESUME
3617        .resume = alc_resume,
3618#endif
3619#ifdef CONFIG_SND_HDA_POWER_SAVE
3620        .check_power_status = alc_check_power_status,
3621#endif
3622};
3623
3624
3625/*
3626 * Test configuration for debugging
3627 *
3628 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
3629 * enum controls.
3630 */
3631#ifdef CONFIG_SND_DEBUG
3632static hda_nid_t alc880_test_dac_nids[4] = {
3633        0x02, 0x03, 0x04, 0x05
3634};
3635
3636static struct hda_input_mux alc880_test_capture_source = {
3637        .num_items = 7,
3638        .items = {
3639                { "In-1", 0x0 },
3640                { "In-2", 0x1 },
3641                { "In-3", 0x2 },
3642                { "In-4", 0x3 },
3643                { "CD", 0x4 },
3644                { "Front", 0x5 },
3645                { "Surround", 0x6 },
3646        },
3647};
3648
3649static struct hda_channel_mode alc880_test_modes[4] = {
3650        { 2, NULL },
3651        { 4, NULL },
3652        { 6, NULL },
3653        { 8, NULL },
3654};
3655
3656static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3657                                 struct snd_ctl_elem_info *uinfo)
3658{
3659        static char *texts[] = {
3660                "N/A", "Line Out", "HP Out",
3661                "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3662        };
3663        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3664        uinfo->count = 1;
3665        uinfo->value.enumerated.items = 8;
3666        if (uinfo->value.enumerated.item >= 8)
3667                uinfo->value.enumerated.item = 7;
3668        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3669        return 0;
3670}
3671
3672static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3673                                struct snd_ctl_elem_value *ucontrol)
3674{
3675        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3676        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3677        unsigned int pin_ctl, item = 0;
3678
3679        pin_ctl = snd_hda_codec_read(codec, nid, 0,
3680                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3681        if (pin_ctl & AC_PINCTL_OUT_EN) {
3682                if (pin_ctl & AC_PINCTL_HP_EN)
3683                        item = 2;
3684                else
3685                        item = 1;
3686        } else if (pin_ctl & AC_PINCTL_IN_EN) {
3687                switch (pin_ctl & AC_PINCTL_VREFEN) {
3688                case AC_PINCTL_VREF_HIZ: item = 3; break;
3689                case AC_PINCTL_VREF_50:  item = 4; break;
3690                case AC_PINCTL_VREF_GRD: item = 5; break;
3691                case AC_PINCTL_VREF_80:  item = 6; break;
3692                case AC_PINCTL_VREF_100: item = 7; break;
3693                }
3694        }
3695        ucontrol->value.enumerated.item[0] = item;
3696        return 0;
3697}
3698
3699static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3700                                struct snd_ctl_elem_value *ucontrol)
3701{
3702        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3703        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3704        static unsigned int ctls[] = {
3705                0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3706                AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3707                AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3708                AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3709                AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3710                AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3711        };
3712        unsigned int old_ctl, new_ctl;
3713
3714        old_ctl = snd_hda_codec_read(codec, nid, 0,
3715                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3716        new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3717        if (old_ctl != new_ctl) {
3718                int val;
3719                snd_hda_codec_write_cache(codec, nid, 0,
3720                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
3721                                          new_ctl);
3722                val = ucontrol->value.enumerated.item[0] >= 3 ?
3723                        HDA_AMP_MUTE : 0;
3724                snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3725                                         HDA_AMP_MUTE, val);
3726                return 1;
3727        }
3728        return 0;
3729}
3730
3731static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3732                                 struct snd_ctl_elem_info *uinfo)
3733{
3734        static char *texts[] = {
3735                "Front", "Surround", "CLFE", "Side"
3736        };
3737        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3738        uinfo->count = 1;
3739        uinfo->value.enumerated.items = 4;
3740        if (uinfo->value.enumerated.item >= 4)
3741                uinfo->value.enumerated.item = 3;
3742        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3743        return 0;
3744}
3745
3746static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3747                                struct snd_ctl_elem_value *ucontrol)
3748{
3749        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3750        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3751        unsigned int sel;
3752
3753        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3754        ucontrol->value.enumerated.item[0] = sel & 3;
3755        return 0;
3756}
3757
3758static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3759                                struct snd_ctl_elem_value *ucontrol)
3760{
3761        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3762        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3763        unsigned int sel;
3764
3765        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3766        if (ucontrol->value.enumerated.item[0] != sel) {
3767                sel = ucontrol->value.enumerated.item[0] & 3;
3768                snd_hda_codec_write_cache(codec, nid, 0,
3769                                          AC_VERB_SET_CONNECT_SEL, sel);
3770                return 1;
3771        }
3772        return 0;
3773}
3774
3775#define PIN_CTL_TEST(xname,nid) {                       \
3776                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
3777                        .name = xname,                 \
3778                        .info = alc_test_pin_ctl_info, \
3779                        .get = alc_test_pin_ctl_get,   \
3780                        .put = alc_test_pin_ctl_put,   \
3781                        .private_value = nid           \
3782                        }
3783
3784#define PIN_SRC_TEST(xname,nid) {                       \
3785                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
3786                        .name = xname,                 \
3787                        .info = alc_test_pin_src_info, \
3788                        .get = alc_test_pin_src_get,   \
3789                        .put = alc_test_pin_src_put,   \
3790                        .private_value = nid           \
3791                        }
3792
3793static struct snd_kcontrol_new alc880_test_mixer[] = {
3794        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3795        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3796        HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3797        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3798        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3799        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3800        HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3801        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3802        PIN_CTL_TEST("Front Pin Mode", 0x14),
3803        PIN_CTL_TEST("Surround Pin Mode", 0x15),
3804        PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3805        PIN_CTL_TEST("Side Pin Mode", 0x17),
3806        PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3807        PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3808        PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3809        PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3810        PIN_SRC_TEST("In-1 Pin Source", 0x18),
3811        PIN_SRC_TEST("In-2 Pin Source", 0x19),
3812        PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3813        PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3814        HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3815        HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3816        HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3817        HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3818        HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3819        HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3820        HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3821        HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3822        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3823        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3824        {
3825                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3826                .name = "Channel Mode",
3827                .info = alc_ch_mode_info,
3828                .get = alc_ch_mode_get,
3829                .put = alc_ch_mode_put,
3830        },
3831        { } /* end */
3832};
3833
3834static struct hda_verb alc880_test_init_verbs[] = {
3835        /* Unmute inputs of 0x0c - 0x0f */
3836        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3837        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3838        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3839        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3840        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3841        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3842        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3843        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3844        /* Vol output for 0x0c-0x0f */
3845        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3846        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3847        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3848        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3849        /* Set output pins 0x14-0x17 */
3850        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3851        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3852        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3853        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3854        /* Unmute output pins 0x14-0x17 */
3855        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3856        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3857        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3858        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3859        /* Set input pins 0x18-0x1c */
3860        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3861        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3862        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3863        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3864        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3865        /* Mute input pins 0x18-0x1b */
3866        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3867        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3868        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3869        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3870        /* ADC set up */
3871        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3872        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3873        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3874        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3875        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3876        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3877        /* Analog input/passthru */
3878        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3879        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3880        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3881        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3882        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3883        { }
3884};
3885#endif
3886
3887/*
3888 */
3889
3890static const char *alc880_models[ALC880_MODEL_LAST] = {
3891        [ALC880_3ST]            = "3stack",
3892        [ALC880_TCL_S700]       = "tcl",
3893        [ALC880_3ST_DIG]        = "3stack-digout",
3894        [ALC880_CLEVO]          = "clevo",
3895        [ALC880_5ST]            = "5stack",
3896        [ALC880_5ST_DIG]        = "5stack-digout",
3897        [ALC880_W810]           = "w810",
3898        [ALC880_Z71V]           = "z71v",
3899        [ALC880_6ST]            = "6stack",
3900        [ALC880_6ST_DIG]        = "6stack-digout",
3901        [ALC880_ASUS]           = "asus",
3902        [ALC880_ASUS_W1V]       = "asus-w1v",
3903        [ALC880_ASUS_DIG]       = "asus-dig",
3904        [ALC880_ASUS_DIG2]      = "asus-dig2",
3905        [ALC880_UNIWILL_DIG]    = "uniwill",
3906        [ALC880_UNIWILL_P53]    = "uniwill-p53",
3907        [ALC880_FUJITSU]        = "fujitsu",
3908        [ALC880_F1734]          = "F1734",
3909        [ALC880_LG]             = "lg",
3910        [ALC880_LG_LW]          = "lg-lw",
3911        [ALC880_MEDION_RIM]     = "medion",
3912#ifdef CONFIG_SND_DEBUG
3913        [ALC880_TEST]           = "test",
3914#endif
3915        [ALC880_AUTO]           = "auto",
3916};
3917
3918static struct snd_pci_quirk alc880_cfg_tbl[] = {
3919        SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3920        SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3921        SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3922        SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3923        SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3924        SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3925        SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3926        SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3927        SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3928        SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3929        SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3930        SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3931        SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3932        SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3933        SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3934        SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3935        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3936        SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3937        /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3938        SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3939        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3940        SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3941        SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3942        SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3943        SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3944        SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3945        SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3946        SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3947        SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3948        SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3949        SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3950        SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3951        SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3952        SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3953        SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3954        SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3955        SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3956        SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3957        SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3958        SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3959        SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3960        SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3961        SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3962        SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3963        SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3964        SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3965        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3966        SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3967        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3968        SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3969        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3970        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3971        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3972        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3973        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3974        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3975        SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3976        SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3977        SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3978        SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3979        SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3980        SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3981        SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3982        SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3983        SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3984        SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3985        SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3986        SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3987        /* default Intel */
3988        SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3989        SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3990        SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3991        {}
3992};
3993
3994/*
3995 * ALC880 codec presets
3996 */
3997static struct alc_config_preset alc880_presets[] = {
3998        [ALC880_3ST] = {
3999                .mixers = { alc880_three_stack_mixer },
4000                .init_verbs = { alc880_volume_init_verbs,
4001                                alc880_pin_3stack_init_verbs },
4002                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4003                .dac_nids = alc880_dac_nids,
4004                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4005                .channel_mode = alc880_threestack_modes,
4006                .need_dac_fix = 1,
4007                .input_mux = &alc880_capture_source,
4008        },
4009        [ALC880_3ST_DIG] = {
4010                .mixers = { alc880_three_stack_mixer },
4011                .init_verbs = { alc880_volume_init_verbs,
4012                                alc880_pin_3stack_init_verbs },
4013                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4014                .dac_nids = alc880_dac_nids,
4015                .dig_out_nid = ALC880_DIGOUT_NID,
4016                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4017                .channel_mode = alc880_threestack_modes,
4018                .need_dac_fix = 1,
4019                .input_mux = &alc880_capture_source,
4020        },
4021        [ALC880_TCL_S700] = {
4022                .mixers = { alc880_tcl_s700_mixer },
4023                .init_verbs = { alc880_volume_init_verbs,
4024                                alc880_pin_tcl_S700_init_verbs,
4025                                alc880_gpio2_init_verbs },
4026                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4027                .dac_nids = alc880_dac_nids,
4028                .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4029                .num_adc_nids = 1, /* single ADC */
4030                .hp_nid = 0x03,
4031                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4032                .channel_mode = alc880_2_jack_modes,
4033                .input_mux = &alc880_capture_source,
4034        },
4035        [ALC880_5ST] = {
4036                .mixers = { alc880_three_stack_mixer,
4037                            alc880_five_stack_mixer},
4038                .init_verbs = { alc880_volume_init_verbs,
4039                                alc880_pin_5stack_init_verbs },
4040                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4041                .dac_nids = alc880_dac_nids,
4042                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4043                .channel_mode = alc880_fivestack_modes,
4044                .input_mux = &alc880_capture_source,
4045        },
4046        [ALC880_5ST_DIG] = {
4047                .mixers = { alc880_three_stack_mixer,
4048                            alc880_five_stack_mixer },
4049                .init_verbs = { alc880_volume_init_verbs,
4050                                alc880_pin_5stack_init_verbs },
4051                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4052                .dac_nids = alc880_dac_nids,
4053                .dig_out_nid = ALC880_DIGOUT_NID,
4054                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4055                .channel_mode = alc880_fivestack_modes,
4056                .input_mux = &alc880_capture_source,
4057        },
4058        [ALC880_6ST] = {
4059                .mixers = { alc880_six_stack_mixer },
4060                .init_verbs = { alc880_volume_init_verbs,
4061                                alc880_pin_6stack_init_verbs },
4062                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4063                .dac_nids = alc880_6st_dac_nids,
4064                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4065                .channel_mode = alc880_sixstack_modes,
4066                .input_mux = &alc880_6stack_capture_source,
4067        },
4068        [ALC880_6ST_DIG] = {
4069                .mixers = { alc880_six_stack_mixer },
4070                .init_verbs = { alc880_volume_init_verbs,
4071                                alc880_pin_6stack_init_verbs },
4072                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4073                .dac_nids = alc880_6st_dac_nids,
4074                .dig_out_nid = ALC880_DIGOUT_NID,
4075                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4076                .channel_mode = alc880_sixstack_modes,
4077                .input_mux = &alc880_6stack_capture_source,
4078        },
4079        [ALC880_W810] = {
4080                .mixers = { alc880_w810_base_mixer },
4081                .init_verbs = { alc880_volume_init_verbs,
4082                                alc880_pin_w810_init_verbs,
4083                                alc880_gpio2_init_verbs },
4084                .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4085                .dac_nids = alc880_w810_dac_nids,
4086                .dig_out_nid = ALC880_DIGOUT_NID,
4087                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4088                .channel_mode = alc880_w810_modes,
4089                .input_mux = &alc880_capture_source,
4090        },
4091        [ALC880_Z71V] = {
4092                .mixers = { alc880_z71v_mixer },
4093                .init_verbs = { alc880_volume_init_verbs,
4094                                alc880_pin_z71v_init_verbs },
4095                .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4096                .dac_nids = alc880_z71v_dac_nids,
4097                .dig_out_nid = ALC880_DIGOUT_NID,
4098                .hp_nid = 0x03,
4099                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4100                .channel_mode = alc880_2_jack_modes,
4101                .input_mux = &alc880_capture_source,
4102        },
4103        [ALC880_F1734] = {
4104                .mixers = { alc880_f1734_mixer },
4105                .init_verbs = { alc880_volume_init_verbs,
4106                                alc880_pin_f1734_init_verbs },
4107                .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4108                .dac_nids = alc880_f1734_dac_nids,
4109                .hp_nid = 0x02,
4110                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4111                .channel_mode = alc880_2_jack_modes,
4112                .input_mux = &alc880_f1734_capture_source,
4113                .unsol_event = alc880_uniwill_p53_unsol_event,
4114                .setup = alc880_uniwill_p53_setup,
4115                .init_hook = alc_automute_amp,
4116        },
4117        [ALC880_ASUS] = {
4118                .mixers = { alc880_asus_mixer },
4119                .init_verbs = { alc880_volume_init_verbs,
4120                                alc880_pin_asus_init_verbs,
4121                                alc880_gpio1_init_verbs },
4122                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4123                .dac_nids = alc880_asus_dac_nids,
4124                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4125                .channel_mode = alc880_asus_modes,
4126                .need_dac_fix = 1,
4127                .input_mux = &alc880_capture_source,
4128        },
4129        [ALC880_ASUS_DIG] = {
4130                .mixers = { alc880_asus_mixer },
4131                .init_verbs = { alc880_volume_init_verbs,
4132                                alc880_pin_asus_init_verbs,
4133                                alc880_gpio1_init_verbs },
4134                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4135                .dac_nids = alc880_asus_dac_nids,
4136                .dig_out_nid = ALC880_DIGOUT_NID,
4137                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4138                .channel_mode = alc880_asus_modes,
4139                .need_dac_fix = 1,
4140                .input_mux = &alc880_capture_source,
4141        },
4142        [ALC880_ASUS_DIG2] = {
4143                .mixers = { alc880_asus_mixer },
4144                .init_verbs = { alc880_volume_init_verbs,
4145                                alc880_pin_asus_init_verbs,
4146                                alc880_gpio2_init_verbs }, /* use GPIO2 */
4147                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4148                .dac_nids = alc880_asus_dac_nids,
4149                .dig_out_nid = ALC880_DIGOUT_NID,
4150                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4151                .channel_mode = alc880_asus_modes,
4152                .need_dac_fix = 1,
4153                .input_mux = &alc880_capture_source,
4154        },
4155        [ALC880_ASUS_W1V] = {
4156                .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4157                .init_verbs = { alc880_volume_init_verbs,
4158                                alc880_pin_asus_init_verbs,
4159                                alc880_gpio1_init_verbs },
4160                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4161                .dac_nids = alc880_asus_dac_nids,
4162                .dig_out_nid = ALC880_DIGOUT_NID,
4163                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4164                .channel_mode = alc880_asus_modes,
4165                .need_dac_fix = 1,
4166                .input_mux = &alc880_capture_source,
4167        },
4168        [ALC880_UNIWILL_DIG] = {
4169                .mixers = { alc880_asus_mixer },
4170                .init_verbs = { alc880_volume_init_verbs,
4171                                alc880_pin_asus_init_verbs },
4172                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4173                .dac_nids = alc880_asus_dac_nids,
4174                .dig_out_nid = ALC880_DIGOUT_NID,
4175                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4176                .channel_mode = alc880_asus_modes,
4177                .need_dac_fix = 1,
4178                .input_mux = &alc880_capture_source,
4179        },
4180        [ALC880_UNIWILL] = {
4181                .mixers = { alc880_uniwill_mixer },
4182                .init_verbs = { alc880_volume_init_verbs,
4183                                alc880_uniwill_init_verbs },
4184                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4185                .dac_nids = alc880_asus_dac_nids,
4186                .dig_out_nid = ALC880_DIGOUT_NID,
4187                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4188                .channel_mode = alc880_threestack_modes,
4189                .need_dac_fix = 1,
4190                .input_mux = &alc880_capture_source,
4191                .unsol_event = alc880_uniwill_unsol_event,
4192                .setup = alc880_uniwill_setup,
4193                .init_hook = alc880_uniwill_init_hook,
4194        },
4195        [ALC880_UNIWILL_P53] = {
4196                .mixers = { alc880_uniwill_p53_mixer },
4197                .init_verbs = { alc880_volume_init_verbs,
4198                                alc880_uniwill_p53_init_verbs },
4199                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4200                .dac_nids = alc880_asus_dac_nids,
4201                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4202                .channel_mode = alc880_threestack_modes,
4203                .input_mux = &alc880_capture_source,
4204                .unsol_event = alc880_uniwill_p53_unsol_event,
4205                .setup = alc880_uniwill_p53_setup,
4206                .init_hook = alc_automute_amp,
4207        },
4208        [ALC880_FUJITSU] = {
4209                .mixers = { alc880_fujitsu_mixer },
4210                .init_verbs = { alc880_volume_init_verbs,
4211                                alc880_uniwill_p53_init_verbs,
4212                                alc880_beep_init_verbs },
4213                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4214                .dac_nids = alc880_dac_nids,
4215                .dig_out_nid = ALC880_DIGOUT_NID,
4216                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4217                .channel_mode = alc880_2_jack_modes,
4218                .input_mux = &alc880_capture_source,
4219                .unsol_event = alc880_uniwill_p53_unsol_event,
4220                .setup = alc880_uniwill_p53_setup,
4221                .init_hook = alc_automute_amp,
4222        },
4223        [ALC880_CLEVO] = {
4224                .mixers = { alc880_three_stack_mixer },
4225                .init_verbs = { alc880_volume_init_verbs,
4226                                alc880_pin_clevo_init_verbs },
4227                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4228                .dac_nids = alc880_dac_nids,
4229                .hp_nid = 0x03,
4230                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4231                .channel_mode = alc880_threestack_modes,
4232                .need_dac_fix = 1,
4233                .input_mux = &alc880_capture_source,
4234        },
4235        [ALC880_LG] = {
4236                .mixers = { alc880_lg_mixer },
4237                .init_verbs = { alc880_volume_init_verbs,
4238                                alc880_lg_init_verbs },
4239                .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4240                .dac_nids = alc880_lg_dac_nids,
4241                .dig_out_nid = ALC880_DIGOUT_NID,
4242                .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4243                .channel_mode = alc880_lg_ch_modes,
4244                .need_dac_fix = 1,
4245                .input_mux = &alc880_lg_capture_source,
4246                .unsol_event = alc_automute_amp_unsol_event,
4247                .setup = alc880_lg_setup,
4248                .init_hook = alc_automute_amp,
4249#ifdef CONFIG_SND_HDA_POWER_SAVE
4250                .loopbacks = alc880_lg_loopbacks,
4251#endif
4252        },
4253        [ALC880_LG_LW] = {
4254                .mixers = { alc880_lg_lw_mixer },
4255                .init_verbs = { alc880_volume_init_verbs,
4256                                alc880_lg_lw_init_verbs },
4257                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4258                .dac_nids = alc880_dac_nids,
4259                .dig_out_nid = ALC880_DIGOUT_NID,
4260                .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4261                .channel_mode = alc880_lg_lw_modes,
4262                .input_mux = &alc880_lg_lw_capture_source,
4263                .unsol_event = alc_automute_amp_unsol_event,
4264                .setup = alc880_lg_lw_setup,
4265                .init_hook = alc_automute_amp,
4266        },
4267        [ALC880_MEDION_RIM] = {
4268                .mixers = { alc880_medion_rim_mixer },
4269                .init_verbs = { alc880_volume_init_verbs,
4270                                alc880_medion_rim_init_verbs,
4271                                alc_gpio2_init_verbs },
4272                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4273                .dac_nids = alc880_dac_nids,
4274                .dig_out_nid = ALC880_DIGOUT_NID,
4275                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4276                .channel_mode = alc880_2_jack_modes,
4277                .input_mux = &alc880_medion_rim_capture_source,
4278                .unsol_event = alc880_medion_rim_unsol_event,
4279                .setup = alc880_medion_rim_setup,
4280                .init_hook = alc880_medion_rim_automute,
4281        },
4282#ifdef CONFIG_SND_DEBUG
4283        [ALC880_TEST] = {
4284                .mixers = { alc880_test_mixer },
4285                .init_verbs = { alc880_test_init_verbs },
4286                .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4287                .dac_nids = alc880_test_dac_nids,
4288                .dig_out_nid = ALC880_DIGOUT_NID,
4289                .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4290                .channel_mode = alc880_test_modes,
4291                .input_mux = &alc880_test_capture_source,
4292        },
4293#endif
4294};
4295
4296/*
4297 * Automatic parse of I/O pins from the BIOS configuration
4298 */
4299
4300enum {
4301        ALC_CTL_WIDGET_VOL,
4302        ALC_CTL_WIDGET_MUTE,
4303        ALC_CTL_BIND_MUTE,
4304};
4305static struct snd_kcontrol_new alc880_control_templates[] = {
4306        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4307        HDA_CODEC_MUTE(NULL, 0, 0, 0),
4308        HDA_BIND_MUTE(NULL, 0, 0, 0),
4309};
4310
4311/* add dynamic controls */
4312static int add_control(struct alc_spec *spec, int type, const char *name,
4313                       unsigned long val)
4314{
4315        struct snd_kcontrol_new *knew;
4316
4317        snd_array_init(&spec->kctls, sizeof(*knew), 32);
4318        knew = snd_array_new(&spec->kctls);
4319        if (!knew)
4320                return -ENOMEM;
4321        *knew = alc880_control_templates[type];
4322        knew->name = kstrdup(name, GFP_KERNEL);
4323        if (!knew->name)
4324                return -ENOMEM;
4325        knew->private_value = val;
4326        return 0;
4327}
4328
4329#define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
4330#define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
4331#define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
4332#define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
4333#define alc880_idx_to_dac(nid)          ((nid) + 0x02)
4334#define alc880_dac_to_idx(nid)          ((nid) - 0x02)
4335#define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
4336#define alc880_idx_to_selector(nid)     ((nid) + 0x10)
4337#define ALC880_PIN_CD_NID               0x1c
4338
4339/* fill in the dac_nids table from the parsed pin configuration */
4340static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4341                                     const struct auto_pin_cfg *cfg)
4342{
4343        hda_nid_t nid;
4344        int assigned[4];
4345        int i, j;
4346
4347        memset(assigned, 0, sizeof(assigned));
4348        spec->multiout.dac_nids = spec->private_dac_nids;
4349
4350        /* check the pins hardwired to audio widget */
4351        for (i = 0; i < cfg->line_outs; i++) {
4352                nid = cfg->line_out_pins[i];
4353                if (alc880_is_fixed_pin(nid)) {
4354                        int idx = alc880_fixed_pin_idx(nid);
4355                        spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4356                        assigned[idx] = 1;
4357                }
4358        }
4359        /* left pins can be connect to any audio widget */
4360        for (i = 0; i < cfg->line_outs; i++) {
4361                nid = cfg->line_out_pins[i];
4362                if (alc880_is_fixed_pin(nid))
4363                        continue;
4364                /* search for an empty channel */
4365                for (j = 0; j < cfg->line_outs; j++) {
4366                        if (!assigned[j]) {
4367                                spec->multiout.dac_nids[i] =
4368                                        alc880_idx_to_dac(j);
4369                                assigned[j] = 1;
4370                                break;
4371                        }
4372                }
4373        }
4374        spec->multiout.num_dacs = cfg->line_outs;
4375        return 0;
4376}
4377
4378/* add playback controls from the parsed DAC table */
4379static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4380                                             const struct auto_pin_cfg *cfg)
4381{
4382        char name[32];
4383        static const char *chname[4] = {
4384                "Front", "Surround", NULL /*CLFE*/, "Side"
4385        };
4386        hda_nid_t nid;
4387        int i, err;
4388
4389        for (i = 0; i < cfg->line_outs; i++) {
4390                if (!spec->multiout.dac_nids[i])
4391                        continue;
4392                nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4393                if (i == 2) {
4394                        /* Center/LFE */
4395                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
4396                                          "Center Playback Volume",
4397                                          HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4398                                                              HDA_OUTPUT));
4399                        if (err < 0)
4400                                return err;
4401                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
4402                                          "LFE Playback Volume",
4403                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4404                                                              HDA_OUTPUT));
4405                        if (err < 0)
4406                                return err;
4407                        err = add_control(spec, ALC_CTL_BIND_MUTE,
4408                                          "Center Playback Switch",
4409                                          HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4410                                                              HDA_INPUT));
4411                        if (err < 0)
4412                                return err;
4413                        err = add_control(spec, ALC_CTL_BIND_MUTE,
4414                                          "LFE Playback Switch",
4415                                          HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4416                                                              HDA_INPUT));
4417                        if (err < 0)
4418                                return err;
4419                } else {
4420                        const char *pfx;
4421                        if (cfg->line_outs == 1 &&
4422                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4423                                pfx = "Speaker";
4424                        else
4425                                pfx = chname[i];
4426                        sprintf(name, "%s Playback Volume", pfx);
4427                        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4428                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4429                                                              HDA_OUTPUT));
4430                        if (err < 0)
4431                                return err;
4432                        sprintf(name, "%s Playback Switch", pfx);
4433                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4434                                          HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4435                                                              HDA_INPUT));
4436                        if (err < 0)
4437                                return err;
4438                }
4439        }
4440        return 0;
4441}
4442
4443/* add playback controls for speaker and HP outputs */
4444static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4445                                        const char *pfx)
4446{
4447        hda_nid_t nid;
4448        int err;
4449        char name[32];
4450
4451        if (!pin)
4452                return 0;
4453
4454        if (alc880_is_fixed_pin(pin)) {
4455                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4456                /* specify the DAC as the extra output */
4457                if (!spec->multiout.hp_nid)
4458                        spec->multiout.hp_nid = nid;
4459                else
4460                        spec->multiout.extra_out_nid[0] = nid;
4461                /* control HP volume/switch on the output mixer amp */
4462                nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4463                sprintf(name, "%s Playback Volume", pfx);
4464                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4465                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4466                if (err < 0)
4467                        return err;
4468                sprintf(name, "%s Playback Switch", pfx);
4469                err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4470                                  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4471                if (err < 0)
4472                        return err;
4473        } else if (alc880_is_multi_pin(pin)) {
4474                /* set manual connection */
4475                /* we have only a switch on HP-out PIN */
4476                sprintf(name, "%s Playback Switch", pfx);
4477                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4478                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4479                if (err < 0)
4480                        return err;
4481        }
4482        return 0;
4483}
4484
4485/* create input playback/capture controls for the given pin */
4486static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4487                            const char *ctlname,
4488                            int idx, hda_nid_t mix_nid)
4489{
4490        char name[32];
4491        int err;
4492
4493        sprintf(name, "%s Playback Volume", ctlname);
4494        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4495                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4496        if (err < 0)
4497                return err;
4498        sprintf(name, "%s Playback Switch", ctlname);
4499        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4500                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4501        if (err < 0)
4502                return err;
4503        return 0;
4504}
4505
4506static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4507{
4508        unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4509        return (pincap & AC_PINCAP_IN) != 0;
4510}
4511
4512/* create playback/capture controls for input pins */
4513static int alc_auto_create_input_ctls(struct hda_codec *codec,
4514                                      const struct auto_pin_cfg *cfg,
4515                                      hda_nid_t mixer,
4516                                      hda_nid_t cap1, hda_nid_t cap2)
4517{
4518        struct alc_spec *spec = codec->spec;
4519        struct hda_input_mux *imux = &spec->private_imux[0];
4520        int i, err, idx;
4521
4522        for (i = 0; i < AUTO_PIN_LAST; i++) {
4523                hda_nid_t pin;
4524
4525                pin = cfg->input_pins[i];
4526                if (!alc_is_input_pin(codec, pin))
4527                        continue;
4528
4529                if (mixer) {
4530                        idx = get_connection_index(codec, mixer, pin);
4531                        if (idx >= 0) {
4532                                err = new_analog_input(spec, pin,
4533                                                       auto_pin_cfg_labels[i],
4534                                                       idx, mixer);
4535                                if (err < 0)
4536                                        return err;
4537                        }
4538                }
4539
4540                if (!cap1)
4541                        continue;
4542                idx = get_connection_index(codec, cap1, pin);
4543                if (idx < 0 && cap2)
4544                        idx = get_connection_index(codec, cap2, pin);
4545                if (idx >= 0) {
4546                        imux->items[imux->num_items].label =
4547                                auto_pin_cfg_labels[i];
4548                        imux->items[imux->num_items].index = idx;
4549                        imux->num_items++;
4550                }
4551        }
4552        return 0;
4553}
4554
4555static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4556                                                const struct auto_pin_cfg *cfg)
4557{
4558        return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4559}
4560
4561static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4562                               unsigned int pin_type)
4563{
4564        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4565                            pin_type);
4566        /* unmute pin */
4567        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4568                            AMP_OUT_UNMUTE);
4569}
4570
4571static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4572                                              hda_nid_t nid, int pin_type,
4573                                              int dac_idx)
4574{
4575        alc_set_pin_output(codec, nid, pin_type);
4576        /* need the manual connection? */
4577        if (alc880_is_multi_pin(nid)) {
4578                struct alc_spec *spec = codec->spec;
4579                int idx = alc880_multi_pin_idx(nid);
4580                snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4581                                    AC_VERB_SET_CONNECT_SEL,
4582                                    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4583        }
4584}
4585
4586static int get_pin_type(int line_out_type)
4587{
4588        if (line_out_type == AUTO_PIN_HP_OUT)
4589                return PIN_HP;
4590        else
4591                return PIN_OUT;
4592}
4593
4594static void alc880_auto_init_multi_out(struct hda_codec *codec)
4595{
4596        struct alc_spec *spec = codec->spec;
4597        int i;
4598
4599        for (i = 0; i < spec->autocfg.line_outs; i++) {
4600                hda_nid_t nid = spec->autocfg.line_out_pins[i];
4601                int pin_type = get_pin_type(spec->autocfg.line_out_type);
4602                alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4603        }
4604}
4605
4606static void alc880_auto_init_extra_out(struct hda_codec *codec)
4607{
4608        struct alc_spec *spec = codec->spec;
4609        hda_nid_t pin;
4610
4611        pin = spec->autocfg.speaker_pins[0];
4612        if (pin) /* connect to front */
4613                alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4614        pin = spec->autocfg.hp_pins[0];
4615        if (pin) /* connect to front */
4616                alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4617}
4618
4619static void alc880_auto_init_analog_input(struct hda_codec *codec)
4620{
4621        struct alc_spec *spec = codec->spec;
4622        int i;
4623
4624        for (i = 0; i < AUTO_PIN_LAST; i++) {
4625                hda_nid_t nid = spec->autocfg.input_pins[i];
4626                if (alc_is_input_pin(codec, nid)) {
4627                        alc_set_input_pin(codec, nid, i);
4628                        if (nid != ALC880_PIN_CD_NID &&
4629                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4630                                snd_hda_codec_write(codec, nid, 0,
4631                                                    AC_VERB_SET_AMP_GAIN_MUTE,
4632                                                    AMP_OUT_MUTE);
4633                }
4634        }
4635}
4636
4637/* parse the BIOS configuration and set up the alc_spec */
4638/* return 1 if successful, 0 if the proper config is not found,
4639 * or a negative error code
4640 */
4641static int alc880_parse_auto_config(struct hda_codec *codec)
4642{
4643        struct alc_spec *spec = codec->spec;
4644        int i, err;
4645        static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4646
4647        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4648                                           alc880_ignore);
4649        if (err < 0)
4650                return err;
4651        if (!spec->autocfg.line_outs)
4652                return 0; /* can't find valid BIOS pin config */
4653
4654        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4655        if (err < 0)
4656                return err;
4657        err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4658        if (err < 0)
4659                return err;
4660        err = alc880_auto_create_extra_out(spec,
4661                                           spec->autocfg.speaker_pins[0],
4662                                           "Speaker");
4663        if (err < 0)
4664                return err;
4665        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4666                                           "Headphone");
4667        if (err < 0)
4668                return err;
4669        err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4670        if (err < 0)
4671                return err;
4672
4673        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4674
4675        /* check multiple SPDIF-out (for recent codecs) */
4676        for (i = 0; i < spec->autocfg.dig_outs; i++) {
4677                hda_nid_t dig_nid;
4678                err = snd_hda_get_connections(codec,
4679                                              spec->autocfg.dig_out_pins[i],
4680                                              &dig_nid, 1);
4681                if (err < 0)
4682                        continue;
4683                if (!i)
4684                        spec->multiout.dig_out_nid = dig_nid;
4685                else {
4686                        spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4687                        if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4688                                break;
4689                        spec->slave_dig_outs[i - 1] = dig_nid;
4690                }
4691        }
4692        if (spec->autocfg.dig_in_pin)
4693                spec->dig_in_nid = ALC880_DIGIN_NID;
4694
4695        if (spec->kctls.list)
4696                add_mixer(spec, spec->kctls.list);
4697
4698        add_verb(spec, alc880_volume_init_verbs);
4699
4700        spec->num_mux_defs = 1;
4701        spec->input_mux = &spec->private_imux[0];
4702
4703        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4704
4705        return 1;
4706}
4707
4708/* additional initialization for auto-configuration model */
4709static void alc880_auto_init(struct hda_codec *codec)
4710{
4711        struct alc_spec *spec = codec->spec;
4712        alc880_auto_init_multi_out(codec);
4713        alc880_auto_init_extra_out(codec);
4714        alc880_auto_init_analog_input(codec);
4715        if (spec->unsol_event)
4716                alc_inithook(codec);
4717}
4718
4719/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4720 * one of two digital mic pins, e.g. on ALC272
4721 */
4722static void fixup_automic_adc(struct hda_codec *codec)
4723{
4724        struct alc_spec *spec = codec->spec;
4725        int i;
4726
4727        for (i = 0; i < spec->num_adc_nids; i++) {
4728                hda_nid_t cap = spec->capsrc_nids ?
4729                        spec->capsrc_nids[i] : spec->adc_nids[i];
4730                int iidx, eidx;
4731
4732                iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4733                if (iidx < 0)
4734                        continue;
4735                eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4736                if (eidx < 0)
4737                        continue;
4738                spec->int_mic.mux_idx = iidx;
4739                spec->ext_mic.mux_idx = eidx;
4740                if (spec->capsrc_nids)
4741                        spec->capsrc_nids += i;
4742                spec->adc_nids += i;
4743                spec->num_adc_nids = 1;
4744                return;
4745        }
4746        snd_printd(KERN_INFO "hda_codec: %s: "
4747                   "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4748                   codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4749        spec->auto_mic = 0; /* disable auto-mic to be sure */
4750}
4751
4752static void set_capture_mixer(struct hda_codec *codec)
4753{
4754        struct alc_spec *spec = codec->spec;
4755        static struct snd_kcontrol_new *caps[2][3] = {
4756                { alc_capture_mixer_nosrc1,
4757                  alc_capture_mixer_nosrc2,
4758                  alc_capture_mixer_nosrc3 },
4759                { alc_capture_mixer1,
4760                  alc_capture_mixer2,
4761                  alc_capture_mixer3 },
4762        };
4763        if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4764                int mux;
4765                if (spec->auto_mic) {
4766                        mux = 0;
4767                        fixup_automic_adc(codec);
4768                } else if (spec->input_mux && spec->input_mux->num_items > 1)
4769                        mux = 1;
4770                else
4771                        mux = 0;
4772                spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4773        }
4774}
4775
4776#define set_beep_amp(spec, nid, idx, dir) \
4777        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4778
4779/*
4780 * OK, here we have finally the patch for ALC880
4781 */
4782
4783static int patch_alc880(struct hda_codec *codec)
4784{
4785        struct alc_spec *spec;
4786        int board_config;
4787        int err;
4788
4789        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4790        if (spec == NULL)
4791                return -ENOMEM;
4792
4793        codec->spec = spec;
4794
4795        board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4796                                                  alc880_models,
4797                                                  alc880_cfg_tbl);
4798        if (board_config < 0) {
4799                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4800                       codec->chip_name);
4801                board_config = ALC880_AUTO;
4802        }
4803
4804        if (board_config == ALC880_AUTO) {
4805                /* automatic parse from the BIOS config */
4806                err = alc880_parse_auto_config(codec);
4807                if (err < 0) {
4808                        alc_free(codec);
4809                        return err;
4810                } else if (!err) {
4811                        printk(KERN_INFO
4812                               "hda_codec: Cannot set up configuration "
4813                               "from BIOS.  Using 3-stack mode...\n");
4814                        board_config = ALC880_3ST;
4815                }
4816        }
4817
4818        err = snd_hda_attach_beep_device(codec, 0x1);
4819        if (err < 0) {
4820                alc_free(codec);
4821                return err;
4822        }
4823
4824        if (board_config != ALC880_AUTO)
4825                setup_preset(codec, &alc880_presets[board_config]);
4826
4827        spec->stream_analog_playback = &alc880_pcm_analog_playback;
4828        spec->stream_analog_capture = &alc880_pcm_analog_capture;
4829        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4830
4831        spec->stream_digital_playback = &alc880_pcm_digital_playback;
4832        spec->stream_digital_capture = &alc880_pcm_digital_capture;
4833
4834        if (!spec->adc_nids && spec->input_mux) {
4835                /* check whether NID 0x07 is valid */
4836                unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4837                /* get type */
4838                wcap = get_wcaps_type(wcap);
4839                if (wcap != AC_WID_AUD_IN) {
4840                        spec->adc_nids = alc880_adc_nids_alt;
4841                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4842                } else {
4843                        spec->adc_nids = alc880_adc_nids;
4844                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4845                }
4846        }
4847        set_capture_mixer(codec);
4848        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4849
4850        spec->vmaster_nid = 0x0c;
4851
4852        codec->patch_ops = alc_patch_ops;
4853        if (board_config == ALC880_AUTO)
4854                spec->init_hook = alc880_auto_init;
4855#ifdef CONFIG_SND_HDA_POWER_SAVE
4856        if (!spec->loopback.amplist)
4857                spec->loopback.amplist = alc880_loopbacks;
4858#endif
4859        codec->proc_widget_hook = print_realtek_coef;
4860
4861        return 0;
4862}
4863
4864
4865/*
4866 * ALC260 support
4867 */
4868
4869static hda_nid_t alc260_dac_nids[1] = {
4870        /* front */
4871        0x02,
4872};
4873
4874static hda_nid_t alc260_adc_nids[1] = {
4875        /* ADC0 */
4876        0x04,
4877};
4878
4879static hda_nid_t alc260_adc_nids_alt[1] = {
4880        /* ADC1 */
4881        0x05,
4882};
4883
4884/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
4885 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4886 */
4887static hda_nid_t alc260_dual_adc_nids[2] = {
4888        /* ADC0, ADC1 */
4889        0x04, 0x05
4890};
4891
4892#define ALC260_DIGOUT_NID       0x03
4893#define ALC260_DIGIN_NID        0x06
4894
4895static struct hda_input_mux alc260_capture_source = {
4896        .num_items = 4,
4897        .items = {
4898                { "Mic", 0x0 },
4899                { "Front Mic", 0x1 },
4900                { "Line", 0x2 },
4901                { "CD", 0x4 },
4902        },
4903};
4904
4905/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4906 * headphone jack and the internal CD lines since these are the only pins at
4907 * which audio can appear.  For flexibility, also allow the option of
4908 * recording the mixer output on the second ADC (ADC0 doesn't have a
4909 * connection to the mixer output).
4910 */
4911static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4912        {
4913                .num_items = 3,
4914                .items = {
4915                        { "Mic/Line", 0x0 },
4916                        { "CD", 0x4 },
4917                        { "Headphone", 0x2 },
4918                },
4919        },
4920        {
4921                .num_items = 4,
4922                .items = {
4923                        { "Mic/Line", 0x0 },
4924                        { "CD", 0x4 },
4925                        { "Headphone", 0x2 },
4926                        { "Mixer", 0x5 },
4927                },
4928        },
4929
4930};
4931
4932/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4933 * the Fujitsu S702x, but jacks are marked differently.
4934 */
4935static struct hda_input_mux alc260_acer_capture_sources[2] = {
4936        {
4937                .num_items = 4,
4938                .items = {
4939                        { "Mic", 0x0 },
4940                        { "Line", 0x2 },
4941                        { "CD", 0x4 },
4942                        { "Headphone", 0x5 },
4943                },
4944        },
4945        {
4946                .num_items = 5,
4947                .items = {
4948                        { "Mic", 0x0 },
4949                        { "Line", 0x2 },
4950                        { "CD", 0x4 },
4951                        { "Headphone", 0x6 },
4952                        { "Mixer", 0x5 },
4953                },
4954        },
4955};
4956
4957/* Maxdata Favorit 100XS */
4958static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4959        {
4960                .num_items = 2,
4961                .items = {
4962                        { "Line/Mic", 0x0 },
4963                        { "CD", 0x4 },
4964                },
4965        },
4966        {
4967                .num_items = 3,
4968                .items = {
4969                        { "Line/Mic", 0x0 },
4970                        { "CD", 0x4 },
4971                        { "Mixer", 0x5 },
4972                },
4973        },
4974};
4975
4976/*
4977 * This is just place-holder, so there's something for alc_build_pcms to look
4978 * at when it calculates the maximum number of channels. ALC260 has no mixer
4979 * element which allows changing the channel mode, so the verb list is
4980 * never used.
4981 */
4982static struct hda_channel_mode alc260_modes[1] = {
4983        { 2, NULL },
4984};
4985
4986
4987/* Mixer combinations
4988 *
4989 * basic: base_output + input + pc_beep + capture
4990 * HP: base_output + input + capture_alt
4991 * HP_3013: hp_3013 + input + capture
4992 * fujitsu: fujitsu + capture
4993 * acer: acer + capture
4994 */
4995
4996static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4997        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4998        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4999        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5000        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5001        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5002        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5003        { } /* end */
5004};
5005
5006static struct snd_kcontrol_new alc260_input_mixer[] = {
5007        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5008        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5009        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5010        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5011        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5012        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5013        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5014        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5015        { } /* end */
5016};
5017
5018/* update HP, line and mono out pins according to the master switch */
5019static void alc260_hp_master_update(struct hda_codec *codec,
5020                                    hda_nid_t hp, hda_nid_t line,
5021                                    hda_nid_t mono)
5022{
5023        struct alc_spec *spec = codec->spec;
5024        unsigned int val = spec->master_sw ? PIN_HP : 0;
5025        /* change HP and line-out pins */
5026        snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5027                            val);
5028        snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5029                            val);
5030        /* mono (speaker) depending on the HP jack sense */
5031        val = (val && !spec->jack_present) ? PIN_OUT : 0;
5032        snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5033                            val);
5034}
5035
5036static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5037                                   struct snd_ctl_elem_value *ucontrol)
5038{
5039        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5040        struct alc_spec *spec = codec->spec;
5041        *ucontrol->value.integer.value = spec->master_sw;
5042        return 0;
5043}
5044
5045static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5046                                   struct snd_ctl_elem_value *ucontrol)
5047{
5048        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5049        struct alc_spec *spec = codec->spec;
5050        int val = !!*ucontrol->value.integer.value;
5051        hda_nid_t hp, line, mono;
5052
5053        if (val == spec->master_sw)
5054                return 0;
5055        spec->master_sw = val;
5056        hp = (kcontrol->private_value >> 16) & 0xff;
5057        line = (kcontrol->private_value >> 8) & 0xff;
5058        mono = kcontrol->private_value & 0xff;
5059        alc260_hp_master_update(codec, hp, line, mono);
5060        return 1;
5061}
5062
5063static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5064        {
5065                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5066                .name = "Master Playback Switch",
5067                .info = snd_ctl_boolean_mono_info,
5068                .get = alc260_hp_master_sw_get,
5069                .put = alc260_hp_master_sw_put,
5070                .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5071        },
5072        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5073        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5074        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5075        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5076        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5077                              HDA_OUTPUT),
5078        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5079        { } /* end */
5080};
5081
5082static struct hda_verb alc260_hp_unsol_verbs[] = {
5083        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5084        {},
5085};
5086
5087static void alc260_hp_automute(struct hda_codec *codec)
5088{
5089        struct alc_spec *spec = codec->spec;
5090        unsigned int present;
5091
5092        present = snd_hda_codec_read(codec, 0x10, 0,
5093                                     AC_VERB_GET_PIN_SENSE, 0);
5094        spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5095        alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5096}
5097
5098static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5099{
5100        if ((res >> 26) == ALC880_HP_EVENT)
5101                alc260_hp_automute(codec);
5102}
5103
5104static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5105        {
5106                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5107                .name = "Master Playback Switch",
5108                .info = snd_ctl_boolean_mono_info,
5109                .get = alc260_hp_master_sw_get,
5110                .put = alc260_hp_master_sw_put,
5111                .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5112        },
5113        HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5114        HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5115        HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5116        HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5117        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5118        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5119        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5120        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5121        { } /* end */
5122};
5123
5124static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5125        .ops = &snd_hda_bind_vol,
5126        .values = {
5127                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5128                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5129                HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5130                0
5131        },
5132};
5133
5134static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5135        .ops = &snd_hda_bind_sw,
5136        .values = {
5137                HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5138                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5139                0
5140        },
5141};
5142
5143static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5144        HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5145        HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5146        HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5147        HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5148        { } /* end */
5149};
5150
5151static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5152        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5153        {},
5154};
5155
5156static void alc260_hp_3013_automute(struct hda_codec *codec)
5157{
5158        struct alc_spec *spec = codec->spec;
5159        unsigned int present;
5160
5161        present = snd_hda_codec_read(codec, 0x15, 0,
5162                                     AC_VERB_GET_PIN_SENSE, 0);
5163        spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5164        alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5165}
5166
5167static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5168                                       unsigned int res)
5169{
5170        if ((res >> 26) == ALC880_HP_EVENT)
5171                alc260_hp_3013_automute(codec);
5172}
5173
5174static void alc260_hp_3012_automute(struct hda_codec *codec)
5175{
5176        unsigned int present, bits;
5177
5178        present = snd_hda_codec_read(codec, 0x10, 0,
5179                        AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
5180
5181        bits = present ? 0 : PIN_OUT;
5182        snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5183                            bits);
5184        snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5185                            bits);
5186        snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5187                            bits);
5188}
5189
5190static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5191                                       unsigned int res)
5192{
5193        if ((res >> 26) == ALC880_HP_EVENT)
5194                alc260_hp_3012_automute(codec);
5195}
5196
5197/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
5198 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
5199 */
5200static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5201        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5202        HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5203        ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5204        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5205        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5206        HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5207        HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5208        ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5209        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5210        HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5211        { } /* end */
5212};
5213
5214/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
5215 * versions of the ALC260 don't act on requests to enable mic bias from NID
5216 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
5217 * datasheet doesn't mention this restriction.  At this stage it's not clear
5218 * whether this behaviour is intentional or is a hardware bug in chip
5219 * revisions available in early 2006.  Therefore for now allow the
5220 * "Headphone Jack Mode" control to span all choices, but if it turns out
5221 * that the lack of mic bias for this NID is intentional we could change the
5222 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5223 *
5224 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5225 * don't appear to make the mic bias available from the "line" jack, even
5226 * though the NID used for this jack (0x14) can supply it.  The theory is
5227 * that perhaps Acer have included blocking capacitors between the ALC260
5228 * and the output jack.  If this turns out to be the case for all such
5229 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5230 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5231 *
5232 * The C20x Tablet series have a mono internal speaker which is controlled
5233 * via the chip's Mono sum widget and pin complex, so include the necessary
5234 * controls for such models.  On models without a "mono speaker" the control
5235 * won't do anything.
5236 */
5237static struct snd_kcontrol_new alc260_acer_mixer[] = {
5238        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5239        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5240        ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5241        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5242                              HDA_OUTPUT),
5243        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5244                           HDA_INPUT),
5245        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5246        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5247        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5248        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5249        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5250        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5251        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5252        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5253        { } /* end */
5254};
5255
5256/* Maxdata Favorit 100XS: one output and one input (0x12) jack
5257 */
5258static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5259        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5260        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5261        ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5262        HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5263        HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5264        ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5265        { } /* end */
5266};
5267
5268/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5269 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
5270 */
5271static struct snd_kcontrol_new alc260_will_mixer[] = {
5272        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5273        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5274        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5275        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5276        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5277        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5278        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5279        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5280        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5281        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5282        { } /* end */
5283};
5284
5285/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5286 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5287 */
5288static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5289        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5290        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5291        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5292        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5293        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5294        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5295        HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5296        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5297        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5298        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5299        { } /* end */
5300};
5301
5302/*
5303 * initialization verbs
5304 */
5305static struct hda_verb alc260_init_verbs[] = {
5306        /* Line In pin widget for input */
5307        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5308        /* CD pin widget for input */
5309        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5310        /* Mic1 (rear panel) pin widget for input and vref at 80% */
5311        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5312        /* Mic2 (front panel) pin widget for input and vref at 80% */
5313        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5314        /* LINE-2 is used for line-out in rear */
5315        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5316        /* select line-out */
5317        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5318        /* LINE-OUT pin */
5319        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5320        /* enable HP */
5321        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5322        /* enable Mono */
5323        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5324        /* mute capture amp left and right */
5325        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5326        /* set connection select to line in (default select for this ADC) */
5327        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5328        /* mute capture amp left and right */
5329        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5330        /* set connection select to line in (default select for this ADC) */
5331        {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5332        /* set vol=0 Line-Out mixer amp left and right */
5333        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5334        /* unmute pin widget amp left and right (no gain on this amp) */
5335        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5336        /* set vol=0 HP mixer amp left and right */
5337        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5338        /* unmute pin widget amp left and right (no gain on this amp) */
5339        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5340        /* set vol=0 Mono mixer amp left and right */
5341        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5342        /* unmute pin widget amp left and right (no gain on this amp) */
5343        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5344        /* unmute LINE-2 out pin */
5345        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5346        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5347         * Line In 2 = 0x03
5348         */
5349        /* mute analog inputs */
5350        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5351        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5352        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5353        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5354        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5355        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5356        /* mute Front out path */
5357        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5358        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5359        /* mute Headphone out path */
5360        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5361        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5362        /* mute Mono out path */
5363        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365        { }
5366};
5367
5368#if 0 /* should be identical with alc260_init_verbs? */
5369static struct hda_verb alc260_hp_init_verbs[] = {
5370        /* Headphone and output */
5371        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5372        /* mono output */
5373        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5374        /* Mic1 (rear panel) pin widget for input and vref at 80% */
5375        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5376        /* Mic2 (front panel) pin widget for input and vref at 80% */
5377        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5378        /* Line In pin widget for input */
5379        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5380        /* Line-2 pin widget for output */
5381        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5382        /* CD pin widget for input */
5383        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5384        /* unmute amp left and right */
5385        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5386        /* set connection select to line in (default select for this ADC) */
5387        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5388        /* unmute Line-Out mixer amp left and right (volume = 0) */
5389        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5390        /* mute pin widget amp left and right (no gain on this amp) */
5391        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5392        /* unmute HP mixer amp left and right (volume = 0) */
5393        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5394        /* mute pin widget amp left and right (no gain on this amp) */
5395        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5396        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5397         * Line In 2 = 0x03
5398         */
5399        /* mute analog inputs */
5400        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5401        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5402        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5403        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5404        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5405        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5406        /* Unmute Front out path */
5407        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5408        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5409        /* Unmute Headphone out path */
5410        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5411        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5412        /* Unmute Mono out path */
5413        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5414        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5415        { }
5416};
5417#endif
5418
5419static struct hda_verb alc260_hp_3013_init_verbs[] = {
5420        /* Line out and output */
5421        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5422        /* mono output */
5423        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5424        /* Mic1 (rear panel) pin widget for input and vref at 80% */
5425        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5426        /* Mic2 (front panel) pin widget for input and vref at 80% */
5427        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5428        /* Line In pin widget for input */
5429        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5430        /* Headphone pin widget for output */
5431        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5432        /* CD pin widget for input */
5433        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5434        /* unmute amp left and right */
5435        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5436        /* set connection select to line in (default select for this ADC) */
5437        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5438        /* unmute Line-Out mixer amp left and right (volume = 0) */
5439        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5440        /* mute pin widget amp left and right (no gain on this amp) */
5441        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5442        /* unmute HP mixer amp left and right (volume = 0) */
5443        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5444        /* mute pin widget amp left and right (no gain on this amp) */
5445        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5446        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5447         * Line In 2 = 0x03
5448         */
5449        /* mute analog inputs */
5450        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5451        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5452        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5453        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5454        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5455        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5456        /* Unmute Front out path */
5457        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5458        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5459        /* Unmute Headphone out path */
5460        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5461        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5462        /* Unmute Mono out path */
5463        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5464        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5465        { }
5466};
5467
5468/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5469 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5470 * audio = 0x16, internal speaker = 0x10.
5471 */
5472static struct hda_verb alc260_fujitsu_init_verbs[] = {
5473        /* Disable all GPIOs */
5474        {0x01, AC_VERB_SET_GPIO_MASK, 0},
5475        /* Internal speaker is connected to headphone pin */
5476        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5477        /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5478        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5479        /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5480        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5481        /* Ensure all other unused pins are disabled and muted. */
5482        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5483        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5484        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5485        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5486        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5487        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5488        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5489        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5490
5491        /* Disable digital (SPDIF) pins */
5492        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5493        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5494
5495        /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5496         * when acting as an output.
5497         */
5498        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5499
5500        /* Start with output sum widgets muted and their output gains at min */
5501        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5502        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5503        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5504        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5505        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5506        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5507        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5508        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5509        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5510
5511        /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5512        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5513        /* Unmute Line1 pin widget output buffer since it starts as an output.
5514         * If the pin mode is changed by the user the pin mode control will
5515         * take care of enabling the pin's input/output buffers as needed.
5516         * Therefore there's no need to enable the input buffer at this
5517         * stage.
5518         */
5519        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5520        /* Unmute input buffer of pin widget used for Line-in (no equiv
5521         * mixer ctrl)
5522         */
5523        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5524
5525        /* Mute capture amp left and right */
5526        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5527        /* Set ADC connection select to match default mixer setting - line
5528         * in (on mic1 pin)
5529         */
5530        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5531
5532        /* Do the same for the second ADC: mute capture input amp and
5533         * set ADC connection to line in (on mic1 pin)
5534         */
5535        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5536        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5537
5538        /* Mute all inputs to mixer widget (even unconnected ones) */
5539        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5540        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5541        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5542        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5543        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5544        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5545        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5546        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5547
5548        { }
5549};
5550
5551/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5552 * similar laptops (adapted from Fujitsu init verbs).
5553 */
5554static struct hda_verb alc260_acer_init_verbs[] = {
5555        /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5556         * the headphone jack.  Turn this on and rely on the standard mute
5557         * methods whenever the user wants to turn these outputs off.
5558         */
5559        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5560        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5561        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5562        /* Internal speaker/Headphone jack is connected to Line-out pin */
5563        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5564        /* Internal microphone/Mic jack is connected to Mic1 pin */
5565        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5566        /* Line In jack is connected to Line1 pin */
5567        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5568        /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5569        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5570        /* Ensure all other unused pins are disabled and muted. */
5571        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5572        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5573        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5574        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5575        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5576        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5577        /* Disable digital (SPDIF) pins */
5578        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5579        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5580
5581        /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5582         * bus when acting as outputs.
5583         */
5584        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5585        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5586
5587        /* Start with output sum widgets muted and their output gains at min */
5588        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5589        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5590        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5591        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5592        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5593        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5594        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5595        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5596        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5597
5598        /* Unmute Line-out pin widget amp left and right
5599         * (no equiv mixer ctrl)
5600         */
5601        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5602        /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5603        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5604        /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5605         * inputs. If the pin mode is changed by the user the pin mode control
5606         * will take care of enabling the pin's input/output buffers as needed.
5607         * Therefore there's no need to enable the input buffer at this
5608         * stage.
5609         */
5610        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5611        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5612
5613        /* Mute capture amp left and right */
5614        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5615        /* Set ADC connection select to match default mixer setting - mic
5616         * (on mic1 pin)
5617         */
5618        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5619
5620        /* Do similar with the second ADC: mute capture input amp and
5621         * set ADC connection to mic to match ALSA's default state.
5622         */
5623        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5624        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5625
5626        /* Mute all inputs to mixer widget (even unconnected ones) */
5627        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5628        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5629        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5630        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5631        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5632        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5633        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5634        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5635
5636        { }
5637};
5638
5639/* Initialisation sequence for Maxdata Favorit 100XS
5640 * (adapted from Acer init verbs).
5641 */
5642static struct hda_verb alc260_favorit100_init_verbs[] = {
5643        /* GPIO 0 enables the output jack.
5644         * Turn this on and rely on the standard mute
5645         * methods whenever the user wants to turn these outputs off.
5646         */
5647        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5648        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5649        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5650        /* Line/Mic input jack is connected to Mic1 pin */
5651        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5652        /* Ensure all other unused pins are disabled and muted. */
5653        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5654        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5655        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5656        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5657        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5658        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5659        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5660        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5661        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5662        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5663        /* Disable digital (SPDIF) pins */
5664        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5665        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5666
5667        /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5668         * bus when acting as outputs.
5669         */
5670        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5671        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5672
5673        /* Start with output sum widgets muted and their output gains at min */
5674        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5675        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5676        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5677        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5678        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5679        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5680        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5681        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5682        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5683
5684        /* Unmute Line-out pin widget amp left and right
5685         * (no equiv mixer ctrl)
5686         */
5687        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5688        /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5689         * inputs. If the pin mode is changed by the user the pin mode control
5690         * will take care of enabling the pin's input/output buffers as needed.
5691         * Therefore there's no need to enable the input buffer at this
5692         * stage.
5693         */
5694        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5695
5696        /* Mute capture amp left and right */
5697        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5698        /* Set ADC connection select to match default mixer setting - mic
5699         * (on mic1 pin)
5700         */
5701        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5702
5703        /* Do similar with the second ADC: mute capture input amp and
5704         * set ADC connection to mic to match ALSA's default state.
5705         */
5706        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5707        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5708
5709        /* Mute all inputs to mixer widget (even unconnected ones) */
5710        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5711        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5712        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5713        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5714        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5715        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5716        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5717        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5718
5719        { }
5720};
5721
5722static struct hda_verb alc260_will_verbs[] = {
5723        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5724        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5725        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5726        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5727        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5728        {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5729        {}
5730};
5731
5732static struct hda_verb alc260_replacer_672v_verbs[] = {
5733        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5734        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5735        {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5736
5737        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5738        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5739        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5740
5741        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5742        {}
5743};
5744
5745/* toggle speaker-output according to the hp-jack state */
5746static void alc260_replacer_672v_automute(struct hda_codec *codec)
5747{
5748        unsigned int present;
5749
5750        /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5751        present = snd_hda_codec_read(codec, 0x0f, 0,
5752                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5753        if (present) {
5754                snd_hda_codec_write_cache(codec, 0x01, 0,
5755                                          AC_VERB_SET_GPIO_DATA, 1);
5756                snd_hda_codec_write_cache(codec, 0x0f, 0,
5757                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
5758                                          PIN_HP);
5759        } else {
5760                snd_hda_codec_write_cache(codec, 0x01, 0,
5761                                          AC_VERB_SET_GPIO_DATA, 0);
5762                snd_hda_codec_write_cache(codec, 0x0f, 0,
5763                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
5764                                          PIN_OUT);
5765        }
5766}
5767
5768static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5769                                       unsigned int res)
5770{
5771        if ((res >> 26) == ALC880_HP_EVENT)
5772                alc260_replacer_672v_automute(codec);
5773}
5774
5775static struct hda_verb alc260_hp_dc7600_verbs[] = {
5776        {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5777        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5778        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5779        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5780        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5781        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5782        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5783        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5784        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5785        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5786        {}
5787};
5788
5789/* Test configuration for debugging, modelled after the ALC880 test
5790 * configuration.
5791 */
5792#ifdef CONFIG_SND_DEBUG
5793static hda_nid_t alc260_test_dac_nids[1] = {
5794        0x02,
5795};
5796static hda_nid_t alc260_test_adc_nids[2] = {
5797        0x04, 0x05,
5798};
5799/* For testing the ALC260, each input MUX needs its own definition since
5800 * the signal assignments are different.  This assumes that the first ADC
5801 * is NID 0x04.
5802 */
5803static struct hda_input_mux alc260_test_capture_sources[2] = {
5804        {
5805                .num_items = 7,
5806                .items = {
5807                        { "MIC1 pin", 0x0 },
5808                        { "MIC2 pin", 0x1 },
5809                        { "LINE1 pin", 0x2 },
5810                        { "LINE2 pin", 0x3 },
5811                        { "CD pin", 0x4 },
5812                        { "LINE-OUT pin", 0x5 },
5813                        { "HP-OUT pin", 0x6 },
5814                },
5815        },
5816        {
5817                .num_items = 8,
5818                .items = {
5819                        { "MIC1 pin", 0x0 },
5820                        { "MIC2 pin", 0x1 },
5821                        { "LINE1 pin", 0x2 },
5822                        { "LINE2 pin", 0x3 },
5823                        { "CD pin", 0x4 },
5824                        { "Mixer", 0x5 },
5825                        { "LINE-OUT pin", 0x6 },
5826                        { "HP-OUT pin", 0x7 },
5827                },
5828        },
5829};
5830static struct snd_kcontrol_new alc260_test_mixer[] = {
5831        /* Output driver widgets */
5832        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5833        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5834        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5835        HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5836        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5837        HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5838
5839        /* Modes for retasking pin widgets
5840         * Note: the ALC260 doesn't seem to act on requests to enable mic
5841         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
5842         * mention this restriction.  At this stage it's not clear whether
5843         * this behaviour is intentional or is a hardware bug in chip
5844         * revisions available at least up until early 2006.  Therefore for
5845         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5846         * choices, but if it turns out that the lack of mic bias for these
5847         * NIDs is intentional we could change their modes from
5848         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5849         */
5850        ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5851        ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5852        ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5853        ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5854        ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5855        ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5856
5857        /* Loopback mixer controls */
5858        HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5859        HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5860        HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5861        HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5862        HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5863        HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5864        HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5865        HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5866        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5867        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5868        HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5869        HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5870        HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5871        HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5872
5873        /* Controls for GPIO pins, assuming they are configured as outputs */
5874        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5875        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5876        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5877        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5878
5879        /* Switches to allow the digital IO pins to be enabled.  The datasheet
5880         * is ambigious as to which NID is which; testing on laptops which
5881         * make this output available should provide clarification.
5882         */
5883        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5884        ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5885
5886        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
5887         * this output to turn on an external amplifier.
5888         */
5889        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5890        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5891
5892        { } /* end */
5893};
5894static struct hda_verb alc260_test_init_verbs[] = {
5895        /* Enable all GPIOs as outputs with an initial value of 0 */
5896        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5897        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5898        {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5899
5900        /* Enable retasking pins as output, initially without power amp */
5901        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5902        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5903        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5904        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5905        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5906        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5907
5908        /* Disable digital (SPDIF) pins initially, but users can enable
5909         * them via a mixer switch.  In the case of SPDIF-out, this initverb
5910         * payload also sets the generation to 0, output to be in "consumer"
5911         * PCM format, copyright asserted, no pre-emphasis and no validity
5912         * control.
5913         */
5914        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5915        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5916
5917        /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5918         * OUT1 sum bus when acting as an output.
5919         */
5920        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5921        {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5922        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5923        {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5924
5925        /* Start with output sum widgets muted and their output gains at min */
5926        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5927        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5928        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5929        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5930        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5931        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5932        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5933        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5934        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5935
5936        /* Unmute retasking pin widget output buffers since the default
5937         * state appears to be output.  As the pin mode is changed by the
5938         * user the pin mode control will take care of enabling the pin's
5939         * input/output buffers as needed.
5940         */
5941        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5942        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5943        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5944        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5945        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5946        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5947        /* Also unmute the mono-out pin widget */
5948        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5949
5950        /* Mute capture amp left and right */
5951        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5952        /* Set ADC connection select to match default mixer setting (mic1
5953         * pin)
5954         */
5955        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5956
5957        /* Do the same for the second ADC: mute capture input amp and
5958         * set ADC connection to mic1 pin
5959         */
5960        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5961        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5962
5963        /* Mute all inputs to mixer widget (even unconnected ones) */
5964        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5965        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5966        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5967        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5968        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5969        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5970        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5971        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5972
5973        { }
5974};
5975#endif
5976
5977#define alc260_pcm_analog_playback      alc880_pcm_analog_alt_playback
5978#define alc260_pcm_analog_capture       alc880_pcm_analog_capture
5979
5980#define alc260_pcm_digital_playback     alc880_pcm_digital_playback
5981#define alc260_pcm_digital_capture      alc880_pcm_digital_capture
5982
5983/*
5984 * for BIOS auto-configuration
5985 */
5986
5987static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5988                                        const char *pfx, int *vol_bits)
5989{
5990        hda_nid_t nid_vol;
5991        unsigned long vol_val, sw_val;
5992        char name[32];
5993        int err;
5994
5995        if (nid >= 0x0f && nid < 0x11) {
5996                nid_vol = nid - 0x7;
5997                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5998                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5999        } else if (nid == 0x11) {
6000                nid_vol = nid - 0x7;
6001                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6002                sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6003        } else if (nid >= 0x12 && nid <= 0x15) {
6004                nid_vol = 0x08;
6005                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6006                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6007        } else
6008                return 0; /* N/A */
6009
6010        if (!(*vol_bits & (1 << nid_vol))) {
6011                /* first control for the volume widget */
6012                snprintf(name, sizeof(name), "%s Playback Volume", pfx);
6013                err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
6014                if (err < 0)
6015                        return err;
6016                *vol_bits |= (1 << nid_vol);
6017        }
6018        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
6019        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
6020        if (err < 0)
6021                return err;
6022        return 1;
6023}
6024
6025/* add playback controls from the parsed DAC table */
6026static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6027                                             const struct auto_pin_cfg *cfg)
6028{
6029        hda_nid_t nid;
6030        int err;
6031        int vols = 0;
6032
6033        spec->multiout.num_dacs = 1;
6034        spec->multiout.dac_nids = spec->private_dac_nids;
6035        spec->multiout.dac_nids[0] = 0x02;
6036
6037        nid = cfg->line_out_pins[0];
6038        if (nid) {
6039                const char *pfx;
6040                if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6041                        pfx = "Master";
6042                else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6043                        pfx = "Speaker";
6044                else
6045                        pfx = "Front";
6046                err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6047                if (err < 0)
6048                        return err;
6049        }
6050
6051        nid = cfg->speaker_pins[0];
6052        if (nid) {
6053                err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6054                if (err < 0)
6055                        return err;
6056        }
6057
6058        nid = cfg->hp_pins[0];
6059        if (nid) {
6060                err = alc260_add_playback_controls(spec, nid, "Headphone",
6061                                                   &vols);
6062                if (err < 0)
6063                        return err;
6064        }
6065        return 0;
6066}
6067
6068/* create playback/capture controls for input pins */
6069static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6070                                                const struct auto_pin_cfg *cfg)
6071{
6072        return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6073}
6074
6075static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6076                                              hda_nid_t nid, int pin_type,
6077                                              int sel_idx)
6078{
6079        alc_set_pin_output(codec, nid, pin_type);
6080        /* need the manual connection? */
6081        if (nid >= 0x12) {
6082                int idx = nid - 0x12;
6083                snd_hda_codec_write(codec, idx + 0x0b, 0,
6084                                    AC_VERB_SET_CONNECT_SEL, sel_idx);
6085        }
6086}
6087
6088static void alc260_auto_init_multi_out(struct hda_codec *codec)
6089{
6090        struct alc_spec *spec = codec->spec;
6091        hda_nid_t nid;
6092
6093        nid = spec->autocfg.line_out_pins[0];
6094        if (nid) {
6095                int pin_type = get_pin_type(spec->autocfg.line_out_type);
6096                alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6097        }
6098
6099        nid = spec->autocfg.speaker_pins[0];
6100        if (nid)
6101                alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6102
6103        nid = spec->autocfg.hp_pins[0];
6104        if (nid)
6105                alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6106}
6107
6108#define ALC260_PIN_CD_NID               0x16
6109static void alc260_auto_init_analog_input(struct hda_codec *codec)
6110{
6111        struct alc_spec *spec = codec->spec;
6112        int i;
6113
6114        for (i = 0; i < AUTO_PIN_LAST; i++) {
6115                hda_nid_t nid = spec->autocfg.input_pins[i];
6116                if (nid >= 0x12) {
6117                        alc_set_input_pin(codec, nid, i);
6118                        if (nid != ALC260_PIN_CD_NID &&
6119                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6120                                snd_hda_codec_write(codec, nid, 0,
6121                                                    AC_VERB_SET_AMP_GAIN_MUTE,
6122                                                    AMP_OUT_MUTE);
6123                }
6124        }
6125}
6126
6127/*
6128 * generic initialization of ADC, input mixers and output mixers
6129 */
6130static struct hda_verb alc260_volume_init_verbs[] = {
6131        /*
6132         * Unmute ADC0-1 and set the default input to mic-in
6133         */
6134        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6135        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6136        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6137        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6138
6139        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6140         * mixer widget
6141         * Note: PASD motherboards uses the Line In 2 as the input for
6142         * front panel mic (mic 2)
6143         */
6144        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6145        /* mute analog inputs */
6146        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6147        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6148        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6149        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6150        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6151
6152        /*
6153         * Set up output mixers (0x08 - 0x0a)
6154         */
6155        /* set vol=0 to output mixers */
6156        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6157        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6158        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6159        /* set up input amps for analog loopback */
6160        /* Amp Indices: DAC = 0, mixer = 1 */
6161        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6162        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6163        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6164        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6165        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6166        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6167
6168        { }
6169};
6170
6171static int alc260_parse_auto_config(struct hda_codec *codec)
6172{
6173        struct alc_spec *spec = codec->spec;
6174        int err;
6175        static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6176
6177        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6178                                           alc260_ignore);
6179        if (err < 0)
6180                return err;
6181        err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6182        if (err < 0)
6183                return err;
6184        if (!spec->kctls.list)
6185                return 0; /* can't find valid BIOS pin config */
6186        err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6187        if (err < 0)
6188                return err;
6189
6190        spec->multiout.max_channels = 2;
6191
6192        if (spec->autocfg.dig_outs)
6193                spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6194        if (spec->kctls.list)
6195                add_mixer(spec, spec->kctls.list);
6196
6197        add_verb(spec, alc260_volume_init_verbs);
6198
6199        spec->num_mux_defs = 1;
6200        spec->input_mux = &spec->private_imux[0];
6201
6202        alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6203
6204        return 1;
6205}
6206
6207/* additional initialization for auto-configuration model */
6208static void alc260_auto_init(struct hda_codec *codec)
6209{
6210        struct alc_spec *spec = codec->spec;
6211        alc260_auto_init_multi_out(codec);
6212        alc260_auto_init_analog_input(codec);
6213        if (spec->unsol_event)
6214                alc_inithook(codec);
6215}
6216
6217#ifdef CONFIG_SND_HDA_POWER_SAVE
6218static struct hda_amp_list alc260_loopbacks[] = {
6219        { 0x07, HDA_INPUT, 0 },
6220        { 0x07, HDA_INPUT, 1 },
6221        { 0x07, HDA_INPUT, 2 },
6222        { 0x07, HDA_INPUT, 3 },
6223        { 0x07, HDA_INPUT, 4 },
6224        { } /* end */
6225};
6226#endif
6227
6228/*
6229 * ALC260 configurations
6230 */
6231static const char *alc260_models[ALC260_MODEL_LAST] = {
6232        [ALC260_BASIC]          = "basic",
6233        [ALC260_HP]             = "hp",
6234        [ALC260_HP_3013]        = "hp-3013",
6235        [ALC260_HP_DC7600]      = "hp-dc7600",
6236        [ALC260_FUJITSU_S702X]  = "fujitsu",
6237        [ALC260_ACER]           = "acer",
6238        [ALC260_WILL]           = "will",
6239        [ALC260_REPLACER_672V]  = "replacer",
6240        [ALC260_FAVORIT100]     = "favorit100",
6241#ifdef CONFIG_SND_DEBUG
6242        [ALC260_TEST]           = "test",
6243#endif
6244        [ALC260_AUTO]           = "auto",
6245};
6246
6247static struct snd_pci_quirk alc260_cfg_tbl[] = {
6248        SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6249        SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6250        SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6251        SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6252        SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6253        SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6254        SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6255        SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6256        SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6257        SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6258        SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6259        SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6260        SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6261        SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6262        SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6263        SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6264        SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6265        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6266        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6267        {}
6268};
6269
6270static struct alc_config_preset alc260_presets[] = {
6271        [ALC260_BASIC] = {
6272                .mixers = { alc260_base_output_mixer,
6273                            alc260_input_mixer },
6274                .init_verbs = { alc260_init_verbs },
6275                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6276                .dac_nids = alc260_dac_nids,
6277                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6278                .adc_nids = alc260_adc_nids,
6279                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6280                .channel_mode = alc260_modes,
6281                .input_mux = &alc260_capture_source,
6282        },
6283        [ALC260_HP] = {
6284                .mixers = { alc260_hp_output_mixer,
6285                            alc260_input_mixer },
6286                .init_verbs = { alc260_init_verbs,
6287                                alc260_hp_unsol_verbs },
6288                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6289                .dac_nids = alc260_dac_nids,
6290                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6291                .adc_nids = alc260_adc_nids_alt,
6292                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6293                .channel_mode = alc260_modes,
6294                .input_mux = &alc260_capture_source,
6295                .unsol_event = alc260_hp_unsol_event,
6296                .init_hook = alc260_hp_automute,
6297        },
6298        [ALC260_HP_DC7600] = {
6299                .mixers = { alc260_hp_dc7600_mixer,
6300                            alc260_input_mixer },
6301                .init_verbs = { alc260_init_verbs,
6302                                alc260_hp_dc7600_verbs },
6303                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6304                .dac_nids = alc260_dac_nids,
6305                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6306                .adc_nids = alc260_adc_nids_alt,
6307                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6308                .channel_mode = alc260_modes,
6309                .input_mux = &alc260_capture_source,
6310                .unsol_event = alc260_hp_3012_unsol_event,
6311                .init_hook = alc260_hp_3012_automute,
6312        },
6313        [ALC260_HP_3013] = {
6314                .mixers = { alc260_hp_3013_mixer,
6315                            alc260_input_mixer },
6316                .init_verbs = { alc260_hp_3013_init_verbs,
6317                                alc260_hp_3013_unsol_verbs },
6318                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6319                .dac_nids = alc260_dac_nids,
6320                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6321                .adc_nids = alc260_adc_nids_alt,
6322                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6323                .channel_mode = alc260_modes,
6324                .input_mux = &alc260_capture_source,
6325                .unsol_event = alc260_hp_3013_unsol_event,
6326                .init_hook = alc260_hp_3013_automute,
6327        },
6328        [ALC260_FUJITSU_S702X] = {
6329                .mixers = { alc260_fujitsu_mixer },
6330                .init_verbs = { alc260_fujitsu_init_verbs },
6331                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6332                .dac_nids = alc260_dac_nids,
6333                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6334                .adc_nids = alc260_dual_adc_nids,
6335                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6336                .channel_mode = alc260_modes,
6337                .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6338                .input_mux = alc260_fujitsu_capture_sources,
6339        },
6340        [ALC260_ACER] = {
6341                .mixers = { alc260_acer_mixer },
6342                .init_verbs = { alc260_acer_init_verbs },
6343                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6344                .dac_nids = alc260_dac_nids,
6345                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6346                .adc_nids = alc260_dual_adc_nids,
6347                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6348                .channel_mode = alc260_modes,
6349                .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6350                .input_mux = alc260_acer_capture_sources,
6351        },
6352        [ALC260_FAVORIT100] = {
6353                .mixers = { alc260_favorit100_mixer },
6354                .init_verbs = { alc260_favorit100_init_verbs },
6355                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6356                .dac_nids = alc260_dac_nids,
6357                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6358                .adc_nids = alc260_dual_adc_nids,
6359                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6360                .channel_mode = alc260_modes,
6361                .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6362                .input_mux = alc260_favorit100_capture_sources,
6363        },
6364        [ALC260_WILL] = {
6365                .mixers = { alc260_will_mixer },
6366                .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6367                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6368                .dac_nids = alc260_dac_nids,
6369                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6370                .adc_nids = alc260_adc_nids,
6371                .dig_out_nid = ALC260_DIGOUT_NID,
6372                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6373                .channel_mode = alc260_modes,
6374                .input_mux = &alc260_capture_source,
6375        },
6376        [ALC260_REPLACER_672V] = {
6377                .mixers = { alc260_replacer_672v_mixer },
6378                .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6379                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6380                .dac_nids = alc260_dac_nids,
6381                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6382                .adc_nids = alc260_adc_nids,
6383                .dig_out_nid = ALC260_DIGOUT_NID,
6384                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6385                .channel_mode = alc260_modes,
6386                .input_mux = &alc260_capture_source,
6387                .unsol_event = alc260_replacer_672v_unsol_event,
6388                .init_hook = alc260_replacer_672v_automute,
6389        },
6390#ifdef CONFIG_SND_DEBUG
6391        [ALC260_TEST] = {
6392                .mixers = { alc260_test_mixer },
6393                .init_verbs = { alc260_test_init_verbs },
6394                .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6395                .dac_nids = alc260_test_dac_nids,
6396                .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6397                .adc_nids = alc260_test_adc_nids,
6398                .num_channel_mode = ARRAY_SIZE(alc260_modes),
6399                .channel_mode = alc260_modes,
6400                .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6401                .input_mux = alc260_test_capture_sources,
6402        },
6403#endif
6404};
6405
6406static int patch_alc260(struct hda_codec *codec)
6407{
6408        struct alc_spec *spec;
6409        int err, board_config;
6410
6411        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6412        if (spec == NULL)
6413                return -ENOMEM;
6414
6415        codec->spec = spec;
6416
6417        board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6418                                                  alc260_models,
6419                                                  alc260_cfg_tbl);
6420        if (board_config < 0) {
6421                snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6422                           codec->chip_name);
6423                board_config = ALC260_AUTO;
6424        }
6425
6426        if (board_config == ALC260_AUTO) {
6427                /* automatic parse from the BIOS config */
6428                err = alc260_parse_auto_config(codec);
6429                if (err < 0) {
6430                        alc_free(codec);
6431                        return err;
6432                } else if (!err) {
6433                        printk(KERN_INFO
6434                               "hda_codec: Cannot set up configuration "
6435                               "from BIOS.  Using base mode...\n");
6436                        board_config = ALC260_BASIC;
6437                }
6438        }
6439
6440        err = snd_hda_attach_beep_device(codec, 0x1);
6441        if (err < 0) {
6442                alc_free(codec);
6443                return err;
6444        }
6445
6446        if (board_config != ALC260_AUTO)
6447                setup_preset(codec, &alc260_presets[board_config]);
6448
6449        spec->stream_analog_playback = &alc260_pcm_analog_playback;
6450        spec->stream_analog_capture = &alc260_pcm_analog_capture;
6451
6452        spec->stream_digital_playback = &alc260_pcm_digital_playback;
6453        spec->stream_digital_capture = &alc260_pcm_digital_capture;
6454
6455        if (!spec->adc_nids && spec->input_mux) {
6456                /* check whether NID 0x04 is valid */
6457                unsigned int wcap = get_wcaps(codec, 0x04);
6458                wcap = get_wcaps_type(wcap);
6459                /* get type */
6460                if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6461                        spec->adc_nids = alc260_adc_nids_alt;
6462                        spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6463                } else {
6464                        spec->adc_nids = alc260_adc_nids;
6465                        spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6466                }
6467        }
6468        set_capture_mixer(codec);
6469        set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6470
6471        spec->vmaster_nid = 0x08;
6472
6473        codec->patch_ops = alc_patch_ops;
6474        if (board_config == ALC260_AUTO)
6475                spec->init_hook = alc260_auto_init;
6476#ifdef CONFIG_SND_HDA_POWER_SAVE
6477        if (!spec->loopback.amplist)
6478                spec->loopback.amplist = alc260_loopbacks;
6479#endif
6480        codec->proc_widget_hook = print_realtek_coef;
6481
6482        return 0;
6483}
6484
6485
6486/*
6487 * ALC882/883/885/888/889 support
6488 *
6489 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6490 * configuration.  Each pin widget can choose any input DACs and a mixer.
6491 * Each ADC is connected from a mixer of all inputs.  This makes possible
6492 * 6-channel independent captures.
6493 *
6494 * In addition, an independent DAC for the multi-playback (not used in this
6495 * driver yet).
6496 */
6497#define ALC882_DIGOUT_NID       0x06
6498#define ALC882_DIGIN_NID        0x0a
6499#define ALC883_DIGOUT_NID       ALC882_DIGOUT_NID
6500#define ALC883_DIGIN_NID        ALC882_DIGIN_NID
6501#define ALC1200_DIGOUT_NID      0x10
6502
6503
6504static struct hda_channel_mode alc882_ch_modes[1] = {
6505        { 8, NULL }
6506};
6507
6508/* DACs */
6509static hda_nid_t alc882_dac_nids[4] = {
6510        /* front, rear, clfe, rear_surr */
6511        0x02, 0x03, 0x04, 0x05
6512};
6513#define alc883_dac_nids         alc882_dac_nids
6514
6515/* ADCs */
6516#define alc882_adc_nids         alc880_adc_nids
6517#define alc882_adc_nids_alt     alc880_adc_nids_alt
6518#define alc883_adc_nids         alc882_adc_nids_alt
6519static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6520static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6521#define alc889_adc_nids         alc880_adc_nids
6522
6523static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6524static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6525#define alc883_capsrc_nids      alc882_capsrc_nids_alt
6526static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6527#define alc889_capsrc_nids      alc882_capsrc_nids
6528
6529/* input MUX */
6530/* FIXME: should be a matrix-type input source selection */
6531
6532static struct hda_input_mux alc882_capture_source = {
6533        .num_items = 4,
6534        .items = {
6535                { "Mic", 0x0 },
6536                { "Front Mic", 0x1 },
6537                { "Line", 0x2 },
6538                { "CD", 0x4 },
6539        },
6540};
6541
6542#define alc883_capture_source   alc882_capture_source
6543
6544static struct hda_input_mux alc889_capture_source = {
6545        .num_items = 3,
6546        .items = {
6547                { "Front Mic", 0x0 },
6548                { "Mic", 0x3 },
6549                { "Line", 0x2 },
6550        },
6551};
6552
6553static struct hda_input_mux mb5_capture_source = {
6554        .num_items = 3,
6555        .items = {
6556                { "Mic", 0x1 },
6557                { "Line", 0x2 },
6558                { "CD", 0x4 },
6559        },
6560};
6561
6562static struct hda_input_mux alc883_3stack_6ch_intel = {
6563        .num_items = 4,
6564        .items = {
6565                { "Mic", 0x1 },
6566                { "Front Mic", 0x0 },
6567                { "Line", 0x2 },
6568                { "CD", 0x4 },
6569        },
6570};
6571
6572static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6573        .num_items = 2,
6574        .items = {
6575                { "Mic", 0x1 },
6576                { "Line", 0x2 },
6577        },
6578};
6579
6580static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6581        .num_items = 4,
6582        .items = {
6583                { "Mic", 0x0 },
6584                { "iMic", 0x1 },
6585                { "Line", 0x2 },
6586                { "CD", 0x4 },
6587        },
6588};
6589
6590static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6591        .num_items = 2,
6592        .items = {
6593                { "Mic", 0x0 },
6594                { "Int Mic", 0x1 },
6595        },
6596};
6597
6598static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6599        .num_items = 3,
6600        .items = {
6601                { "Mic", 0x0 },
6602                { "Front Mic", 0x1 },
6603                { "Line", 0x4 },
6604        },
6605};
6606
6607static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6608        .num_items = 2,
6609        .items = {
6610                { "Mic", 0x0 },
6611                { "Line", 0x2 },
6612        },
6613};
6614
6615static struct hda_input_mux alc889A_mb31_capture_source = {
6616        .num_items = 2,
6617        .items = {
6618                { "Mic", 0x0 },
6619                /* Front Mic (0x01) unused */
6620                { "Line", 0x2 },
6621                /* Line 2 (0x03) unused */
6622                /* CD (0x04) unsused? */
6623        },
6624};
6625
6626/*
6627 * 2ch mode
6628 */
6629static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6630        { 2, NULL }
6631};
6632
6633/*
6634 * 2ch mode
6635 */
6636static struct hda_verb alc882_3ST_ch2_init[] = {
6637        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6638        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6639        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6640        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6641        { } /* end */
6642};
6643
6644/*
6645 * 4ch mode
6646 */
6647static struct hda_verb alc882_3ST_ch4_init[] = {
6648        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6649        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6650        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6651        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6652        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6653        { } /* end */
6654};
6655
6656/*
6657 * 6ch mode
6658 */
6659static struct hda_verb alc882_3ST_ch6_init[] = {
6660        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6661        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6662        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6663        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6664        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6665        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6666        { } /* end */
6667};
6668
6669static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6670        { 2, alc882_3ST_ch2_init },
6671        { 4, alc882_3ST_ch4_init },
6672        { 6, alc882_3ST_ch6_init },
6673};
6674
6675#define alc883_3ST_6ch_modes    alc882_3ST_6ch_modes
6676
6677/*
6678 * 2ch mode
6679 */
6680static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6681        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6682        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6683        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6684        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6685        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6686        { } /* end */
6687};
6688
6689/*
6690 * 4ch mode
6691 */
6692static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6693        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6694        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6695        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6696        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6697        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6698        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6699        { } /* end */
6700};
6701
6702/*
6703 * 6ch mode
6704 */
6705static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6706        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6707        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6708        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6709        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6710        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6711        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6712        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6713        { } /* end */
6714};
6715
6716static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6717        { 2, alc883_3ST_ch2_clevo_init },
6718        { 4, alc883_3ST_ch4_clevo_init },
6719        { 6, alc883_3ST_ch6_clevo_init },
6720};
6721
6722
6723/*
6724 * 6ch mode
6725 */
6726static struct hda_verb alc882_sixstack_ch6_init[] = {
6727        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6728        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6729        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6730        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6731        { } /* end */
6732};
6733
6734/*
6735 * 8ch mode
6736 */
6737static struct hda_verb alc882_sixstack_ch8_init[] = {
6738        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6739        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6740        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6741        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6742        { } /* end */
6743};
6744
6745static struct hda_channel_mode alc882_sixstack_modes[2] = {
6746        { 6, alc882_sixstack_ch6_init },
6747        { 8, alc882_sixstack_ch8_init },
6748};
6749
6750/*
6751 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6752 */
6753
6754/*
6755 * 2ch mode
6756 */
6757static struct hda_verb alc885_mbp_ch2_init[] = {
6758        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6759        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6760        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6761        { } /* end */
6762};
6763
6764/*
6765 * 4ch mode
6766 */
6767static struct hda_verb alc885_mbp_ch4_init[] = {
6768        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6769        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6770        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6771        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6773        { } /* end */
6774};
6775
6776static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6777        { 2, alc885_mbp_ch2_init },
6778        { 4, alc885_mbp_ch4_init },
6779};
6780
6781/*
6782 * 2ch
6783 * Speakers/Woofer/HP = Front
6784 * LineIn = Input
6785 */
6786static struct hda_verb alc885_mb5_ch2_init[] = {
6787        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6788        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6789        { } /* end */
6790};
6791
6792/*
6793 * 6ch mode
6794 * Speakers/HP = Front
6795 * Woofer = LFE
6796 * LineIn = Surround
6797 */
6798static struct hda_verb alc885_mb5_ch6_init[] = {
6799        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6800        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6801        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6802        { } /* end */
6803};
6804
6805static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6806        { 2, alc885_mb5_ch2_init },
6807        { 6, alc885_mb5_ch6_init },
6808};
6809
6810
6811/*
6812 * 2ch mode
6813 */
6814static struct hda_verb alc883_4ST_ch2_init[] = {
6815        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6816        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6817        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6818        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6819        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6820        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6821        { } /* end */
6822};
6823
6824/*
6825 * 4ch mode
6826 */
6827static struct hda_verb alc883_4ST_ch4_init[] = {
6828        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6829        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6830        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6831        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6832        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6833        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6834        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6835        { } /* end */
6836};
6837
6838/*
6839 * 6ch mode
6840 */
6841static struct hda_verb alc883_4ST_ch6_init[] = {
6842        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6843        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6844        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6845        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6846        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6847        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6848        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6849        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6850        { } /* end */
6851};
6852
6853/*
6854 * 8ch mode
6855 */
6856static struct hda_verb alc883_4ST_ch8_init[] = {
6857        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6858        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6859        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6860        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6861        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6862        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6863        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6864        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6865        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6866        { } /* end */
6867};
6868
6869static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6870        { 2, alc883_4ST_ch2_init },
6871        { 4, alc883_4ST_ch4_init },
6872        { 6, alc883_4ST_ch6_init },
6873        { 8, alc883_4ST_ch8_init },
6874};
6875
6876
6877/*
6878 * 2ch mode
6879 */
6880static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6881        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6882        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6883        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6884        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6885        { } /* end */
6886};
6887
6888/*
6889 * 4ch mode
6890 */
6891static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6892        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6893        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6894        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6895        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6896        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6897        { } /* end */
6898};
6899
6900/*
6901 * 6ch mode
6902 */
6903static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6904        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6905        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6906        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6907        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6908        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6909        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6910        { } /* end */
6911};
6912
6913static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6914        { 2, alc883_3ST_ch2_intel_init },
6915        { 4, alc883_3ST_ch4_intel_init },
6916        { 6, alc883_3ST_ch6_intel_init },
6917};
6918
6919/*
6920 * 2ch mode
6921 */
6922static struct hda_verb alc889_ch2_intel_init[] = {
6923        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6924        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6925        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6926        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6927        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6928        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6929        { } /* end */
6930};
6931
6932/*
6933 * 6ch mode
6934 */
6935static struct hda_verb alc889_ch6_intel_init[] = {
6936        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6937        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6938        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6939        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6940        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6941        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6942        { } /* end */
6943};
6944
6945/*
6946 * 8ch mode
6947 */
6948static struct hda_verb alc889_ch8_intel_init[] = {
6949        { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6950        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6951        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6952        { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6953        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6954        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6955        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6956        { } /* end */
6957};
6958
6959static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6960        { 2, alc889_ch2_intel_init },
6961        { 6, alc889_ch6_intel_init },
6962        { 8, alc889_ch8_intel_init },
6963};
6964
6965/*
6966 * 6ch mode
6967 */
6968static struct hda_verb alc883_sixstack_ch6_init[] = {
6969        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6970        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6971        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6972        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6973        { } /* end */
6974};
6975
6976/*
6977 * 8ch mode
6978 */
6979static struct hda_verb alc883_sixstack_ch8_init[] = {
6980        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6981        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6982        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6983        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6984        { } /* end */
6985};
6986
6987static struct hda_channel_mode alc883_sixstack_modes[2] = {
6988        { 6, alc883_sixstack_ch6_init },
6989        { 8, alc883_sixstack_ch8_init },
6990};
6991
6992
6993/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6994 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6995 */
6996static struct snd_kcontrol_new alc882_base_mixer[] = {
6997        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6998        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6999        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7000        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7001        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7002        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7003        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7004        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7005        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7006        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7007        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7008        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7009        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7010        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7011        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7012        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7013        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7014        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7015        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7016        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7017        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7018        { } /* end */
7019};
7020
7021static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7022        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7023        HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7024        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7025        HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7026        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7027        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7028        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7029        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7030        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7031        HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7032        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7033        { } /* end */
7034};
7035
7036static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7037        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7038        HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7039        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7040        HDA_BIND_MUTE   ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7041        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7042        HDA_BIND_MUTE   ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7043        HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7044        HDA_BIND_MUTE   ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
7045        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7046        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7047        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7048        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7049        HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7050        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7051        { } /* end */
7052};
7053
7054static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7055        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7056        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7057        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7058        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7059        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7060        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7061        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7062        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7063        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7064        { } /* end */
7065};
7066
7067static struct snd_kcontrol_new alc882_targa_mixer[] = {
7068        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7069        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7070        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7071        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7072        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7073        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7074        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7075        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7076        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7077        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7078        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7079        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7080        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7081        { } /* end */
7082};
7083
7084/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7085 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7086 */
7087static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7088        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7089        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7090        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7091        HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7092        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7093        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7094        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7095        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7096        HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7097        HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7098        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7099        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7100        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7101        { } /* end */
7102};
7103
7104static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7105        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7106        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7107        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7108        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7109        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7110        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7111        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7112        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7113        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7114        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7115        { } /* end */
7116};
7117
7118static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7119        {
7120                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7121                .name = "Channel Mode",
7122                .info = alc_ch_mode_info,
7123                .get = alc_ch_mode_get,
7124                .put = alc_ch_mode_put,
7125        },
7126        { } /* end */
7127};
7128
7129static struct hda_verb alc882_base_init_verbs[] = {
7130        /* Front mixer: unmute input/output amp left and right (volume = 0) */
7131        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7132        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7133        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7134        /* Rear mixer */
7135        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7136        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7137        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7138        /* CLFE mixer */
7139        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7140        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7141        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7142        /* Side mixer */
7143        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7144        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7145        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7146
7147        /* mute analog input loopbacks */
7148        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7149        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7150        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7151        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7152        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7153
7154        /* Front Pin: output 0 (0x0c) */
7155        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7156        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7157        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7158        /* Rear Pin: output 1 (0x0d) */
7159        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7160        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7161        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7162        /* CLFE Pin: output 2 (0x0e) */
7163        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7164        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7165        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7166        /* Side Pin: output 3 (0x0f) */
7167        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7168        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7169        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7170        /* Mic (rear) pin: input vref at 80% */
7171        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7172        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7173        /* Front Mic pin: input vref at 80% */
7174        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7175        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7176        /* Line In pin: input */
7177        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7178        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7179        /* Line-2 In: Headphone output (output 0 - 0x0c) */
7180        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7181        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7182        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7183        /* CD pin widget for input */
7184        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7185
7186        /* FIXME: use matrix-type input source selection */
7187        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7188        /* Input mixer2 */
7189        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7190        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7191        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7192        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7193        /* Input mixer3 */
7194        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7195        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7196        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7197        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7198        /* ADC2: mute amp left and right */
7199        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7200        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7201        /* ADC3: mute amp left and right */
7202        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7203        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7204
7205        { }
7206};
7207
7208static struct hda_verb alc882_adc1_init_verbs[] = {
7209        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7210        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7211        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7212        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7213        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7214        /* ADC1: mute amp left and right */
7215        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7216        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7217        { }
7218};
7219
7220static struct hda_verb alc882_eapd_verbs[] = {
7221        /* change to EAPD mode */
7222        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7223        {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7224        { }
7225};
7226
7227static struct hda_verb alc889_eapd_verbs[] = {
7228        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7229        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7230        { }
7231};
7232
7233static struct hda_verb alc_hp15_unsol_verbs[] = {
7234        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7235        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7236        {}
7237};
7238
7239static struct hda_verb alc885_init_verbs[] = {
7240        /* Front mixer: unmute input/output amp left and right (volume = 0) */
7241        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7242        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7243        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7244        /* Rear mixer */
7245        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7246        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7247        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7248        /* CLFE mixer */
7249        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7250        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7251        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7252        /* Side mixer */
7253        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7254        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7255        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7256
7257        /* mute analog input loopbacks */
7258        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7259        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7260        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7261
7262        /* Front HP Pin: output 0 (0x0c) */
7263        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7264        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7265        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7266        /* Front Pin: output 0 (0x0c) */
7267        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7268        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7269        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7270        /* Rear Pin: output 1 (0x0d) */
7271        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7272        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7273        {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7274        /* CLFE Pin: output 2 (0x0e) */
7275        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7276        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7277        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7278        /* Side Pin: output 3 (0x0f) */
7279        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7280        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7281        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7282        /* Mic (rear) pin: input vref at 80% */
7283        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7284        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7285        /* Front Mic pin: input vref at 80% */
7286        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7287        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7288        /* Line In pin: input */
7289        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7290        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7291
7292        /* Mixer elements: 0x18, , 0x1a, 0x1b */
7293        /* Input mixer1 */
7294        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7295        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7296        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7297        /* Input mixer2 */
7298        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7300        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7301        /* Input mixer3 */
7302        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7303        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7304        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7305        /* ADC2: mute amp left and right */
7306        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7307        /* ADC3: mute amp left and right */
7308        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7309
7310        { }
7311};
7312
7313static struct hda_verb alc885_init_input_verbs[] = {
7314        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7315        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7316        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7317        { }
7318};
7319
7320
7321/* Unmute Selector 24h and set the default input to front mic */
7322static struct hda_verb alc889_init_input_verbs[] = {
7323        {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7324        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7325        { }
7326};
7327
7328
7329#define alc883_init_verbs       alc882_base_init_verbs
7330
7331/* Mac Pro test */
7332static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7333        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7334        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7335        HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7336        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7337        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7338        /* FIXME: this looks suspicious...
7339        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
7340        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
7341        */
7342        { } /* end */
7343};
7344
7345static struct hda_verb alc882_macpro_init_verbs[] = {
7346        /* Front mixer: unmute input/output amp left and right (volume = 0) */
7347        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7348        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7349        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7350        /* Front Pin: output 0 (0x0c) */
7351        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7352        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7353        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7354        /* Front Mic pin: input vref at 80% */
7355        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7356        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7357        /* Speaker:  output */
7358        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7359        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7360        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7361        /* Headphone output (output 0 - 0x0c) */
7362        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7363        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7364        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7365
7366        /* FIXME: use matrix-type input source selection */
7367        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7368        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7369        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7370        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7371        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7372        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7373        /* Input mixer2 */
7374        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7375        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7376        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7377        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7378        /* Input mixer3 */
7379        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7380        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7381        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7382        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7383        /* ADC1: mute amp left and right */
7384        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7385        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7386        /* ADC2: mute amp left and right */
7387        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7388        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7389        /* ADC3: mute amp left and right */
7390        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7391        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7392
7393        { }
7394};
7395
7396/* Macbook 5,1 */
7397static struct hda_verb alc885_mb5_init_verbs[] = {
7398        /* DACs */
7399        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7400        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7401        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7402        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7403        /* Front mixer */
7404        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7405        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7406        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7407        /* Surround mixer */
7408        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7409        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7410        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7411        /* LFE mixer */
7412        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7413        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7414        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7415        /* HP mixer */
7416        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7417        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7418        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7419        /* Front Pin (0x0c) */
7420        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7421        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7422        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7423        /* LFE Pin (0x0e) */
7424        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7425        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7426        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7427        /* HP Pin (0x0f) */
7428        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7429        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7430        {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7431        /* Front Mic pin: input vref at 80% */
7432        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7433        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7434        /* Line In pin */
7435        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7436        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7437
7438        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7439        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7440        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7441        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7442        { }
7443};
7444
7445/* Macbook Pro rev3 */
7446static struct hda_verb alc885_mbp3_init_verbs[] = {
7447        /* Front mixer: unmute input/output amp left and right (volume = 0) */
7448        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7449        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7450        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7451        /* Rear mixer */
7452        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7453        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7454        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7455        /* HP mixer */
7456        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7457        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7458        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7459        /* Front Pin: output 0 (0x0c) */
7460        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7461        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7462        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7463        /* HP Pin: output 0 (0x0e) */
7464        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7465        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7466        {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7467        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7468        /* Mic (rear) pin: input vref at 80% */
7469        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7470        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7471        /* Front Mic pin: input vref at 80% */
7472        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7473        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7474        /* Line In pin: use output 1 when in LineOut mode */
7475        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7476        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7477        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7478
7479        /* FIXME: use matrix-type input source selection */
7480        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7481        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7482        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7483        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7484        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7485        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7486        /* Input mixer2 */
7487        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7488        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7489        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7490        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7491        /* Input mixer3 */
7492        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7493        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7494        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7495        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7496        /* ADC1: mute amp left and right */
7497        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7498        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7499        /* ADC2: mute amp left and right */
7500        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7501        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7502        /* ADC3: mute amp left and right */
7503        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7504        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7505
7506        { }
7507};
7508
7509/* iMac 24 mixer. */
7510static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7511        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7512        HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7513        { } /* end */
7514};
7515
7516/* iMac 24 init verbs. */
7517static struct hda_verb alc885_imac24_init_verbs[] = {
7518        /* Internal speakers: output 0 (0x0c) */
7519        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7520        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7521        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7522        /* Internal speakers: output 0 (0x0c) */
7523        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7524        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7525        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7526        /* Headphone: output 0 (0x0c) */
7527        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7528        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7529        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7530        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7531        /* Front Mic: input vref at 80% */
7532        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7533        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7534        { }
7535};
7536
7537/* Toggle speaker-output according to the hp-jack state */
7538static void alc885_imac24_setup(struct hda_codec *codec)
7539{
7540        struct alc_spec *spec = codec->spec;
7541
7542        spec->autocfg.hp_pins[0] = 0x14;
7543        spec->autocfg.speaker_pins[0] = 0x18;
7544        spec->autocfg.speaker_pins[1] = 0x1a;
7545}
7546
7547static void alc885_mbp3_setup(struct hda_codec *codec)
7548{
7549        struct alc_spec *spec = codec->spec;
7550
7551        spec->autocfg.hp_pins[0] = 0x15;
7552        spec->autocfg.speaker_pins[0] = 0x14;
7553}
7554
7555
7556static struct hda_verb alc882_targa_verbs[] = {
7557        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7558        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7559
7560        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7561        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7562
7563        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7564        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7565        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7566
7567        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7568        { } /* end */
7569};
7570
7571/* toggle speaker-output according to the hp-jack state */
7572static void alc882_targa_automute(struct hda_codec *codec)
7573{
7574        struct alc_spec *spec = codec->spec;
7575        alc_automute_amp(codec);
7576        snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7577                                  spec->jack_present ? 1 : 3);
7578}
7579
7580static void alc882_targa_setup(struct hda_codec *codec)
7581{
7582        struct alc_spec *spec = codec->spec;
7583
7584        spec->autocfg.hp_pins[0] = 0x14;
7585        spec->autocfg.speaker_pins[0] = 0x1b;
7586}
7587
7588static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7589{
7590        if ((res >> 26) == ALC880_HP_EVENT)
7591                alc882_targa_automute(codec);
7592}
7593
7594static struct hda_verb alc882_asus_a7j_verbs[] = {
7595        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7596        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7597
7598        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7599        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7600        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7601
7602        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7603        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7604        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7605
7606        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7607        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7608        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7609        { } /* end */
7610};
7611
7612static struct hda_verb alc882_asus_a7m_verbs[] = {
7613        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7614        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7615
7616        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7617        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7618        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7619
7620        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7621        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7622        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7623
7624        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7625        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7626        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7627        { } /* end */
7628};
7629
7630static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7631{
7632        unsigned int gpiostate, gpiomask, gpiodir;
7633
7634        gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7635                                       AC_VERB_GET_GPIO_DATA, 0);
7636
7637        if (!muted)
7638                gpiostate |= (1 << pin);
7639        else
7640                gpiostate &= ~(1 << pin);
7641
7642        gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7643                                      AC_VERB_GET_GPIO_MASK, 0);
7644        gpiomask |= (1 << pin);
7645
7646        gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7647                                     AC_VERB_GET_GPIO_DIRECTION, 0);
7648        gpiodir |= (1 << pin);
7649
7650
7651        snd_hda_codec_write(codec, codec->afg, 0,
7652                            AC_VERB_SET_GPIO_MASK, gpiomask);
7653        snd_hda_codec_write(codec, codec->afg, 0,
7654                            AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7655
7656        msleep(1);
7657
7658        snd_hda_codec_write(codec, codec->afg, 0,
7659                            AC_VERB_SET_GPIO_DATA, gpiostate);
7660}
7661
7662/* set up GPIO at initialization */
7663static void alc885_macpro_init_hook(struct hda_codec *codec)
7664{
7665        alc882_gpio_mute(codec, 0, 0);
7666        alc882_gpio_mute(codec, 1, 0);
7667}
7668
7669/* set up GPIO and update auto-muting at initialization */
7670static void alc885_imac24_init_hook(struct hda_codec *codec)
7671{
7672        alc885_macpro_init_hook(codec);
7673        alc_automute_amp(codec);
7674}
7675
7676/*
7677 * generic initialization of ADC, input mixers and output mixers
7678 */
7679static struct hda_verb alc883_auto_init_verbs[] = {
7680        /*
7681         * Unmute ADC0-2 and set the default input to mic-in
7682         */
7683        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7684        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7685        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7686        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7687
7688        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7689         * mixer widget
7690         * Note: PASD motherboards uses the Line In 2 as the input for
7691         * front panel mic (mic 2)
7692         */
7693        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7694        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7695        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7696        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7697        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7698        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7699
7700        /*
7701         * Set up output mixers (0x0c - 0x0f)
7702         */
7703        /* set vol=0 to output mixers */
7704        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7705        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7706        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7707        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7708        /* set up input amps for analog loopback */
7709        /* Amp Indices: DAC = 0, mixer = 1 */
7710        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7711        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7712        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7713        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7714        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7715        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7716        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7719        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7720
7721        /* FIXME: use matrix-type input source selection */
7722        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7723        /* Input mixer2 */
7724        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7725        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7726        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7727        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7728        /* Input mixer3 */
7729        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7730        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7731        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7732        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7733
7734        { }
7735};
7736
7737/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7738static struct hda_verb alc889A_mb31_ch2_init[] = {
7739        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
7740        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7741        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
7742        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
7743        { } /* end */
7744};
7745
7746/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7747static struct hda_verb alc889A_mb31_ch4_init[] = {
7748        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},             /* HP as front */
7749        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7750        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
7751        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7752        { } /* end */
7753};
7754
7755/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7756static struct hda_verb alc889A_mb31_ch5_init[] = {
7757        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as rear */
7758        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7759        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},    /* Line as input */
7760        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Line off */
7761        { } /* end */
7762};
7763
7764/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7765static struct hda_verb alc889A_mb31_ch6_init[] = {
7766        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},             /* HP as front */
7767        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},   /* Subwoofer off */
7768        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},   /* Line as output */
7769        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7770        { } /* end */
7771};
7772
7773static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7774        { 2, alc889A_mb31_ch2_init },
7775        { 4, alc889A_mb31_ch4_init },
7776        { 5, alc889A_mb31_ch5_init },
7777        { 6, alc889A_mb31_ch6_init },
7778};
7779
7780static struct hda_verb alc883_medion_eapd_verbs[] = {
7781        /* eanable EAPD on medion laptop */
7782        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7783        {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7784        { }
7785};
7786
7787#define alc883_base_mixer       alc882_base_mixer
7788
7789static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7790        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7791        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7792        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7793        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7794        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7795        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7796        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7797        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7798        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7799        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7800        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7801        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7802        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7803        { } /* end */
7804};
7805
7806static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7807        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7808        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7809        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7810        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7811        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7812        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7813        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7814        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7815        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7816        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7817        { } /* end */
7818};
7819
7820static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7821        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7822        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7823        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7824        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7825        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7826        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7827        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7828        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7829        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7830        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7831        { } /* end */
7832};
7833
7834static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7835        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7836        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7837        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7838        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7839        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7840        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7841        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7842        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7843        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7844        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7845        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7846        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7847        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7848        { } /* end */
7849};
7850
7851static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7852        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7853        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7854        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7855        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7856        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7857        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7858        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7859        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7860        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7861        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7862        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7863        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7864        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7865        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7866        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7867        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7868        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7869        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7870        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7871        { } /* end */
7872};
7873
7874static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7875        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7876        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7877        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7878        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7879        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7880                              HDA_OUTPUT),
7881        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7882        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7883        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7884        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7885        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7886        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7887        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7888        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7889        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7890        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7891        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7892        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7893        HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7894        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7895        { } /* end */
7896};
7897
7898static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7899        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7900        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7901        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7902        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7903        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7904                              HDA_OUTPUT),
7905        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7906        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7907        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7908        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7909        HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7910        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7911        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7912        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7913        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7914        HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7915        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7916        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7917        HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7918        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7919        { } /* end */
7920};
7921
7922static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7923        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7924        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7925        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7926        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7927        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7928        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7929        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7930        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7931        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7932        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7933        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7934        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7935        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7936        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7937        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7938        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7939        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7940        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7941        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7942        { } /* end */
7943};
7944
7945static struct snd_kcontrol_new alc883_targa_mixer[] = {
7946        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7947        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7948        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7949        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7950        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7951        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7952        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7953        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7954        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7955        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7956        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7957        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7958        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7959        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7960        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7961        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7962        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7963        { } /* end */
7964};
7965
7966static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7967        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7968        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7969        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7970        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7971        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7972        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7973        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7974        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7975        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7976        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7977        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7978        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7979        { } /* end */
7980};
7981
7982static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
7983        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7984        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7985        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7986        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7987        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7988        { } /* end */
7989};
7990
7991static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7992        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7993        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7994        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7995        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7996        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7997        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7998        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7999        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8000        { } /* end */
8001};
8002
8003static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8004        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8005        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8006        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8007        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8008        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8009        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8010        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8011        HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8012        HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8013        { } /* end */
8014};
8015
8016static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8017        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8018        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8019        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8020        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8021        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8022        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8023        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8024        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8025        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8026        { } /* end */
8027};
8028
8029static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8030        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8031        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8032        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8033        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8034        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8035        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8036        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8037        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8038        { } /* end */
8039};
8040
8041static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8042        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8043        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8044        HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8045        HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8046        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8047        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8048        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8049        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8050        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8051        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8052        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8053        { } /* end */
8054};
8055
8056static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8057        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8058        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8059        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8060        HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8061        HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8062                                                0x0d, 1, 0x0, HDA_OUTPUT),
8063        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8064        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8065        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8066        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8067        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8068        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8069        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8070        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8071        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8072        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8073        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8074        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8075        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8076        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8077        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8078        { } /* end */
8079};
8080
8081static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8082        /* Output mixers */
8083        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8084        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8085        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8086        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8087        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8088                HDA_OUTPUT),
8089        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8090        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8091        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8092        /* Output switches */
8093        HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8094        HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8095        HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8096        /* Boost mixers */
8097        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8098        HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8099        /* Input mixers */
8100        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8101        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8102        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8103        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8104        { } /* end */
8105};
8106
8107static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8108        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8109        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8110        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8111        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8112        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8113        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8114        { } /* end */
8115};
8116
8117static struct hda_bind_ctls alc883_bind_cap_vol = {
8118        .ops = &snd_hda_bind_vol,
8119        .values = {
8120                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8121                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8122                0
8123        },
8124};
8125
8126static struct hda_bind_ctls alc883_bind_cap_switch = {
8127        .ops = &snd_hda_bind_sw,
8128        .values = {
8129                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8130                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8131                0
8132        },
8133};
8134
8135static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8136        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8137        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8138        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8139        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8140        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8141        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8142        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8143        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8144        { } /* end */
8145};
8146
8147static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8148        HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8149        HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8150        {
8151                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8152                /* .name = "Capture Source", */
8153                .name = "Input Source",
8154                .count = 1,
8155                .info = alc_mux_enum_info,
8156                .get = alc_mux_enum_get,
8157                .put = alc_mux_enum_put,
8158        },
8159        { } /* end */
8160};
8161
8162static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8163        {
8164                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8165                .name = "Channel Mode",
8166                .info = alc_ch_mode_info,
8167                .get = alc_ch_mode_get,
8168                .put = alc_ch_mode_put,
8169        },
8170        { } /* end */
8171};
8172
8173/* toggle speaker-output according to the hp-jack state */
8174static void alc883_mitac_setup(struct hda_codec *codec)
8175{
8176        struct alc_spec *spec = codec->spec;
8177
8178        spec->autocfg.hp_pins[0] = 0x15;
8179        spec->autocfg.speaker_pins[0] = 0x14;
8180        spec->autocfg.speaker_pins[1] = 0x17;
8181}
8182
8183/* auto-toggle front mic */
8184/*
8185static void alc883_mitac_mic_automute(struct hda_codec *codec)
8186{
8187        unsigned int present;
8188        unsigned char bits;
8189
8190        present = snd_hda_codec_read(codec, 0x18, 0,
8191                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8192        bits = present ? HDA_AMP_MUTE : 0;
8193        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8194}
8195*/
8196
8197static struct hda_verb alc883_mitac_verbs[] = {
8198        /* HP */
8199        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8200        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8201        /* Subwoofer */
8202        {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8203        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8204
8205        /* enable unsolicited event */
8206        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8207        /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8208
8209        { } /* end */
8210};
8211
8212static struct hda_verb alc883_clevo_m540r_verbs[] = {
8213        /* HP */
8214        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8215        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8216        /* Int speaker */
8217        /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8218
8219        /* enable unsolicited event */
8220        /*
8221        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8222        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8223        */
8224
8225        { } /* end */
8226};
8227
8228static struct hda_verb alc883_clevo_m720_verbs[] = {
8229        /* HP */
8230        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8231        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8232        /* Int speaker */
8233        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8234        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8235
8236        /* enable unsolicited event */
8237        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8238        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8239
8240        { } /* end */
8241};
8242
8243static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8244        /* HP */
8245        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8246        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8247        /* Subwoofer */
8248        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8249        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8250
8251        /* enable unsolicited event */
8252        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8253
8254        { } /* end */
8255};
8256
8257static struct hda_verb alc883_targa_verbs[] = {
8258        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8259        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8260
8261        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8262        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8263
8264/* Connect Line-Out side jack (SPDIF) to Side */
8265        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8266        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8267        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8268/* Connect Mic jack to CLFE */
8269        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8270        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8271        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8272/* Connect Line-in jack to Surround */
8273        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8274        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8275        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8276/* Connect HP out jack to Front */
8277        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8278        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8279        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8280
8281        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8282
8283        { } /* end */
8284};
8285
8286static struct hda_verb alc883_lenovo_101e_verbs[] = {
8287        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8288        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8289        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8290        { } /* end */
8291};
8292
8293static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8294        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8295        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8296        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8297        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8298        { } /* end */
8299};
8300
8301static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8302        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8303        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8304        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8305        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8306        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
8307        { } /* end */
8308};
8309
8310static struct hda_verb alc883_haier_w66_verbs[] = {
8311        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8313
8314        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8315
8316        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8317        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8318        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8319        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8320        { } /* end */
8321};
8322
8323static struct hda_verb alc888_lenovo_sky_verbs[] = {
8324        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8326        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8327        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8328        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8329        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8330        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8331        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8332        { } /* end */
8333};
8334
8335static struct hda_verb alc888_6st_dell_verbs[] = {
8336        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8337        { }
8338};
8339
8340static struct hda_verb alc883_vaiott_verbs[] = {
8341        /* HP */
8342        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8343        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8344
8345        /* enable unsolicited event */
8346        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8347
8348        { } /* end */
8349};
8350
8351static void alc888_3st_hp_setup(struct hda_codec *codec)
8352{
8353        struct alc_spec *spec = codec->spec;
8354
8355        spec->autocfg.hp_pins[0] = 0x1b;
8356        spec->autocfg.speaker_pins[0] = 0x14;
8357        spec->autocfg.speaker_pins[1] = 0x16;
8358        spec->autocfg.speaker_pins[2] = 0x18;
8359}
8360
8361static struct hda_verb alc888_3st_hp_verbs[] = {
8362        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
8363        {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
8364        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
8365        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8366        { } /* end */
8367};
8368
8369/*
8370 * 2ch mode
8371 */
8372static struct hda_verb alc888_3st_hp_2ch_init[] = {
8373        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8374        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8375        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8376        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8377        { } /* end */
8378};
8379
8380/*
8381 * 4ch mode
8382 */
8383static struct hda_verb alc888_3st_hp_4ch_init[] = {
8384        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8385        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8386        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8387        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8388        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8389        { } /* end */
8390};
8391
8392/*
8393 * 6ch mode
8394 */
8395static struct hda_verb alc888_3st_hp_6ch_init[] = {
8396        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8397        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8398        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8399        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8400        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8401        { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8402        { } /* end */
8403};
8404
8405static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8406        { 2, alc888_3st_hp_2ch_init },
8407        { 4, alc888_3st_hp_4ch_init },
8408        { 6, alc888_3st_hp_6ch_init },
8409};
8410
8411/* toggle front-jack and RCA according to the hp-jack state */
8412static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8413{
8414        unsigned int present;
8415
8416        present = snd_hda_codec_read(codec, 0x1b, 0,
8417                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8418        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8419                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8420        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8421                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8422}
8423
8424/* toggle RCA according to the front-jack state */
8425static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8426{
8427        unsigned int present;
8428
8429        present = snd_hda_codec_read(codec, 0x14, 0,
8430                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8431        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8432                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8433}
8434
8435static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8436                                             unsigned int res)
8437{
8438        if ((res >> 26) == ALC880_HP_EVENT)
8439                alc888_lenovo_ms7195_front_automute(codec);
8440        if ((res >> 26) == ALC880_FRONT_EVENT)
8441                alc888_lenovo_ms7195_rca_automute(codec);
8442}
8443
8444static struct hda_verb alc883_medion_md2_verbs[] = {
8445        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8446        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8447
8448        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8449
8450        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8451        { } /* end */
8452};
8453
8454/* toggle speaker-output according to the hp-jack state */
8455static void alc883_medion_md2_setup(struct hda_codec *codec)
8456{
8457        struct alc_spec *spec = codec->spec;
8458
8459        spec->autocfg.hp_pins[0] = 0x14;
8460        spec->autocfg.speaker_pins[0] = 0x15;
8461}
8462
8463/* toggle speaker-output according to the hp-jack state */
8464#define alc883_targa_init_hook          alc882_targa_init_hook
8465#define alc883_targa_unsol_event        alc882_targa_unsol_event
8466
8467static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8468{
8469        unsigned int present;
8470
8471        present = snd_hda_codec_read(codec, 0x18, 0,
8472                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8473        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8474                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8475}
8476
8477static void alc883_clevo_m720_setup(struct hda_codec *codec)
8478{
8479        struct alc_spec *spec = codec->spec;
8480
8481        spec->autocfg.hp_pins[0] = 0x15;
8482        spec->autocfg.speaker_pins[0] = 0x14;
8483}
8484
8485static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8486{
8487        alc_automute_amp(codec);
8488        alc883_clevo_m720_mic_automute(codec);
8489}
8490
8491static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8492                                           unsigned int res)
8493{
8494        switch (res >> 26) {
8495        case ALC880_MIC_EVENT:
8496                alc883_clevo_m720_mic_automute(codec);
8497                break;
8498        default:
8499                alc_automute_amp_unsol_event(codec, res);
8500                break;
8501        }
8502}
8503
8504/* toggle speaker-output according to the hp-jack state */
8505static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8506{
8507        struct alc_spec *spec = codec->spec;
8508
8509        spec->autocfg.hp_pins[0] = 0x14;
8510        spec->autocfg.speaker_pins[0] = 0x15;
8511}
8512
8513static void alc883_haier_w66_setup(struct hda_codec *codec)
8514{
8515        struct alc_spec *spec = codec->spec;
8516
8517        spec->autocfg.hp_pins[0] = 0x1b;
8518        spec->autocfg.speaker_pins[0] = 0x14;
8519}
8520
8521static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8522{
8523        unsigned int present;
8524        unsigned char bits;
8525
8526        present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8527                & AC_PINSENSE_PRESENCE;
8528        bits = present ? HDA_AMP_MUTE : 0;
8529        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8530                                 HDA_AMP_MUTE, bits);
8531}
8532
8533static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8534{
8535        unsigned int present;
8536        unsigned char bits;
8537
8538        present = snd_hda_codec_read(codec, 0x1b, 0,
8539                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8540        bits = present ? HDA_AMP_MUTE : 0;
8541        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8542                                 HDA_AMP_MUTE, bits);
8543        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8544                                 HDA_AMP_MUTE, bits);
8545}
8546
8547static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8548                                           unsigned int res)
8549{
8550        if ((res >> 26) == ALC880_HP_EVENT)
8551                alc883_lenovo_101e_all_automute(codec);
8552        if ((res >> 26) == ALC880_FRONT_EVENT)
8553                alc883_lenovo_101e_ispeaker_automute(codec);
8554}
8555
8556/* toggle speaker-output according to the hp-jack state */
8557static void alc883_acer_aspire_setup(struct hda_codec *codec)
8558{
8559        struct alc_spec *spec = codec->spec;
8560
8561        spec->autocfg.hp_pins[0] = 0x14;
8562        spec->autocfg.speaker_pins[0] = 0x15;
8563        spec->autocfg.speaker_pins[1] = 0x16;
8564}
8565
8566static struct hda_verb alc883_acer_eapd_verbs[] = {
8567        /* HP Pin: output 0 (0x0c) */
8568        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8569        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8571        /* Front Pin: output 0 (0x0c) */
8572        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8573        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8574        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8575        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8576        /* eanable EAPD on medion laptop */
8577        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8578        {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8579        /* enable unsolicited event */
8580        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8581        { }
8582};
8583
8584static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8585        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8586        {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8587        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8588        { } /* end */
8589};
8590
8591static void alc888_6st_dell_setup(struct hda_codec *codec)
8592{
8593        struct alc_spec *spec = codec->spec;
8594
8595        spec->autocfg.hp_pins[0] = 0x1b;
8596        spec->autocfg.speaker_pins[0] = 0x14;
8597        spec->autocfg.speaker_pins[1] = 0x15;
8598        spec->autocfg.speaker_pins[2] = 0x16;
8599        spec->autocfg.speaker_pins[3] = 0x17;
8600}
8601
8602static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8603{
8604        struct alc_spec *spec = codec->spec;
8605
8606        spec->autocfg.hp_pins[0] = 0x1b;
8607        spec->autocfg.speaker_pins[0] = 0x14;
8608        spec->autocfg.speaker_pins[1] = 0x15;
8609        spec->autocfg.speaker_pins[2] = 0x16;
8610        spec->autocfg.speaker_pins[3] = 0x17;
8611        spec->autocfg.speaker_pins[4] = 0x1a;
8612}
8613
8614static void alc883_vaiott_setup(struct hda_codec *codec)
8615{
8616        struct alc_spec *spec = codec->spec;
8617
8618        spec->autocfg.hp_pins[0] = 0x15;
8619        spec->autocfg.speaker_pins[0] = 0x14;
8620        spec->autocfg.speaker_pins[1] = 0x17;
8621}
8622
8623static struct hda_verb alc888_asus_m90v_verbs[] = {
8624        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8627        /* enable unsolicited event */
8628        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8629        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8630        { } /* end */
8631};
8632
8633static void alc883_mode2_setup(struct hda_codec *codec)
8634{
8635        struct alc_spec *spec = codec->spec;
8636
8637        spec->autocfg.hp_pins[0] = 0x1b;
8638        spec->autocfg.speaker_pins[0] = 0x14;
8639        spec->autocfg.speaker_pins[1] = 0x15;
8640        spec->autocfg.speaker_pins[2] = 0x16;
8641        spec->ext_mic.pin = 0x18;
8642        spec->int_mic.pin = 0x19;
8643        spec->ext_mic.mux_idx = 0;
8644        spec->int_mic.mux_idx = 1;
8645        spec->auto_mic = 1;
8646}
8647
8648static struct hda_verb alc888_asus_eee1601_verbs[] = {
8649        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8650        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8651        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8652        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8653        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8654        {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8655        {0x20, AC_VERB_SET_PROC_COEF,  0x0838},
8656        /* enable unsolicited event */
8657        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8658        { } /* end */
8659};
8660
8661static void alc883_eee1601_inithook(struct hda_codec *codec)
8662{
8663        struct alc_spec *spec = codec->spec;
8664
8665        spec->autocfg.hp_pins[0] = 0x14;
8666        spec->autocfg.speaker_pins[0] = 0x1b;
8667        alc_automute_pin(codec);
8668}
8669
8670static struct hda_verb alc889A_mb31_verbs[] = {
8671        /* Init rear pin (used as headphone output) */
8672        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},    /* Apple Headphones */
8673        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},           /* Connect to front */
8674        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8675        /* Init line pin (used as output in 4ch and 6ch mode) */
8676        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},           /* Connect to CLFE */
8677        /* Init line 2 pin (used as headphone out by default) */
8678        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},  /* Use as input */
8679        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8680        { } /* end */
8681};
8682
8683/* Mute speakers according to the headphone jack state */
8684static void alc889A_mb31_automute(struct hda_codec *codec)
8685{
8686        unsigned int present;
8687
8688        /* Mute only in 2ch or 4ch mode */
8689        if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8690            == 0x00) {
8691                present = snd_hda_codec_read(codec, 0x15, 0,
8692                        AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8693                snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
8694                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8695                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8696                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8697        }
8698}
8699
8700static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8701{
8702        if ((res >> 26) == ALC880_HP_EVENT)
8703                alc889A_mb31_automute(codec);
8704}
8705
8706
8707#ifdef CONFIG_SND_HDA_POWER_SAVE
8708#define alc882_loopbacks        alc880_loopbacks
8709#endif
8710
8711/* pcm configuration: identical with ALC880 */
8712#define alc882_pcm_analog_playback      alc880_pcm_analog_playback
8713#define alc882_pcm_analog_capture       alc880_pcm_analog_capture
8714#define alc882_pcm_digital_playback     alc880_pcm_digital_playback
8715#define alc882_pcm_digital_capture      alc880_pcm_digital_capture
8716
8717static hda_nid_t alc883_slave_dig_outs[] = {
8718        ALC1200_DIGOUT_NID, 0,
8719};
8720
8721static hda_nid_t alc1200_slave_dig_outs[] = {
8722        ALC883_DIGOUT_NID, 0,
8723};
8724
8725/*
8726 * configuration and preset
8727 */
8728static const char *alc882_models[ALC882_MODEL_LAST] = {
8729        [ALC882_3ST_DIG]        = "3stack-dig",
8730        [ALC882_6ST_DIG]        = "6stack-dig",
8731        [ALC882_ARIMA]          = "arima",
8732        [ALC882_W2JC]           = "w2jc",
8733        [ALC882_TARGA]          = "targa",
8734        [ALC882_ASUS_A7J]       = "asus-a7j",
8735        [ALC882_ASUS_A7M]       = "asus-a7m",
8736        [ALC885_MACPRO]         = "macpro",
8737        [ALC885_MB5]            = "mb5",
8738        [ALC885_MBP3]           = "mbp3",
8739        [ALC885_IMAC24]         = "imac24",
8740        [ALC883_3ST_2ch_DIG]    = "3stack-2ch-dig",
8741        [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
8742        [ALC883_3ST_6ch]        = "3stack-6ch",
8743        [ALC883_6ST_DIG]        = "alc883-6stack-dig",
8744        [ALC883_TARGA_DIG]      = "targa-dig",
8745        [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
8746        [ALC883_TARGA_8ch_DIG]  = "targa-8ch-dig",
8747        [ALC883_ACER]           = "acer",
8748        [ALC883_ACER_ASPIRE]    = "acer-aspire",
8749        [ALC888_ACER_ASPIRE_4930G]      = "acer-aspire-4930g",
8750        [ALC888_ACER_ASPIRE_6530G]      = "acer-aspire-6530g",
8751        [ALC888_ACER_ASPIRE_8930G]      = "acer-aspire-8930g",
8752        [ALC888_ACER_ASPIRE_7730G]      = "acer-aspire-7730g",
8753        [ALC883_MEDION]         = "medion",
8754        [ALC883_MEDION_MD2]     = "medion-md2",
8755        [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
8756        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8757        [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
8758        [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8759        [ALC888_LENOVO_SKY] = "lenovo-sky",
8760        [ALC883_HAIER_W66]      = "haier-w66",
8761        [ALC888_3ST_HP]         = "3stack-hp",
8762        [ALC888_6ST_DELL]       = "6stack-dell",
8763        [ALC883_MITAC]          = "mitac",
8764        [ALC883_CLEVO_M540R]    = "clevo-m540r",
8765        [ALC883_CLEVO_M720]     = "clevo-m720",
8766        [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8767        [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8768        [ALC883_3ST_6ch_INTEL]  = "3stack-6ch-intel",
8769        [ALC889A_INTEL]         = "intel-alc889a",
8770        [ALC889_INTEL]          = "intel-x58",
8771        [ALC1200_ASUS_P5Q]      = "asus-p5q",
8772        [ALC889A_MB31]          = "mb31",
8773        [ALC883_SONY_VAIO_TT]   = "sony-vaio-tt",
8774        [ALC882_AUTO]           = "auto",
8775};
8776
8777static struct snd_pci_quirk alc882_cfg_tbl[] = {
8778        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8779
8780        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8781        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8782        SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8783        SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8784        SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8785        SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8786        SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8787                ALC888_ACER_ASPIRE_4930G),
8788        SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8789                ALC888_ACER_ASPIRE_4930G),
8790        SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8791                ALC888_ACER_ASPIRE_8930G),
8792        SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8793                ALC888_ACER_ASPIRE_8930G),
8794        SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8795        SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8796        SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8797                ALC888_ACER_ASPIRE_6530G),
8798        SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8799                ALC888_ACER_ASPIRE_6530G),
8800        SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8801                ALC888_ACER_ASPIRE_7730G),
8802        /* default Acer -- disabled as it causes more problems.
8803         *    model=auto should work fine now
8804         */
8805        /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8806
8807        SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8808
8809        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8810        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8811        SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8812        SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8813        SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8814        SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8815
8816        SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8817        SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8818        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8819        SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8820        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8821        SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8822        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8823        SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8824        SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8825        SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8826        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8827
8828        SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8829        SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8830        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8831        SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8832        SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8833        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8834        SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8835        SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8836        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8837
8838        SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8839        SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8840        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8841        SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
8842        SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8843        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8844        SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8845        SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8846        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8847        SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8848        SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8849        SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8850        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8851        SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8852        SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
8853        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8854        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8855        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8856        SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8857        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8858        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8859        SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8860        SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8861        SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8862        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8863        SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8864        SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8865        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8866        SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8867
8868        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8869        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8870        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8871        SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
8872        SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8873        SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8874        /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8875        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8876        SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8877                      ALC883_FUJITSU_PI2515),
8878        SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8879                ALC888_FUJITSU_XA3530),
8880        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8881        SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8882        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8883        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8884        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8885        SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8886        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8887        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8888        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8889
8890        SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8891        SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8892        SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8893        SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8894        SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8895        SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
8896        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8897
8898        {}
8899};
8900
8901/* codec SSID table for Intel Mac */
8902static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8903        SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8904        SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8905        SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8906        SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8907        SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8908        SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8909        SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8910        SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8911        SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8912        SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8913        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8914        /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
8915         * so apparently no perfect solution yet
8916         */
8917        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8918        SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
8919        {} /* terminator */
8920};
8921
8922static struct alc_config_preset alc882_presets[] = {
8923        [ALC882_3ST_DIG] = {
8924                .mixers = { alc882_base_mixer },
8925                .init_verbs = { alc882_base_init_verbs,
8926                                alc882_adc1_init_verbs },
8927                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8928                .dac_nids = alc882_dac_nids,
8929                .dig_out_nid = ALC882_DIGOUT_NID,
8930                .dig_in_nid = ALC882_DIGIN_NID,
8931                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8932                .channel_mode = alc882_ch_modes,
8933                .need_dac_fix = 1,
8934                .input_mux = &alc882_capture_source,
8935        },
8936        [ALC882_6ST_DIG] = {
8937                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8938                .init_verbs = { alc882_base_init_verbs,
8939                                alc882_adc1_init_verbs },
8940                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8941                .dac_nids = alc882_dac_nids,
8942                .dig_out_nid = ALC882_DIGOUT_NID,
8943                .dig_in_nid = ALC882_DIGIN_NID,
8944                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8945                .channel_mode = alc882_sixstack_modes,
8946                .input_mux = &alc882_capture_source,
8947        },
8948        [ALC882_ARIMA] = {
8949                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8950                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8951                                alc882_eapd_verbs },
8952                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8953                .dac_nids = alc882_dac_nids,
8954                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8955                .channel_mode = alc882_sixstack_modes,
8956                .input_mux = &alc882_capture_source,
8957        },
8958        [ALC882_W2JC] = {
8959                .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8960                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8961                                alc882_eapd_verbs, alc880_gpio1_init_verbs },
8962                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8963                .dac_nids = alc882_dac_nids,
8964                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8965                .channel_mode = alc880_threestack_modes,
8966                .need_dac_fix = 1,
8967                .input_mux = &alc882_capture_source,
8968                .dig_out_nid = ALC882_DIGOUT_NID,
8969        },
8970        [ALC885_MBP3] = {
8971                .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8972                .init_verbs = { alc885_mbp3_init_verbs,
8973                                alc880_gpio1_init_verbs },
8974                .num_dacs = 2,
8975                .dac_nids = alc882_dac_nids,
8976                .hp_nid = 0x04,
8977                .channel_mode = alc885_mbp_4ch_modes,
8978                .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
8979                .input_mux = &alc882_capture_source,
8980                .dig_out_nid = ALC882_DIGOUT_NID,
8981                .dig_in_nid = ALC882_DIGIN_NID,
8982                .unsol_event = alc_automute_amp_unsol_event,
8983                .setup = alc885_mbp3_setup,
8984                .init_hook = alc_automute_amp,
8985        },
8986        [ALC885_MB5] = {
8987                .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8988                .init_verbs = { alc885_mb5_init_verbs,
8989                                alc880_gpio1_init_verbs },
8990                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8991                .dac_nids = alc882_dac_nids,
8992                .channel_mode = alc885_mb5_6ch_modes,
8993                .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8994                .input_mux = &mb5_capture_source,
8995                .dig_out_nid = ALC882_DIGOUT_NID,
8996                .dig_in_nid = ALC882_DIGIN_NID,
8997        },
8998        [ALC885_MACPRO] = {
8999                .mixers = { alc882_macpro_mixer },
9000                .init_verbs = { alc882_macpro_init_verbs },
9001                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9002                .dac_nids = alc882_dac_nids,
9003                .dig_out_nid = ALC882_DIGOUT_NID,
9004                .dig_in_nid = ALC882_DIGIN_NID,
9005                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9006                .channel_mode = alc882_ch_modes,
9007                .input_mux = &alc882_capture_source,
9008                .init_hook = alc885_macpro_init_hook,
9009        },
9010        [ALC885_IMAC24] = {
9011                .mixers = { alc885_imac24_mixer },
9012                .init_verbs = { alc885_imac24_init_verbs },
9013                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9014                .dac_nids = alc882_dac_nids,
9015                .dig_out_nid = ALC882_DIGOUT_NID,
9016                .dig_in_nid = ALC882_DIGIN_NID,
9017                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9018                .channel_mode = alc882_ch_modes,
9019                .input_mux = &alc882_capture_source,
9020                .unsol_event = alc_automute_amp_unsol_event,
9021                .setup = alc885_imac24_setup,
9022                .init_hook = alc885_imac24_init_hook,
9023        },
9024        [ALC882_TARGA] = {
9025                .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9026                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9027                                alc880_gpio3_init_verbs, alc882_targa_verbs},
9028                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9029                .dac_nids = alc882_dac_nids,
9030                .dig_out_nid = ALC882_DIGOUT_NID,
9031                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9032                .adc_nids = alc882_adc_nids,
9033                .capsrc_nids = alc882_capsrc_nids,
9034                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9035                .channel_mode = alc882_3ST_6ch_modes,
9036                .need_dac_fix = 1,
9037                .input_mux = &alc882_capture_source,
9038                .unsol_event = alc882_targa_unsol_event,
9039                .setup = alc882_targa_setup,
9040                .init_hook = alc882_targa_automute,
9041        },
9042        [ALC882_ASUS_A7J] = {
9043                .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9044                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9045                                alc882_asus_a7j_verbs},
9046                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9047                .dac_nids = alc882_dac_nids,
9048                .dig_out_nid = ALC882_DIGOUT_NID,
9049                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9050                .adc_nids = alc882_adc_nids,
9051                .capsrc_nids = alc882_capsrc_nids,
9052                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9053                .channel_mode = alc882_3ST_6ch_modes,
9054                .need_dac_fix = 1,
9055                .input_mux = &alc882_capture_source,
9056        },
9057        [ALC882_ASUS_A7M] = {
9058                .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9059                .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9060                                alc882_eapd_verbs, alc880_gpio1_init_verbs,
9061                                alc882_asus_a7m_verbs },
9062                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9063                .dac_nids = alc882_dac_nids,
9064                .dig_out_nid = ALC882_DIGOUT_NID,
9065                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9066                .channel_mode = alc880_threestack_modes,
9067                .need_dac_fix = 1,
9068                .input_mux = &alc882_capture_source,
9069        },
9070        [ALC883_3ST_2ch_DIG] = {
9071                .mixers = { alc883_3ST_2ch_mixer },
9072                .init_verbs = { alc883_init_verbs },
9073                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9074                .dac_nids = alc883_dac_nids,
9075                .dig_out_nid = ALC883_DIGOUT_NID,
9076                .dig_in_nid = ALC883_DIGIN_NID,
9077                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9078                .channel_mode = alc883_3ST_2ch_modes,
9079                .input_mux = &alc883_capture_source,
9080        },
9081        [ALC883_3ST_6ch_DIG] = {
9082                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9083                .init_verbs = { alc883_init_verbs },
9084                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9085                .dac_nids = alc883_dac_nids,
9086                .dig_out_nid = ALC883_DIGOUT_NID,
9087                .dig_in_nid = ALC883_DIGIN_NID,
9088                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9089                .channel_mode = alc883_3ST_6ch_modes,
9090                .need_dac_fix = 1,
9091                .input_mux = &alc883_capture_source,
9092        },
9093        [ALC883_3ST_6ch] = {
9094                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9095                .init_verbs = { alc883_init_verbs },
9096                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9097                .dac_nids = alc883_dac_nids,
9098                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9099                .channel_mode = alc883_3ST_6ch_modes,
9100                .need_dac_fix = 1,
9101                .input_mux = &alc883_capture_source,
9102        },
9103        [ALC883_3ST_6ch_INTEL] = {
9104                .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9105                .init_verbs = { alc883_init_verbs },
9106                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9107                .dac_nids = alc883_dac_nids,
9108                .dig_out_nid = ALC883_DIGOUT_NID,
9109                .dig_in_nid = ALC883_DIGIN_NID,
9110                .slave_dig_outs = alc883_slave_dig_outs,
9111                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9112                .channel_mode = alc883_3ST_6ch_intel_modes,
9113                .need_dac_fix = 1,
9114                .input_mux = &alc883_3stack_6ch_intel,
9115        },
9116        [ALC889A_INTEL] = {
9117                .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9118                .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9119                                alc_hp15_unsol_verbs },
9120                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9121                .dac_nids = alc883_dac_nids,
9122                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9123                .adc_nids = alc889_adc_nids,
9124                .dig_out_nid = ALC883_DIGOUT_NID,
9125                .dig_in_nid = ALC883_DIGIN_NID,
9126                .slave_dig_outs = alc883_slave_dig_outs,
9127                .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9128                .channel_mode = alc889_8ch_intel_modes,
9129                .capsrc_nids = alc889_capsrc_nids,
9130                .input_mux = &alc889_capture_source,
9131                .setup = alc889_automute_setup,
9132                .init_hook = alc_automute_amp,
9133                .unsol_event = alc_automute_amp_unsol_event,
9134                .need_dac_fix = 1,
9135        },
9136        [ALC889_INTEL] = {
9137                .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9138                .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9139                                alc889_eapd_verbs, alc_hp15_unsol_verbs},
9140                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9141                .dac_nids = alc883_dac_nids,
9142                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9143                .adc_nids = alc889_adc_nids,
9144                .dig_out_nid = ALC883_DIGOUT_NID,
9145                .dig_in_nid = ALC883_DIGIN_NID,
9146                .slave_dig_outs = alc883_slave_dig_outs,
9147                .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9148                .channel_mode = alc889_8ch_intel_modes,
9149                .capsrc_nids = alc889_capsrc_nids,
9150                .input_mux = &alc889_capture_source,
9151                .setup = alc889_automute_setup,
9152                .init_hook = alc889_intel_init_hook,
9153                .unsol_event = alc_automute_amp_unsol_event,
9154                .need_dac_fix = 1,
9155        },
9156        [ALC883_6ST_DIG] = {
9157                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9158                .init_verbs = { alc883_init_verbs },
9159                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9160                .dac_nids = alc883_dac_nids,
9161                .dig_out_nid = ALC883_DIGOUT_NID,
9162                .dig_in_nid = ALC883_DIGIN_NID,
9163                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9164                .channel_mode = alc883_sixstack_modes,
9165                .input_mux = &alc883_capture_source,
9166        },
9167        [ALC883_TARGA_DIG] = {
9168                .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9169                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9170                                alc883_targa_verbs},
9171                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9172                .dac_nids = alc883_dac_nids,
9173                .dig_out_nid = ALC883_DIGOUT_NID,
9174                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9175                .channel_mode = alc883_3ST_6ch_modes,
9176                .need_dac_fix = 1,
9177                .input_mux = &alc883_capture_source,
9178                .unsol_event = alc883_targa_unsol_event,
9179                .setup = alc882_targa_setup,
9180                .init_hook = alc882_targa_automute,
9181        },
9182        [ALC883_TARGA_2ch_DIG] = {
9183                .mixers = { alc883_targa_2ch_mixer},
9184                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9185                                alc883_targa_verbs},
9186                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9187                .dac_nids = alc883_dac_nids,
9188                .adc_nids = alc883_adc_nids_alt,
9189                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9190                .dig_out_nid = ALC883_DIGOUT_NID,
9191                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9192                .channel_mode = alc883_3ST_2ch_modes,
9193                .input_mux = &alc883_capture_source,
9194                .unsol_event = alc883_targa_unsol_event,
9195                .setup = alc882_targa_setup,
9196                .init_hook = alc882_targa_automute,
9197        },
9198        [ALC883_TARGA_8ch_DIG] = {
9199                .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9200                            alc883_chmode_mixer },
9201                .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9202                                alc883_targa_verbs },
9203                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9204                .dac_nids = alc883_dac_nids,
9205                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9206                .adc_nids = alc883_adc_nids_rev,
9207                .capsrc_nids = alc883_capsrc_nids_rev,
9208                .dig_out_nid = ALC883_DIGOUT_NID,
9209                .dig_in_nid = ALC883_DIGIN_NID,
9210                .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9211                .channel_mode = alc883_4ST_8ch_modes,
9212                .need_dac_fix = 1,
9213                .input_mux = &alc883_capture_source,
9214                .unsol_event = alc883_targa_unsol_event,
9215                .setup = alc882_targa_setup,
9216                .init_hook = alc882_targa_automute,
9217        },
9218        [ALC883_ACER] = {
9219                .mixers = { alc883_base_mixer },
9220                /* On TravelMate laptops, GPIO 0 enables the internal speaker
9221                 * and the headphone jack.  Turn this on and rely on the
9222                 * standard mute methods whenever the user wants to turn
9223                 * these outputs off.
9224                 */
9225                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9226                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9227                .dac_nids = alc883_dac_nids,
9228                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9229                .channel_mode = alc883_3ST_2ch_modes,
9230                .input_mux = &alc883_capture_source,
9231        },
9232        [ALC883_ACER_ASPIRE] = {
9233                .mixers = { alc883_acer_aspire_mixer },
9234                .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9235                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9236                .dac_nids = alc883_dac_nids,
9237                .dig_out_nid = ALC883_DIGOUT_NID,
9238                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9239                .channel_mode = alc883_3ST_2ch_modes,
9240                .input_mux = &alc883_capture_source,
9241                .unsol_event = alc_automute_amp_unsol_event,
9242                .setup = alc883_acer_aspire_setup,
9243                .init_hook = alc_automute_amp,
9244        },
9245        [ALC888_ACER_ASPIRE_4930G] = {
9246                .mixers = { alc888_base_mixer,
9247                                alc883_chmode_mixer },
9248                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9249                                alc888_acer_aspire_4930g_verbs },
9250                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9251                .dac_nids = alc883_dac_nids,
9252                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9253                .adc_nids = alc883_adc_nids_rev,
9254                .capsrc_nids = alc883_capsrc_nids_rev,
9255                .dig_out_nid = ALC883_DIGOUT_NID,
9256                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9257                .channel_mode = alc883_3ST_6ch_modes,
9258                .need_dac_fix = 1,
9259                .num_mux_defs =
9260                        ARRAY_SIZE(alc888_2_capture_sources),
9261                .input_mux = alc888_2_capture_sources,
9262                .unsol_event = alc_automute_amp_unsol_event,
9263                .setup = alc888_acer_aspire_4930g_setup,
9264                .init_hook = alc_automute_amp,
9265        },
9266        [ALC888_ACER_ASPIRE_6530G] = {
9267                .mixers = { alc888_acer_aspire_6530_mixer },
9268                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9269                                alc888_acer_aspire_6530g_verbs },
9270                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9271                .dac_nids = alc883_dac_nids,
9272                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9273                .adc_nids = alc883_adc_nids_rev,
9274                .capsrc_nids = alc883_capsrc_nids_rev,
9275                .dig_out_nid = ALC883_DIGOUT_NID,
9276                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9277                .channel_mode = alc883_3ST_2ch_modes,
9278                .num_mux_defs =
9279                        ARRAY_SIZE(alc888_2_capture_sources),
9280                .input_mux = alc888_acer_aspire_6530_sources,
9281                .unsol_event = alc_automute_amp_unsol_event,
9282                .setup = alc888_acer_aspire_6530g_setup,
9283                .init_hook = alc_automute_amp,
9284        },
9285        [ALC888_ACER_ASPIRE_8930G] = {
9286                .mixers = { alc888_base_mixer,
9287                                alc883_chmode_mixer },
9288                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9289                                alc889_acer_aspire_8930g_verbs },
9290                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9291                .dac_nids = alc883_dac_nids,
9292                .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9293                .adc_nids = alc889_adc_nids,
9294                .capsrc_nids = alc889_capsrc_nids,
9295                .dig_out_nid = ALC883_DIGOUT_NID,
9296                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9297                .channel_mode = alc883_3ST_6ch_modes,
9298                .need_dac_fix = 1,
9299                .const_channel_count = 6,
9300                .num_mux_defs =
9301                        ARRAY_SIZE(alc889_capture_sources),
9302                .input_mux = alc889_capture_sources,
9303                .unsol_event = alc_automute_amp_unsol_event,
9304                .setup = alc889_acer_aspire_8930g_setup,
9305                .init_hook = alc_automute_amp,
9306        },
9307        [ALC888_ACER_ASPIRE_7730G] = {
9308                .mixers = { alc883_3ST_6ch_mixer,
9309                                alc883_chmode_mixer },
9310                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9311                                alc888_acer_aspire_7730G_verbs },
9312                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9313                .dac_nids = alc883_dac_nids,
9314                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9315                .adc_nids = alc883_adc_nids_rev,
9316                .capsrc_nids = alc883_capsrc_nids_rev,
9317                .dig_out_nid = ALC883_DIGOUT_NID,
9318                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9319                .channel_mode = alc883_3ST_6ch_modes,
9320                .need_dac_fix = 1,
9321                .const_channel_count = 6,
9322                .input_mux = &alc883_capture_source,
9323                .unsol_event = alc_automute_amp_unsol_event,
9324                .setup = alc888_acer_aspire_6530g_setup,
9325                .init_hook = alc_automute_amp,
9326        },
9327        [ALC883_MEDION] = {
9328                .mixers = { alc883_fivestack_mixer,
9329                            alc883_chmode_mixer },
9330                .init_verbs = { alc883_init_verbs,
9331                                alc883_medion_eapd_verbs },
9332                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9333                .dac_nids = alc883_dac_nids,
9334                .adc_nids = alc883_adc_nids_alt,
9335                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9336                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9337                .channel_mode = alc883_sixstack_modes,
9338                .input_mux = &alc883_capture_source,
9339        },
9340        [ALC883_MEDION_MD2] = {
9341                .mixers = { alc883_medion_md2_mixer},
9342                .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9343                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9344                .dac_nids = alc883_dac_nids,
9345                .dig_out_nid = ALC883_DIGOUT_NID,
9346                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9347                .channel_mode = alc883_3ST_2ch_modes,
9348                .input_mux = &alc883_capture_source,
9349                .unsol_event = alc_automute_amp_unsol_event,
9350                .setup = alc883_medion_md2_setup,
9351                .init_hook = alc_automute_amp,
9352        },
9353        [ALC883_LAPTOP_EAPD] = {
9354                .mixers = { alc883_base_mixer },
9355                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9356                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9357                .dac_nids = alc883_dac_nids,
9358                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9359                .channel_mode = alc883_3ST_2ch_modes,
9360                .input_mux = &alc883_capture_source,
9361        },
9362        [ALC883_CLEVO_M540R] = {
9363                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9364                .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9365                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9366                .dac_nids = alc883_dac_nids,
9367                .dig_out_nid = ALC883_DIGOUT_NID,
9368                .dig_in_nid = ALC883_DIGIN_NID,
9369                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9370                .channel_mode = alc883_3ST_6ch_clevo_modes,
9371                .need_dac_fix = 1,
9372                .input_mux = &alc883_capture_source,
9373                /* This machine has the hardware HP auto-muting, thus
9374                 * we need no software mute via unsol event
9375                 */
9376        },
9377        [ALC883_CLEVO_M720] = {
9378                .mixers = { alc883_clevo_m720_mixer },
9379                .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9380                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9381                .dac_nids = alc883_dac_nids,
9382                .dig_out_nid = ALC883_DIGOUT_NID,
9383                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9384                .channel_mode = alc883_3ST_2ch_modes,
9385                .input_mux = &alc883_capture_source,
9386                .unsol_event = alc883_clevo_m720_unsol_event,
9387                .setup = alc883_clevo_m720_setup,
9388                .init_hook = alc883_clevo_m720_init_hook,
9389        },
9390        [ALC883_LENOVO_101E_2ch] = {
9391                .mixers = { alc883_lenovo_101e_2ch_mixer},
9392                .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9393                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9394                .dac_nids = alc883_dac_nids,
9395                .adc_nids = alc883_adc_nids_alt,
9396                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9397                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9398                .channel_mode = alc883_3ST_2ch_modes,
9399                .input_mux = &alc883_lenovo_101e_capture_source,
9400                .unsol_event = alc883_lenovo_101e_unsol_event,
9401                .init_hook = alc883_lenovo_101e_all_automute,
9402        },
9403        [ALC883_LENOVO_NB0763] = {
9404                .mixers = { alc883_lenovo_nb0763_mixer },
9405                .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9406                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9407                .dac_nids = alc883_dac_nids,
9408                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9409                .channel_mode = alc883_3ST_2ch_modes,
9410                .need_dac_fix = 1,
9411                .input_mux = &alc883_lenovo_nb0763_capture_source,
9412                .unsol_event = alc_automute_amp_unsol_event,
9413                .setup = alc883_medion_md2_setup,
9414                .init_hook = alc_automute_amp,
9415        },
9416        [ALC888_LENOVO_MS7195_DIG] = {
9417                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9418                .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9419                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9420                .dac_nids = alc883_dac_nids,
9421                .dig_out_nid = ALC883_DIGOUT_NID,
9422                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9423                .channel_mode = alc883_3ST_6ch_modes,
9424                .need_dac_fix = 1,
9425                .input_mux = &alc883_capture_source,
9426                .unsol_event = alc883_lenovo_ms7195_unsol_event,
9427                .init_hook = alc888_lenovo_ms7195_front_automute,
9428        },
9429        [ALC883_HAIER_W66] = {
9430                .mixers = { alc883_targa_2ch_mixer},
9431                .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9432                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9433                .dac_nids = alc883_dac_nids,
9434                .dig_out_nid = ALC883_DIGOUT_NID,
9435                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9436                .channel_mode = alc883_3ST_2ch_modes,
9437                .input_mux = &alc883_capture_source,
9438                .unsol_event = alc_automute_amp_unsol_event,
9439                .setup = alc883_haier_w66_setup,
9440                .init_hook = alc_automute_amp,
9441        },
9442        [ALC888_3ST_HP] = {
9443                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9444                .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9445                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9446                .dac_nids = alc883_dac_nids,
9447                .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9448                .channel_mode = alc888_3st_hp_modes,
9449                .need_dac_fix = 1,
9450                .input_mux = &alc883_capture_source,
9451                .unsol_event = alc_automute_amp_unsol_event,
9452                .setup = alc888_3st_hp_setup,
9453                .init_hook = alc_automute_amp,
9454        },
9455        [ALC888_6ST_DELL] = {
9456                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9457                .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9458                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9459                .dac_nids = alc883_dac_nids,
9460                .dig_out_nid = ALC883_DIGOUT_NID,
9461                .dig_in_nid = ALC883_DIGIN_NID,
9462                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9463                .channel_mode = alc883_sixstack_modes,
9464                .input_mux = &alc883_capture_source,
9465                .unsol_event = alc_automute_amp_unsol_event,
9466                .setup = alc888_6st_dell_setup,
9467                .init_hook = alc_automute_amp,
9468        },
9469        [ALC883_MITAC] = {
9470                .mixers = { alc883_mitac_mixer },
9471                .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9472                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9473                .dac_nids = alc883_dac_nids,
9474                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9475                .channel_mode = alc883_3ST_2ch_modes,
9476                .input_mux = &alc883_capture_source,
9477                .unsol_event = alc_automute_amp_unsol_event,
9478                .setup = alc883_mitac_setup,
9479                .init_hook = alc_automute_amp,
9480        },
9481        [ALC883_FUJITSU_PI2515] = {
9482                .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9483                .init_verbs = { alc883_init_verbs,
9484                                alc883_2ch_fujitsu_pi2515_verbs},
9485                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9486                .dac_nids = alc883_dac_nids,
9487                .dig_out_nid = ALC883_DIGOUT_NID,
9488                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9489                .channel_mode = alc883_3ST_2ch_modes,
9490                .input_mux = &alc883_fujitsu_pi2515_capture_source,
9491                .unsol_event = alc_automute_amp_unsol_event,
9492                .setup = alc883_2ch_fujitsu_pi2515_setup,
9493                .init_hook = alc_automute_amp,
9494        },
9495        [ALC888_FUJITSU_XA3530] = {
9496                .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9497                .init_verbs = { alc883_init_verbs,
9498                        alc888_fujitsu_xa3530_verbs },
9499                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9500                .dac_nids = alc883_dac_nids,
9501                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9502                .adc_nids = alc883_adc_nids_rev,
9503                .capsrc_nids = alc883_capsrc_nids_rev,
9504                .dig_out_nid = ALC883_DIGOUT_NID,
9505                .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9506                .channel_mode = alc888_4ST_8ch_intel_modes,
9507                .num_mux_defs =
9508                        ARRAY_SIZE(alc888_2_capture_sources),
9509                .input_mux = alc888_2_capture_sources,
9510                .unsol_event = alc_automute_amp_unsol_event,
9511                .setup = alc888_fujitsu_xa3530_setup,
9512                .init_hook = alc_automute_amp,
9513        },
9514        [ALC888_LENOVO_SKY] = {
9515                .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9516                .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9517                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9518                .dac_nids = alc883_dac_nids,
9519                .dig_out_nid = ALC883_DIGOUT_NID,
9520                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9521                .channel_mode = alc883_sixstack_modes,
9522                .need_dac_fix = 1,
9523                .input_mux = &alc883_lenovo_sky_capture_source,
9524                .unsol_event = alc_automute_amp_unsol_event,
9525                .setup = alc888_lenovo_sky_setup,
9526                .init_hook = alc_automute_amp,
9527        },
9528        [ALC888_ASUS_M90V] = {
9529                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9530                .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9531                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9532                .dac_nids = alc883_dac_nids,
9533                .dig_out_nid = ALC883_DIGOUT_NID,
9534                .dig_in_nid = ALC883_DIGIN_NID,
9535                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9536                .channel_mode = alc883_3ST_6ch_modes,
9537                .need_dac_fix = 1,
9538                .input_mux = &alc883_fujitsu_pi2515_capture_source,
9539                .unsol_event = alc_sku_unsol_event,
9540                .setup = alc883_mode2_setup,
9541                .init_hook = alc_inithook,
9542        },
9543        [ALC888_ASUS_EEE1601] = {
9544                .mixers = { alc883_asus_eee1601_mixer },
9545                .cap_mixer = alc883_asus_eee1601_cap_mixer,
9546                .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9547                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9548                .dac_nids = alc883_dac_nids,
9549                .dig_out_nid = ALC883_DIGOUT_NID,
9550                .dig_in_nid = ALC883_DIGIN_NID,
9551                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9552                .channel_mode = alc883_3ST_2ch_modes,
9553                .need_dac_fix = 1,
9554                .input_mux = &alc883_asus_eee1601_capture_source,
9555                .unsol_event = alc_sku_unsol_event,
9556                .init_hook = alc883_eee1601_inithook,
9557        },
9558        [ALC1200_ASUS_P5Q] = {
9559                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9560                .init_verbs = { alc883_init_verbs },
9561                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9562                .dac_nids = alc883_dac_nids,
9563                .dig_out_nid = ALC1200_DIGOUT_NID,
9564                .dig_in_nid = ALC883_DIGIN_NID,
9565                .slave_dig_outs = alc1200_slave_dig_outs,
9566                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9567                .channel_mode = alc883_sixstack_modes,
9568                .input_mux = &alc883_capture_source,
9569        },
9570        [ALC889A_MB31] = {
9571                .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9572                .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9573                        alc880_gpio1_init_verbs },
9574                .adc_nids = alc883_adc_nids,
9575                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9576                .dac_nids = alc883_dac_nids,
9577                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9578                .channel_mode = alc889A_mb31_6ch_modes,
9579                .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9580                .input_mux = &alc889A_mb31_capture_source,
9581                .dig_out_nid = ALC883_DIGOUT_NID,
9582                .unsol_event = alc889A_mb31_unsol_event,
9583                .init_hook = alc889A_mb31_automute,
9584        },
9585        [ALC883_SONY_VAIO_TT] = {
9586                .mixers = { alc883_vaiott_mixer },
9587                .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9588                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9589                .dac_nids = alc883_dac_nids,
9590                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9591                .channel_mode = alc883_3ST_2ch_modes,
9592                .input_mux = &alc883_capture_source,
9593                .unsol_event = alc_automute_amp_unsol_event,
9594                .setup = alc883_vaiott_setup,
9595                .init_hook = alc_automute_amp,
9596        },
9597};
9598
9599
9600/*
9601 * Pin config fixes
9602 */
9603enum {
9604        PINFIX_ABIT_AW9D_MAX
9605};
9606
9607static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9608        { 0x15, 0x01080104 }, /* side */
9609        { 0x16, 0x01011012 }, /* rear */
9610        { 0x17, 0x01016011 }, /* clfe */
9611        { }
9612};
9613
9614static const struct alc_fixup alc882_fixups[] = {
9615        [PINFIX_ABIT_AW9D_MAX] = {
9616                .pins = alc882_abit_aw9d_pinfix
9617        },
9618};
9619
9620static struct snd_pci_quirk alc882_fixup_tbl[] = {
9621        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9622        {}
9623};
9624
9625/*
9626 * BIOS auto configuration
9627 */
9628static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9629                                                const struct auto_pin_cfg *cfg)
9630{
9631        return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9632}
9633
9634static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9635                                              hda_nid_t nid, int pin_type,
9636                                              int dac_idx)
9637{
9638        /* set as output */
9639        struct alc_spec *spec = codec->spec;
9640        int idx;
9641
9642        alc_set_pin_output(codec, nid, pin_type);
9643        if (spec->multiout.dac_nids[dac_idx] == 0x25)
9644                idx = 4;
9645        else
9646                idx = spec->multiout.dac_nids[dac_idx] - 2;
9647        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9648
9649}
9650
9651static void alc882_auto_init_multi_out(struct hda_codec *codec)
9652{
9653        struct alc_spec *spec = codec->spec;
9654        int i;
9655
9656        for (i = 0; i <= HDA_SIDE; i++) {
9657                hda_nid_t nid = spec->autocfg.line_out_pins[i];
9658                int pin_type = get_pin_type(spec->autocfg.line_out_type);
9659                if (nid)
9660                        alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9661                                                          i);
9662        }
9663}
9664
9665static void alc882_auto_init_hp_out(struct hda_codec *codec)
9666{
9667        struct alc_spec *spec = codec->spec;
9668        hda_nid_t pin;
9669
9670        pin = spec->autocfg.hp_pins[0];
9671        if (pin) /* connect to front */
9672                /* use dac 0 */
9673                alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9674        pin = spec->autocfg.speaker_pins[0];
9675        if (pin)
9676                alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9677}
9678
9679static void alc882_auto_init_analog_input(struct hda_codec *codec)
9680{
9681        struct alc_spec *spec = codec->spec;
9682        int i;
9683
9684        for (i = 0; i < AUTO_PIN_LAST; i++) {
9685                hda_nid_t nid = spec->autocfg.input_pins[i];
9686                if (!nid)
9687                        continue;
9688                alc_set_input_pin(codec, nid, i);
9689                if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9690                        snd_hda_codec_write(codec, nid, 0,
9691                                            AC_VERB_SET_AMP_GAIN_MUTE,
9692                                            AMP_OUT_MUTE);
9693        }
9694}
9695
9696static void alc882_auto_init_input_src(struct hda_codec *codec)
9697{
9698        struct alc_spec *spec = codec->spec;
9699        int c;
9700
9701        for (c = 0; c < spec->num_adc_nids; c++) {
9702                hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9703                hda_nid_t nid = spec->capsrc_nids[c];
9704                unsigned int mux_idx;
9705                const struct hda_input_mux *imux;
9706                int conns, mute, idx, item;
9707
9708                conns = snd_hda_get_connections(codec, nid, conn_list,
9709                                                ARRAY_SIZE(conn_list));
9710                if (conns < 0)
9711                        continue;
9712                mux_idx = c >= spec->num_mux_defs ? 0 : c;
9713                imux = &spec->input_mux[mux_idx];
9714                for (idx = 0; idx < conns; idx++) {
9715                        /* if the current connection is the selected one,
9716                         * unmute it as default - otherwise mute it
9717                         */
9718                        mute = AMP_IN_MUTE(idx);
9719                        for (item = 0; item < imux->num_items; item++) {
9720                                if (imux->items[item].index == idx) {
9721                                        if (spec->cur_mux[c] == item)
9722                                                mute = AMP_IN_UNMUTE(idx);
9723                                        break;
9724                                }
9725                        }
9726                        /* check if we have a selector or mixer
9727                         * we could check for the widget type instead, but
9728                         * just check for Amp-In presence (in case of mixer
9729                         * without amp-in there is something wrong, this
9730                         * function shouldn't be used or capsrc nid is wrong)
9731                         */
9732                        if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9733                                snd_hda_codec_write(codec, nid, 0,
9734                                                    AC_VERB_SET_AMP_GAIN_MUTE,
9735                                                    mute);
9736                        else if (mute != AMP_IN_MUTE(idx))
9737                                snd_hda_codec_write(codec, nid, 0,
9738                                                    AC_VERB_SET_CONNECT_SEL,
9739                                                    idx);
9740                }
9741        }
9742}
9743
9744/* add mic boosts if needed */
9745static int alc_auto_add_mic_boost(struct hda_codec *codec)
9746{
9747        struct alc_spec *spec = codec->spec;
9748        int err;
9749        hda_nid_t nid;
9750
9751        nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9752        if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9753                err = add_control(spec, ALC_CTL_WIDGET_VOL,
9754                                  "Mic Boost",
9755                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9756                if (err < 0)
9757                        return err;
9758        }
9759        nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9760        if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9761                err = add_control(spec, ALC_CTL_WIDGET_VOL,
9762                                  "Front Mic Boost",
9763                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9764                if (err < 0)
9765                        return err;
9766        }
9767        return 0;
9768}
9769
9770/* almost identical with ALC880 parser... */
9771static int alc882_parse_auto_config(struct hda_codec *codec)
9772{
9773        struct alc_spec *spec = codec->spec;
9774        static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9775        int i, err;
9776
9777        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9778                                           alc882_ignore);
9779        if (err < 0)
9780                return err;
9781        if (!spec->autocfg.line_outs)
9782                return 0; /* can't find valid BIOS pin config */
9783
9784        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9785        if (err < 0)
9786                return err;
9787        err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9788        if (err < 0)
9789                return err;
9790        err = alc880_auto_create_extra_out(spec,
9791                                           spec->autocfg.speaker_pins[0],
9792                                           "Speaker");
9793        if (err < 0)
9794                return err;
9795        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9796                                           "Headphone");
9797        if (err < 0)
9798                return err;
9799        err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
9800        if (err < 0)
9801                return err;
9802
9803        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9804
9805        /* check multiple SPDIF-out (for recent codecs) */
9806        for (i = 0; i < spec->autocfg.dig_outs; i++) {
9807                hda_nid_t dig_nid;
9808                err = snd_hda_get_connections(codec,
9809                                              spec->autocfg.dig_out_pins[i],
9810                                              &dig_nid, 1);
9811                if (err < 0)
9812                        continue;
9813                if (!i)
9814                        spec->multiout.dig_out_nid = dig_nid;
9815                else {
9816                        spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9817                        if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
9818                                break;
9819                        spec->slave_dig_outs[i - 1] = dig_nid;
9820                }
9821        }
9822        if (spec->autocfg.dig_in_pin)
9823                spec->dig_in_nid = ALC880_DIGIN_NID;
9824
9825        if (spec->kctls.list)
9826                add_mixer(spec, spec->kctls.list);
9827
9828        add_verb(spec, alc883_auto_init_verbs);
9829        /* if ADC 0x07 is available, initialize it, too */
9830        if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
9831                add_verb(spec, alc882_adc1_init_verbs);
9832
9833        spec->num_mux_defs = 1;
9834        spec->input_mux = &spec->private_imux[0];
9835
9836        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9837
9838        err = alc_auto_add_mic_boost(codec);
9839        if (err < 0)
9840                return err;
9841
9842        return 1; /* config found */
9843}
9844
9845/* additional initialization for auto-configuration model */
9846static void alc882_auto_init(struct hda_codec *codec)
9847{
9848        struct alc_spec *spec = codec->spec;
9849        alc882_auto_init_multi_out(codec);
9850        alc882_auto_init_hp_out(codec);
9851        alc882_auto_init_analog_input(codec);
9852        alc882_auto_init_input_src(codec);
9853        if (spec->unsol_event)
9854                alc_inithook(codec);
9855}
9856
9857static int patch_alc882(struct hda_codec *codec)
9858{
9859        struct alc_spec *spec;
9860        int err, board_config;
9861
9862        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9863        if (spec == NULL)
9864                return -ENOMEM;
9865
9866        codec->spec = spec;
9867
9868        switch (codec->vendor_id) {
9869        case 0x10ec0882:
9870        case 0x10ec0885:
9871                break;
9872        default:
9873                /* ALC883 and variants */
9874                alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9875                break;
9876        }
9877
9878        board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9879                                                  alc882_models,
9880                                                  alc882_cfg_tbl);
9881
9882        if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9883                board_config = snd_hda_check_board_codec_sid_config(codec,
9884                        ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9885
9886        if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9887                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9888                       codec->chip_name);
9889                board_config = ALC882_AUTO;
9890        }
9891
9892        alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9893
9894        if (board_config == ALC882_AUTO) {
9895                /* automatic parse from the BIOS config */
9896                err = alc882_parse_auto_config(codec);
9897                if (err < 0) {
9898                        alc_free(codec);
9899                        return err;
9900                } else if (!err) {
9901                        printk(KERN_INFO
9902                               "hda_codec: Cannot set up configuration "
9903                               "from BIOS.  Using base mode...\n");
9904                        board_config = ALC882_3ST_DIG;
9905                }
9906        }
9907
9908        err = snd_hda_attach_beep_device(codec, 0x1);
9909        if (err < 0) {
9910                alc_free(codec);
9911                return err;
9912        }
9913
9914        if (board_config != ALC882_AUTO)
9915                setup_preset(codec, &alc882_presets[board_config]);
9916
9917        spec->stream_analog_playback = &alc882_pcm_analog_playback;
9918        spec->stream_analog_capture = &alc882_pcm_analog_capture;
9919        /* FIXME: setup DAC5 */
9920        /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9921        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9922
9923        spec->stream_digital_playback = &alc882_pcm_digital_playback;
9924        spec->stream_digital_capture = &alc882_pcm_digital_capture;
9925
9926        if (codec->vendor_id == 0x10ec0888)
9927                spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9928
9929        if (!spec->adc_nids && spec->input_mux) {
9930                int i;
9931                spec->num_adc_nids = 0;
9932                for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9933                        hda_nid_t cap;
9934                        hda_nid_t nid = alc882_adc_nids[i];
9935                        unsigned int wcap = get_wcaps(codec, nid);
9936                        /* get type */
9937                        wcap = get_wcaps_type(wcap);
9938                        if (wcap != AC_WID_AUD_IN)
9939                                continue;
9940                        spec->private_adc_nids[spec->num_adc_nids] = nid;
9941                        err = snd_hda_get_connections(codec, nid, &cap, 1);
9942                        if (err < 0)
9943                                continue;
9944                        spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9945                        spec->num_adc_nids++;
9946                }
9947                spec->adc_nids = spec->private_adc_nids;
9948                spec->capsrc_nids = spec->private_capsrc_nids;
9949        }
9950
9951        set_capture_mixer(codec);
9952        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9953
9954        spec->vmaster_nid = 0x0c;
9955
9956        codec->patch_ops = alc_patch_ops;
9957        if (board_config == ALC882_AUTO)
9958                spec->init_hook = alc882_auto_init;
9959#ifdef CONFIG_SND_HDA_POWER_SAVE
9960        if (!spec->loopback.amplist)
9961                spec->loopback.amplist = alc882_loopbacks;
9962#endif
9963        codec->proc_widget_hook = print_realtek_coef;
9964
9965        return 0;
9966}
9967
9968
9969/*
9970 * ALC262 support
9971 */
9972
9973#define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
9974#define ALC262_DIGIN_NID        ALC880_DIGIN_NID
9975
9976#define alc262_dac_nids         alc260_dac_nids
9977#define alc262_adc_nids         alc882_adc_nids
9978#define alc262_adc_nids_alt     alc882_adc_nids_alt
9979#define alc262_capsrc_nids      alc882_capsrc_nids
9980#define alc262_capsrc_nids_alt  alc882_capsrc_nids_alt
9981
9982#define alc262_modes            alc260_modes
9983#define alc262_capture_source   alc882_capture_source
9984
9985static hda_nid_t alc262_dmic_adc_nids[1] = {
9986        /* ADC0 */
9987        0x09
9988};
9989
9990static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9991
9992static struct snd_kcontrol_new alc262_base_mixer[] = {
9993        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9994        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9995        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9996        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9997        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9998        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9999        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10000        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10001        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10002        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10003        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10004        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10005        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10006        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10007        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10008        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10009        { } /* end */
10010};
10011
10012/* update HP, line and mono-out pins according to the master switch */
10013static void alc262_hp_master_update(struct hda_codec *codec)
10014{
10015        struct alc_spec *spec = codec->spec;
10016        int val = spec->master_sw;
10017
10018        /* HP & line-out */
10019        snd_hda_codec_write_cache(codec, 0x1b, 0,
10020                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
10021                                  val ? PIN_HP : 0);
10022        snd_hda_codec_write_cache(codec, 0x15, 0,
10023                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
10024                                  val ? PIN_HP : 0);
10025        /* mono (speaker) depending on the HP jack sense */
10026        val = val && !spec->jack_present;
10027        snd_hda_codec_write_cache(codec, 0x16, 0,
10028                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
10029                                  val ? PIN_OUT : 0);
10030}
10031
10032static void alc262_hp_bpc_automute(struct hda_codec *codec)
10033{
10034        struct alc_spec *spec = codec->spec;
10035        unsigned int presence;
10036        presence = snd_hda_codec_read(codec, 0x1b, 0,
10037                                      AC_VERB_GET_PIN_SENSE, 0);
10038        spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10039        alc262_hp_master_update(codec);
10040}
10041
10042static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10043{
10044        if ((res >> 26) != ALC880_HP_EVENT)
10045                return;
10046        alc262_hp_bpc_automute(codec);
10047}
10048
10049static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10050{
10051        struct alc_spec *spec = codec->spec;
10052        unsigned int presence;
10053        presence = snd_hda_codec_read(codec, 0x15, 0,
10054                                      AC_VERB_GET_PIN_SENSE, 0);
10055        spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10056        alc262_hp_master_update(codec);
10057}
10058
10059static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10060                                           unsigned int res)
10061{
10062        if ((res >> 26) != ALC880_HP_EVENT)
10063                return;
10064        alc262_hp_wildwest_automute(codec);
10065}
10066
10067#define alc262_hp_master_sw_get         alc260_hp_master_sw_get
10068
10069static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10070                                   struct snd_ctl_elem_value *ucontrol)
10071{
10072        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10073        struct alc_spec *spec = codec->spec;
10074        int val = !!*ucontrol->value.integer.value;
10075
10076        if (val == spec->master_sw)
10077                return 0;
10078        spec->master_sw = val;
10079        alc262_hp_master_update(codec);
10080        return 1;
10081}
10082
10083#define ALC262_HP_MASTER_SWITCH                                 \
10084        {                                                       \
10085                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
10086                .name = "Master Playback Switch",               \
10087                .info = snd_ctl_boolean_mono_info,              \
10088                .get = alc262_hp_master_sw_get,                 \
10089                .put = alc262_hp_master_sw_put,                 \
10090        }
10091
10092static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10093        ALC262_HP_MASTER_SWITCH,
10094        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10095        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10096        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10097        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10098                              HDA_OUTPUT),
10099        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10100                            HDA_OUTPUT),
10101        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10102        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10103        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10104        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10105        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10106        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10107        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10108        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10109        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10110        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10111        HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10112        HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10113        { } /* end */
10114};
10115
10116static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10117        ALC262_HP_MASTER_SWITCH,
10118        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10119        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10120        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10121        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10122        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10123                              HDA_OUTPUT),
10124        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10125                            HDA_OUTPUT),
10126        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10127        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10128        HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10129        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10130        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10131        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10132        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10133        { } /* end */
10134};
10135
10136static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10137        HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10138        HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10139        HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10140        { } /* end */
10141};
10142
10143/* mute/unmute internal speaker according to the hp jack and mute state */
10144static void alc262_hp_t5735_setup(struct hda_codec *codec)
10145{
10146        struct alc_spec *spec = codec->spec;
10147
10148        spec->autocfg.hp_pins[0] = 0x15;
10149        spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
10150}
10151
10152static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10153        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10154        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10155        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10156        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10157        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10158        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10159        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10160        { } /* end */
10161};
10162
10163static struct hda_verb alc262_hp_t5735_verbs[] = {
10164        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10165        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10166
10167        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10168        { }
10169};
10170
10171static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10172        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10173        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10174        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10175        HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10176        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10177        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10178        { } /* end */
10179};
10180
10181static struct hda_verb alc262_hp_rp5700_verbs[] = {
10182        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10183        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10184        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10185        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10186        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10187        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10188        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10189        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10190        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10191        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10192        {}
10193};
10194
10195static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10196        .num_items = 1,
10197        .items = {
10198                { "Line", 0x1 },
10199        },
10200};
10201
10202/* bind hp and internal speaker mute (with plug check) as master switch */
10203static void alc262_hippo_master_update(struct hda_codec *codec)
10204{
10205        struct alc_spec *spec = codec->spec;
10206        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10207        hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10208        hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10209        unsigned int mute;
10210
10211        /* HP */
10212        mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10213        snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10214                                 HDA_AMP_MUTE, mute);
10215        /* mute internal speaker per jack sense */
10216        if (spec->jack_present)
10217                mute = HDA_AMP_MUTE;
10218        if (line_nid)
10219                snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10220                                         HDA_AMP_MUTE, mute);
10221        if (speaker_nid && speaker_nid != line_nid)
10222                snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10223                                         HDA_AMP_MUTE, mute);
10224}
10225
10226#define alc262_hippo_master_sw_get      alc262_hp_master_sw_get
10227
10228static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10229                                      struct snd_ctl_elem_value *ucontrol)
10230{
10231        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10232        struct alc_spec *spec = codec->spec;
10233        int val = !!*ucontrol->value.integer.value;
10234
10235        if (val == spec->master_sw)
10236                return 0;
10237        spec->master_sw = val;
10238        alc262_hippo_master_update(codec);
10239        return 1;
10240}
10241
10242#define ALC262_HIPPO_MASTER_SWITCH                              \
10243        {                                                       \
10244                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
10245                .name = "Master Playback Switch",               \
10246                .info = snd_ctl_boolean_mono_info,              \
10247                .get = alc262_hippo_master_sw_get,              \
10248                .put = alc262_hippo_master_sw_put,              \
10249        }
10250
10251static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10252        ALC262_HIPPO_MASTER_SWITCH,
10253        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10254        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10255        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10256        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10257        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10258        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10259        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10260        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10261        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10262        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10263        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10264        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10265        { } /* end */
10266};
10267
10268static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10269        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10270        ALC262_HIPPO_MASTER_SWITCH,
10271        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10272        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10273        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10274        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10275        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10276        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10277        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10278        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10279        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10280        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10281        { } /* end */
10282};
10283
10284/* mute/unmute internal speaker according to the hp jack and mute state */
10285static void alc262_hippo_automute(struct hda_codec *codec)
10286{
10287        struct alc_spec *spec = codec->spec;
10288        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10289        unsigned int present;
10290
10291        /* need to execute and sync at first */
10292        snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10293        present = snd_hda_codec_read(codec, hp_nid, 0,
10294                                     AC_VERB_GET_PIN_SENSE, 0);
10295        spec->jack_present = (present & 0x80000000) != 0;
10296        alc262_hippo_master_update(codec);
10297}
10298
10299static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10300{
10301        if ((res >> 26) != ALC880_HP_EVENT)
10302                return;
10303        alc262_hippo_automute(codec);
10304}
10305
10306static void alc262_hippo_setup(struct hda_codec *codec)
10307{
10308        struct alc_spec *spec = codec->spec;
10309
10310        spec->autocfg.hp_pins[0] = 0x15;
10311        spec->autocfg.speaker_pins[0] = 0x14;
10312}
10313
10314static void alc262_hippo1_setup(struct hda_codec *codec)
10315{
10316        struct alc_spec *spec = codec->spec;
10317
10318        spec->autocfg.hp_pins[0] = 0x1b;
10319        spec->autocfg.speaker_pins[0] = 0x14;
10320}
10321
10322
10323static struct snd_kcontrol_new alc262_sony_mixer[] = {
10324        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10325        ALC262_HIPPO_MASTER_SWITCH,
10326        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10327        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10328        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10329        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10330        { } /* end */
10331};
10332
10333static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10334        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10335        ALC262_HIPPO_MASTER_SWITCH,
10336        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10337        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10338        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10339        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10340        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10341        { } /* end */
10342};
10343
10344static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10345        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10346        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10347        HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10348        HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10349        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10350        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10351        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10352        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10353        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10354        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10355        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10356        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10357        { } /* end */
10358};
10359
10360static struct hda_verb alc262_tyan_verbs[] = {
10361        /* Headphone automute */
10362        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10363        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10364        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10365
10366        /* P11 AUX_IN, white 4-pin connector */
10367        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10368        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10369        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10370        {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10371
10372        {}
10373};
10374
10375/* unsolicited event for HP jack sensing */
10376static void alc262_tyan_setup(struct hda_codec *codec)
10377{
10378        struct alc_spec *spec = codec->spec;
10379
10380        spec->autocfg.hp_pins[0] = 0x1b;
10381        spec->autocfg.speaker_pins[0] = 0x15;
10382}
10383
10384
10385#define alc262_capture_mixer            alc882_capture_mixer
10386#define alc262_capture_alt_mixer        alc882_capture_alt_mixer
10387
10388/*
10389 * generic initialization of ADC, input mixers and output mixers
10390 */
10391static struct hda_verb alc262_init_verbs[] = {
10392        /*
10393         * Unmute ADC0-2 and set the default input to mic-in
10394         */
10395        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10396        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10397        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10398        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10399        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10400        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10401
10402        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10403         * mixer widget
10404         * Note: PASD motherboards uses the Line In 2 as the input for
10405         * front panel mic (mic 2)
10406         */
10407        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10408        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10409        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10410        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10411        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10412        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10413
10414        /*
10415         * Set up output mixers (0x0c - 0x0e)
10416         */
10417        /* set vol=0 to output mixers */
10418        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10419        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10420        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10421        /* set up input amps for analog loopback */
10422        /* Amp Indices: DAC = 0, mixer = 1 */
10423        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10424        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10425        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10426        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10427        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10428        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10429
10430        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10431        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10432        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10433        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10434        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10435        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10436
10437        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10438        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10439        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10440        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10441        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10442
10443        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10444        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10445
10446        /* FIXME: use matrix-type input source selection */
10447        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10448        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10449        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10450        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10451        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10452        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10453        /* Input mixer2 */
10454        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10455        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10456        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10457        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10458        /* Input mixer3 */
10459        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10460        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10461        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10462        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10463
10464        { }
10465};
10466
10467static struct hda_verb alc262_eapd_verbs[] = {
10468        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10469        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10470        { }
10471};
10472
10473static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10474        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10475        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10476        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10477
10478        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10479        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10480        {}
10481};
10482
10483static struct hda_verb alc262_sony_unsol_verbs[] = {
10484        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10485        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10486        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
10487
10488        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10489        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10490        {}
10491};
10492
10493static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10494        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10495        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10496        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10497        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10498        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10499        { } /* end */
10500};
10501
10502static struct hda_verb alc262_toshiba_s06_verbs[] = {
10503        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10504        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10505        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10506        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10507        {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10508        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10509        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10510        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10511        {}
10512};
10513
10514static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10515{
10516        struct alc_spec *spec = codec->spec;
10517
10518        spec->autocfg.hp_pins[0] = 0x15;
10519        spec->autocfg.speaker_pins[0] = 0x14;
10520        spec->ext_mic.pin = 0x18;
10521        spec->ext_mic.mux_idx = 0;
10522        spec->int_mic.pin = 0x12;
10523        spec->int_mic.mux_idx = 9;
10524        spec->auto_mic = 1;
10525}
10526
10527/*
10528 * nec model
10529 *  0x15 = headphone
10530 *  0x16 = internal speaker
10531 *  0x18 = external mic
10532 */
10533
10534static struct snd_kcontrol_new alc262_nec_mixer[] = {
10535        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10536        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10537
10538        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10539        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10540        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10541
10542        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10543        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10544        { } /* end */
10545};
10546
10547static struct hda_verb alc262_nec_verbs[] = {
10548        /* Unmute Speaker */
10549        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10550
10551        /* Headphone */
10552        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10553        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10554
10555        /* External mic to headphone */
10556        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10557        /* External mic to speaker */
10558        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10559        {}
10560};
10561
10562/*
10563 * fujitsu model
10564 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
10565 *  0x1b = port replicator headphone out
10566 */
10567
10568#define ALC_HP_EVENT    0x37
10569
10570static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10571        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10572        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10573        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10574        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10575        {}
10576};
10577
10578static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10579        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10580        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10581        {}
10582};
10583
10584static struct hda_input_mux alc262_fujitsu_capture_source = {
10585        .num_items = 3,
10586        .items = {
10587                { "Mic", 0x0 },
10588                { "Int Mic", 0x1 },
10589                { "CD", 0x4 },
10590        },
10591};
10592
10593static struct hda_input_mux alc262_HP_capture_source = {
10594        .num_items = 5,
10595        .items = {
10596                { "Mic", 0x0 },
10597                { "Front Mic", 0x1 },
10598                { "Line", 0x2 },
10599                { "CD", 0x4 },
10600                { "AUX IN", 0x6 },
10601        },
10602};
10603
10604static struct hda_input_mux alc262_HP_D7000_capture_source = {
10605        .num_items = 4,
10606        .items = {
10607                { "Mic", 0x0 },
10608                { "Front Mic", 0x2 },
10609                { "Line", 0x1 },
10610                { "CD", 0x4 },
10611        },
10612};
10613
10614/* mute/unmute internal speaker according to the hp jacks and mute state */
10615static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10616{
10617        struct alc_spec *spec = codec->spec;
10618        unsigned int mute;
10619
10620        if (force || !spec->sense_updated) {
10621                unsigned int present;
10622                /* need to execute and sync at first */
10623                snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10624                /* check laptop HP jack */
10625                present = snd_hda_codec_read(codec, 0x14, 0,
10626                                             AC_VERB_GET_PIN_SENSE, 0);
10627                /* need to execute and sync at first */
10628                snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10629                /* check docking HP jack */
10630                present |= snd_hda_codec_read(codec, 0x1b, 0,
10631                                              AC_VERB_GET_PIN_SENSE, 0);
10632                if (present & AC_PINSENSE_PRESENCE)
10633                        spec->jack_present = 1;
10634                else
10635                        spec->jack_present = 0;
10636                spec->sense_updated = 1;
10637        }
10638        /* unmute internal speaker only if both HPs are unplugged and
10639         * master switch is on
10640         */
10641        if (spec->jack_present)
10642                mute = HDA_AMP_MUTE;
10643        else
10644                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10645        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10646                                 HDA_AMP_MUTE, mute);
10647}
10648
10649/* unsolicited event for HP jack sensing */
10650static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10651                                       unsigned int res)
10652{
10653        if ((res >> 26) != ALC_HP_EVENT)
10654                return;
10655        alc262_fujitsu_automute(codec, 1);
10656}
10657
10658static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10659{
10660        alc262_fujitsu_automute(codec, 1);
10661}
10662
10663/* bind volumes of both NID 0x0c and 0x0d */
10664static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10665        .ops = &snd_hda_bind_vol,
10666        .values = {
10667                HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10668                HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10669                0
10670        },
10671};
10672
10673/* mute/unmute internal speaker according to the hp jack and mute state */
10674static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10675{
10676        struct alc_spec *spec = codec->spec;
10677        unsigned int mute;
10678
10679        if (force || !spec->sense_updated) {
10680                unsigned int present_int_hp;
10681                /* need to execute and sync at first */
10682                snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10683                present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10684                                        AC_VERB_GET_PIN_SENSE, 0);
10685                spec->jack_present = (present_int_hp & 0x80000000) != 0;
10686                spec->sense_updated = 1;
10687        }
10688        if (spec->jack_present) {
10689                /* mute internal speaker */
10690                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10691                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
10692                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10693                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
10694        } else {
10695                /* unmute internal speaker if necessary */
10696                mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10697                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10698                                         HDA_AMP_MUTE, mute);
10699                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10700                                         HDA_AMP_MUTE, mute);
10701        }
10702}
10703
10704/* unsolicited event for HP jack sensing */
10705static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10706                                       unsigned int res)
10707{
10708        if ((res >> 26) != ALC_HP_EVENT)
10709                return;
10710        alc262_lenovo_3000_automute(codec, 1);
10711}
10712
10713static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10714                                  int dir, int idx, long *valp)
10715{
10716        int i, change = 0;
10717
10718        for (i = 0; i < 2; i++, valp++)
10719                change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10720                                                   HDA_AMP_MUTE,
10721                                                   *valp ? 0 : HDA_AMP_MUTE);
10722        return change;
10723}
10724
10725/* bind hp and internal speaker mute (with plug check) */
10726static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10727                                         struct snd_ctl_elem_value *ucontrol)
10728{
10729        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10730        long *valp = ucontrol->value.integer.value;
10731        int change;
10732
10733        change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10734        change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10735        if (change)
10736                alc262_fujitsu_automute(codec, 0);
10737        return change;
10738}
10739
10740static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10741        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10742        {
10743                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10744                .name = "Master Playback Switch",
10745                .info = snd_hda_mixer_amp_switch_info,
10746                .get = snd_hda_mixer_amp_switch_get,
10747                .put = alc262_fujitsu_master_sw_put,
10748                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10749        },
10750        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10751        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10752        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10753        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10754        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10755        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10756        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10757        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10758        { } /* end */
10759};
10760
10761/* bind hp and internal speaker mute (with plug check) */
10762static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10763                                         struct snd_ctl_elem_value *ucontrol)
10764{
10765        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10766        long *valp = ucontrol->value.integer.value;
10767        int change;
10768
10769        change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10770        if (change)
10771                alc262_lenovo_3000_automute(codec, 0);
10772        return change;
10773}
10774
10775static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10776        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10777        {
10778                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10779                .name = "Master Playback Switch",
10780                .info = snd_hda_mixer_amp_switch_info,
10781                .get = snd_hda_mixer_amp_switch_get,
10782                .put = alc262_lenovo_3000_master_sw_put,
10783                .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10784        },
10785        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10786        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10787        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10788        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10789        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10790        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10791        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10792        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10793        { } /* end */
10794};
10795
10796static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10797        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10798        ALC262_HIPPO_MASTER_SWITCH,
10799        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10800        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10801        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10802        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10803        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10804        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10805        { } /* end */
10806};
10807
10808/* additional init verbs for Benq laptops */
10809static struct hda_verb alc262_EAPD_verbs[] = {
10810        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10811        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
10812        {}
10813};
10814
10815static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10816        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10817        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10818
10819        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10820        {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
10821        {}
10822};
10823
10824/* Samsung Q1 Ultra Vista model setup */
10825static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10826        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10827        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10828        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10829        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10830        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10831        HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10832        { } /* end */
10833};
10834
10835static struct hda_verb alc262_ultra_verbs[] = {
10836        /* output mixer */
10837        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10838        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10839        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10840        /* speaker */
10841        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10842        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10843        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10844        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10845        /* HP */
10846        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10847        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10848        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10849        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10850        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10851        /* internal mic */
10852        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10853        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10854        /* ADC, choose mic */
10855        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10856        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10857        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10858        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10859        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10860        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10861        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10862        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10863        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10864        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10865        {}
10866};
10867
10868/* mute/unmute internal speaker according to the hp jack and mute state */
10869static void alc262_ultra_automute(struct hda_codec *codec)
10870{
10871        struct alc_spec *spec = codec->spec;
10872        unsigned int mute;
10873
10874        mute = 0;
10875        /* auto-mute only when HP is used as HP */
10876        if (!spec->cur_mux[0]) {
10877                unsigned int present;
10878                /* need to execute and sync at first */
10879                snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10880                present = snd_hda_codec_read(codec, 0x15, 0,
10881                                             AC_VERB_GET_PIN_SENSE, 0);
10882                spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10883                if (spec->jack_present)
10884                        mute = HDA_AMP_MUTE;
10885        }
10886        /* mute/unmute internal speaker */
10887        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10888                                 HDA_AMP_MUTE, mute);
10889        /* mute/unmute HP */
10890        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10891                                 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10892}
10893
10894/* unsolicited event for HP jack sensing */
10895static void alc262_ultra_unsol_event(struct hda_codec *codec,
10896                                       unsigned int res)
10897{
10898        if ((res >> 26) != ALC880_HP_EVENT)
10899                return;
10900        alc262_ultra_automute(codec);
10901}
10902
10903static struct hda_input_mux alc262_ultra_capture_source = {
10904        .num_items = 2,
10905        .items = {
10906                { "Mic", 0x1 },
10907                { "Headphone", 0x7 },
10908        },
10909};
10910
10911static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10912                                     struct snd_ctl_elem_value *ucontrol)
10913{
10914        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10915        struct alc_spec *spec = codec->spec;
10916        int ret;
10917
10918        ret = alc_mux_enum_put(kcontrol, ucontrol);
10919        if (!ret)
10920                return 0;
10921        /* reprogram the HP pin as mic or HP according to the input source */
10922        snd_hda_codec_write_cache(codec, 0x15, 0,
10923                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
10924                                  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10925        alc262_ultra_automute(codec); /* mute/unmute HP */
10926        return ret;
10927}
10928
10929static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10930        HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10931        HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10932        {
10933                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10934                .name = "Capture Source",
10935                .info = alc_mux_enum_info,
10936                .get = alc_mux_enum_get,
10937                .put = alc262_ultra_mux_enum_put,
10938        },
10939        { } /* end */
10940};
10941
10942/* We use two mixers depending on the output pin; 0x16 is a mono output
10943 * and thus it's bound with a different mixer.
10944 * This function returns which mixer amp should be used.
10945 */
10946static int alc262_check_volbit(hda_nid_t nid)
10947{
10948        if (!nid)
10949                return 0;
10950        else if (nid == 0x16)
10951                return 2;
10952        else
10953                return 1;
10954}
10955
10956static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10957                                  const char *pfx, int *vbits)
10958{
10959        char name[32];
10960        unsigned long val;
10961        int vbit;
10962
10963        vbit = alc262_check_volbit(nid);
10964        if (!vbit)
10965                return 0;
10966        if (*vbits & vbit) /* a volume control for this mixer already there */
10967                return 0;
10968        *vbits |= vbit;
10969        snprintf(name, sizeof(name), "%s Playback Volume", pfx);
10970        if (vbit == 2)
10971                val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10972        else
10973                val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10974        return add_control(spec, ALC_CTL_WIDGET_VOL, name, val);
10975}
10976
10977static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10978                                 const char *pfx)
10979{
10980        char name[32];
10981        unsigned long val;
10982
10983        if (!nid)
10984                return 0;
10985        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
10986        if (nid == 0x16)
10987                val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10988        else
10989                val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10990        return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val);
10991}
10992
10993/* add playback controls from the parsed DAC table */
10994static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10995                                             const struct auto_pin_cfg *cfg)
10996{
10997        const char *pfx;
10998        int vbits;
10999        int err;
11000
11001        spec->multiout.num_dacs = 1;    /* only use one dac */
11002        spec->multiout.dac_nids = spec->private_dac_nids;
11003        spec->multiout.dac_nids[0] = 2;
11004
11005        if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11006                pfx = "Master";
11007        else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11008                pfx = "Speaker";
11009        else
11010                pfx = "Front";
11011        err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11012        if (err < 0)
11013                return err;
11014        err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11015        if (err < 0)
11016                return err;
11017        err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11018        if (err < 0)
11019                return err;
11020
11021        vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11022                alc262_check_volbit(cfg->speaker_pins[0]) |
11023                alc262_check_volbit(cfg->hp_pins[0]);
11024        if (vbits == 1 || vbits == 2)
11025                pfx = "Master"; /* only one mixer is used */
11026        else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11027                pfx = "Speaker";
11028        else
11029                pfx = "Front";
11030        vbits = 0;
11031        err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11032        if (err < 0)
11033                return err;
11034        err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11035                                     &vbits);
11036        if (err < 0)
11037                return err;
11038        err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11039                                     &vbits);
11040        if (err < 0)
11041                return err;
11042        return 0;
11043}
11044
11045#define alc262_auto_create_input_ctls \
11046        alc880_auto_create_input_ctls
11047
11048/*
11049 * generic initialization of ADC, input mixers and output mixers
11050 */
11051static struct hda_verb alc262_volume_init_verbs[] = {
11052        /*
11053         * Unmute ADC0-2 and set the default input to mic-in
11054         */
11055        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11056        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11057        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11058        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11059        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11060        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11061
11062        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11063         * mixer widget
11064         * Note: PASD motherboards uses the Line In 2 as the input for
11065         * front panel mic (mic 2)
11066         */
11067        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11068        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11069        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11070        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11071        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11072        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11073
11074        /*
11075         * Set up output mixers (0x0c - 0x0f)
11076         */
11077        /* set vol=0 to output mixers */
11078        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11079        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11080        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11081
11082        /* set up input amps for analog loopback */
11083        /* Amp Indices: DAC = 0, mixer = 1 */
11084        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11085        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11086        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11087        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11088        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11089        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11090
11091        /* FIXME: use matrix-type input source selection */
11092        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11093        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11094        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11095        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11096        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11097        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11098        /* Input mixer2 */
11099        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11100        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11101        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11102        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11103        /* Input mixer3 */
11104        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11105        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11106        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11107        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11108
11109        { }
11110};
11111
11112static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11113        /*
11114         * Unmute ADC0-2 and set the default input to mic-in
11115         */
11116        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11117        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11118        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11119        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11120        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11121        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11122
11123        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11124         * mixer widget
11125         * Note: PASD motherboards uses the Line In 2 as the input for
11126         * front panel mic (mic 2)
11127         */
11128        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11129        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11130        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11131        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11132        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11133        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11134        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11135        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11136
11137        /*
11138         * Set up output mixers (0x0c - 0x0e)
11139         */
11140        /* set vol=0 to output mixers */
11141        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11142        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11143        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11144
11145        /* set up input amps for analog loopback */
11146        /* Amp Indices: DAC = 0, mixer = 1 */
11147        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11149        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11150        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11151        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11152        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11153
11154        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11155        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11156        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11157
11158        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11159        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11160
11161        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11162        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11163
11164        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11165        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11166        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11167        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11168        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11169
11170        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11171        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11172        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11173        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11174        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11175        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11176
11177
11178        /* FIXME: use matrix-type input source selection */
11179        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11180        /* Input mixer1: only unmute Mic */
11181        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11182        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11183        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11184        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11185        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11186        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11187        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11188        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11189        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11190        /* Input mixer2 */
11191        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11192        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11193        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11194        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11195        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11196        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11197        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11198        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11199        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11200        /* Input mixer3 */
11201        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11202        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11203        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11204        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11205        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11206        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11207        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11208        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11209        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11210
11211        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11212
11213        { }
11214};
11215
11216static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11217        /*
11218         * Unmute ADC0-2 and set the default input to mic-in
11219         */
11220        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11221        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11222        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11223        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11224        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11225        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11226
11227        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11228         * mixer widget
11229         * Note: PASD motherboards uses the Line In 2 as the input for front
11230         * panel mic (mic 2)
11231         */
11232        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11233        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11234        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11235        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11236        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11237        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11238        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11239        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11240        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11241        /*
11242         * Set up output mixers (0x0c - 0x0e)
11243         */
11244        /* set vol=0 to output mixers */
11245        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11246        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11247        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11248
11249        /* set up input amps for analog loopback */
11250        /* Amp Indices: DAC = 0, mixer = 1 */
11251        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11252        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11253        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11254        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11255        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11256        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11257
11258
11259        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
11260        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
11261        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
11262        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
11263        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
11264        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
11265        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
11266
11267        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11268        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11269
11270        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11271        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11272
11273        /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11274        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11275        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11276        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11277        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11278        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11279
11280        /* FIXME: use matrix-type input source selection */
11281        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11282        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11283        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11284        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11285        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11286        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11287        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11288        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
11289        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11290        /* Input mixer2 */
11291        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11292        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11293        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11294        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11295        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11296        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11297        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11298        /* Input mixer3 */
11299        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11300        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11301        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11302        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11303        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11304        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11305        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11306
11307        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11308
11309        { }
11310};
11311
11312static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11313
11314        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Front Speaker */
11315        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11316        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11317
11318        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* MIC jack */
11319        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
11320        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11321        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11322
11323        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP  jack */
11324        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11325        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11326        {}
11327};
11328
11329
11330#ifdef CONFIG_SND_HDA_POWER_SAVE
11331#define alc262_loopbacks        alc880_loopbacks
11332#endif
11333
11334/* pcm configuration: identical with ALC880 */
11335#define alc262_pcm_analog_playback      alc880_pcm_analog_playback
11336#define alc262_pcm_analog_capture       alc880_pcm_analog_capture
11337#define alc262_pcm_digital_playback     alc880_pcm_digital_playback
11338#define alc262_pcm_digital_capture      alc880_pcm_digital_capture
11339
11340/*
11341 * BIOS auto configuration
11342 */
11343static int alc262_parse_auto_config(struct hda_codec *codec)
11344{
11345        struct alc_spec *spec = codec->spec;
11346        int err;
11347        static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11348
11349        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11350                                           alc262_ignore);
11351        if (err < 0)
11352                return err;
11353        if (!spec->autocfg.line_outs) {
11354                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11355                        spec->multiout.max_channels = 2;
11356                        spec->no_analog = 1;
11357                        goto dig_only;
11358                }
11359                return 0; /* can't find valid BIOS pin config */
11360        }
11361        err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11362        if (err < 0)
11363                return err;
11364        err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11365        if (err < 0)
11366                return err;
11367
11368        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11369
11370 dig_only:
11371        if (spec->autocfg.dig_outs) {
11372                spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11373                spec->dig_out_type = spec->autocfg.dig_out_type[0];
11374        }
11375        if (spec->autocfg.dig_in_pin)
11376                spec->dig_in_nid = ALC262_DIGIN_NID;
11377
11378        if (spec->kctls.list)
11379                add_mixer(spec, spec->kctls.list);
11380
11381        add_verb(spec, alc262_volume_init_verbs);
11382        spec->num_mux_defs = 1;
11383        spec->input_mux = &spec->private_imux[0];
11384
11385        err = alc_auto_add_mic_boost(codec);
11386        if (err < 0)
11387                return err;
11388
11389        alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11390
11391        return 1;
11392}
11393
11394#define alc262_auto_init_multi_out      alc882_auto_init_multi_out
11395#define alc262_auto_init_hp_out         alc882_auto_init_hp_out
11396#define alc262_auto_init_analog_input   alc882_auto_init_analog_input
11397#define alc262_auto_init_input_src      alc882_auto_init_input_src
11398
11399
11400/* init callback for auto-configuration model -- overriding the default init */
11401static void alc262_auto_init(struct hda_codec *codec)
11402{
11403        struct alc_spec *spec = codec->spec;
11404        alc262_auto_init_multi_out(codec);
11405        alc262_auto_init_hp_out(codec);
11406        alc262_auto_init_analog_input(codec);
11407        alc262_auto_init_input_src(codec);
11408        if (spec->unsol_event)
11409                alc_inithook(codec);
11410}
11411
11412/*
11413 * configuration and preset
11414 */
11415static const char *alc262_models[ALC262_MODEL_LAST] = {
11416        [ALC262_BASIC]          = "basic",
11417        [ALC262_HIPPO]          = "hippo",
11418        [ALC262_HIPPO_1]        = "hippo_1",
11419        [ALC262_FUJITSU]        = "fujitsu",
11420        [ALC262_HP_BPC]         = "hp-bpc",
11421        [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11422        [ALC262_HP_TC_T5735]    = "hp-tc-t5735",
11423        [ALC262_HP_RP5700]      = "hp-rp5700",
11424        [ALC262_BENQ_ED8]       = "benq",
11425        [ALC262_BENQ_T31]       = "benq-t31",
11426        [ALC262_SONY_ASSAMD]    = "sony-assamd",
11427        [ALC262_TOSHIBA_S06]    = "toshiba-s06",
11428        [ALC262_TOSHIBA_RX1]    = "toshiba-rx1",
11429        [ALC262_ULTRA]          = "ultra",
11430        [ALC262_LENOVO_3000]    = "lenovo-3000",
11431        [ALC262_NEC]            = "nec",
11432        [ALC262_TYAN]           = "tyan",
11433        [ALC262_AUTO]           = "auto",
11434};
11435
11436static struct snd_pci_quirk alc262_cfg_tbl[] = {
11437        SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11438        SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11439        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11440                           ALC262_HP_BPC),
11441        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11442                           ALC262_HP_BPC),
11443        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11444                           ALC262_HP_BPC),
11445        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11446        SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11447        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11448        SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11449        SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11450        SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11451        SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11452        SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11453        SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11454        SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11455        SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11456        SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11457                      ALC262_HP_TC_T5735),
11458        SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11459        SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11460        SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11461        SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11462        SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11463        SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11464        SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11465        SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
11466        SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11467                           ALC262_SONY_ASSAMD),
11468        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11469                      ALC262_TOSHIBA_RX1),
11470        SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11471        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11472        SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11473        SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11474        SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11475                           ALC262_ULTRA),
11476        SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11477        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11478        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11479        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11480        SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11481        {}
11482};
11483
11484static struct alc_config_preset alc262_presets[] = {
11485        [ALC262_BASIC] = {
11486                .mixers = { alc262_base_mixer },
11487                .init_verbs = { alc262_init_verbs },
11488                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11489                .dac_nids = alc262_dac_nids,
11490                .hp_nid = 0x03,
11491                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11492                .channel_mode = alc262_modes,
11493                .input_mux = &alc262_capture_source,
11494        },
11495        [ALC262_HIPPO] = {
11496                .mixers = { alc262_hippo_mixer },
11497                .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11498                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11499                .dac_nids = alc262_dac_nids,
11500                .hp_nid = 0x03,
11501                .dig_out_nid = ALC262_DIGOUT_NID,
11502                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11503                .channel_mode = alc262_modes,
11504                .input_mux = &alc262_capture_source,
11505                .unsol_event = alc262_hippo_unsol_event,
11506                .setup = alc262_hippo_setup,
11507                .init_hook = alc262_hippo_automute,
11508        },
11509        [ALC262_HIPPO_1] = {
11510                .mixers = { alc262_hippo1_mixer },
11511                .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11512                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11513                .dac_nids = alc262_dac_nids,
11514                .hp_nid = 0x02,
11515                .dig_out_nid = ALC262_DIGOUT_NID,
11516                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11517                .channel_mode = alc262_modes,
11518                .input_mux = &alc262_capture_source,
11519                .unsol_event = alc262_hippo_unsol_event,
11520                .setup = alc262_hippo1_setup,
11521                .init_hook = alc262_hippo_automute,
11522        },
11523        [ALC262_FUJITSU] = {
11524                .mixers = { alc262_fujitsu_mixer },
11525                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11526                                alc262_fujitsu_unsol_verbs },
11527                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11528                .dac_nids = alc262_dac_nids,
11529                .hp_nid = 0x03,
11530                .dig_out_nid = ALC262_DIGOUT_NID,
11531                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11532                .channel_mode = alc262_modes,
11533                .input_mux = &alc262_fujitsu_capture_source,
11534                .unsol_event = alc262_fujitsu_unsol_event,
11535                .init_hook = alc262_fujitsu_init_hook,
11536        },
11537        [ALC262_HP_BPC] = {
11538                .mixers = { alc262_HP_BPC_mixer },
11539                .init_verbs = { alc262_HP_BPC_init_verbs },
11540                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11541                .dac_nids = alc262_dac_nids,
11542                .hp_nid = 0x03,
11543                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11544                .channel_mode = alc262_modes,
11545                .input_mux = &alc262_HP_capture_source,
11546                .unsol_event = alc262_hp_bpc_unsol_event,
11547                .init_hook = alc262_hp_bpc_automute,
11548        },
11549        [ALC262_HP_BPC_D7000_WF] = {
11550                .mixers = { alc262_HP_BPC_WildWest_mixer },
11551                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11552                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11553                .dac_nids = alc262_dac_nids,
11554                .hp_nid = 0x03,
11555                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11556                .channel_mode = alc262_modes,
11557                .input_mux = &alc262_HP_D7000_capture_source,
11558                .unsol_event = alc262_hp_wildwest_unsol_event,
11559                .init_hook = alc262_hp_wildwest_automute,
11560        },
11561        [ALC262_HP_BPC_D7000_WL] = {
11562                .mixers = { alc262_HP_BPC_WildWest_mixer,
11563                            alc262_HP_BPC_WildWest_option_mixer },
11564                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11565                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11566                .dac_nids = alc262_dac_nids,
11567                .hp_nid = 0x03,
11568                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11569                .channel_mode = alc262_modes,
11570                .input_mux = &alc262_HP_D7000_capture_source,
11571                .unsol_event = alc262_hp_wildwest_unsol_event,
11572                .init_hook = alc262_hp_wildwest_automute,
11573        },
11574        [ALC262_HP_TC_T5735] = {
11575                .mixers = { alc262_hp_t5735_mixer },
11576                .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11577                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11578                .dac_nids = alc262_dac_nids,
11579                .hp_nid = 0x03,
11580                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11581                .channel_mode = alc262_modes,
11582                .input_mux = &alc262_capture_source,
11583                .unsol_event = alc_automute_amp_unsol_event,
11584                .setup = alc262_hp_t5735_setup,
11585                .init_hook = alc_automute_amp,
11586        },
11587        [ALC262_HP_RP5700] = {
11588                .mixers = { alc262_hp_rp5700_mixer },
11589                .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11590                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11591                .dac_nids = alc262_dac_nids,
11592                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11593                .channel_mode = alc262_modes,
11594                .input_mux = &alc262_hp_rp5700_capture_source,
11595        },
11596        [ALC262_BENQ_ED8] = {
11597                .mixers = { alc262_base_mixer },
11598                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11599                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11600                .dac_nids = alc262_dac_nids,
11601                .hp_nid = 0x03,
11602                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11603                .channel_mode = alc262_modes,
11604                .input_mux = &alc262_capture_source,
11605        },
11606        [ALC262_SONY_ASSAMD] = {
11607                .mixers = { alc262_sony_mixer },
11608                .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11609                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11610                .dac_nids = alc262_dac_nids,
11611                .hp_nid = 0x02,
11612                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11613                .channel_mode = alc262_modes,
11614                .input_mux = &alc262_capture_source,
11615                .unsol_event = alc262_hippo_unsol_event,
11616                .setup = alc262_hippo_setup,
11617                .init_hook = alc262_hippo_automute,
11618        },
11619        [ALC262_BENQ_T31] = {
11620                .mixers = { alc262_benq_t31_mixer },
11621                .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11622                                alc_hp15_unsol_verbs },
11623                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11624                .dac_nids = alc262_dac_nids,
11625                .hp_nid = 0x03,
11626                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11627                .channel_mode = alc262_modes,
11628                .input_mux = &alc262_capture_source,
11629                .unsol_event = alc262_hippo_unsol_event,
11630                .setup = alc262_hippo_setup,
11631                .init_hook = alc262_hippo_automute,
11632        },
11633        [ALC262_ULTRA] = {
11634                .mixers = { alc262_ultra_mixer },
11635                .cap_mixer = alc262_ultra_capture_mixer,
11636                .init_verbs = { alc262_ultra_verbs },
11637                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11638                .dac_nids = alc262_dac_nids,
11639                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11640                .channel_mode = alc262_modes,
11641                .input_mux = &alc262_ultra_capture_source,
11642                .adc_nids = alc262_adc_nids, /* ADC0 */
11643                .capsrc_nids = alc262_capsrc_nids,
11644                .num_adc_nids = 1, /* single ADC */
11645                .unsol_event = alc262_ultra_unsol_event,
11646                .init_hook = alc262_ultra_automute,
11647        },
11648        [ALC262_LENOVO_3000] = {
11649                .mixers = { alc262_lenovo_3000_mixer },
11650                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11651                                alc262_lenovo_3000_unsol_verbs },
11652                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11653                .dac_nids = alc262_dac_nids,
11654                .hp_nid = 0x03,
11655                .dig_out_nid = ALC262_DIGOUT_NID,
11656                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11657                .channel_mode = alc262_modes,
11658                .input_mux = &alc262_fujitsu_capture_source,
11659                .unsol_event = alc262_lenovo_3000_unsol_event,
11660        },
11661        [ALC262_NEC] = {
11662                .mixers = { alc262_nec_mixer },
11663                .init_verbs = { alc262_nec_verbs },
11664                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11665                .dac_nids = alc262_dac_nids,
11666                .hp_nid = 0x03,
11667                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11668                .channel_mode = alc262_modes,
11669                .input_mux = &alc262_capture_source,
11670        },
11671        [ALC262_TOSHIBA_S06] = {
11672                .mixers = { alc262_toshiba_s06_mixer },
11673                .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11674                                                        alc262_eapd_verbs },
11675                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11676                .capsrc_nids = alc262_dmic_capsrc_nids,
11677                .dac_nids = alc262_dac_nids,
11678                .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11679                .num_adc_nids = 1, /* single ADC */
11680                .dig_out_nid = ALC262_DIGOUT_NID,
11681                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11682                .channel_mode = alc262_modes,
11683                .unsol_event = alc_sku_unsol_event,
11684                .setup = alc262_toshiba_s06_setup,
11685                .init_hook = alc_inithook,
11686        },
11687        [ALC262_TOSHIBA_RX1] = {
11688                .mixers = { alc262_toshiba_rx1_mixer },
11689                .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11690                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11691                .dac_nids = alc262_dac_nids,
11692                .hp_nid = 0x03,
11693                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11694                .channel_mode = alc262_modes,
11695                .input_mux = &alc262_capture_source,
11696                .unsol_event = alc262_hippo_unsol_event,
11697                .setup = alc262_hippo_setup,
11698                .init_hook = alc262_hippo_automute,
11699        },
11700        [ALC262_TYAN] = {
11701                .mixers = { alc262_tyan_mixer },
11702                .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11703                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11704                .dac_nids = alc262_dac_nids,
11705                .hp_nid = 0x02,
11706                .dig_out_nid = ALC262_DIGOUT_NID,
11707                .num_channel_mode = ARRAY_SIZE(alc262_modes),
11708                .channel_mode = alc262_modes,
11709                .input_mux = &alc262_capture_source,
11710                .unsol_event = alc_automute_amp_unsol_event,
11711                .setup = alc262_tyan_setup,
11712                .init_hook = alc_automute_amp,
11713        },
11714};
11715
11716static int patch_alc262(struct hda_codec *codec)
11717{
11718        struct alc_spec *spec;
11719        int board_config;
11720        int err;
11721
11722        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11723        if (spec == NULL)
11724                return -ENOMEM;
11725
11726        codec->spec = spec;
11727#if 0
11728        /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
11729         * under-run
11730         */
11731        {
11732        int tmp;
11733        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11734        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11735        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11736        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11737        }
11738#endif
11739
11740        alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11741
11742        board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11743                                                  alc262_models,
11744                                                  alc262_cfg_tbl);
11745
11746        if (board_config < 0) {
11747                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11748                       codec->chip_name);
11749                board_config = ALC262_AUTO;
11750        }
11751
11752        if (board_config == ALC262_AUTO) {
11753                /* automatic parse from the BIOS config */
11754                err = alc262_parse_auto_config(codec);
11755                if (err < 0) {
11756                        alc_free(codec);
11757                        return err;
11758                } else if (!err) {
11759                        printk(KERN_INFO
11760                               "hda_codec: Cannot set up configuration "
11761                               "from BIOS.  Using base mode...\n");
11762                        board_config = ALC262_BASIC;
11763                }
11764        }
11765
11766        if (!spec->no_analog) {
11767                err = snd_hda_attach_beep_device(codec, 0x1);
11768                if (err < 0) {
11769                        alc_free(codec);
11770                        return err;
11771                }
11772        }
11773
11774        if (board_config != ALC262_AUTO)
11775                setup_preset(codec, &alc262_presets[board_config]);
11776
11777        spec->stream_analog_playback = &alc262_pcm_analog_playback;
11778        spec->stream_analog_capture = &alc262_pcm_analog_capture;
11779
11780        spec->stream_digital_playback = &alc262_pcm_digital_playback;
11781        spec->stream_digital_capture = &alc262_pcm_digital_capture;
11782
11783        if (!spec->adc_nids && spec->input_mux) {
11784                int i;
11785                /* check whether the digital-mic has to be supported */
11786                for (i = 0; i < spec->input_mux->num_items; i++) {
11787                        if (spec->input_mux->items[i].index >= 9)
11788                                break;
11789                }
11790                if (i < spec->input_mux->num_items) {
11791                        /* use only ADC0 */
11792                        spec->adc_nids = alc262_dmic_adc_nids;
11793                        spec->num_adc_nids = 1;
11794                        spec->capsrc_nids = alc262_dmic_capsrc_nids;
11795                } else {
11796                        /* all analog inputs */
11797                        /* check whether NID 0x07 is valid */
11798                        unsigned int wcap = get_wcaps(codec, 0x07);
11799
11800                        /* get type */
11801                        wcap = get_wcaps_type(wcap);
11802                        if (wcap != AC_WID_AUD_IN) {
11803                                spec->adc_nids = alc262_adc_nids_alt;
11804                                spec->num_adc_nids =
11805                                        ARRAY_SIZE(alc262_adc_nids_alt);
11806                                spec->capsrc_nids = alc262_capsrc_nids_alt;
11807                        } else {
11808                                spec->adc_nids = alc262_adc_nids;
11809                                spec->num_adc_nids =
11810                                        ARRAY_SIZE(alc262_adc_nids);
11811                                spec->capsrc_nids = alc262_capsrc_nids;
11812                        }
11813                }
11814        }
11815        if (!spec->cap_mixer && !spec->no_analog)
11816                set_capture_mixer(codec);
11817        if (!spec->no_analog)
11818                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11819
11820        spec->vmaster_nid = 0x0c;
11821
11822        codec->patch_ops = alc_patch_ops;
11823        if (board_config == ALC262_AUTO)
11824                spec->init_hook = alc262_auto_init;
11825#ifdef CONFIG_SND_HDA_POWER_SAVE
11826        if (!spec->loopback.amplist)
11827                spec->loopback.amplist = alc262_loopbacks;
11828#endif
11829        codec->proc_widget_hook = print_realtek_coef;
11830
11831        return 0;
11832}
11833
11834/*
11835 *  ALC268 channel source setting (2 channel)
11836 */
11837#define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
11838#define alc268_modes            alc260_modes
11839
11840static hda_nid_t alc268_dac_nids[2] = {
11841        /* front, hp */
11842        0x02, 0x03
11843};
11844
11845static hda_nid_t alc268_adc_nids[2] = {
11846        /* ADC0-1 */
11847        0x08, 0x07
11848};
11849
11850static hda_nid_t alc268_adc_nids_alt[1] = {
11851        /* ADC0 */
11852        0x08
11853};
11854
11855static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11856
11857static struct snd_kcontrol_new alc268_base_mixer[] = {
11858        /* output mixer control */
11859        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11860        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11861        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11862        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11863        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11864        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11865        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11866        { }
11867};
11868
11869static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11870        /* output mixer control */
11871        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11872        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11873        ALC262_HIPPO_MASTER_SWITCH,
11874        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11875        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11876        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11877        { }
11878};
11879
11880/* bind Beep switches of both NID 0x0f and 0x10 */
11881static struct hda_bind_ctls alc268_bind_beep_sw = {
11882        .ops = &snd_hda_bind_sw,
11883        .values = {
11884                HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11885                HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11886                0
11887        },
11888};
11889
11890static struct snd_kcontrol_new alc268_beep_mixer[] = {
11891        HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11892        HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11893        { }
11894};
11895
11896static struct hda_verb alc268_eapd_verbs[] = {
11897        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11898        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11899        { }
11900};
11901
11902/* Toshiba specific */
11903static struct hda_verb alc268_toshiba_verbs[] = {
11904        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11905        { } /* end */
11906};
11907
11908/* Acer specific */
11909/* bind volumes of both NID 0x02 and 0x03 */
11910static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11911        .ops = &snd_hda_bind_vol,
11912        .values = {
11913                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11914                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11915                0
11916        },
11917};
11918
11919/* mute/unmute internal speaker according to the hp jack and mute state */
11920static void alc268_acer_automute(struct hda_codec *codec, int force)
11921{
11922        struct alc_spec *spec = codec->spec;
11923        unsigned int mute;
11924
11925        if (force || !spec->sense_updated) {
11926                unsigned int present;
11927                present = snd_hda_codec_read(codec, 0x14, 0,
11928                                         AC_VERB_GET_PIN_SENSE, 0);
11929                spec->jack_present = (present & 0x80000000) != 0;
11930                spec->sense_updated = 1;
11931        }
11932        if (spec->jack_present)
11933                mute = HDA_AMP_MUTE; /* mute internal speaker */
11934        else /* unmute internal speaker if necessary */
11935                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11936        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11937                                 HDA_AMP_MUTE, mute);
11938}
11939
11940
11941/* bind hp and internal speaker mute (with plug check) */
11942static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11943                                     struct snd_ctl_elem_value *ucontrol)
11944{
11945        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11946        long *valp = ucontrol->value.integer.value;
11947        int change;
11948
11949        change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11950        if (change)
11951                alc268_acer_automute(codec, 0);
11952        return change;
11953}
11954
11955static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11956        /* output mixer control */
11957        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11958        {
11959                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11960                .name = "Master Playback Switch",
11961                .info = snd_hda_mixer_amp_switch_info,
11962                .get = snd_hda_mixer_amp_switch_get,
11963                .put = alc268_acer_master_sw_put,
11964                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11965        },
11966        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11967        { }
11968};
11969
11970static struct snd_kcontrol_new alc268_acer_mixer[] = {
11971        /* output mixer control */
11972        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11973        {
11974                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11975                .name = "Master Playback Switch",
11976                .info = snd_hda_mixer_amp_switch_info,
11977                .get = snd_hda_mixer_amp_switch_get,
11978                .put = alc268_acer_master_sw_put,
11979                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11980        },
11981        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11982        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11983        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11984        { }
11985};
11986
11987static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11988        /* output mixer control */
11989        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11990        {
11991                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11992                .name = "Master Playback Switch",
11993                .info = snd_hda_mixer_amp_switch_info,
11994                .get = snd_hda_mixer_amp_switch_get,
11995                .put = alc268_acer_master_sw_put,
11996                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11997        },
11998        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11999        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12000        { }
12001};
12002
12003static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12004        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12005        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12006        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12007        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12008        {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12009        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12010        { }
12011};
12012
12013static struct hda_verb alc268_acer_verbs[] = {
12014        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12015        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12016        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12017        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12018        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12019        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12020        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12021        { }
12022};
12023
12024/* unsolicited event for HP jack sensing */
12025#define alc268_toshiba_unsol_event      alc262_hippo_unsol_event
12026#define alc268_toshiba_setup            alc262_hippo_setup
12027#define alc268_toshiba_automute         alc262_hippo_automute
12028
12029static void alc268_acer_unsol_event(struct hda_codec *codec,
12030                                       unsigned int res)
12031{
12032        if ((res >> 26) != ALC880_HP_EVENT)
12033                return;
12034        alc268_acer_automute(codec, 1);
12035}
12036
12037static void alc268_acer_init_hook(struct hda_codec *codec)
12038{
12039        alc268_acer_automute(codec, 1);
12040}
12041
12042/* toggle speaker-output according to the hp-jack state */
12043static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12044{
12045        unsigned int present;
12046        unsigned char bits;
12047
12048        present = snd_hda_codec_read(codec, 0x15, 0,
12049                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12050        bits = present ? AMP_IN_MUTE(0) : 0;
12051        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12052                                AMP_IN_MUTE(0), bits);
12053        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12054                                AMP_IN_MUTE(0), bits);
12055}
12056
12057static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12058                                    unsigned int res)
12059{
12060        switch (res >> 26) {
12061        case ALC880_HP_EVENT:
12062                alc268_aspire_one_speaker_automute(codec);
12063                break;
12064        case ALC880_MIC_EVENT:
12065                alc_mic_automute(codec);
12066                break;
12067        }
12068}
12069
12070static void alc268_acer_lc_setup(struct hda_codec *codec)
12071{
12072        struct alc_spec *spec = codec->spec;
12073        spec->ext_mic.pin = 0x18;
12074        spec->ext_mic.mux_idx = 0;
12075        spec->int_mic.pin = 0x12;
12076        spec->int_mic.mux_idx = 6;
12077        spec->auto_mic = 1;
12078}
12079
12080static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12081{
12082        alc268_aspire_one_speaker_automute(codec);
12083        alc_mic_automute(codec);
12084}
12085
12086static struct snd_kcontrol_new alc268_dell_mixer[] = {
12087        /* output mixer control */
12088        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12089        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12090        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12091        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12092        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12093        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12094        { }
12095};
12096
12097static struct hda_verb alc268_dell_verbs[] = {
12098        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12099        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12100        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12101        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12102        { }
12103};
12104
12105/* mute/unmute internal speaker according to the hp jack and mute state */
12106static void alc268_dell_setup(struct hda_codec *codec)
12107{
12108        struct alc_spec *spec = codec->spec;
12109
12110        spec->autocfg.hp_pins[0] = 0x15;
12111        spec->autocfg.speaker_pins[0] = 0x14;
12112        spec->ext_mic.pin = 0x18;
12113        spec->ext_mic.mux_idx = 0;
12114        spec->int_mic.pin = 0x19;
12115        spec->int_mic.mux_idx = 1;
12116        spec->auto_mic = 1;
12117}
12118
12119static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12120        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12121        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12122        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12123        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12124        HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12125        HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12126        HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12127        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12128        { }
12129};
12130
12131static struct hda_verb alc267_quanta_il1_verbs[] = {
12132        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12133        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12134        { }
12135};
12136
12137static void alc267_quanta_il1_setup(struct hda_codec *codec)
12138{
12139        struct alc_spec *spec = codec->spec;
12140        spec->autocfg.hp_pins[0] = 0x15;
12141        spec->autocfg.speaker_pins[0] = 0x14;
12142        spec->ext_mic.pin = 0x18;
12143        spec->ext_mic.mux_idx = 0;
12144        spec->int_mic.pin = 0x19;
12145        spec->int_mic.mux_idx = 1;
12146        spec->auto_mic = 1;
12147}
12148
12149/*
12150 * generic initialization of ADC, input mixers and output mixers
12151 */
12152static struct hda_verb alc268_base_init_verbs[] = {
12153        /* Unmute DAC0-1 and set vol = 0 */
12154        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12155        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12156
12157        /*
12158         * Set up output mixers (0x0c - 0x0e)
12159         */
12160        /* set vol=0 to output mixers */
12161        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12162        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12163
12164        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12165        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12166
12167        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12168        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12169        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12170        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12171        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12172        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12173        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12174        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12175
12176        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12177        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12178        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12179        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12180        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12181
12182        /* set PCBEEP vol = 0, mute connections */
12183        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12184        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12185        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12186
12187        /* Unmute Selector 23h,24h and set the default input to mic-in */
12188
12189        {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12190        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12191        {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12192        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12193
12194        { }
12195};
12196
12197/*
12198 * generic initialization of ADC, input mixers and output mixers
12199 */
12200static struct hda_verb alc268_volume_init_verbs[] = {
12201        /* set output DAC */
12202        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12203        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12204
12205        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12206        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12207        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12208        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12209        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12210
12211        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12212        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12213        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12214
12215        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12216        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12217
12218        /* set PCBEEP vol = 0, mute connections */
12219        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12220        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12221        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12222
12223        { }
12224};
12225
12226static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12227        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12228        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12229        { } /* end */
12230};
12231
12232static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12233        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12234        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12235        _DEFINE_CAPSRC(1),
12236        { } /* end */
12237};
12238
12239static struct snd_kcontrol_new alc268_capture_mixer[] = {
12240        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12241        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12242        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12243        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12244        _DEFINE_CAPSRC(2),
12245        { } /* end */
12246};
12247
12248static struct hda_input_mux alc268_capture_source = {
12249        .num_items = 4,
12250        .items = {
12251                { "Mic", 0x0 },
12252                { "Front Mic", 0x1 },
12253                { "Line", 0x2 },
12254                { "CD", 0x3 },
12255        },
12256};
12257
12258static struct hda_input_mux alc268_acer_capture_source = {
12259        .num_items = 3,
12260        .items = {
12261                { "Mic", 0x0 },
12262                { "Internal Mic", 0x1 },
12263                { "Line", 0x2 },
12264        },
12265};
12266
12267static struct hda_input_mux alc268_acer_dmic_capture_source = {
12268        .num_items = 3,
12269        .items = {
12270                { "Mic", 0x0 },
12271                { "Internal Mic", 0x6 },
12272                { "Line", 0x2 },
12273        },
12274};
12275
12276#ifdef CONFIG_SND_DEBUG
12277static struct snd_kcontrol_new alc268_test_mixer[] = {
12278        /* Volume widgets */
12279        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12280        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12281        HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12282        HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12283        HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12284        HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12285        HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12286        HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12287        HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12288        HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12289        HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12290        HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12291        HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12292        /* The below appears problematic on some hardwares */
12293        /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12294        HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12295        HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12296        HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12297        HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12298
12299        /* Modes for retasking pin widgets */
12300        ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12301        ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12302        ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12303        ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12304
12305        /* Controls for GPIO pins, assuming they are configured as outputs */
12306        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12307        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12308        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12309        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12310
12311        /* Switches to allow the digital SPDIF output pin to be enabled.
12312         * The ALC268 does not have an SPDIF input.
12313         */
12314        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12315
12316        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
12317         * this output to turn on an external amplifier.
12318         */
12319        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12320        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12321
12322        { } /* end */
12323};
12324#endif
12325
12326/* create input playback/capture controls for the given pin */
12327static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12328                                    const char *ctlname, int idx)
12329{
12330        char name[32];
12331        hda_nid_t dac;
12332        int err;
12333
12334        sprintf(name, "%s Playback Volume", ctlname);
12335        switch (nid) {
12336        case 0x14:
12337        case 0x16:
12338                dac = 0x02;
12339                break;
12340        case 0x15:
12341                dac = 0x03;
12342                break;
12343        default:
12344                return 0;
12345        }
12346        if (spec->multiout.dac_nids[0] != dac &&
12347            spec->multiout.dac_nids[1] != dac) {
12348                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12349                                  HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12350                                                      HDA_OUTPUT));
12351                if (err < 0)
12352                        return err;
12353                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12354        }
12355
12356        sprintf(name, "%s Playback Switch", ctlname);
12357        if (nid != 0x16)
12358                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12359                          HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12360        else /* mono */
12361                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12362                          HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12363        if (err < 0)
12364                return err;
12365        return 0;
12366}
12367
12368/* add playback controls from the parsed DAC table */
12369static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12370                                             const struct auto_pin_cfg *cfg)
12371{
12372        hda_nid_t nid;
12373        int err;
12374
12375        spec->multiout.dac_nids = spec->private_dac_nids;
12376
12377        nid = cfg->line_out_pins[0];
12378        if (nid) {
12379                const char *name;
12380                if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12381                        name = "Speaker";
12382                else
12383                        name = "Front";
12384                err = alc268_new_analog_output(spec, nid, name, 0);
12385                if (err < 0)
12386                        return err;
12387        }
12388
12389        nid = cfg->speaker_pins[0];
12390        if (nid == 0x1d) {
12391                err = add_control(spec, ALC_CTL_WIDGET_VOL,
12392                                  "Speaker Playback Volume",
12393                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12394                if (err < 0)
12395                        return err;
12396        } else {
12397                err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12398                if (err < 0)
12399                        return err;
12400        }
12401        nid = cfg->hp_pins[0];
12402        if (nid) {
12403                err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12404                if (err < 0)
12405                        return err;
12406        }
12407
12408        nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12409        if (nid == 0x16) {
12410                err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12411                                  "Mono Playback Switch",
12412                                  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12413                if (err < 0)
12414                        return err;
12415        }
12416        return 0;
12417}
12418
12419/* create playback/capture controls for input pins */
12420static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12421                                                const struct auto_pin_cfg *cfg)
12422{
12423        return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12424}
12425
12426static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12427                                              hda_nid_t nid, int pin_type)
12428{
12429        int idx;
12430
12431        alc_set_pin_output(codec, nid, pin_type);
12432        if (nid == 0x14 || nid == 0x16)
12433                idx = 0;
12434        else
12435                idx = 1;
12436        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12437}
12438
12439static void alc268_auto_init_multi_out(struct hda_codec *codec)
12440{
12441        struct alc_spec *spec = codec->spec;
12442        hda_nid_t nid = spec->autocfg.line_out_pins[0];
12443        if (nid) {
12444                int pin_type = get_pin_type(spec->autocfg.line_out_type);
12445                alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12446        }
12447}
12448
12449static void alc268_auto_init_hp_out(struct hda_codec *codec)
12450{
12451        struct alc_spec *spec = codec->spec;
12452        hda_nid_t pin;
12453
12454        pin = spec->autocfg.hp_pins[0];
12455        if (pin)
12456                alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12457        pin = spec->autocfg.speaker_pins[0];
12458        if (pin)
12459                alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12460}
12461
12462static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12463{
12464        struct alc_spec *spec = codec->spec;
12465        hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12466        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12467        hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12468        unsigned int    dac_vol1, dac_vol2;
12469
12470        if (line_nid == 0x1d || speaker_nid == 0x1d) {
12471                snd_hda_codec_write(codec, speaker_nid, 0,
12472                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12473                /* mute mixer inputs from 0x1d */
12474                snd_hda_codec_write(codec, 0x0f, 0,
12475                                    AC_VERB_SET_AMP_GAIN_MUTE,
12476                                    AMP_IN_UNMUTE(1));
12477                snd_hda_codec_write(codec, 0x10, 0,
12478                                    AC_VERB_SET_AMP_GAIN_MUTE,
12479                                    AMP_IN_UNMUTE(1));
12480        } else {
12481                /* unmute mixer inputs from 0x1d */
12482                snd_hda_codec_write(codec, 0x0f, 0,
12483                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12484                snd_hda_codec_write(codec, 0x10, 0,
12485                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12486        }
12487
12488        dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
12489        if (line_nid == 0x14)
12490                dac_vol2 = AMP_OUT_ZERO;
12491        else if (line_nid == 0x15)
12492                dac_vol1 = AMP_OUT_ZERO;
12493        if (hp_nid == 0x14)
12494                dac_vol2 = AMP_OUT_ZERO;
12495        else if (hp_nid == 0x15)
12496                dac_vol1 = AMP_OUT_ZERO;
12497        if (line_nid != 0x16 || hp_nid != 0x16 ||
12498            spec->autocfg.line_out_pins[1] != 0x16 ||
12499            spec->autocfg.line_out_pins[2] != 0x16)
12500                dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12501
12502        snd_hda_codec_write(codec, 0x02, 0,
12503                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12504        snd_hda_codec_write(codec, 0x03, 0,
12505                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12506}
12507
12508/* pcm configuration: identical with ALC880 */
12509#define alc268_pcm_analog_playback      alc880_pcm_analog_playback
12510#define alc268_pcm_analog_capture       alc880_pcm_analog_capture
12511#define alc268_pcm_analog_alt_capture   alc880_pcm_analog_alt_capture
12512#define alc268_pcm_digital_playback     alc880_pcm_digital_playback
12513
12514/*
12515 * BIOS auto configuration
12516 */
12517static int alc268_parse_auto_config(struct hda_codec *codec)
12518{
12519        struct alc_spec *spec = codec->spec;
12520        int err;
12521        static hda_nid_t alc268_ignore[] = { 0 };
12522
12523        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12524                                           alc268_ignore);
12525        if (err < 0)
12526                return err;
12527        if (!spec->autocfg.line_outs) {
12528                if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12529                        spec->multiout.max_channels = 2;
12530                        spec->no_analog = 1;
12531                        goto dig_only;
12532                }
12533                return 0; /* can't find valid BIOS pin config */
12534        }
12535        err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12536        if (err < 0)
12537                return err;
12538        err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12539        if (err < 0)
12540                return err;
12541
12542        spec->multiout.max_channels = 2;
12543
12544 dig_only:
12545        /* digital only support output */
12546        if (spec->autocfg.dig_outs) {
12547                spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12548                spec->dig_out_type = spec->autocfg.dig_out_type[0];
12549        }
12550        if (spec->kctls.list)
12551                add_mixer(spec, spec->kctls.list);
12552
12553        if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12554                add_mixer(spec, alc268_beep_mixer);
12555
12556        add_verb(spec, alc268_volume_init_verbs);
12557        spec->num_mux_defs = 2;
12558        spec->input_mux = &spec->private_imux[0];
12559
12560        err = alc_auto_add_mic_boost(codec);
12561        if (err < 0)
12562                return err;
12563
12564        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12565
12566        return 1;
12567}
12568
12569#define alc268_auto_init_analog_input   alc882_auto_init_analog_input
12570
12571/* init callback for auto-configuration model -- overriding the default init */
12572static void alc268_auto_init(struct hda_codec *codec)
12573{
12574        struct alc_spec *spec = codec->spec;
12575        alc268_auto_init_multi_out(codec);
12576        alc268_auto_init_hp_out(codec);
12577        alc268_auto_init_mono_speaker_out(codec);
12578        alc268_auto_init_analog_input(codec);
12579        if (spec->unsol_event)
12580                alc_inithook(codec);
12581}
12582
12583/*
12584 * configuration and preset
12585 */
12586static const char *alc268_models[ALC268_MODEL_LAST] = {
12587        [ALC267_QUANTA_IL1]     = "quanta-il1",
12588        [ALC268_3ST]            = "3stack",
12589        [ALC268_TOSHIBA]        = "toshiba",
12590        [ALC268_ACER]           = "acer",
12591        [ALC268_ACER_DMIC]      = "acer-dmic",
12592        [ALC268_ACER_ASPIRE_ONE]        = "acer-aspire",
12593        [ALC268_DELL]           = "dell",
12594        [ALC268_ZEPTO]          = "zepto",
12595#ifdef CONFIG_SND_DEBUG
12596        [ALC268_TEST]           = "test",
12597#endif
12598        [ALC268_AUTO]           = "auto",
12599};
12600
12601static struct snd_pci_quirk alc268_cfg_tbl[] = {
12602        SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12603        SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12604        SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12605        SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12606        SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12607        SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12608                                                ALC268_ACER_ASPIRE_ONE),
12609        SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12610        SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
12611                        "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
12612        /* almost compatible with toshiba but with optional digital outs;
12613         * auto-probing seems working fine
12614         */
12615        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12616                           ALC268_AUTO),
12617        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12618        SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12619        SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12620        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12621        SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12622        SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12623        {}
12624};
12625
12626/* Toshiba laptops have no unique PCI SSID but only codec SSID */
12627static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12628        SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12629        SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12630        SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12631                           ALC268_TOSHIBA),
12632        {}
12633};
12634
12635static struct alc_config_preset alc268_presets[] = {
12636        [ALC267_QUANTA_IL1] = {
12637                .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12638                            alc268_capture_nosrc_mixer },
12639                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12640                                alc267_quanta_il1_verbs },
12641                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12642                .dac_nids = alc268_dac_nids,
12643                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12644                .adc_nids = alc268_adc_nids_alt,
12645                .hp_nid = 0x03,
12646                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12647                .channel_mode = alc268_modes,
12648                .unsol_event = alc_sku_unsol_event,
12649                .setup = alc267_quanta_il1_setup,
12650                .init_hook = alc_inithook,
12651        },
12652        [ALC268_3ST] = {
12653                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12654                            alc268_beep_mixer },
12655                .init_verbs = { alc268_base_init_verbs },
12656                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12657                .dac_nids = alc268_dac_nids,
12658                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12659                .adc_nids = alc268_adc_nids_alt,
12660                .capsrc_nids = alc268_capsrc_nids,
12661                .hp_nid = 0x03,
12662                .dig_out_nid = ALC268_DIGOUT_NID,
12663                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12664                .channel_mode = alc268_modes,
12665                .input_mux = &alc268_capture_source,
12666        },
12667        [ALC268_TOSHIBA] = {
12668                .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12669                            alc268_beep_mixer },
12670                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12671                                alc268_toshiba_verbs },
12672                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12673                .dac_nids = alc268_dac_nids,
12674                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12675                .adc_nids = alc268_adc_nids_alt,
12676                .capsrc_nids = alc268_capsrc_nids,
12677                .hp_nid = 0x03,
12678                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12679                .channel_mode = alc268_modes,
12680                .input_mux = &alc268_capture_source,
12681                .unsol_event = alc268_toshiba_unsol_event,
12682                .setup = alc268_toshiba_setup,
12683                .init_hook = alc268_toshiba_automute,
12684        },
12685        [ALC268_ACER] = {
12686                .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12687                            alc268_beep_mixer },
12688                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12689                                alc268_acer_verbs },
12690                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12691                .dac_nids = alc268_dac_nids,
12692                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12693                .adc_nids = alc268_adc_nids_alt,
12694                .capsrc_nids = alc268_capsrc_nids,
12695                .hp_nid = 0x02,
12696                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12697                .channel_mode = alc268_modes,
12698                .input_mux = &alc268_acer_capture_source,
12699                .unsol_event = alc268_acer_unsol_event,
12700                .init_hook = alc268_acer_init_hook,
12701        },
12702        [ALC268_ACER_DMIC] = {
12703                .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12704                            alc268_beep_mixer },
12705                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12706                                alc268_acer_verbs },
12707                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12708                .dac_nids = alc268_dac_nids,
12709                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12710                .adc_nids = alc268_adc_nids_alt,
12711                .capsrc_nids = alc268_capsrc_nids,
12712                .hp_nid = 0x02,
12713                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12714                .channel_mode = alc268_modes,
12715                .input_mux = &alc268_acer_dmic_capture_source,
12716                .unsol_event = alc268_acer_unsol_event,
12717                .init_hook = alc268_acer_init_hook,
12718        },
12719        [ALC268_ACER_ASPIRE_ONE] = {
12720                .mixers = { alc268_acer_aspire_one_mixer,
12721                            alc268_beep_mixer,
12722                            alc268_capture_nosrc_mixer },
12723                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12724                                alc268_acer_aspire_one_verbs },
12725                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12726                .dac_nids = alc268_dac_nids,
12727                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12728                .adc_nids = alc268_adc_nids_alt,
12729                .capsrc_nids = alc268_capsrc_nids,
12730                .hp_nid = 0x03,
12731                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12732                .channel_mode = alc268_modes,
12733                .unsol_event = alc268_acer_lc_unsol_event,
12734                .setup = alc268_acer_lc_setup,
12735                .init_hook = alc268_acer_lc_init_hook,
12736        },
12737        [ALC268_DELL] = {
12738                .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12739                            alc268_capture_nosrc_mixer },
12740                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12741                                alc268_dell_verbs },
12742                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12743                .dac_nids = alc268_dac_nids,
12744                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12745                .adc_nids = alc268_adc_nids_alt,
12746                .capsrc_nids = alc268_capsrc_nids,
12747                .hp_nid = 0x02,
12748                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12749                .channel_mode = alc268_modes,
12750                .unsol_event = alc_sku_unsol_event,
12751                .setup = alc268_dell_setup,
12752                .init_hook = alc_inithook,
12753        },
12754        [ALC268_ZEPTO] = {
12755                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12756                            alc268_beep_mixer },
12757                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12758                                alc268_toshiba_verbs },
12759                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12760                .dac_nids = alc268_dac_nids,
12761                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12762                .adc_nids = alc268_adc_nids_alt,
12763                .capsrc_nids = alc268_capsrc_nids,
12764                .hp_nid = 0x03,
12765                .dig_out_nid = ALC268_DIGOUT_NID,
12766                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12767                .channel_mode = alc268_modes,
12768                .input_mux = &alc268_capture_source,
12769                .setup = alc268_toshiba_setup,
12770                .init_hook = alc268_toshiba_automute,
12771        },
12772#ifdef CONFIG_SND_DEBUG
12773        [ALC268_TEST] = {
12774                .mixers = { alc268_test_mixer, alc268_capture_mixer },
12775                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12776                                alc268_volume_init_verbs },
12777                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12778                .dac_nids = alc268_dac_nids,
12779                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12780                .adc_nids = alc268_adc_nids_alt,
12781                .capsrc_nids = alc268_capsrc_nids,
12782                .hp_nid = 0x03,
12783                .dig_out_nid = ALC268_DIGOUT_NID,
12784                .num_channel_mode = ARRAY_SIZE(alc268_modes),
12785                .channel_mode = alc268_modes,
12786                .input_mux = &alc268_capture_source,
12787        },
12788#endif
12789};
12790
12791static int patch_alc268(struct hda_codec *codec)
12792{
12793        struct alc_spec *spec;
12794        int board_config;
12795        int i, has_beep, err;
12796
12797        spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12798        if (spec == NULL)
12799                return -ENOMEM;
12800
12801        codec->spec = spec;
12802
12803        board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12804                                                  alc268_models,
12805                                                  alc268_cfg_tbl);
12806
12807        if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12808                board_config = snd_hda_check_board_codec_sid_config(codec,
12809                        ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12810
12811        if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12812                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12813                       codec->chip_name);
12814                board_config = ALC268_AUTO;
12815        }
12816
12817        if (board_config == ALC268_AUTO) {
12818                /* automatic parse from the BIOS config */
12819                err = alc268_parse_auto_config(codec);
12820                if (err < 0) {
12821                        alc_free(codec);
12822                        return err;
12823                } else if (!err) {
12824                        printk(KERN_INFO
12825                               "hda_codec: Cannot set up configuration "
12826                               "from BIOS.  Using base mode...\n");
12827                        board_config = ALC268_3ST;
12828                }
12829        }
12830
12831        if (board_config != ALC268_AUTO)
12832                setup_preset(codec, &alc268_presets[board_config]);
12833
12834        spec->stream_analog_playback = &alc268_pcm_analog_playback;
12835        spec->stream_analog_capture = &alc268_pcm_analog_capture;
12836        spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12837
12838        spec->stream_digital_playback = &alc268_pcm_digital_playback;
12839
12840        has_beep = 0;
12841        for (i = 0; i < spec->num_mixers; i++) {
12842                if (spec->mixers[i] == alc268_beep_mixer) {
12843                        has_beep = 1;
12844                        break;
12845                }
12846        }
12847
12848        if (has_beep) {
12849                err = snd_hda_attach_beep_device(codec, 0x1);
12850                if (err < 0) {
12851                        alc_free(codec);
12852                        return err;
12853                }
12854                if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12855                        /* override the amp caps for beep generator */
12856                        snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12857                                          (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12858                                          (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12859                                          (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12860                                          (0 << AC_AMPCAP_MUTE_SHIFT));
12861        }
12862
12863        if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12864                /* check whether NID 0x07 is valid */
12865                unsigned int wcap = get_wcaps(codec, 0x07);
12866                int i;
12867
12868                spec->capsrc_nids = alc268_capsrc_nids;
12869                /* get type */
12870                wcap = get_wcaps_type(wcap);
12871                if (spec->auto_mic ||
12872                    wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12873                        spec->adc_nids = alc268_adc_nids_alt;
12874                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12875                        if (spec->auto_mic)
12876                                fixup_automic_adc(codec);
12877                        if (spec->auto_mic || spec->input_mux->num_items == 1)
12878                                add_mixer(spec, alc268_capture_nosrc_mixer);
12879                        else
12880                                add_mixer(spec, alc268_capture_alt_mixer);
12881                } else {
12882                        spec->adc_nids = alc268_adc_nids;
12883                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12884                        add_mixer(spec, alc268_capture_mixer);
12885                }
12886                /* set default input source */
12887                for (i = 0; i < spec->num_adc_nids; i++)
12888                        snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12889                                0, AC_VERB_SET_CONNECT_SEL,
12890                                i < spec->num_mux_defs ?
12891                                spec->input_mux[i].items[0].index :
12892                                spec->input_mux->items[0].index);
12893        }
12894
12895        spec->vmaster_nid = 0x02;
12896
12897        codec->patch_ops = alc_patch_ops;
12898        if (board_config == ALC268_AUTO)
12899                spec->init_hook = alc268_auto_init;
12900
12901        codec->proc_widget_hook = print_realtek_coef;
12902
12903        return 0;
12904}
12905
12906/*
12907 *  ALC269 channel source setting (2 channel)
12908 */
12909#define ALC269_DIGOUT_NID       ALC880_DIGOUT_NID
12910
12911#define alc269_dac_nids         alc260_dac_nids
12912
12913static hda_nid_t alc269_adc_nids[1] = {
12914        /* ADC1 */
12915        0x08,
12916};
12917
12918static hda_nid_t alc269_capsrc_nids[1] = {
12919        0x23,
12920};
12921
12922/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12923 *       not a mux!
12924 */
12925
12926#define alc269_modes            alc260_modes
12927#define alc269_capture_source   alc880_lg_lw_capture_source
12928
12929static struct snd_kcontrol_new alc269_base_mixer[] = {
12930        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12931        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12932        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12933        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12934        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12935        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12936        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12937        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12938        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12939        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12940        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12941        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12942        { } /* end */
12943};
12944
12945static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12946        /* output mixer control */
12947        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12948        {
12949                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12950                .name = "Master Playback Switch",
12951                .info = snd_hda_mixer_amp_switch_info,
12952                .get = snd_hda_mixer_amp_switch_get,
12953                .put = alc268_acer_master_sw_put,
12954                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12955        },
12956        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12957        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12958        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12959        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12960        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12961        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12962        { }
12963};
12964
12965static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12966        /* output mixer control */
12967        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12968        {
12969                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12970                .name = "Master Playback Switch",
12971                .info = snd_hda_mixer_amp_switch_info,
12972                .get = snd_hda_mixer_amp_switch_get,
12973                .put = alc268_acer_master_sw_put,
12974                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12975        },
12976        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12977        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12978        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12979        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12980        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12981        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12982        HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12983        HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12984        HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12985        { }
12986};
12987
12988static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12989        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12990        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12991        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12992        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12993        { } /* end */
12994};
12995
12996/* capture mixer elements */
12997static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12998        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12999        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13000        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13001        { } /* end */
13002};
13003
13004/* FSC amilo */
13005#define alc269_fujitsu_mixer    alc269_eeepc_mixer
13006
13007static struct hda_verb alc269_quanta_fl1_verbs[] = {
13008        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13009        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13010        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13011        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13012        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13013        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13014        { }
13015};
13016
13017static struct hda_verb alc269_lifebook_verbs[] = {
13018        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13019        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13020        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13021        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13022        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13023        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13024        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13025        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13026        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13027        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13028        { }
13029};
13030
13031/* toggle speaker-output according to the hp-jack state */
13032static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13033{
13034        unsigned int present;
13035        unsigned char bits;
13036
13037        present = snd_hda_codec_read(codec, 0x15, 0,
13038                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13039        bits = present ? AMP_IN_MUTE(0) : 0;
13040        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13041                        AMP_IN_MUTE(0), bits);
13042        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13043                        AMP_IN_MUTE(0), bits);
13044
13045        snd_hda_codec_write(codec, 0x20, 0,
13046                        AC_VERB_SET_COEF_INDEX, 0x0c);
13047        snd_hda_codec_write(codec, 0x20, 0,
13048                        AC_VERB_SET_PROC_COEF, 0x680);
13049
13050        snd_hda_codec_write(codec, 0x20, 0,
13051                        AC_VERB_SET_COEF_INDEX, 0x0c);
13052        snd_hda_codec_write(codec, 0x20, 0,
13053                        AC_VERB_SET_PROC_COEF, 0x480);
13054}
13055
13056/* toggle speaker-output according to the hp-jacks state */
13057static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13058{
13059        unsigned int present;
13060        unsigned char bits;
13061
13062        /* Check laptop headphone socket */
13063        present = snd_hda_codec_read(codec, 0x15, 0,
13064                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13065
13066        /* Check port replicator headphone socket */
13067        present |= snd_hda_codec_read(codec, 0x1a, 0,
13068                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13069
13070        bits = present ? AMP_IN_MUTE(0) : 0;
13071        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13072                        AMP_IN_MUTE(0), bits);
13073        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13074                        AMP_IN_MUTE(0), bits);
13075
13076        snd_hda_codec_write(codec, 0x20, 0,
13077                        AC_VERB_SET_COEF_INDEX, 0x0c);
13078        snd_hda_codec_write(codec, 0x20, 0,
13079                        AC_VERB_SET_PROC_COEF, 0x680);
13080
13081        snd_hda_codec_write(codec, 0x20, 0,
13082                        AC_VERB_SET_COEF_INDEX, 0x0c);
13083        snd_hda_codec_write(codec, 0x20, 0,
13084                        AC_VERB_SET_PROC_COEF, 0x480);
13085}
13086
13087static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13088{
13089        unsigned int present_laptop;
13090        unsigned int present_dock;
13091
13092        present_laptop = snd_hda_codec_read(codec, 0x18, 0,
13093                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13094
13095        present_dock = snd_hda_codec_read(codec, 0x1b, 0,
13096                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13097
13098        /* Laptop mic port overrides dock mic port, design decision */
13099        if (present_dock)
13100                snd_hda_codec_write(codec, 0x23, 0,
13101                                AC_VERB_SET_CONNECT_SEL, 0x3);
13102        if (present_laptop)
13103                snd_hda_codec_write(codec, 0x23, 0,
13104                                AC_VERB_SET_CONNECT_SEL, 0x0);
13105        if (!present_dock && !present_laptop)
13106                snd_hda_codec_write(codec, 0x23, 0,
13107                                AC_VERB_SET_CONNECT_SEL, 0x1);
13108}
13109
13110static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13111                                    unsigned int res)
13112{
13113        switch (res >> 26) {
13114        case ALC880_HP_EVENT:
13115                alc269_quanta_fl1_speaker_automute(codec);
13116                break;
13117        case ALC880_MIC_EVENT:
13118                alc_mic_automute(codec);
13119                break;
13120        }
13121}
13122
13123static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13124                                        unsigned int res)
13125{
13126        if ((res >> 26) == ALC880_HP_EVENT)
13127                alc269_lifebook_speaker_automute(codec);
13128        if ((res >> 26) == ALC880_MIC_EVENT)
13129                alc269_lifebook_mic_autoswitch(codec);
13130}
13131
13132static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13133{
13134        struct alc_spec *spec = codec->spec;
13135        spec->ext_mic.pin = 0x18;
13136        spec->ext_mic.mux_idx = 0;
13137        spec->int_mic.pin = 0x19;
13138        spec->int_mic.mux_idx = 1;
13139        spec->auto_mic = 1;
13140}
13141
13142static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13143{
13144        alc269_quanta_fl1_speaker_automute(codec);
13145        alc_mic_automute(codec);
13146}
13147
13148static void alc269_lifebook_init_hook(struct hda_codec *codec)
13149{
13150        alc269_lifebook_speaker_automute(codec);
13151        alc269_lifebook_mic_autoswitch(codec);
13152}
13153
13154static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13155        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13156        {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13157        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13158        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13159        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13160        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13161        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13162        {}
13163};
13164
13165static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13166        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13167        {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13168        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13169        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13170        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13171        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13172        {}
13173};
13174
13175/* toggle speaker-output according to the hp-jack state */
13176static void alc269_speaker_automute(struct hda_codec *codec)
13177{
13178        unsigned int present;
13179        unsigned char bits;
13180
13181        present = snd_hda_codec_read(codec, 0x15, 0,
13182                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13183        bits = present ? AMP_IN_MUTE(0) : 0;
13184        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13185                                AMP_IN_MUTE(0), bits);
13186        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13187                                AMP_IN_MUTE(0), bits);
13188}
13189
13190/* unsolicited event for HP jack sensing */
13191static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13192                                     unsigned int res)
13193{
13194        switch (res >> 26) {
13195        case ALC880_HP_EVENT:
13196                alc269_speaker_automute(codec);
13197                break;
13198        case ALC880_MIC_EVENT:
13199                alc_mic_automute(codec);
13200                break;
13201        }
13202}
13203
13204static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13205{
13206        struct alc_spec *spec = codec->spec;
13207        spec->ext_mic.pin = 0x18;
13208        spec->ext_mic.mux_idx = 0;
13209        spec->int_mic.pin = 0x12;
13210        spec->int_mic.mux_idx = 5;
13211        spec->auto_mic = 1;
13212}
13213
13214static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13215{
13216        struct alc_spec *spec = codec->spec;
13217        spec->ext_mic.pin = 0x18;
13218        spec->ext_mic.mux_idx = 0;
13219        spec->int_mic.pin = 0x19;
13220        spec->int_mic.mux_idx = 1;
13221        spec->auto_mic = 1;
13222}
13223
13224static void alc269_eeepc_inithook(struct hda_codec *codec)
13225{
13226        alc269_speaker_automute(codec);
13227        alc_mic_automute(codec);
13228}
13229
13230/*
13231 * generic initialization of ADC, input mixers and output mixers
13232 */
13233static struct hda_verb alc269_init_verbs[] = {
13234        /*
13235         * Unmute ADC0 and set the default input to mic-in
13236         */
13237        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13238
13239        /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13240         * analog-loopback mixer widget
13241         * Note: PASD motherboards uses the Line In 2 as the input for
13242         * front panel mic (mic 2)
13243         */
13244        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13245        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13246        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13247        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13248        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13249        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13250
13251        /*
13252         * Set up output mixers (0x0c - 0x0e)
13253         */
13254        /* set vol=0 to output mixers */
13255        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13256        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13257
13258        /* set up input amps for analog loopback */
13259        /* Amp Indices: DAC = 0, mixer = 1 */
13260        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13261        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13262        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13263        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13264        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13265        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13266
13267        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13268        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13269        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13270        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13271        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13272        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13273        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13274
13275        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13276        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13277        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13278        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13279        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13280        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13281        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13282
13283        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13284        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13285
13286        /* FIXME: use matrix-type input source selection */
13287        /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13288        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13289        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13290        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13291        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13292        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13293
13294        /* set EAPD */
13295        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13296        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13297        { }
13298};
13299
13300#define alc269_auto_create_multi_out_ctls \
13301        alc268_auto_create_multi_out_ctls
13302#define alc269_auto_create_input_ctls \
13303        alc268_auto_create_input_ctls
13304
13305#ifdef CONFIG_SND_HDA_POWER_SAVE
13306#define alc269_loopbacks        alc880_loopbacks
13307#endif
13308
13309/* pcm configuration: identical with ALC880 */
13310#define alc269_pcm_analog_playback      alc880_pcm_analog_playback
13311#define alc269_pcm_analog_capture       alc880_pcm_analog_capture
13312#define alc269_pcm_digital_playback     alc880_pcm_digital_playback
13313#define alc269_pcm_digital_capture      alc880_pcm_digital_capture
13314
13315static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13316        .substreams = 1,
13317        .channels_min = 2,
13318        .channels_max = 8,
13319        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13320        /* NID is set in alc_build_pcms */
13321        .ops = {
13322                .open = alc880_playback_pcm_open,
13323                .prepare = alc880_playback_pcm_prepare,
13324                .cleanup = alc880_playback_pcm_cleanup
13325        },
13326};
13327
13328static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13329        .substreams = 1,
13330        .channels_min = 2,
13331        .channels_max = 2,
13332        .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13333        /* NID is set in alc_build_pcms */
13334};
13335
13336/*
13337 * BIOS auto configuration
13338 */
13339static int alc269_parse_auto_config(struct hda_codec *codec)
13340{
13341        struct alc_spec *spec = codec->spec;
13342        int err;
13343        static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13344
13345        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13346                                           alc269_ignore);
13347        if (err < 0)
13348                return err;
13349
13350        err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13351        if (err < 0)
13352                return err;
13353        err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13354        if (err < 0)
13355                return err;
13356
13357        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13358
13359        if (spec->autocfg.dig_outs)
13360                spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13361
13362        if (spec->kctls.list)
13363                add_mixer(spec, spec->kctls.list);
13364
13365        add_verb(spec, alc269_init_verbs);
13366        spec->num_mux_defs = 1;
13367        spec->input_mux = &spec->private_imux[0];
13368        /* set default input source */
13369        snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13370                                  0, AC_VERB_SET_CONNECT_SEL,
13371                                  spec->input_mux->items[0].index);
13372
13373        err = alc_auto_add_mic_boost(codec);
13374        if (err < 0)
13375                return err;
13376
13377        if (!spec->cap_mixer && !spec->no_analog)
13378                set_capture_mixer(codec);
13379
13380        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13381
13382        return 1;
13383}
13384
13385#define alc269_auto_init_multi_out      alc268_auto_init_multi_out
13386#define alc269_auto_init_hp_out         alc268_auto_init_hp_out
13387#define alc269_auto_init_analog_input   alc882_auto_init_analog_input
13388
13389
13390/* init callback for auto-configuration model -- overriding the default init */
13391static void alc269_auto_init(struct hda_codec *codec)
13392{
13393        struct alc_spec *spec = codec->spec;
13394        alc269_auto_init_multi_out(codec);
13395        alc269_auto_init_hp_out(codec);
13396        alc269_auto_init_analog_input(codec);
13397        if (spec->unsol_event)
13398                alc_inithook(codec);
13399}
13400
13401/*
13402 * configuration and preset
13403 */
13404static const char *alc269_models[ALC269_MODEL_LAST] = {
13405        [ALC269_BASIC]                  = "basic",
13406        [ALC269_QUANTA_FL1]             = "quanta",
13407        [ALC269_ASUS_EEEPC_P703]        = "eeepc-p703",
13408        [ALC269_ASUS_EEEPC_P901]        = "eeepc-p901",
13409        [ALC269_FUJITSU]                = "fujitsu",
13410        [ALC269_LIFEBOOK]               = "lifebook",
13411        [ALC269_AUTO]                   = "auto",
13412};
13413
13414static struct snd_pci_quirk alc269_cfg_tbl[] = {
13415        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13416        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13417                      ALC269_ASUS_EEEPC_P703),
13418        SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13419        SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13420        SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13421        SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13422        SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13423        SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13424        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13425                      ALC269_ASUS_EEEPC_P901),
13426        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13427                      ALC269_ASUS_EEEPC_P901),
13428        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13429        SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13430        SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13431        {}
13432};
13433
13434static struct alc_config_preset alc269_presets[] = {
13435        [ALC269_BASIC] = {
13436                .mixers = { alc269_base_mixer },
13437                .init_verbs = { alc269_init_verbs },
13438                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13439                .dac_nids = alc269_dac_nids,
13440                .hp_nid = 0x03,
13441                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13442                .channel_mode = alc269_modes,
13443                .input_mux = &alc269_capture_source,
13444        },
13445        [ALC269_QUANTA_FL1] = {
13446                .mixers = { alc269_quanta_fl1_mixer },
13447                .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13448                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13449                .dac_nids = alc269_dac_nids,
13450                .hp_nid = 0x03,
13451                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13452                .channel_mode = alc269_modes,
13453                .input_mux = &alc269_capture_source,
13454                .unsol_event = alc269_quanta_fl1_unsol_event,
13455                .setup = alc269_quanta_fl1_setup,
13456                .init_hook = alc269_quanta_fl1_init_hook,
13457        },
13458        [ALC269_ASUS_EEEPC_P703] = {
13459                .mixers = { alc269_eeepc_mixer },
13460                .cap_mixer = alc269_epc_capture_mixer,
13461                .init_verbs = { alc269_init_verbs,
13462                                alc269_eeepc_amic_init_verbs },
13463                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13464                .dac_nids = alc269_dac_nids,
13465                .hp_nid = 0x03,
13466                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13467                .channel_mode = alc269_modes,
13468                .unsol_event = alc269_eeepc_unsol_event,
13469                .setup = alc269_eeepc_amic_setup,
13470                .init_hook = alc269_eeepc_inithook,
13471        },
13472        [ALC269_ASUS_EEEPC_P901] = {
13473                .mixers = { alc269_eeepc_mixer },
13474                .cap_mixer = alc269_epc_capture_mixer,
13475                .init_verbs = { alc269_init_verbs,
13476                                alc269_eeepc_dmic_init_verbs },
13477                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13478                .dac_nids = alc269_dac_nids,
13479                .hp_nid = 0x03,
13480                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13481                .channel_mode = alc269_modes,
13482                .unsol_event = alc269_eeepc_unsol_event,
13483                .setup = alc269_eeepc_dmic_setup,
13484                .init_hook = alc269_eeepc_inithook,
13485        },
13486        [ALC269_FUJITSU] = {
13487                .mixers = { alc269_fujitsu_mixer },
13488                .cap_mixer = alc269_epc_capture_mixer,
13489                .init_verbs = { alc269_init_verbs,
13490                                alc269_eeepc_dmic_init_verbs },
13491                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13492                .dac_nids = alc269_dac_nids,
13493                .hp_nid = 0x03,
13494                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13495                .channel_mode = alc269_modes,
13496                .unsol_event = alc269_eeepc_unsol_event,
13497                .setup = alc269_eeepc_dmic_setup,
13498                .init_hook = alc269_eeepc_inithook,
13499        },
13500        [ALC269_LIFEBOOK] = {
13501                .mixers = { alc269_lifebook_mixer },
13502                .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13503                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13504                .dac_nids = alc269_dac_nids,
13505                .hp_nid = 0x03,
13506                .num_channel_mode = ARRAY_SIZE(alc269_modes),
13507                .channel_mode = alc269_modes,
13508                .input_mux = &alc269_capture_source,
13509                .unsol_event = alc269_lifebook_unsol_event,
13510                .init_hook = alc269_lifebook_init_hook,
13511        },
13512};
13513
13514static int patch_alc269(struct hda_codec *codec)
13515{
13516        struct alc_spec *spec;
13517        int board_config;
13518        int err;
13519
13520        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13521        if (spec == NULL)
13522                return -ENOMEM;
13523
13524        codec->spec = spec;
13525
13526        alc_fix_pll_init(codec, 0x20, 0x04, 15);
13527
13528        board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13529                                                  alc269_models,
13530                                                  alc269_cfg_tbl);
13531
13532        if (board_config < 0) {
13533                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13534                       codec->chip_name);
13535                board_config = ALC269_AUTO;
13536        }
13537
13538        if (board_config == ALC269_AUTO) {
13539                /* automatic parse from the BIOS config */
13540                err = alc269_parse_auto_config(codec);
13541                if (err < 0) {
13542                        alc_free(codec);
13543                        return err;
13544                } else if (!err) {
13545                        printk(KERN_INFO
13546                               "hda_codec: Cannot set up configuration "
13547                               "from BIOS.  Using base mode...\n");
13548                        board_config = ALC269_BASIC;
13549                }
13550        }
13551
13552        err = snd_hda_attach_beep_device(codec, 0x1);
13553        if (err < 0) {
13554                alc_free(codec);
13555                return err;
13556        }
13557
13558        if (board_config != ALC269_AUTO)
13559                setup_preset(codec, &alc269_presets[board_config]);
13560
13561        if (codec->subsystem_id == 0x17aa3bf8) {
13562                /* Due to a hardware problem on Lenovo Ideadpad, we need to
13563                 * fix the sample rate of analog I/O to 44.1kHz
13564                 */
13565                spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13566                spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13567        } else {
13568                spec->stream_analog_playback = &alc269_pcm_analog_playback;
13569                spec->stream_analog_capture = &alc269_pcm_analog_capture;
13570        }
13571        spec->stream_digital_playback = &alc269_pcm_digital_playback;
13572        spec->stream_digital_capture = &alc269_pcm_digital_capture;
13573
13574        spec->adc_nids = alc269_adc_nids;
13575        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13576        spec->capsrc_nids = alc269_capsrc_nids;
13577        if (!spec->cap_mixer)
13578                set_capture_mixer(codec);
13579        set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13580
13581        spec->vmaster_nid = 0x02;
13582
13583        codec->patch_ops = alc_patch_ops;
13584        if (board_config == ALC269_AUTO)
13585                spec->init_hook = alc269_auto_init;
13586#ifdef CONFIG_SND_HDA_POWER_SAVE
13587        if (!spec->loopback.amplist)
13588                spec->loopback.amplist = alc269_loopbacks;
13589#endif
13590        codec->proc_widget_hook = print_realtek_coef;
13591
13592        return 0;
13593}
13594
13595/*
13596 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
13597 */
13598
13599/*
13600 * set the path ways for 2 channel output
13601 * need to set the codec line out and mic 1 pin widgets to inputs
13602 */
13603static struct hda_verb alc861_threestack_ch2_init[] = {
13604        /* set pin widget 1Ah (line in) for input */
13605        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13606        /* set pin widget 18h (mic1/2) for input, for mic also enable
13607         * the vref
13608         */
13609        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13610
13611        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13612#if 0
13613        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13614        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13615#endif
13616        { } /* end */
13617};
13618/*
13619 * 6ch mode
13620 * need to set the codec line out and mic 1 pin widgets to outputs
13621 */
13622static struct hda_verb alc861_threestack_ch6_init[] = {
13623        /* set pin widget 1Ah (line in) for output (Back Surround)*/
13624        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13625        /* set pin widget 18h (mic1) for output (CLFE)*/
13626        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13627
13628        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13629        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13630
13631        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13632#if 0
13633        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13634        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13635#endif
13636        { } /* end */
13637};
13638
13639static struct hda_channel_mode alc861_threestack_modes[2] = {
13640        { 2, alc861_threestack_ch2_init },
13641        { 6, alc861_threestack_ch6_init },
13642};
13643/* Set mic1 as input and unmute the mixer */
13644static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13645        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13646        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13647        { } /* end */
13648};
13649/* Set mic1 as output and mute mixer */
13650static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13651        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13652        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13653        { } /* end */
13654};
13655
13656static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13657        { 2, alc861_uniwill_m31_ch2_init },
13658        { 4, alc861_uniwill_m31_ch4_init },
13659};
13660
13661/* Set mic1 and line-in as input and unmute the mixer */
13662static struct hda_verb alc861_asus_ch2_init[] = {
13663        /* set pin widget 1Ah (line in) for input */
13664        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13665        /* set pin widget 18h (mic1/2) for input, for mic also enable
13666         * the vref
13667         */
13668        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13669
13670        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13671#if 0
13672        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13673        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13674#endif
13675        { } /* end */
13676};
13677/* Set mic1 nad line-in as output and mute mixer */
13678static struct hda_verb alc861_asus_ch6_init[] = {
13679        /* set pin widget 1Ah (line in) for output (Back Surround)*/
13680        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13681        /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13682        /* set pin widget 18h (mic1) for output (CLFE)*/
13683        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13684        /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13685        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13686        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13687
13688        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13689#if 0
13690        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13691        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13692#endif
13693        { } /* end */
13694};
13695
13696static struct hda_channel_mode alc861_asus_modes[2] = {
13697        { 2, alc861_asus_ch2_init },
13698        { 6, alc861_asus_ch6_init },
13699};
13700
13701/* patch-ALC861 */
13702
13703static struct snd_kcontrol_new alc861_base_mixer[] = {
13704        /* output mixer control */
13705        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13706        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13707        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13708        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13709        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13710
13711        /*Input mixer control */
13712        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13713           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13714        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13715        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13716        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13717        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13718        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13719        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13720        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13721        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13722
13723        { } /* end */
13724};
13725
13726static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13727        /* output mixer control */
13728        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13729        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13730        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13731        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13732        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13733
13734        /* Input mixer control */
13735        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13736           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13737        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13738        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13739        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13740        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13741        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13742        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13743        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13744        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13745
13746        {
13747                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13748                .name = "Channel Mode",
13749                .info = alc_ch_mode_info,
13750                .get = alc_ch_mode_get,
13751                .put = alc_ch_mode_put,
13752                .private_value = ARRAY_SIZE(alc861_threestack_modes),
13753        },
13754        { } /* end */
13755};
13756
13757static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13758        /* output mixer control */
13759        HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13760        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13761        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13762
13763        { } /* end */
13764};
13765
13766static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13767        /* output mixer control */
13768        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13769        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13770        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13771        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13772        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13773
13774        /* Input mixer control */
13775        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13776           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13777        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13778        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13779        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13780        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13781        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13782        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13783        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13784        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13785
13786        {
13787                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13788                .name = "Channel Mode",
13789                .info = alc_ch_mode_info,
13790                .get = alc_ch_mode_get,
13791                .put = alc_ch_mode_put,
13792                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13793        },
13794        { } /* end */
13795};
13796
13797static struct snd_kcontrol_new alc861_asus_mixer[] = {
13798        /* output mixer control */
13799        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13800        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13801        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13802        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13803        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13804
13805        /* Input mixer control */
13806        HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13807        HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13808        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13809        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13810        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13811        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13812        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13813        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13814        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13815        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13816
13817        {
13818                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13819                .name = "Channel Mode",
13820                .info = alc_ch_mode_info,
13821                .get = alc_ch_mode_get,
13822                .put = alc_ch_mode_put,
13823                .private_value = ARRAY_SIZE(alc861_asus_modes),
13824        },
13825        { }
13826};
13827
13828/* additional mixer */
13829static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13830        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13831        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13832        { }
13833};
13834
13835/*
13836 * generic initialization of ADC, input mixers and output mixers
13837 */
13838static struct hda_verb alc861_base_init_verbs[] = {
13839        /*
13840         * Unmute ADC0 and set the default input to mic-in
13841         */
13842        /* port-A for surround (rear panel) */
13843        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13844        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13845        /* port-B for mic-in (rear panel) with vref */
13846        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13847        /* port-C for line-in (rear panel) */
13848        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13849        /* port-D for Front */
13850        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13851        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13852        /* port-E for HP out (front panel) */
13853        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13854        /* route front PCM to HP */
13855        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13856        /* port-F for mic-in (front panel) with vref */
13857        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13858        /* port-G for CLFE (rear panel) */
13859        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13860        { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13861        /* port-H for side (rear panel) */
13862        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13863        { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13864        /* CD-in */
13865        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13866        /* route front mic to ADC1*/
13867        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13868        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13869
13870        /* Unmute DAC0~3 & spdif out*/
13871        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13872        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13873        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13874        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13875        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13876
13877        /* Unmute Mixer 14 (mic) 1c (Line in)*/
13878        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13879        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13880        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13881        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13882
13883        /* Unmute Stereo Mixer 15 */
13884        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13885        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13886        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13887        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13888
13889        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13890        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13891        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13892        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13893        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13894        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13895        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13896        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13897        /* hp used DAC 3 (Front) */
13898        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13899        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13900
13901        { }
13902};
13903
13904static struct hda_verb alc861_threestack_init_verbs[] = {
13905        /*
13906         * Unmute ADC0 and set the default input to mic-in
13907         */
13908        /* port-A for surround (rear panel) */
13909        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13910        /* port-B for mic-in (rear panel) with vref */
13911        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13912        /* port-C for line-in (rear panel) */
13913        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13914        /* port-D for Front */
13915        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13916        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13917        /* port-E for HP out (front panel) */
13918        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13919        /* route front PCM to HP */
13920        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13921        /* port-F for mic-in (front panel) with vref */
13922        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13923        /* port-G for CLFE (rear panel) */
13924        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13925        /* port-H for side (rear panel) */
13926        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13927        /* CD-in */
13928        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13929        /* route front mic to ADC1*/
13930        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13931        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13932        /* Unmute DAC0~3 & spdif out*/
13933        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13934        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13935        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13936        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13937        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13938
13939        /* Unmute Mixer 14 (mic) 1c (Line in)*/
13940        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13941        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13942        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13943        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13944
13945        /* Unmute Stereo Mixer 15 */
13946        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13947        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13948        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13949        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13950
13951        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13952        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13953        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13954        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13955        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13956        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13957        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13958        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13959        /* hp used DAC 3 (Front) */
13960        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13961        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13962        { }
13963};
13964
13965static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13966        /*
13967         * Unmute ADC0 and set the default input to mic-in
13968         */
13969        /* port-A for surround (rear panel) */
13970        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13971        /* port-B for mic-in (rear panel) with vref */
13972        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13973        /* port-C for line-in (rear panel) */
13974        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13975        /* port-D for Front */
13976        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13977        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13978        /* port-E for HP out (front panel) */
13979        /* this has to be set to VREF80 */
13980        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13981        /* route front PCM to HP */
13982        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13983        /* port-F for mic-in (front panel) with vref */
13984        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13985        /* port-G for CLFE (rear panel) */
13986        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13987        /* port-H for side (rear panel) */
13988        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13989        /* CD-in */
13990        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13991        /* route front mic to ADC1*/
13992        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13993        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13994        /* Unmute DAC0~3 & spdif out*/
13995        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13996        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13997        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13998        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13999        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14000
14001        /* Unmute Mixer 14 (mic) 1c (Line in)*/
14002        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14003        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14004        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14005        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14006
14007        /* Unmute Stereo Mixer 15 */
14008        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14009        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14010        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14011        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14012
14013        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14014        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14015        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14016        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14017        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14018        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14019        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14020        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14021        /* hp used DAC 3 (Front) */
14022        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14023        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14024        { }
14025};
14026
14027static struct hda_verb alc861_asus_init_verbs[] = {
14028        /*
14029         * Unmute ADC0 and set the default input to mic-in
14030         */
14031        /* port-A for surround (rear panel)
14032         * according to codec#0 this is the HP jack
14033         */
14034        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14035        /* route front PCM to HP */
14036        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14037        /* port-B for mic-in (rear panel) with vref */
14038        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14039        /* port-C for line-in (rear panel) */
14040        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14041        /* port-D for Front */
14042        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14043        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14044        /* port-E for HP out (front panel) */
14045        /* this has to be set to VREF80 */
14046        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14047        /* route front PCM to HP */
14048        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14049        /* port-F for mic-in (front panel) with vref */
14050        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14051        /* port-G for CLFE (rear panel) */
14052        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14053        /* port-H for side (rear panel) */
14054        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14055        /* CD-in */
14056        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14057        /* route front mic to ADC1*/
14058        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14059        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14060        /* Unmute DAC0~3 & spdif out*/
14061        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14062        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14063        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14064        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14065        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14066        /* Unmute Mixer 14 (mic) 1c (Line in)*/
14067        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14068        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14069        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14070        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14071
14072        /* Unmute Stereo Mixer 15 */
14073        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14074        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14075        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14076        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14077
14078        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14079        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14080        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14081        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14082        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14083        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14084        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14085        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14086        /* hp used DAC 3 (Front) */
14087        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14088        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14089        { }
14090};
14091
14092/* additional init verbs for ASUS laptops */
14093static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14094        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14095        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14096        { }
14097};
14098
14099/*
14100 * generic initialization of ADC, input mixers and output mixers
14101 */
14102static struct hda_verb alc861_auto_init_verbs[] = {
14103        /*
14104         * Unmute ADC0 and set the default input to mic-in
14105         */
14106        /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14107        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14108
14109        /* Unmute DAC0~3 & spdif out*/
14110        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14111        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14112        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14113        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14114        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14115
14116        /* Unmute Mixer 14 (mic) 1c (Line in)*/
14117        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14118        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14119        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14120        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14121
14122        /* Unmute Stereo Mixer 15 */
14123        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14124        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14125        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14126        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14127
14128        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14129        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14130        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14131        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14132        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14133        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14134        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14135        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14136
14137        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14138        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14139        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14140        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14141        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14142        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14143        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14144        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14145
14146        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
14147
14148        { }
14149};
14150
14151static struct hda_verb alc861_toshiba_init_verbs[] = {
14152        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14153
14154        { }
14155};
14156
14157/* toggle speaker-output according to the hp-jack state */
14158static void alc861_toshiba_automute(struct hda_codec *codec)
14159{
14160        unsigned int present;
14161
14162        present = snd_hda_codec_read(codec, 0x0f, 0,
14163                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14164        snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14165                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14166        snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14167                                 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14168}
14169
14170static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14171                                       unsigned int res)
14172{
14173        if ((res >> 26) == ALC880_HP_EVENT)
14174                alc861_toshiba_automute(codec);
14175}
14176
14177/* pcm configuration: identical with ALC880 */
14178#define alc861_pcm_analog_playback      alc880_pcm_analog_playback
14179#define alc861_pcm_analog_capture       alc880_pcm_analog_capture
14180#define alc861_pcm_digital_playback     alc880_pcm_digital_playback
14181#define alc861_pcm_digital_capture      alc880_pcm_digital_capture
14182
14183
14184#define ALC861_DIGOUT_NID       0x07
14185
14186static struct hda_channel_mode alc861_8ch_modes[1] = {
14187        { 8, NULL }
14188};
14189
14190static hda_nid_t alc861_dac_nids[4] = {
14191        /* front, surround, clfe, side */
14192        0x03, 0x06, 0x05, 0x04
14193};
14194
14195static hda_nid_t alc660_dac_nids[3] = {
14196        /* front, clfe, surround */
14197        0x03, 0x05, 0x06
14198};
14199
14200static hda_nid_t alc861_adc_nids[1] = {
14201        /* ADC0-2 */
14202        0x08,
14203};
14204
14205static struct hda_input_mux alc861_capture_source = {
14206        .num_items = 5,
14207        .items = {
14208                { "Mic", 0x0 },
14209                { "Front Mic", 0x3 },
14210                { "Line", 0x1 },
14211                { "CD", 0x4 },
14212                { "Mixer", 0x5 },
14213        },
14214};
14215
14216static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14217{
14218        struct alc_spec *spec = codec->spec;
14219        hda_nid_t mix, srcs[5];
14220        int i, j, num;
14221
14222        if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14223                return 0;
14224        num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14225        if (num < 0)
14226                return 0;
14227        for (i = 0; i < num; i++) {
14228                unsigned int type;
14229                type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14230                if (type != AC_WID_AUD_OUT)
14231                        continue;
14232                for (j = 0; j < spec->multiout.num_dacs; j++)
14233                        if (spec->multiout.dac_nids[j] == srcs[i])
14234                                break;
14235                if (j >= spec->multiout.num_dacs)
14236                        return srcs[i];
14237        }
14238        return 0;
14239}
14240
14241/* fill in the dac_nids table from the parsed pin configuration */
14242static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14243                                     const struct auto_pin_cfg *cfg)
14244{
14245        struct alc_spec *spec = codec->spec;
14246        int i;
14247        hda_nid_t nid, dac;
14248
14249        spec->multiout.dac_nids = spec->private_dac_nids;
14250        for (i = 0; i < cfg->line_outs; i++) {
14251                nid = cfg->line_out_pins[i];
14252                dac = alc861_look_for_dac(codec, nid);
14253                if (!dac)
14254                        continue;
14255                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14256        }
14257        return 0;
14258}
14259
14260static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14261                                hda_nid_t nid, unsigned int chs)
14262{
14263        char name[32];
14264        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14265        return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14266                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14267}
14268
14269/* add playback controls from the parsed DAC table */
14270static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14271                                             const struct auto_pin_cfg *cfg)
14272{
14273        struct alc_spec *spec = codec->spec;
14274        static const char *chname[4] = {
14275                "Front", "Surround", NULL /*CLFE*/, "Side"
14276        };
14277        hda_nid_t nid;
14278        int i, err;
14279
14280        if (cfg->line_outs == 1) {
14281                const char *pfx = NULL;
14282                if (!cfg->hp_outs)
14283                        pfx = "Master";
14284                else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14285                        pfx = "Speaker";
14286                if (pfx) {
14287                        nid = spec->multiout.dac_nids[0];
14288                        return alc861_create_out_sw(codec, pfx, nid, 3);
14289                }
14290        }
14291
14292        for (i = 0; i < cfg->line_outs; i++) {
14293                nid = spec->multiout.dac_nids[i];
14294                if (!nid)
14295                        continue;
14296                if (i == 2) {
14297                        /* Center/LFE */
14298                        err = alc861_create_out_sw(codec, "Center", nid, 1);
14299                        if (err < 0)
14300                                return err;
14301                        err = alc861_create_out_sw(codec, "LFE", nid, 2);
14302                        if (err < 0)
14303                                return err;
14304                } else {
14305                        err = alc861_create_out_sw(codec, chname[i], nid, 3);
14306                        if (err < 0)
14307                                return err;
14308                }
14309        }
14310        return 0;
14311}
14312
14313static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14314{
14315        struct alc_spec *spec = codec->spec;
14316        int err;
14317        hda_nid_t nid;
14318
14319        if (!pin)
14320                return 0;
14321
14322        if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14323                nid = alc861_look_for_dac(codec, pin);
14324                if (nid) {
14325                        err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14326                        if (err < 0)
14327                                return err;
14328                        spec->multiout.hp_nid = nid;
14329                }
14330        }
14331        return 0;
14332}
14333
14334/* create playback/capture controls for input pins */
14335static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14336                                                const struct auto_pin_cfg *cfg)
14337{
14338        return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14339}
14340
14341static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14342                                              hda_nid_t nid,
14343                                              int pin_type, hda_nid_t dac)
14344{
14345        hda_nid_t mix, srcs[5];
14346        int i, num;
14347
14348        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14349                            pin_type);
14350        snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14351                            AMP_OUT_UNMUTE);
14352        if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14353                return;
14354        num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14355        if (num < 0)
14356                return;
14357        for (i = 0; i < num; i++) {
14358                unsigned int mute;
14359                if (srcs[i] == dac || srcs[i] == 0x15)
14360                        mute = AMP_IN_UNMUTE(i);
14361                else
14362                        mute = AMP_IN_MUTE(i);
14363                snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14364                                    mute);
14365        }
14366}
14367
14368static void alc861_auto_init_multi_out(struct hda_codec *codec)
14369{
14370        struct alc_spec *spec = codec->spec;
14371        int i;
14372
14373        for (i = 0; i < spec->autocfg.line_outs; i++) {
14374                hda_nid_t nid = spec->autocfg.line_out_pins[i];
14375                int pin_type = get_pin_type(spec->autocfg.line_out_type);
14376                if (nid)
14377                        alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14378                                                          spec->multiout.dac_nids[i]);
14379        }
14380}
14381
14382static void alc861_auto_init_hp_out(struct hda_codec *codec)
14383{
14384        struct alc_spec *spec = codec->spec;
14385
14386        if (spec->autocfg.hp_outs)
14387                alc861_auto_set_output_and_unmute(codec,
14388                                                  spec->autocfg.hp_pins[0],
14389                                                  PIN_HP,
14390                                                  spec->multiout.hp_nid);
14391        if (spec->autocfg.speaker_outs)
14392                alc861_auto_set_output_and_unmute(codec,
14393                                                  spec->autocfg.speaker_pins[0],
14394                                                  PIN_OUT,
14395                                                  spec->multiout.dac_nids[0]);
14396}
14397
14398static void alc861_auto_init_analog_input(struct hda_codec *codec)
14399{
14400        struct alc_spec *spec = codec->spec;
14401        int i;
14402
14403        for (i = 0; i < AUTO_PIN_LAST; i++) {
14404                hda_nid_t nid = spec->autocfg.input_pins[i];
14405                if (nid >= 0x0c && nid <= 0x11)
14406                        alc_set_input_pin(codec, nid, i);
14407        }
14408}
14409
14410/* parse the BIOS configuration and set up the alc_spec */
14411/* return 1 if successful, 0 if the proper config is not found,
14412 * or a negative error code
14413 */
14414static int alc861_parse_auto_config(struct hda_codec *codec)
14415{
14416        struct alc_spec *spec = codec->spec;
14417        int err;
14418        static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14419
14420        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14421                                           alc861_ignore);
14422        if (err < 0)
14423                return err;
14424        if (!spec->autocfg.line_outs)
14425                return 0; /* can't find valid BIOS pin config */
14426
14427        err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14428        if (err < 0)
14429                return err;
14430        err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14431        if (err < 0)
14432                return err;
14433        err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14434        if (err < 0)
14435                return err;
14436        err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14437        if (err < 0)
14438                return err;
14439
14440        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14441
14442        if (spec->autocfg.dig_outs)
14443                spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14444
14445        if (spec->kctls.list)
14446                add_mixer(spec, spec->kctls.list);
14447
14448        add_verb(spec, alc861_auto_init_verbs);
14449
14450        spec->num_mux_defs = 1;
14451        spec->input_mux = &spec->private_imux[0];
14452
14453        spec->adc_nids = alc861_adc_nids;
14454        spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14455        set_capture_mixer(codec);
14456
14457        alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14458
14459        return 1;
14460}
14461
14462/* additional initialization for auto-configuration model */
14463static void alc861_auto_init(struct hda_codec *codec)
14464{
14465        struct alc_spec *spec = codec->spec;
14466        alc861_auto_init_multi_out(codec);
14467        alc861_auto_init_hp_out(codec);
14468        alc861_auto_init_analog_input(codec);
14469        if (spec->unsol_event)
14470                alc_inithook(codec);
14471}
14472
14473#ifdef CONFIG_SND_HDA_POWER_SAVE
14474static struct hda_amp_list alc861_loopbacks[] = {
14475        { 0x15, HDA_INPUT, 0 },
14476        { 0x15, HDA_INPUT, 1 },
14477        { 0x15, HDA_INPUT, 2 },
14478        { 0x15, HDA_INPUT, 3 },
14479        { } /* end */
14480};
14481#endif
14482
14483
14484/*
14485 * configuration and preset
14486 */
14487static const char *alc861_models[ALC861_MODEL_LAST] = {
14488        [ALC861_3ST]            = "3stack",
14489        [ALC660_3ST]            = "3stack-660",
14490        [ALC861_3ST_DIG]        = "3stack-dig",
14491        [ALC861_6ST_DIG]        = "6stack-dig",
14492        [ALC861_UNIWILL_M31]    = "uniwill-m31",
14493        [ALC861_TOSHIBA]        = "toshiba",
14494        [ALC861_ASUS]           = "asus",
14495        [ALC861_ASUS_LAPTOP]    = "asus-laptop",
14496        [ALC861_AUTO]           = "auto",
14497};
14498
14499static struct snd_pci_quirk alc861_cfg_tbl[] = {
14500        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14501        SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14502        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14503        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14504        SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14505        SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14506        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14507        /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14508         *        Any other models that need this preset?
14509         */
14510        /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14511        SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14512        SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14513        SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14514        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14515        SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14516        /* FIXME: the below seems conflict */
14517        /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14518        SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14519        SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14520        {}
14521};
14522
14523static struct alc_config_preset alc861_presets[] = {
14524        [ALC861_3ST] = {
14525                .mixers = { alc861_3ST_mixer },
14526                .init_verbs = { alc861_threestack_init_verbs },
14527                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14528                .dac_nids = alc861_dac_nids,
14529                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14530                .channel_mode = alc861_threestack_modes,
14531                .need_dac_fix = 1,
14532                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14533                .adc_nids = alc861_adc_nids,
14534                .input_mux = &alc861_capture_source,
14535        },
14536        [ALC861_3ST_DIG] = {
14537                .mixers = { alc861_base_mixer },
14538                .init_verbs = { alc861_threestack_init_verbs },
14539                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14540                .dac_nids = alc861_dac_nids,
14541                .dig_out_nid = ALC861_DIGOUT_NID,
14542                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14543                .channel_mode = alc861_threestack_modes,
14544                .need_dac_fix = 1,
14545                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14546                .adc_nids = alc861_adc_nids,
14547                .input_mux = &alc861_capture_source,
14548        },
14549        [ALC861_6ST_DIG] = {
14550                .mixers = { alc861_base_mixer },
14551                .init_verbs = { alc861_base_init_verbs },
14552                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14553                .dac_nids = alc861_dac_nids,
14554                .dig_out_nid = ALC861_DIGOUT_NID,
14555                .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14556                .channel_mode = alc861_8ch_modes,
14557                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14558                .adc_nids = alc861_adc_nids,
14559                .input_mux = &alc861_capture_source,
14560        },
14561        [ALC660_3ST] = {
14562                .mixers = { alc861_3ST_mixer },
14563                .init_verbs = { alc861_threestack_init_verbs },
14564                .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14565                .dac_nids = alc660_dac_nids,
14566                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14567                .channel_mode = alc861_threestack_modes,
14568                .need_dac_fix = 1,
14569                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14570                .adc_nids = alc861_adc_nids,
14571                .input_mux = &alc861_capture_source,
14572        },
14573        [ALC861_UNIWILL_M31] = {
14574                .mixers = { alc861_uniwill_m31_mixer },
14575                .init_verbs = { alc861_uniwill_m31_init_verbs },
14576                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14577                .dac_nids = alc861_dac_nids,
14578                .dig_out_nid = ALC861_DIGOUT_NID,
14579                .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14580                .channel_mode = alc861_uniwill_m31_modes,
14581                .need_dac_fix = 1,
14582                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14583                .adc_nids = alc861_adc_nids,
14584                .input_mux = &alc861_capture_source,
14585        },
14586        [ALC861_TOSHIBA] = {
14587                .mixers = { alc861_toshiba_mixer },
14588                .init_verbs = { alc861_base_init_verbs,
14589                                alc861_toshiba_init_verbs },
14590                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14591                .dac_nids = alc861_dac_nids,
14592                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14593                .channel_mode = alc883_3ST_2ch_modes,
14594                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14595                .adc_nids = alc861_adc_nids,
14596                .input_mux = &alc861_capture_source,
14597                .unsol_event = alc861_toshiba_unsol_event,
14598                .init_hook = alc861_toshiba_automute,
14599        },
14600        [ALC861_ASUS] = {
14601                .mixers = { alc861_asus_mixer },
14602                .init_verbs = { alc861_asus_init_verbs },
14603                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14604                .dac_nids = alc861_dac_nids,
14605                .dig_out_nid = ALC861_DIGOUT_NID,
14606                .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14607                .channel_mode = alc861_asus_modes,
14608                .need_dac_fix = 1,
14609                .hp_nid = 0x06,
14610                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14611                .adc_nids = alc861_adc_nids,
14612                .input_mux = &alc861_capture_source,
14613        },
14614        [ALC861_ASUS_LAPTOP] = {
14615                .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14616                .init_verbs = { alc861_asus_init_verbs,
14617                                alc861_asus_laptop_init_verbs },
14618                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14619                .dac_nids = alc861_dac_nids,
14620                .dig_out_nid = ALC861_DIGOUT_NID,
14621                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14622                .channel_mode = alc883_3ST_2ch_modes,
14623                .need_dac_fix = 1,
14624                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14625                .adc_nids = alc861_adc_nids,
14626                .input_mux = &alc861_capture_source,
14627        },
14628};
14629
14630
14631static int patch_alc861(struct hda_codec *codec)
14632{
14633        struct alc_spec *spec;
14634        int board_config;
14635        int err;
14636
14637        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14638        if (spec == NULL)
14639                return -ENOMEM;
14640
14641        codec->spec = spec;
14642
14643        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14644                                                  alc861_models,
14645                                                  alc861_cfg_tbl);
14646
14647        if (board_config < 0) {
14648                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14649                       codec->chip_name);
14650                board_config = ALC861_AUTO;
14651        }
14652
14653        if (board_config == ALC861_AUTO) {
14654                /* automatic parse from the BIOS config */
14655                err = alc861_parse_auto_config(codec);
14656                if (err < 0) {
14657                        alc_free(codec);
14658                        return err;
14659                } else if (!err) {
14660                        printk(KERN_INFO
14661                               "hda_codec: Cannot set up configuration "
14662                               "from BIOS.  Using base mode...\n");
14663                   board_config = ALC861_3ST_DIG;
14664                }
14665        }
14666
14667        err = snd_hda_attach_beep_device(codec, 0x23);
14668        if (err < 0) {
14669                alc_free(codec);
14670                return err;
14671        }
14672
14673        if (board_config != ALC861_AUTO)
14674                setup_preset(codec, &alc861_presets[board_config]);
14675
14676        spec->stream_analog_playback = &alc861_pcm_analog_playback;
14677        spec->stream_analog_capture = &alc861_pcm_analog_capture;
14678
14679        spec->stream_digital_playback = &alc861_pcm_digital_playback;
14680        spec->stream_digital_capture = &alc861_pcm_digital_capture;
14681
14682        set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14683
14684        spec->vmaster_nid = 0x03;
14685
14686        codec->patch_ops = alc_patch_ops;
14687        if (board_config == ALC861_AUTO)
14688                spec->init_hook = alc861_auto_init;
14689#ifdef CONFIG_SND_HDA_POWER_SAVE
14690        if (!spec->loopback.amplist)
14691                spec->loopback.amplist = alc861_loopbacks;
14692#endif
14693        codec->proc_widget_hook = print_realtek_coef;
14694
14695        return 0;
14696}
14697
14698/*
14699 * ALC861-VD support
14700 *
14701 * Based on ALC882
14702 *
14703 * In addition, an independent DAC
14704 */
14705#define ALC861VD_DIGOUT_NID     0x06
14706
14707static hda_nid_t alc861vd_dac_nids[4] = {
14708        /* front, surr, clfe, side surr */
14709        0x02, 0x03, 0x04, 0x05
14710};
14711
14712/* dac_nids for ALC660vd are in a different order - according to
14713 * Realtek's driver.
14714 * This should probably result in a different mixer for 6stack models
14715 * of ALC660vd codecs, but for now there is only 3stack mixer
14716 * - and it is the same as in 861vd.
14717 * adc_nids in ALC660vd are (is) the same as in 861vd
14718 */
14719static hda_nid_t alc660vd_dac_nids[3] = {
14720        /* front, rear, clfe, rear_surr */
14721        0x02, 0x04, 0x03
14722};
14723
14724static hda_nid_t alc861vd_adc_nids[1] = {
14725        /* ADC0 */
14726        0x09,
14727};
14728
14729static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14730
14731/* input MUX */
14732/* FIXME: should be a matrix-type input source selection */
14733static struct hda_input_mux alc861vd_capture_source = {
14734        .num_items = 4,
14735        .items = {
14736                { "Mic", 0x0 },
14737                { "Front Mic", 0x1 },
14738                { "Line", 0x2 },
14739                { "CD", 0x4 },
14740        },
14741};
14742
14743static struct hda_input_mux alc861vd_dallas_capture_source = {
14744        .num_items = 2,
14745        .items = {
14746                { "Ext Mic", 0x0 },
14747                { "Int Mic", 0x1 },
14748        },
14749};
14750
14751static struct hda_input_mux alc861vd_hp_capture_source = {
14752        .num_items = 2,
14753        .items = {
14754                { "Front Mic", 0x0 },
14755                { "ATAPI Mic", 0x1 },
14756        },
14757};
14758
14759/*
14760 * 2ch mode
14761 */
14762static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14763        { 2, NULL }
14764};
14765
14766/*
14767 * 6ch mode
14768 */
14769static struct hda_verb alc861vd_6stack_ch6_init[] = {
14770        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14771        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14772        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14773        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14774        { } /* end */
14775};
14776
14777/*
14778 * 8ch mode
14779 */
14780static struct hda_verb alc861vd_6stack_ch8_init[] = {
14781        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14782        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14783        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14784        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14785        { } /* end */
14786};
14787
14788static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14789        { 6, alc861vd_6stack_ch6_init },
14790        { 8, alc861vd_6stack_ch8_init },
14791};
14792
14793static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14794        {
14795                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14796                .name = "Channel Mode",
14797                .info = alc_ch_mode_info,
14798                .get = alc_ch_mode_get,
14799                .put = alc_ch_mode_put,
14800        },
14801        { } /* end */
14802};
14803
14804/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14805 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14806 */
14807static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14808        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14809        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14810
14811        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14812        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14813
14814        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14815                                HDA_OUTPUT),
14816        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14817                                HDA_OUTPUT),
14818        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14819        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14820
14821        HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14822        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14823
14824        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14825
14826        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14827        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14828        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14829
14830        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14831        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14832        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14833
14834        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14835        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14836
14837        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14838        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14839
14840        { } /* end */
14841};
14842
14843static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14844        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14845        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14846
14847        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14848
14849        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14850        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14851        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14852
14853        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14854        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14855        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14856
14857        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14858        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14859
14860        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14861        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14862
14863        { } /* end */
14864};
14865
14866static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14867        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14868        /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14869        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14870
14871        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14872
14873        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14874        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14875        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14876
14877        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14878        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14879        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14880
14881        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14882        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14883
14884        { } /* end */
14885};
14886
14887/* Pin assignment: Speaker=0x14, HP = 0x15,
14888 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14889 */
14890static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14891        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14892        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14893        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14894        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14895        HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14896        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14897        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14898        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14899        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14900        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14901        { } /* end */
14902};
14903
14904/* Pin assignment: Speaker=0x14, Line-out = 0x15,
14905 *                 Front Mic=0x18, ATAPI Mic = 0x19,
14906 */
14907static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14908        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14909        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14910        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14911        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14912        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14913        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14914        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14915        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14916
14917        { } /* end */
14918};
14919
14920/*
14921 * generic initialization of ADC, input mixers and output mixers
14922 */
14923static struct hda_verb alc861vd_volume_init_verbs[] = {
14924        /*
14925         * Unmute ADC0 and set the default input to mic-in
14926         */
14927        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14928        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14929
14930        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14931         * the analog-loopback mixer widget
14932         */
14933        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14934        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14935        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14936        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14937        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14938        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14939
14940        /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14941        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14942        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14943        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14944        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14945
14946        /*
14947         * Set up output mixers (0x02 - 0x05)
14948         */
14949        /* set vol=0 to output mixers */
14950        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14951        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14952        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14953        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14954
14955        /* set up input amps for analog loopback */
14956        /* Amp Indices: DAC = 0, mixer = 1 */
14957        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14958        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14959        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14960        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14961        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14962        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14963        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14964        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14965
14966        { }
14967};
14968
14969/*
14970 * 3-stack pin configuration:
14971 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14972 */
14973static struct hda_verb alc861vd_3stack_init_verbs[] = {
14974        /*
14975         * Set pin mode and muting
14976         */
14977        /* set front pin widgets 0x14 for output */
14978        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14979        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14980        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14981
14982        /* Mic (rear) pin: input vref at 80% */
14983        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14984        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14985        /* Front Mic pin: input vref at 80% */
14986        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14987        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14988        /* Line In pin: input */
14989        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14990        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14991        /* Line-2 In: Headphone output (output 0 - 0x0c) */
14992        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14993        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14994        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14995        /* CD pin widget for input */
14996        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14997
14998        { }
14999};
15000
15001/*
15002 * 6-stack pin configuration:
15003 */
15004static struct hda_verb alc861vd_6stack_init_verbs[] = {
15005        /*
15006         * Set pin mode and muting
15007         */
15008        /* set front pin widgets 0x14 for output */
15009        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15010        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15011        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15012
15013        /* Rear Pin: output 1 (0x0d) */
15014        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15015        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15016        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15017        /* CLFE Pin: output 2 (0x0e) */
15018        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15019        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15020        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15021        /* Side Pin: output 3 (0x0f) */
15022        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15023        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15024        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15025
15026        /* Mic (rear) pin: input vref at 80% */
15027        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15028        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15029        /* Front Mic pin: input vref at 80% */
15030        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15031        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15032        /* Line In pin: input */
15033        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15034        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15035        /* Line-2 In: Headphone output (output 0 - 0x0c) */
15036        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15037        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15038        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15039        /* CD pin widget for input */
15040        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15041
15042        { }
15043};
15044
15045static struct hda_verb alc861vd_eapd_verbs[] = {
15046        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15047        { }
15048};
15049
15050static struct hda_verb alc660vd_eapd_verbs[] = {
15051        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15052        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15053        { }
15054};
15055
15056static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15057        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15058        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15059        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15060        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15061        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15062        {}
15063};
15064
15065static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15066{
15067        unsigned int present;
15068        unsigned char bits;
15069
15070        present = snd_hda_codec_read(codec, 0x18, 0,
15071                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15072        bits = present ? HDA_AMP_MUTE : 0;
15073        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15074                                 HDA_AMP_MUTE, bits);
15075}
15076
15077static void alc861vd_lenovo_setup(struct hda_codec *codec)
15078{
15079        struct alc_spec *spec = codec->spec;
15080        spec->autocfg.hp_pins[0] = 0x1b;
15081        spec->autocfg.speaker_pins[0] = 0x14;
15082}
15083
15084static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15085{
15086        alc_automute_amp(codec);
15087        alc861vd_lenovo_mic_automute(codec);
15088}
15089
15090static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15091                                        unsigned int res)
15092{
15093        switch (res >> 26) {
15094        case ALC880_MIC_EVENT:
15095                alc861vd_lenovo_mic_automute(codec);
15096                break;
15097        default:
15098                alc_automute_amp_unsol_event(codec, res);
15099                break;
15100        }
15101}
15102
15103static struct hda_verb alc861vd_dallas_verbs[] = {
15104        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15105        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15106        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15107        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15108
15109        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15111        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15112        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15113        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15114        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15115        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15116        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15117
15118        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15119        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15120        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15121        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15122        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15123        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15124        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15125        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15126
15127        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15128        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15129        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15130        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15131        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15132        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15133        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15134        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15135
15136        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15137        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15138        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15139        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15140
15141        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15142        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15143        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15144
15145        { } /* end */
15146};
15147
15148/* toggle speaker-output according to the hp-jack state */
15149static void alc861vd_dallas_setup(struct hda_codec *codec)
15150{
15151        struct alc_spec *spec = codec->spec;
15152
15153        spec->autocfg.hp_pins[0] = 0x15;
15154        spec->autocfg.speaker_pins[0] = 0x14;
15155}
15156
15157#ifdef CONFIG_SND_HDA_POWER_SAVE
15158#define alc861vd_loopbacks      alc880_loopbacks
15159#endif
15160
15161/* pcm configuration: identical with ALC880 */
15162#define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
15163#define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
15164#define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
15165#define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
15166
15167/*
15168 * configuration and preset
15169 */
15170static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15171        [ALC660VD_3ST]          = "3stack-660",
15172        [ALC660VD_3ST_DIG]      = "3stack-660-digout",
15173        [ALC660VD_ASUS_V1S]     = "asus-v1s",
15174        [ALC861VD_3ST]          = "3stack",
15175        [ALC861VD_3ST_DIG]      = "3stack-digout",
15176        [ALC861VD_6ST_DIG]      = "6stack-digout",
15177        [ALC861VD_LENOVO]       = "lenovo",
15178        [ALC861VD_DALLAS]       = "dallas",
15179        [ALC861VD_HP]           = "hp",
15180        [ALC861VD_AUTO]         = "auto",
15181};
15182
15183static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15184        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15185        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15186        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15187        /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15188        SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15189        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15190        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15191        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15192        /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15193        SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
15194        SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15195        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15196        SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15197        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15198        SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15199        {}
15200};
15201
15202static struct alc_config_preset alc861vd_presets[] = {
15203        [ALC660VD_3ST] = {
15204                .mixers = { alc861vd_3st_mixer },
15205                .init_verbs = { alc861vd_volume_init_verbs,
15206                                 alc861vd_3stack_init_verbs },
15207                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15208                .dac_nids = alc660vd_dac_nids,
15209                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15210                .channel_mode = alc861vd_3stack_2ch_modes,
15211                .input_mux = &alc861vd_capture_source,
15212        },
15213        [ALC660VD_3ST_DIG] = {
15214                .mixers = { alc861vd_3st_mixer },
15215                .init_verbs = { alc861vd_volume_init_verbs,
15216                                 alc861vd_3stack_init_verbs },
15217                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15218                .dac_nids = alc660vd_dac_nids,
15219                .dig_out_nid = ALC861VD_DIGOUT_NID,
15220                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15221                .channel_mode = alc861vd_3stack_2ch_modes,
15222                .input_mux = &alc861vd_capture_source,
15223        },
15224        [ALC861VD_3ST] = {
15225                .mixers = { alc861vd_3st_mixer },
15226                .init_verbs = { alc861vd_volume_init_verbs,
15227                                 alc861vd_3stack_init_verbs },
15228                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15229                .dac_nids = alc861vd_dac_nids,
15230                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15231                .channel_mode = alc861vd_3stack_2ch_modes,
15232                .input_mux = &alc861vd_capture_source,
15233        },
15234        [ALC861VD_3ST_DIG] = {
15235                .mixers = { alc861vd_3st_mixer },
15236                .init_verbs = { alc861vd_volume_init_verbs,
15237                                 alc861vd_3stack_init_verbs },
15238                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15239                .dac_nids = alc861vd_dac_nids,
15240                .dig_out_nid = ALC861VD_DIGOUT_NID,
15241                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15242                .channel_mode = alc861vd_3stack_2ch_modes,
15243                .input_mux = &alc861vd_capture_source,
15244        },
15245        [ALC861VD_6ST_DIG] = {
15246                .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15247                .init_verbs = { alc861vd_volume_init_verbs,
15248                                alc861vd_6stack_init_verbs },
15249                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15250                .dac_nids = alc861vd_dac_nids,
15251                .dig_out_nid = ALC861VD_DIGOUT_NID,
15252                .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15253                .channel_mode = alc861vd_6stack_modes,
15254                .input_mux = &alc861vd_capture_source,
15255        },
15256        [ALC861VD_LENOVO] = {
15257                .mixers = { alc861vd_lenovo_mixer },
15258                .init_verbs = { alc861vd_volume_init_verbs,
15259                                alc861vd_3stack_init_verbs,
15260                                alc861vd_eapd_verbs,
15261                                alc861vd_lenovo_unsol_verbs },
15262                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15263                .dac_nids = alc660vd_dac_nids,
15264                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15265                .channel_mode = alc861vd_3stack_2ch_modes,
15266                .input_mux = &alc861vd_capture_source,
15267                .unsol_event = alc861vd_lenovo_unsol_event,
15268                .setup = alc861vd_lenovo_setup,
15269                .init_hook = alc861vd_lenovo_init_hook,
15270        },
15271        [ALC861VD_DALLAS] = {
15272                .mixers = { alc861vd_dallas_mixer },
15273                .init_verbs = { alc861vd_dallas_verbs },
15274                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15275                .dac_nids = alc861vd_dac_nids,
15276                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15277                .channel_mode = alc861vd_3stack_2ch_modes,
15278                .input_mux = &alc861vd_dallas_capture_source,
15279                .unsol_event = alc_automute_amp_unsol_event,
15280                .setup = alc861vd_dallas_setup,
15281                .init_hook = alc_automute_amp,
15282        },
15283        [ALC861VD_HP] = {
15284                .mixers = { alc861vd_hp_mixer },
15285                .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15286                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15287                .dac_nids = alc861vd_dac_nids,
15288                .dig_out_nid = ALC861VD_DIGOUT_NID,
15289                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15290                .channel_mode = alc861vd_3stack_2ch_modes,
15291                .input_mux = &alc861vd_hp_capture_source,
15292                .unsol_event = alc_automute_amp_unsol_event,
15293                .setup = alc861vd_dallas_setup,
15294                .init_hook = alc_automute_amp,
15295        },
15296        [ALC660VD_ASUS_V1S] = {
15297                .mixers = { alc861vd_lenovo_mixer },
15298                .init_verbs = { alc861vd_volume_init_verbs,
15299                                alc861vd_3stack_init_verbs,
15300                                alc861vd_eapd_verbs,
15301                                alc861vd_lenovo_unsol_verbs },
15302                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15303                .dac_nids = alc660vd_dac_nids,
15304                .dig_out_nid = ALC861VD_DIGOUT_NID,
15305                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15306                .channel_mode = alc861vd_3stack_2ch_modes,
15307                .input_mux = &alc861vd_capture_source,
15308                .unsol_event = alc861vd_lenovo_unsol_event,
15309                .setup = alc861vd_lenovo_setup,
15310                .init_hook = alc861vd_lenovo_init_hook,
15311        },
15312};
15313
15314/*
15315 * BIOS auto configuration
15316 */
15317static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15318                                                const struct auto_pin_cfg *cfg)
15319{
15320        return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15321}
15322
15323
15324static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15325                                hda_nid_t nid, int pin_type, int dac_idx)
15326{
15327        alc_set_pin_output(codec, nid, pin_type);
15328}
15329
15330static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15331{
15332        struct alc_spec *spec = codec->spec;
15333        int i;
15334
15335        for (i = 0; i <= HDA_SIDE; i++) {
15336                hda_nid_t nid = spec->autocfg.line_out_pins[i];
15337                int pin_type = get_pin_type(spec->autocfg.line_out_type);
15338                if (nid)
15339                        alc861vd_auto_set_output_and_unmute(codec, nid,
15340                                                            pin_type, i);
15341        }
15342}
15343
15344
15345static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15346{
15347        struct alc_spec *spec = codec->spec;
15348        hda_nid_t pin;
15349
15350        pin = spec->autocfg.hp_pins[0];
15351        if (pin) /* connect to front and use dac 0 */
15352                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15353        pin = spec->autocfg.speaker_pins[0];
15354        if (pin)
15355                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15356}
15357
15358#define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
15359
15360static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15361{
15362        struct alc_spec *spec = codec->spec;
15363        int i;
15364
15365        for (i = 0; i < AUTO_PIN_LAST; i++) {
15366                hda_nid_t nid = spec->autocfg.input_pins[i];
15367                if (alc_is_input_pin(codec, nid)) {
15368                        alc_set_input_pin(codec, nid, i);
15369                        if (nid != ALC861VD_PIN_CD_NID &&
15370                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15371                                snd_hda_codec_write(codec, nid, 0,
15372                                                AC_VERB_SET_AMP_GAIN_MUTE,
15373                                                AMP_OUT_MUTE);
15374                }
15375        }
15376}
15377
15378#define alc861vd_auto_init_input_src    alc882_auto_init_input_src
15379
15380#define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
15381#define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
15382
15383/* add playback controls from the parsed DAC table */
15384/* Based on ALC880 version. But ALC861VD has separate,
15385 * different NIDs for mute/unmute switch and volume control */
15386static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15387                                             const struct auto_pin_cfg *cfg)
15388{
15389        char name[32];
15390        static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15391        hda_nid_t nid_v, nid_s;
15392        int i, err;
15393
15394        for (i = 0; i < cfg->line_outs; i++) {
15395                if (!spec->multiout.dac_nids[i])
15396                        continue;
15397                nid_v = alc861vd_idx_to_mixer_vol(
15398                                alc880_dac_to_idx(
15399                                        spec->multiout.dac_nids[i]));
15400                nid_s = alc861vd_idx_to_mixer_switch(
15401                                alc880_dac_to_idx(
15402                                        spec->multiout.dac_nids[i]));
15403
15404                if (i == 2) {
15405                        /* Center/LFE */
15406                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
15407                                          "Center Playback Volume",
15408                                          HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15409                                                              HDA_OUTPUT));
15410                        if (err < 0)
15411                                return err;
15412                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
15413                                          "LFE Playback Volume",
15414                                          HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15415                                                              HDA_OUTPUT));
15416                        if (err < 0)
15417                                return err;
15418                        err = add_control(spec, ALC_CTL_BIND_MUTE,
15419                                          "Center Playback Switch",
15420                                          HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15421                                                              HDA_INPUT));
15422                        if (err < 0)
15423                                return err;
15424                        err = add_control(spec, ALC_CTL_BIND_MUTE,
15425                                          "LFE Playback Switch",
15426                                          HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15427                                                              HDA_INPUT));
15428                        if (err < 0)
15429                                return err;
15430                } else {
15431                        const char *pfx;
15432                        if (cfg->line_outs == 1 &&
15433                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15434                                if (!cfg->hp_pins)
15435                                        pfx = "Speaker";
15436                                else
15437                                        pfx = "PCM";
15438                        } else
15439                                pfx = chname[i];
15440                        sprintf(name, "%s Playback Volume", pfx);
15441                        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15442                                          HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15443                                                              HDA_OUTPUT));
15444                        if (err < 0)
15445                                return err;
15446                        if (cfg->line_outs == 1 &&
15447                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15448                                pfx = "Speaker";
15449                        sprintf(name, "%s Playback Switch", pfx);
15450                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15451                                          HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15452                                                              HDA_INPUT));
15453                        if (err < 0)
15454                                return err;
15455                }
15456        }
15457        return 0;
15458}
15459
15460/* add playback controls for speaker and HP outputs */
15461/* Based on ALC880 version. But ALC861VD has separate,
15462 * different NIDs for mute/unmute switch and volume control */
15463static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15464                                        hda_nid_t pin, const char *pfx)
15465{
15466        hda_nid_t nid_v, nid_s;
15467        int err;
15468        char name[32];
15469
15470        if (!pin)
15471                return 0;
15472
15473        if (alc880_is_fixed_pin(pin)) {
15474                nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15475                /* specify the DAC as the extra output */
15476                if (!spec->multiout.hp_nid)
15477                        spec->multiout.hp_nid = nid_v;
15478                else
15479                        spec->multiout.extra_out_nid[0] = nid_v;
15480                /* control HP volume/switch on the output mixer amp */
15481                nid_v = alc861vd_idx_to_mixer_vol(
15482                                alc880_fixed_pin_idx(pin));
15483                nid_s = alc861vd_idx_to_mixer_switch(
15484                                alc880_fixed_pin_idx(pin));
15485
15486                sprintf(name, "%s Playback Volume", pfx);
15487                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15488                                  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15489                if (err < 0)
15490                        return err;
15491                sprintf(name, "%s Playback Switch", pfx);
15492                err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15493                                  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15494                if (err < 0)
15495                        return err;
15496        } else if (alc880_is_multi_pin(pin)) {
15497                /* set manual connection */
15498                /* we have only a switch on HP-out PIN */
15499                sprintf(name, "%s Playback Switch", pfx);
15500                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15501                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15502                if (err < 0)
15503                        return err;
15504        }
15505        return 0;
15506}
15507
15508/* parse the BIOS configuration and set up the alc_spec
15509 * return 1 if successful, 0 if the proper config is not found,
15510 * or a negative error code
15511 * Based on ALC880 version - had to change it to override
15512 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15513static int alc861vd_parse_auto_config(struct hda_codec *codec)
15514{
15515        struct alc_spec *spec = codec->spec;
15516        int err;
15517        static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15518
15519        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15520                                           alc861vd_ignore);
15521        if (err < 0)
15522                return err;
15523        if (!spec->autocfg.line_outs)
15524                return 0; /* can't find valid BIOS pin config */
15525
15526        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15527        if (err < 0)
15528                return err;
15529        err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15530        if (err < 0)
15531                return err;
15532        err = alc861vd_auto_create_extra_out(spec,
15533                                             spec->autocfg.speaker_pins[0],
15534                                             "Speaker");
15535        if (err < 0)
15536                return err;
15537        err = alc861vd_auto_create_extra_out(spec,
15538                                             spec->autocfg.hp_pins[0],
15539                                             "Headphone");
15540        if (err < 0)
15541                return err;
15542        err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15543        if (err < 0)
15544                return err;
15545
15546        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15547
15548        if (spec->autocfg.dig_outs)
15549                spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15550
15551        if (spec->kctls.list)
15552                add_mixer(spec, spec->kctls.list);
15553
15554        add_verb(spec, alc861vd_volume_init_verbs);
15555
15556        spec->num_mux_defs = 1;
15557        spec->input_mux = &spec->private_imux[0];
15558
15559        err = alc_auto_add_mic_boost(codec);
15560        if (err < 0)
15561                return err;
15562
15563        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15564
15565        return 1;
15566}
15567
15568/* additional initialization for auto-configuration model */
15569static void alc861vd_auto_init(struct hda_codec *codec)
15570{
15571        struct alc_spec *spec = codec->spec;
15572        alc861vd_auto_init_multi_out(codec);
15573        alc861vd_auto_init_hp_out(codec);
15574        alc861vd_auto_init_analog_input(codec);
15575        alc861vd_auto_init_input_src(codec);
15576        if (spec->unsol_event)
15577                alc_inithook(codec);
15578}
15579
15580enum {
15581        ALC660VD_FIX_ASUS_GPIO1
15582};
15583
15584/* reset GPIO1 */
15585static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15586        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15587        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15588        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15589        { }
15590};
15591
15592static const struct alc_fixup alc861vd_fixups[] = {
15593        [ALC660VD_FIX_ASUS_GPIO1] = {
15594                .verbs = alc660vd_fix_asus_gpio1_verbs,
15595        },
15596};
15597
15598static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15599        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15600        {}
15601};
15602
15603static int patch_alc861vd(struct hda_codec *codec)
15604{
15605        struct alc_spec *spec;
15606        int err, board_config;
15607
15608        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15609        if (spec == NULL)
15610                return -ENOMEM;
15611
15612        codec->spec = spec;
15613
15614        board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15615                                                  alc861vd_models,
15616                                                  alc861vd_cfg_tbl);
15617
15618        if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15619                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15620                       codec->chip_name);
15621                board_config = ALC861VD_AUTO;
15622        }
15623
15624        alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15625
15626        if (board_config == ALC861VD_AUTO) {
15627                /* automatic parse from the BIOS config */
15628                err = alc861vd_parse_auto_config(codec);
15629                if (err < 0) {
15630                        alc_free(codec);
15631                        return err;
15632                } else if (!err) {
15633                        printk(KERN_INFO
15634                               "hda_codec: Cannot set up configuration "
15635                               "from BIOS.  Using base mode...\n");
15636                        board_config = ALC861VD_3ST;
15637                }
15638        }
15639
15640        err = snd_hda_attach_beep_device(codec, 0x23);
15641        if (err < 0) {
15642                alc_free(codec);
15643                return err;
15644        }
15645
15646        if (board_config != ALC861VD_AUTO)
15647                setup_preset(codec, &alc861vd_presets[board_config]);
15648
15649        if (codec->vendor_id == 0x10ec0660) {
15650                /* always turn on EAPD */
15651                add_verb(spec, alc660vd_eapd_verbs);
15652        }
15653
15654        spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15655        spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15656
15657        spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15658        spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15659
15660        if (!spec->adc_nids) {
15661                spec->adc_nids = alc861vd_adc_nids;
15662                spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15663        }
15664        if (!spec->capsrc_nids)
15665                spec->capsrc_nids = alc861vd_capsrc_nids;
15666
15667        set_capture_mixer(codec);
15668        set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15669
15670        spec->vmaster_nid = 0x02;
15671
15672        codec->patch_ops = alc_patch_ops;
15673
15674        if (board_config == ALC861VD_AUTO)
15675                spec->init_hook = alc861vd_auto_init;
15676#ifdef CONFIG_SND_HDA_POWER_SAVE
15677        if (!spec->loopback.amplist)
15678                spec->loopback.amplist = alc861vd_loopbacks;
15679#endif
15680        codec->proc_widget_hook = print_realtek_coef;
15681
15682        return 0;
15683}
15684
15685/*
15686 * ALC662 support
15687 *
15688 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15689 * configuration.  Each pin widget can choose any input DACs and a mixer.
15690 * Each ADC is connected from a mixer of all inputs.  This makes possible
15691 * 6-channel independent captures.
15692 *
15693 * In addition, an independent DAC for the multi-playback (not used in this
15694 * driver yet).
15695 */
15696#define ALC662_DIGOUT_NID       0x06
15697#define ALC662_DIGIN_NID        0x0a
15698
15699static hda_nid_t alc662_dac_nids[4] = {
15700        /* front, rear, clfe, rear_surr */
15701        0x02, 0x03, 0x04
15702};
15703
15704static hda_nid_t alc272_dac_nids[2] = {
15705        0x02, 0x03
15706};
15707
15708static hda_nid_t alc662_adc_nids[2] = {
15709        /* ADC1-2 */
15710        0x09, 0x08
15711};
15712
15713static hda_nid_t alc272_adc_nids[1] = {
15714        /* ADC1-2 */
15715        0x08,
15716};
15717
15718static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15719static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15720
15721
15722/* input MUX */
15723/* FIXME: should be a matrix-type input source selection */
15724static struct hda_input_mux alc662_capture_source = {
15725        .num_items = 4,
15726        .items = {
15727                { "Mic", 0x0 },
15728                { "Front Mic", 0x1 },
15729                { "Line", 0x2 },
15730                { "CD", 0x4 },
15731        },
15732};
15733
15734static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15735        .num_items = 2,
15736        .items = {
15737                { "Mic", 0x1 },
15738                { "Line", 0x2 },
15739        },
15740};
15741
15742static struct hda_input_mux alc663_capture_source = {
15743        .num_items = 3,
15744        .items = {
15745                { "Mic", 0x0 },
15746                { "Front Mic", 0x1 },
15747                { "Line", 0x2 },
15748        },
15749};
15750
15751#if 0 /* set to 1 for testing other input sources below */
15752static struct hda_input_mux alc272_nc10_capture_source = {
15753        .num_items = 16,
15754        .items = {
15755                { "Autoselect Mic", 0x0 },
15756                { "Internal Mic", 0x1 },
15757                { "In-0x02", 0x2 },
15758                { "In-0x03", 0x3 },
15759                { "In-0x04", 0x4 },
15760                { "In-0x05", 0x5 },
15761                { "In-0x06", 0x6 },
15762                { "In-0x07", 0x7 },
15763                { "In-0x08", 0x8 },
15764                { "In-0x09", 0x9 },
15765                { "In-0x0a", 0x0a },
15766                { "In-0x0b", 0x0b },
15767                { "In-0x0c", 0x0c },
15768                { "In-0x0d", 0x0d },
15769                { "In-0x0e", 0x0e },
15770                { "In-0x0f", 0x0f },
15771        },
15772};
15773#endif
15774
15775/*
15776 * 2ch mode
15777 */
15778static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15779        { 2, NULL }
15780};
15781
15782/*
15783 * 2ch mode
15784 */
15785static struct hda_verb alc662_3ST_ch2_init[] = {
15786        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15787        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15788        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15789        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15790        { } /* end */
15791};
15792
15793/*
15794 * 6ch mode
15795 */
15796static struct hda_verb alc662_3ST_ch6_init[] = {
15797        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15798        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15799        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15800        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15801        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15802        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15803        { } /* end */
15804};
15805
15806static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15807        { 2, alc662_3ST_ch2_init },
15808        { 6, alc662_3ST_ch6_init },
15809};
15810
15811/*
15812 * 2ch mode
15813 */
15814static struct hda_verb alc662_sixstack_ch6_init[] = {
15815        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15816        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15817        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15818        { } /* end */
15819};
15820
15821/*
15822 * 6ch mode
15823 */
15824static struct hda_verb alc662_sixstack_ch8_init[] = {
15825        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15826        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15827        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15828        { } /* end */
15829};
15830
15831static struct hda_channel_mode alc662_5stack_modes[2] = {
15832        { 2, alc662_sixstack_ch6_init },
15833        { 6, alc662_sixstack_ch8_init },
15834};
15835
15836/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15837 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15838 */
15839
15840static struct snd_kcontrol_new alc662_base_mixer[] = {
15841        /* output mixer control */
15842        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15843        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15844        HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15845        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15846        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15847        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15848        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15849        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15850        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15851
15852        /*Input mixer control */
15853        HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15854        HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15855        HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15856        HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15857        HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15858        HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15859        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15860        HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15861        { } /* end */
15862};
15863
15864static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15865        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15866        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15867        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15868        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15869        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15870        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15871        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15872        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15873        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15874        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15875        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15876        { } /* end */
15877};
15878
15879static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15880        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15881        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15882        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15883        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15884        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15885        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15886        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15887        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15888        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15889        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15890        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15891        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15892        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15893        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15894        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15895        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15896        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15897        { } /* end */
15898};
15899
15900static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15901        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15902        HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15903        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15904        HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15905        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15906        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15907        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15908        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15909        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15910        { } /* end */
15911};
15912
15913static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15914        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15915        ALC262_HIPPO_MASTER_SWITCH,
15916
15917        HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15918        HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15919        HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15920
15921        HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15922        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15923        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15924        { } /* end */
15925};
15926
15927static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15928        ALC262_HIPPO_MASTER_SWITCH,
15929        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15930        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15931        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15932        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15933        HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15934        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15935        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15936        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15937        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15938        { } /* end */
15939};
15940
15941static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15942        .ops = &snd_hda_bind_vol,
15943        .values = {
15944                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15945                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15946                0
15947        },
15948};
15949
15950static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15951        .ops = &snd_hda_bind_sw,
15952        .values = {
15953                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15954                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15955                0
15956        },
15957};
15958
15959static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15960        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15961        HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15962        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15963        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15964        { } /* end */
15965};
15966
15967static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15968        .ops = &snd_hda_bind_sw,
15969        .values = {
15970                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15971                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15972                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15973                0
15974        },
15975};
15976
15977static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15978        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15979        HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15980        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15981        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15982        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15983        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15984
15985        { } /* end */
15986};
15987
15988static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15989        .ops = &snd_hda_bind_sw,
15990        .values = {
15991                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15992                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15993                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15994                0
15995        },
15996};
15997
15998static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15999        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16000        HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16001        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16002        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16003        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16004        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16005        { } /* end */
16006};
16007
16008static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
16009        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16010        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16011        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16012        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16013        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16014        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16015        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16016        { } /* end */
16017};
16018
16019static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16020        .ops = &snd_hda_bind_vol,
16021        .values = {
16022                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16023                HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16024                0
16025        },
16026};
16027
16028static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16029        .ops = &snd_hda_bind_sw,
16030        .values = {
16031                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16032                HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16033                0
16034        },
16035};
16036
16037static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16038        HDA_BIND_VOL("Master Playback Volume",
16039                                &alc663_asus_two_bind_master_vol),
16040        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16041        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16042        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16043        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16044        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16045        { } /* end */
16046};
16047
16048static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16049        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16050        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16051        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16052        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16053        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16054        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16055        { } /* end */
16056};
16057
16058static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16059        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16060        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16061        HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16062        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16063        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16064
16065        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16066        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16067        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16068        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16069        { } /* end */
16070};
16071
16072static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16073        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16074        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16075        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16076
16077        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16078        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16079        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16080        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16081        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16082        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16083        { } /* end */
16084};
16085
16086static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16087        {
16088                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16089                .name = "Channel Mode",
16090                .info = alc_ch_mode_info,
16091                .get = alc_ch_mode_get,
16092                .put = alc_ch_mode_put,
16093        },
16094        { } /* end */
16095};
16096
16097static struct hda_verb alc662_init_verbs[] = {
16098        /* ADC: mute amp left and right */
16099        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16100        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16101        /* Front mixer: unmute input/output amp left and right (volume = 0) */
16102
16103        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16104        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16105        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16106        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16107        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16108
16109        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16110        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16111        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16112        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16113        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16114        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16115
16116        /* Front Pin: output 0 (0x0c) */
16117        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16118        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16119
16120        /* Rear Pin: output 1 (0x0d) */
16121        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16122        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16123
16124        /* CLFE Pin: output 2 (0x0e) */
16125        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16126        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16127
16128        /* Mic (rear) pin: input vref at 80% */
16129        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16130        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16131        /* Front Mic pin: input vref at 80% */
16132        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16133        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16134        /* Line In pin: input */
16135        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16136        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16137        /* Line-2 In: Headphone output (output 0 - 0x0c) */
16138        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16139        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16140        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16141        /* CD pin widget for input */
16142        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16143
16144        /* FIXME: use matrix-type input source selection */
16145        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16146        /* Input mixer */
16147        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16148        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16149
16150        /* always trun on EAPD */
16151        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16152        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16153
16154        { }
16155};
16156
16157static struct hda_verb alc662_sue_init_verbs[] = {
16158        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16159        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16160        {}
16161};
16162
16163static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16164        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16165        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16166        {}
16167};
16168
16169/* Set Unsolicited Event*/
16170static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16171        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16172        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16173        {}
16174};
16175
16176/*
16177 * generic initialization of ADC, input mixers and output mixers
16178 */
16179static struct hda_verb alc662_auto_init_verbs[] = {
16180        /*
16181         * Unmute ADC and set the default input to mic-in
16182         */
16183        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16184        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16185
16186        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16187         * mixer widget
16188         * Note: PASD motherboards uses the Line In 2 as the input for front
16189         * panel mic (mic 2)
16190         */
16191        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16192        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16193        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16194        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16195        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16196        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16197
16198        /*
16199         * Set up output mixers (0x0c - 0x0f)
16200         */
16201        /* set vol=0 to output mixers */
16202        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16203        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16204        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16205
16206        /* set up input amps for analog loopback */
16207        /* Amp Indices: DAC = 0, mixer = 1 */
16208        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16209        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16210        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16211        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16212        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16213        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16214
16215
16216        /* FIXME: use matrix-type input source selection */
16217        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16218        /* Input mixer */
16219        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16220        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16221        { }
16222};
16223
16224/* additional verbs for ALC663 */
16225static struct hda_verb alc663_auto_init_verbs[] = {
16226        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16227        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16228        { }
16229};
16230
16231static struct hda_verb alc663_m51va_init_verbs[] = {
16232        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16233        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16234        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16235        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16236        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16237        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16238        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16239        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16240        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16241        {}
16242};
16243
16244static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16245        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16246        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16247        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16248        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16249        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16250        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16251        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16252        {}
16253};
16254
16255static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16256        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16257        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16258        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16259        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
16260        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16261        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16262        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16263        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16264        {}
16265};
16266
16267static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16268        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16269        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16271        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16272        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16273        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16274        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16275        {}
16276};
16277
16278static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16279        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16280        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16281        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16282        {0x21, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
16283        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16284        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16285        {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},   /* Headphone */
16286        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16287        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16288        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16289        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16290        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16291        {}
16292};
16293
16294static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16295        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16296        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16297        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16298        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16299        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16300        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16301        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16302        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16303        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16304        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16305        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16306        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16307        {}
16308};
16309
16310static struct hda_verb alc663_g71v_init_verbs[] = {
16311        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16312        /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16313        /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16314
16315        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16316        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16317        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
16318
16319        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16320        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16321        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16322        {}
16323};
16324
16325static struct hda_verb alc663_g50v_init_verbs[] = {
16326        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16327        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16328        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Headphone */
16329
16330        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16331        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16332        {}
16333};
16334
16335static struct hda_verb alc662_ecs_init_verbs[] = {
16336        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16337        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16338        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16339        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16340        {}
16341};
16342
16343static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16344        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16345        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16346        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16347        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16348        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16349        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16350        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16351        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16352        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16353        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16354        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16355        {}
16356};
16357
16358static struct hda_verb alc272_dell_init_verbs[] = {
16359        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16360        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16361        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16362        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16363        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16364        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16365        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Headphone */
16366        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16367        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16368        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16369        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16370        {}
16371};
16372
16373static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16374        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16375        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16376        { } /* end */
16377};
16378
16379static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16380        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16381        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16382        { } /* end */
16383};
16384
16385static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16386{
16387        unsigned int present;
16388        unsigned char bits;
16389
16390        present = snd_hda_codec_read(codec, 0x14, 0,
16391                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16392        bits = present ? HDA_AMP_MUTE : 0;
16393        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16394                                 HDA_AMP_MUTE, bits);
16395}
16396
16397static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16398{
16399        unsigned int present;
16400        unsigned char bits;
16401
16402        present = snd_hda_codec_read(codec, 0x1b, 0,
16403                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16404        bits = present ? HDA_AMP_MUTE : 0;
16405        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16406                                 HDA_AMP_MUTE, bits);
16407        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16408                                 HDA_AMP_MUTE, bits);
16409}
16410
16411static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16412                                           unsigned int res)
16413{
16414        if ((res >> 26) == ALC880_HP_EVENT)
16415                alc662_lenovo_101e_all_automute(codec);
16416        if ((res >> 26) == ALC880_FRONT_EVENT)
16417                alc662_lenovo_101e_ispeaker_automute(codec);
16418}
16419
16420/* unsolicited event for HP jack sensing */
16421static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16422                                     unsigned int res)
16423{
16424        if ((res >> 26) == ALC880_MIC_EVENT)
16425                alc_mic_automute(codec);
16426        else
16427                alc262_hippo_unsol_event(codec, res);
16428}
16429
16430static void alc662_eeepc_setup(struct hda_codec *codec)
16431{
16432        struct alc_spec *spec = codec->spec;
16433
16434        alc262_hippo1_setup(codec);
16435        spec->ext_mic.pin = 0x18;
16436        spec->ext_mic.mux_idx = 0;
16437        spec->int_mic.pin = 0x19;
16438        spec->int_mic.mux_idx = 1;
16439        spec->auto_mic = 1;
16440}
16441
16442static void alc662_eeepc_inithook(struct hda_codec *codec)
16443{
16444        alc262_hippo_automute(codec);
16445        alc_mic_automute(codec);
16446}
16447
16448static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16449{
16450        struct alc_spec *spec = codec->spec;
16451
16452        spec->autocfg.hp_pins[0] = 0x14;
16453        spec->autocfg.speaker_pins[0] = 0x1b;
16454}
16455
16456#define alc662_eeepc_ep20_inithook      alc262_hippo_master_update
16457
16458static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16459{
16460        unsigned int present;
16461        unsigned char bits;
16462
16463        present = snd_hda_codec_read(codec, 0x21, 0,
16464                        AC_VERB_GET_PIN_SENSE, 0)
16465                        & AC_PINSENSE_PRESENCE;
16466        bits = present ? HDA_AMP_MUTE : 0;
16467        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16468                                AMP_IN_MUTE(0), bits);
16469        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16470                                AMP_IN_MUTE(0), bits);
16471}
16472
16473static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16474{
16475        unsigned int present;
16476        unsigned char bits;
16477
16478        present = snd_hda_codec_read(codec, 0x21, 0,
16479                        AC_VERB_GET_PIN_SENSE, 0)
16480                        & AC_PINSENSE_PRESENCE;
16481        bits = present ? HDA_AMP_MUTE : 0;
16482        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16483                                AMP_IN_MUTE(0), bits);
16484        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16485                                AMP_IN_MUTE(0), bits);
16486        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16487                                AMP_IN_MUTE(0), bits);
16488        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16489                                AMP_IN_MUTE(0), bits);
16490}
16491
16492static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16493{
16494        unsigned int present;
16495        unsigned char bits;
16496
16497        present = snd_hda_codec_read(codec, 0x15, 0,
16498                        AC_VERB_GET_PIN_SENSE, 0)
16499                        & AC_PINSENSE_PRESENCE;
16500        bits = present ? HDA_AMP_MUTE : 0;
16501        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16502                                AMP_IN_MUTE(0), bits);
16503        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16504                                AMP_IN_MUTE(0), bits);
16505        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16506                                AMP_IN_MUTE(0), bits);
16507        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16508                                AMP_IN_MUTE(0), bits);
16509}
16510
16511static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16512{
16513        unsigned int present;
16514        unsigned char bits;
16515
16516        present = snd_hda_codec_read(codec, 0x1b, 0,
16517                        AC_VERB_GET_PIN_SENSE, 0)
16518                        & AC_PINSENSE_PRESENCE;
16519        bits = present ? 0 : PIN_OUT;
16520        snd_hda_codec_write(codec, 0x14, 0,
16521                         AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16522}
16523
16524static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16525{
16526        unsigned int present1, present2;
16527
16528        present1 = snd_hda_codec_read(codec, 0x21, 0,
16529                        AC_VERB_GET_PIN_SENSE, 0)
16530                        & AC_PINSENSE_PRESENCE;
16531        present2 = snd_hda_codec_read(codec, 0x15, 0,
16532                        AC_VERB_GET_PIN_SENSE, 0)
16533                        & AC_PINSENSE_PRESENCE;
16534
16535        if (present1 || present2) {
16536                snd_hda_codec_write_cache(codec, 0x14, 0,
16537                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16538        } else {
16539                snd_hda_codec_write_cache(codec, 0x14, 0,
16540                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16541        }
16542}
16543
16544static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16545{
16546        unsigned int present1, present2;
16547
16548        present1 = snd_hda_codec_read(codec, 0x1b, 0,
16549                                AC_VERB_GET_PIN_SENSE, 0)
16550                                & AC_PINSENSE_PRESENCE;
16551        present2 = snd_hda_codec_read(codec, 0x15, 0,
16552                                AC_VERB_GET_PIN_SENSE, 0)
16553                                & AC_PINSENSE_PRESENCE;
16554
16555        if (present1 || present2) {
16556                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16557                                AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16558                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16559                                AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16560        } else {
16561                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16562                                AMP_IN_MUTE(0), 0);
16563                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16564                                AMP_IN_MUTE(0), 0);
16565        }
16566}
16567
16568static void alc663_m51va_unsol_event(struct hda_codec *codec,
16569                                           unsigned int res)
16570{
16571        switch (res >> 26) {
16572        case ALC880_HP_EVENT:
16573                alc663_m51va_speaker_automute(codec);
16574                break;
16575        case ALC880_MIC_EVENT:
16576                alc_mic_automute(codec);
16577                break;
16578        }
16579}
16580
16581static void alc663_m51va_setup(struct hda_codec *codec)
16582{
16583        struct alc_spec *spec = codec->spec;
16584        spec->ext_mic.pin = 0x18;
16585        spec->ext_mic.mux_idx = 0;
16586        spec->int_mic.pin = 0x12;
16587        spec->int_mic.mux_idx = 1;
16588        spec->auto_mic = 1;
16589}
16590
16591static void alc663_m51va_inithook(struct hda_codec *codec)
16592{
16593        alc663_m51va_speaker_automute(codec);
16594        alc_mic_automute(codec);
16595}
16596
16597/* ***************** Mode1 ******************************/
16598#define alc663_mode1_unsol_event        alc663_m51va_unsol_event
16599#define alc663_mode1_setup              alc663_m51va_setup
16600#define alc663_mode1_inithook           alc663_m51va_inithook
16601
16602/* ***************** Mode2 ******************************/
16603static void alc662_mode2_unsol_event(struct hda_codec *codec,
16604                                           unsigned int res)
16605{
16606        switch (res >> 26) {
16607        case ALC880_HP_EVENT:
16608                alc662_f5z_speaker_automute(codec);
16609                break;
16610        case ALC880_MIC_EVENT:
16611                alc_mic_automute(codec);
16612                break;
16613        }
16614}
16615
16616#define alc662_mode2_setup      alc663_m51va_setup
16617
16618static void alc662_mode2_inithook(struct hda_codec *codec)
16619{
16620        alc662_f5z_speaker_automute(codec);
16621        alc_mic_automute(codec);
16622}
16623/* ***************** Mode3 ******************************/
16624static void alc663_mode3_unsol_event(struct hda_codec *codec,
16625                                           unsigned int res)
16626{
16627        switch (res >> 26) {
16628        case ALC880_HP_EVENT:
16629                alc663_two_hp_m1_speaker_automute(codec);
16630                break;
16631        case ALC880_MIC_EVENT:
16632                alc_mic_automute(codec);
16633                break;
16634        }
16635}
16636
16637#define alc663_mode3_setup      alc663_m51va_setup
16638
16639static void alc663_mode3_inithook(struct hda_codec *codec)
16640{
16641        alc663_two_hp_m1_speaker_automute(codec);
16642        alc_mic_automute(codec);
16643}
16644/* ***************** Mode4 ******************************/
16645static void alc663_mode4_unsol_event(struct hda_codec *codec,
16646                                           unsigned int res)
16647{
16648        switch (res >> 26) {
16649        case ALC880_HP_EVENT:
16650                alc663_21jd_two_speaker_automute(codec);
16651                break;
16652        case ALC880_MIC_EVENT:
16653                alc_mic_automute(codec);
16654                break;
16655        }
16656}
16657
16658#define alc663_mode4_setup      alc663_m51va_setup
16659
16660static void alc663_mode4_inithook(struct hda_codec *codec)
16661{
16662        alc663_21jd_two_speaker_automute(codec);
16663        alc_mic_automute(codec);
16664}
16665/* ***************** Mode5 ******************************/
16666static void alc663_mode5_unsol_event(struct hda_codec *codec,
16667                                           unsigned int res)
16668{
16669        switch (res >> 26) {
16670        case ALC880_HP_EVENT:
16671                alc663_15jd_two_speaker_automute(codec);
16672                break;
16673        case ALC880_MIC_EVENT:
16674                alc_mic_automute(codec);
16675                break;
16676        }
16677}
16678
16679#define alc663_mode5_setup      alc663_m51va_setup
16680
16681static void alc663_mode5_inithook(struct hda_codec *codec)
16682{
16683        alc663_15jd_two_speaker_automute(codec);
16684        alc_mic_automute(codec);
16685}
16686/* ***************** Mode6 ******************************/
16687static void alc663_mode6_unsol_event(struct hda_codec *codec,
16688                                           unsigned int res)
16689{
16690        switch (res >> 26) {
16691        case ALC880_HP_EVENT:
16692                alc663_two_hp_m2_speaker_automute(codec);
16693                break;
16694        case ALC880_MIC_EVENT:
16695                alc_mic_automute(codec);
16696                break;
16697        }
16698}
16699
16700#define alc663_mode6_setup      alc663_m51va_setup
16701
16702static void alc663_mode6_inithook(struct hda_codec *codec)
16703{
16704        alc663_two_hp_m2_speaker_automute(codec);
16705        alc_mic_automute(codec);
16706}
16707
16708static void alc663_g71v_hp_automute(struct hda_codec *codec)
16709{
16710        unsigned int present;
16711        unsigned char bits;
16712
16713        present = snd_hda_codec_read(codec, 0x21, 0,
16714                                     AC_VERB_GET_PIN_SENSE, 0)
16715                & AC_PINSENSE_PRESENCE;
16716        bits = present ? HDA_AMP_MUTE : 0;
16717        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16718                                 HDA_AMP_MUTE, bits);
16719        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16720                                 HDA_AMP_MUTE, bits);
16721}
16722
16723static void alc663_g71v_front_automute(struct hda_codec *codec)
16724{
16725        unsigned int present;
16726        unsigned char bits;
16727
16728        present = snd_hda_codec_read(codec, 0x15, 0,
16729                                     AC_VERB_GET_PIN_SENSE, 0)
16730                & AC_PINSENSE_PRESENCE;
16731        bits = present ? HDA_AMP_MUTE : 0;
16732        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16733                                 HDA_AMP_MUTE, bits);
16734}
16735
16736static void alc663_g71v_unsol_event(struct hda_codec *codec,
16737                                           unsigned int res)
16738{
16739        switch (res >> 26) {
16740        case ALC880_HP_EVENT:
16741                alc663_g71v_hp_automute(codec);
16742                break;
16743        case ALC880_FRONT_EVENT:
16744                alc663_g71v_front_automute(codec);
16745                break;
16746        case ALC880_MIC_EVENT:
16747                alc_mic_automute(codec);
16748                break;
16749        }
16750}
16751
16752#define alc663_g71v_setup       alc663_m51va_setup
16753
16754static void alc663_g71v_inithook(struct hda_codec *codec)
16755{
16756        alc663_g71v_front_automute(codec);
16757        alc663_g71v_hp_automute(codec);
16758        alc_mic_automute(codec);
16759}
16760
16761static void alc663_g50v_unsol_event(struct hda_codec *codec,
16762                                           unsigned int res)
16763{
16764        switch (res >> 26) {
16765        case ALC880_HP_EVENT:
16766                alc663_m51va_speaker_automute(codec);
16767                break;
16768        case ALC880_MIC_EVENT:
16769                alc_mic_automute(codec);
16770                break;
16771        }
16772}
16773
16774#define alc663_g50v_setup       alc663_m51va_setup
16775
16776static void alc663_g50v_inithook(struct hda_codec *codec)
16777{
16778        alc663_m51va_speaker_automute(codec);
16779        alc_mic_automute(codec);
16780}
16781
16782static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16783        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16784        ALC262_HIPPO_MASTER_SWITCH,
16785
16786        HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16787        HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16788        HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16789
16790        HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16791        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16792        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16793        { } /* end */
16794};
16795
16796static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16797        /* Master Playback automatically created from Speaker and Headphone */
16798        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16799        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16800        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16801        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16802
16803        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16804        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16805        HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16806
16807        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16808        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16809        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16810        { } /* end */
16811};
16812
16813#ifdef CONFIG_SND_HDA_POWER_SAVE
16814#define alc662_loopbacks        alc880_loopbacks
16815#endif
16816
16817
16818/* pcm configuration: identical with ALC880 */
16819#define alc662_pcm_analog_playback      alc880_pcm_analog_playback
16820#define alc662_pcm_analog_capture       alc880_pcm_analog_capture
16821#define alc662_pcm_digital_playback     alc880_pcm_digital_playback
16822#define alc662_pcm_digital_capture      alc880_pcm_digital_capture
16823
16824/*
16825 * configuration and preset
16826 */
16827static const char *alc662_models[ALC662_MODEL_LAST] = {
16828        [ALC662_3ST_2ch_DIG]    = "3stack-dig",
16829        [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
16830        [ALC662_3ST_6ch]        = "3stack-6ch",
16831        [ALC662_5ST_DIG]        = "6stack-dig",
16832        [ALC662_LENOVO_101E]    = "lenovo-101e",
16833        [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16834        [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16835        [ALC662_ECS] = "ecs",
16836        [ALC663_ASUS_M51VA] = "m51va",
16837        [ALC663_ASUS_G71V] = "g71v",
16838        [ALC663_ASUS_H13] = "h13",
16839        [ALC663_ASUS_G50V] = "g50v",
16840        [ALC663_ASUS_MODE1] = "asus-mode1",
16841        [ALC662_ASUS_MODE2] = "asus-mode2",
16842        [ALC663_ASUS_MODE3] = "asus-mode3",
16843        [ALC663_ASUS_MODE4] = "asus-mode4",
16844        [ALC663_ASUS_MODE5] = "asus-mode5",
16845        [ALC663_ASUS_MODE6] = "asus-mode6",
16846        [ALC272_DELL]           = "dell",
16847        [ALC272_DELL_ZM1]       = "dell-zm1",
16848        [ALC272_SAMSUNG_NC10]   = "samsung-nc10",
16849        [ALC662_AUTO]           = "auto",
16850};
16851
16852static struct snd_pci_quirk alc662_cfg_tbl[] = {
16853        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16854        SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16855        SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16856        SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16857        SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16858        SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16859        SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16860        SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16861        SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16862        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16863        SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16864        SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16865        SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16866        SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16867        SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16868        SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16869        SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16870        SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16871        SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16872        SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16873        SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16874        SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16875        SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16876        SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16877        SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16878        SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16879        /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16880        SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16881        SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16882        SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16883        SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16884        SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16885        SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16886        SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16887        SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16888        SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16889        SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16890        SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16891        SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16892        SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16893        SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16894        /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16895        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16896        SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16897        SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16898        SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16899        SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16900        SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16901        SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16902        SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16903        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16904        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16905                      ALC662_3ST_6ch_DIG),
16906        SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16907        SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16908        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16909                      ALC662_3ST_6ch_DIG),
16910        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16911        SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16912        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16913        SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16914                                        ALC662_3ST_6ch_DIG),
16915        SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16916                           ALC663_ASUS_H13),
16917        {}
16918};
16919
16920static struct alc_config_preset alc662_presets[] = {
16921        [ALC662_3ST_2ch_DIG] = {
16922                .mixers = { alc662_3ST_2ch_mixer },
16923                .init_verbs = { alc662_init_verbs },
16924                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16925                .dac_nids = alc662_dac_nids,
16926                .dig_out_nid = ALC662_DIGOUT_NID,
16927                .dig_in_nid = ALC662_DIGIN_NID,
16928                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16929                .channel_mode = alc662_3ST_2ch_modes,
16930                .input_mux = &alc662_capture_source,
16931        },
16932        [ALC662_3ST_6ch_DIG] = {
16933                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16934                .init_verbs = { alc662_init_verbs },
16935                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16936                .dac_nids = alc662_dac_nids,
16937                .dig_out_nid = ALC662_DIGOUT_NID,
16938                .dig_in_nid = ALC662_DIGIN_NID,
16939                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16940                .channel_mode = alc662_3ST_6ch_modes,
16941                .need_dac_fix = 1,
16942                .input_mux = &alc662_capture_source,
16943        },
16944        [ALC662_3ST_6ch] = {
16945                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16946                .init_verbs = { alc662_init_verbs },
16947                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16948                .dac_nids = alc662_dac_nids,
16949                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16950                .channel_mode = alc662_3ST_6ch_modes,
16951                .need_dac_fix = 1,
16952                .input_mux = &alc662_capture_source,
16953        },
16954        [ALC662_5ST_DIG] = {
16955                .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16956                .init_verbs = { alc662_init_verbs },
16957                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16958                .dac_nids = alc662_dac_nids,
16959                .dig_out_nid = ALC662_DIGOUT_NID,
16960                .dig_in_nid = ALC662_DIGIN_NID,
16961                .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16962                .channel_mode = alc662_5stack_modes,
16963                .input_mux = &alc662_capture_source,
16964        },
16965        [ALC662_LENOVO_101E] = {
16966                .mixers = { alc662_lenovo_101e_mixer },
16967                .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16968                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16969                .dac_nids = alc662_dac_nids,
16970                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16971                .channel_mode = alc662_3ST_2ch_modes,
16972                .input_mux = &alc662_lenovo_101e_capture_source,
16973                .unsol_event = alc662_lenovo_101e_unsol_event,
16974                .init_hook = alc662_lenovo_101e_all_automute,
16975        },
16976        [ALC662_ASUS_EEEPC_P701] = {
16977                .mixers = { alc662_eeepc_p701_mixer },
16978                .init_verbs = { alc662_init_verbs,
16979                                alc662_eeepc_sue_init_verbs },
16980                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16981                .dac_nids = alc662_dac_nids,
16982                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16983                .channel_mode = alc662_3ST_2ch_modes,
16984                .unsol_event = alc662_eeepc_unsol_event,
16985                .setup = alc662_eeepc_setup,
16986                .init_hook = alc662_eeepc_inithook,
16987        },
16988        [ALC662_ASUS_EEEPC_EP20] = {
16989                .mixers = { alc662_eeepc_ep20_mixer,
16990                            alc662_chmode_mixer },
16991                .init_verbs = { alc662_init_verbs,
16992                                alc662_eeepc_ep20_sue_init_verbs },
16993                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16994                .dac_nids = alc662_dac_nids,
16995                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16996                .channel_mode = alc662_3ST_6ch_modes,
16997                .input_mux = &alc662_lenovo_101e_capture_source,
16998                .unsol_event = alc662_eeepc_unsol_event,
16999                .setup = alc662_eeepc_ep20_setup,
17000                .init_hook = alc662_eeepc_ep20_inithook,
17001        },
17002        [ALC662_ECS] = {
17003                .mixers = { alc662_ecs_mixer },
17004                .init_verbs = { alc662_init_verbs,
17005                                alc662_ecs_init_verbs },
17006                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17007                .dac_nids = alc662_dac_nids,
17008                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17009                .channel_mode = alc662_3ST_2ch_modes,
17010                .unsol_event = alc662_eeepc_unsol_event,
17011                .setup = alc662_eeepc_setup,
17012                .init_hook = alc662_eeepc_inithook,
17013        },
17014        [ALC663_ASUS_M51VA] = {
17015                .mixers = { alc663_m51va_mixer },
17016                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17017                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17018                .dac_nids = alc662_dac_nids,
17019                .dig_out_nid = ALC662_DIGOUT_NID,
17020                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17021                .channel_mode = alc662_3ST_2ch_modes,
17022                .unsol_event = alc663_m51va_unsol_event,
17023                .setup = alc663_m51va_setup,
17024                .init_hook = alc663_m51va_inithook,
17025        },
17026        [ALC663_ASUS_G71V] = {
17027                .mixers = { alc663_g71v_mixer },
17028                .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17029                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17030                .dac_nids = alc662_dac_nids,
17031                .dig_out_nid = ALC662_DIGOUT_NID,
17032                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17033                .channel_mode = alc662_3ST_2ch_modes,
17034                .unsol_event = alc663_g71v_unsol_event,
17035                .setup = alc663_g71v_setup,
17036                .init_hook = alc663_g71v_inithook,
17037        },
17038        [ALC663_ASUS_H13] = {
17039                .mixers = { alc663_m51va_mixer },
17040                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17041                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17042                .dac_nids = alc662_dac_nids,
17043                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17044                .channel_mode = alc662_3ST_2ch_modes,
17045                .unsol_event = alc663_m51va_unsol_event,
17046                .init_hook = alc663_m51va_inithook,
17047        },
17048        [ALC663_ASUS_G50V] = {
17049                .mixers = { alc663_g50v_mixer },
17050                .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17051                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17052                .dac_nids = alc662_dac_nids,
17053                .dig_out_nid = ALC662_DIGOUT_NID,
17054                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17055                .channel_mode = alc662_3ST_6ch_modes,
17056                .input_mux = &alc663_capture_source,
17057                .unsol_event = alc663_g50v_unsol_event,
17058                .setup = alc663_g50v_setup,
17059                .init_hook = alc663_g50v_inithook,
17060        },
17061        [ALC663_ASUS_MODE1] = {
17062                .mixers = { alc663_m51va_mixer },
17063                .cap_mixer = alc662_auto_capture_mixer,
17064                .init_verbs = { alc662_init_verbs,
17065                                alc663_21jd_amic_init_verbs },
17066                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17067                .hp_nid = 0x03,
17068                .dac_nids = alc662_dac_nids,
17069                .dig_out_nid = ALC662_DIGOUT_NID,
17070                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17071                .channel_mode = alc662_3ST_2ch_modes,
17072                .unsol_event = alc663_mode1_unsol_event,
17073                .setup = alc663_mode1_setup,
17074                .init_hook = alc663_mode1_inithook,
17075        },
17076        [ALC662_ASUS_MODE2] = {
17077                .mixers = { alc662_1bjd_mixer },
17078                .cap_mixer = alc662_auto_capture_mixer,
17079                .init_verbs = { alc662_init_verbs,
17080                                alc662_1bjd_amic_init_verbs },
17081                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17082                .dac_nids = alc662_dac_nids,
17083                .dig_out_nid = ALC662_DIGOUT_NID,
17084                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17085                .channel_mode = alc662_3ST_2ch_modes,
17086                .unsol_event = alc662_mode2_unsol_event,
17087                .setup = alc662_mode2_setup,
17088                .init_hook = alc662_mode2_inithook,
17089        },
17090        [ALC663_ASUS_MODE3] = {
17091                .mixers = { alc663_two_hp_m1_mixer },
17092                .cap_mixer = alc662_auto_capture_mixer,
17093                .init_verbs = { alc662_init_verbs,
17094                                alc663_two_hp_amic_m1_init_verbs },
17095                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17096                .hp_nid = 0x03,
17097                .dac_nids = alc662_dac_nids,
17098                .dig_out_nid = ALC662_DIGOUT_NID,
17099                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17100                .channel_mode = alc662_3ST_2ch_modes,
17101                .unsol_event = alc663_mode3_unsol_event,
17102                .setup = alc663_mode3_setup,
17103                .init_hook = alc663_mode3_inithook,
17104        },
17105        [ALC663_ASUS_MODE4] = {
17106                .mixers = { alc663_asus_21jd_clfe_mixer },
17107                .cap_mixer = alc662_auto_capture_mixer,
17108                .init_verbs = { alc662_init_verbs,
17109                                alc663_21jd_amic_init_verbs},
17110                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17111                .hp_nid = 0x03,
17112                .dac_nids = alc662_dac_nids,
17113                .dig_out_nid = ALC662_DIGOUT_NID,
17114                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17115                .channel_mode = alc662_3ST_2ch_modes,
17116                .unsol_event = alc663_mode4_unsol_event,
17117                .setup = alc663_mode4_setup,
17118                .init_hook = alc663_mode4_inithook,
17119        },
17120        [ALC663_ASUS_MODE5] = {
17121                .mixers = { alc663_asus_15jd_clfe_mixer },
17122                .cap_mixer = alc662_auto_capture_mixer,
17123                .init_verbs = { alc662_init_verbs,
17124                                alc663_15jd_amic_init_verbs },
17125                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17126                .hp_nid = 0x03,
17127                .dac_nids = alc662_dac_nids,
17128                .dig_out_nid = ALC662_DIGOUT_NID,
17129                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17130                .channel_mode = alc662_3ST_2ch_modes,
17131                .unsol_event = alc663_mode5_unsol_event,
17132                .setup = alc663_mode5_setup,
17133                .init_hook = alc663_mode5_inithook,
17134        },
17135        [ALC663_ASUS_MODE6] = {
17136                .mixers = { alc663_two_hp_m2_mixer },
17137                .cap_mixer = alc662_auto_capture_mixer,
17138                .init_verbs = { alc662_init_verbs,
17139                                alc663_two_hp_amic_m2_init_verbs },
17140                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17141                .hp_nid = 0x03,
17142                .dac_nids = alc662_dac_nids,
17143                .dig_out_nid = ALC662_DIGOUT_NID,
17144                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17145                .channel_mode = alc662_3ST_2ch_modes,
17146                .unsol_event = alc663_mode6_unsol_event,
17147                .setup = alc663_mode6_setup,
17148                .init_hook = alc663_mode6_inithook,
17149        },
17150        [ALC272_DELL] = {
17151                .mixers = { alc663_m51va_mixer },
17152                .cap_mixer = alc272_auto_capture_mixer,
17153                .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17154                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17155                .dac_nids = alc662_dac_nids,
17156                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17157                .adc_nids = alc272_adc_nids,
17158                .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17159                .capsrc_nids = alc272_capsrc_nids,
17160                .channel_mode = alc662_3ST_2ch_modes,
17161                .unsol_event = alc663_m51va_unsol_event,
17162                .setup = alc663_m51va_setup,
17163                .init_hook = alc663_m51va_inithook,
17164        },
17165        [ALC272_DELL_ZM1] = {
17166                .mixers = { alc663_m51va_mixer },
17167                .cap_mixer = alc662_auto_capture_mixer,
17168                .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17169                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17170                .dac_nids = alc662_dac_nids,
17171                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17172                .adc_nids = alc662_adc_nids,
17173                .num_adc_nids = 1,
17174                .capsrc_nids = alc662_capsrc_nids,
17175                .channel_mode = alc662_3ST_2ch_modes,
17176                .unsol_event = alc663_m51va_unsol_event,
17177                .setup = alc663_m51va_setup,
17178                .init_hook = alc663_m51va_inithook,
17179        },
17180        [ALC272_SAMSUNG_NC10] = {
17181                .mixers = { alc272_nc10_mixer },
17182                .init_verbs = { alc662_init_verbs,
17183                                alc663_21jd_amic_init_verbs },
17184                .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17185                .dac_nids = alc272_dac_nids,
17186                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17187                .channel_mode = alc662_3ST_2ch_modes,
17188                /*.input_mux = &alc272_nc10_capture_source,*/
17189                .unsol_event = alc663_mode4_unsol_event,
17190                .setup = alc663_mode4_setup,
17191                .init_hook = alc663_mode4_inithook,
17192        },
17193};
17194
17195
17196/*
17197 * BIOS auto configuration
17198 */
17199
17200/* convert from MIX nid to DAC */
17201static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17202{
17203        if (nid == 0x0f)
17204                return 0x02;
17205        else if (nid >= 0x0c && nid <= 0x0e)
17206                return nid - 0x0c + 0x02;
17207        else
17208                return 0;
17209}
17210
17211/* get MIX nid connected to the given pin targeted to DAC */
17212static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17213                                   hda_nid_t dac)
17214{
17215        hda_nid_t mix[4];
17216        int i, num;
17217
17218        num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17219        for (i = 0; i < num; i++) {
17220                if (alc662_mix_to_dac(mix[i]) == dac)
17221                        return mix[i];
17222        }
17223        return 0;
17224}
17225
17226/* look for an empty DAC slot */
17227static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17228{
17229        struct alc_spec *spec = codec->spec;
17230        hda_nid_t srcs[5];
17231        int i, j, num;
17232
17233        num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17234        if (num < 0)
17235                return 0;
17236        for (i = 0; i < num; i++) {
17237                hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17238                if (!nid)
17239                        continue;
17240                for (j = 0; j < spec->multiout.num_dacs; j++)
17241                        if (spec->multiout.dac_nids[j] == nid)
17242                                break;
17243                if (j >= spec->multiout.num_dacs)
17244                        return nid;
17245        }
17246        return 0;
17247}
17248
17249/* fill in the dac_nids table from the parsed pin configuration */
17250static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17251                                     const struct auto_pin_cfg *cfg)
17252{
17253        struct alc_spec *spec = codec->spec;
17254        int i;
17255        hda_nid_t dac;
17256
17257        spec->multiout.dac_nids = spec->private_dac_nids;
17258        for (i = 0; i < cfg->line_outs; i++) {
17259                dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17260                if (!dac)
17261                        continue;
17262                spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17263        }
17264        return 0;
17265}
17266
17267static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17268                              hda_nid_t nid, unsigned int chs)
17269{
17270        char name[32];
17271        sprintf(name, "%s Playback Volume", pfx);
17272        return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17273                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17274}
17275
17276static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17277                             hda_nid_t nid, unsigned int chs)
17278{
17279        char name[32];
17280        sprintf(name, "%s Playback Switch", pfx);
17281        return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17282                           HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17283}
17284
17285#define alc662_add_stereo_vol(spec, pfx, nid) \
17286        alc662_add_vol_ctl(spec, pfx, nid, 3)
17287#define alc662_add_stereo_sw(spec, pfx, nid) \
17288        alc662_add_sw_ctl(spec, pfx, nid, 3)
17289
17290/* add playback controls from the parsed DAC table */
17291static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17292                                             const struct auto_pin_cfg *cfg)
17293{
17294        struct alc_spec *spec = codec->spec;
17295        static const char *chname[4] = {
17296                "Front", "Surround", NULL /*CLFE*/, "Side"
17297        };
17298        hda_nid_t nid, mix;
17299        int i, err;
17300
17301        for (i = 0; i < cfg->line_outs; i++) {
17302                nid = spec->multiout.dac_nids[i];
17303                if (!nid)
17304                        continue;
17305                mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17306                if (!mix)
17307                        continue;
17308                if (i == 2) {
17309                        /* Center/LFE */
17310                        err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17311                        if (err < 0)
17312                                return err;
17313                        err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17314                        if (err < 0)
17315                                return err;
17316                        err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17317                        if (err < 0)
17318                                return err;
17319                        err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17320                        if (err < 0)
17321                                return err;
17322                } else {
17323                        const char *pfx;
17324                        if (cfg->line_outs == 1 &&
17325                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17326                                if (cfg->hp_outs)
17327                                        pfx = "Speaker";
17328                                else
17329                                        pfx = "PCM";
17330                        } else
17331                                pfx = chname[i];
17332                        err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17333                        if (err < 0)
17334                                return err;
17335                        if (cfg->line_outs == 1 &&
17336                            cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17337                                pfx = "Speaker";
17338                        err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17339                        if (err < 0)
17340                                return err;
17341                }
17342        }
17343        return 0;
17344}
17345
17346/* add playback controls for speaker and HP outputs */
17347/* return DAC nid if any new DAC is assigned */
17348static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17349                                        const char *pfx)
17350{
17351        struct alc_spec *spec = codec->spec;
17352        hda_nid_t nid, mix;
17353        int err;
17354
17355        if (!pin)
17356                return 0;
17357        nid = alc662_look_for_dac(codec, pin);
17358        if (!nid) {
17359                char name[32];
17360                /* the corresponding DAC is already occupied */
17361                if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17362                        return 0; /* no way */
17363                /* create a switch only */
17364                sprintf(name, "%s Playback Switch", pfx);
17365                return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17366                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17367        }
17368
17369        mix = alc662_dac_to_mix(codec, pin, nid);
17370        if (!mix)
17371                return 0;
17372        err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17373        if (err < 0)
17374                return err;
17375        err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17376        if (err < 0)
17377                return err;
17378        return nid;
17379}
17380
17381/* create playback/capture controls for input pins */
17382#define alc662_auto_create_input_ctls \
17383        alc882_auto_create_input_ctls
17384
17385static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17386                                              hda_nid_t nid, int pin_type,
17387                                              hda_nid_t dac)
17388{
17389        int i, num;
17390        hda_nid_t srcs[4];
17391
17392        alc_set_pin_output(codec, nid, pin_type);
17393        /* need the manual connection? */
17394        num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17395        if (num <= 1)
17396                return;
17397        for (i = 0; i < num; i++) {
17398                if (alc662_mix_to_dac(srcs[i]) != dac)
17399                        continue;
17400                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17401                return;
17402        }
17403}
17404
17405static void alc662_auto_init_multi_out(struct hda_codec *codec)
17406{
17407        struct alc_spec *spec = codec->spec;
17408        int pin_type = get_pin_type(spec->autocfg.line_out_type);
17409        int i;
17410
17411        for (i = 0; i <= HDA_SIDE; i++) {
17412                hda_nid_t nid = spec->autocfg.line_out_pins[i];
17413                if (nid)
17414                        alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17415                                        spec->multiout.dac_nids[i]);
17416        }
17417}
17418
17419static void alc662_auto_init_hp_out(struct hda_codec *codec)
17420{
17421        struct alc_spec *spec = codec->spec;
17422        hda_nid_t pin;
17423
17424        pin = spec->autocfg.hp_pins[0];
17425        if (pin)
17426                alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17427                                                  spec->multiout.hp_nid);
17428        pin = spec->autocfg.speaker_pins[0];
17429        if (pin)
17430                alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17431                                        spec->multiout.extra_out_nid[0]);
17432}
17433
17434#define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
17435
17436static void alc662_auto_init_analog_input(struct hda_codec *codec)
17437{
17438        struct alc_spec *spec = codec->spec;
17439        int i;
17440
17441        for (i = 0; i < AUTO_PIN_LAST; i++) {
17442                hda_nid_t nid = spec->autocfg.input_pins[i];
17443                if (alc_is_input_pin(codec, nid)) {
17444                        alc_set_input_pin(codec, nid, i);
17445                        if (nid != ALC662_PIN_CD_NID &&
17446                            (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17447                                snd_hda_codec_write(codec, nid, 0,
17448                                                    AC_VERB_SET_AMP_GAIN_MUTE,
17449                                                    AMP_OUT_MUTE);
17450                }
17451        }
17452}
17453
17454#define alc662_auto_init_input_src      alc882_auto_init_input_src
17455
17456static int alc662_parse_auto_config(struct hda_codec *codec)
17457{
17458        struct alc_spec *spec = codec->spec;
17459        int err;
17460        static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17461
17462        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17463                                           alc662_ignore);
17464        if (err < 0)
17465                return err;
17466        if (!spec->autocfg.line_outs)
17467                return 0; /* can't find valid BIOS pin config */
17468
17469        err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17470        if (err < 0)
17471                return err;
17472        err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17473        if (err < 0)
17474                return err;
17475        err = alc662_auto_create_extra_out(codec,
17476                                           spec->autocfg.speaker_pins[0],
17477                                           "Speaker");
17478        if (err < 0)
17479                return err;
17480        if (err)
17481                spec->multiout.extra_out_nid[0] = err;
17482        err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17483                                           "Headphone");
17484        if (err < 0)
17485                return err;
17486        if (err)
17487                spec->multiout.hp_nid = err;
17488        err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17489        if (err < 0)
17490                return err;
17491
17492        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17493
17494        if (spec->autocfg.dig_outs)
17495                spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17496
17497        if (spec->kctls.list)
17498                add_mixer(spec, spec->kctls.list);
17499
17500        spec->num_mux_defs = 1;
17501        spec->input_mux = &spec->private_imux[0];
17502
17503        add_verb(spec, alc662_auto_init_verbs);
17504        if (codec->vendor_id == 0x10ec0663)
17505                add_verb(spec, alc663_auto_init_verbs);
17506
17507        err = alc_auto_add_mic_boost(codec);
17508        if (err < 0)
17509                return err;
17510
17511        alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17512
17513        return 1;
17514}
17515
17516/* additional initialization for auto-configuration model */
17517static void alc662_auto_init(struct hda_codec *codec)
17518{
17519        struct alc_spec *spec = codec->spec;
17520        alc662_auto_init_multi_out(codec);
17521        alc662_auto_init_hp_out(codec);
17522        alc662_auto_init_analog_input(codec);
17523        alc662_auto_init_input_src(codec);
17524        if (spec->unsol_event)
17525                alc_inithook(codec);
17526}
17527
17528static int patch_alc662(struct hda_codec *codec)
17529{
17530        struct alc_spec *spec;
17531        int err, board_config;
17532
17533        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17534        if (!spec)
17535                return -ENOMEM;
17536
17537        codec->spec = spec;
17538
17539        alc_fix_pll_init(codec, 0x20, 0x04, 15);
17540
17541        board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17542                                                  alc662_models,
17543                                                  alc662_cfg_tbl);
17544        if (board_config < 0) {
17545                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17546                       codec->chip_name);
17547                board_config = ALC662_AUTO;
17548        }
17549
17550        if (board_config == ALC662_AUTO) {
17551                /* automatic parse from the BIOS config */
17552                err = alc662_parse_auto_config(codec);
17553                if (err < 0) {
17554                        alc_free(codec);
17555                        return err;
17556                } else if (!err) {
17557                        printk(KERN_INFO
17558                               "hda_codec: Cannot set up configuration "
17559                               "from BIOS.  Using base mode...\n");
17560                        board_config = ALC662_3ST_2ch_DIG;
17561                }
17562        }
17563
17564        err = snd_hda_attach_beep_device(codec, 0x1);
17565        if (err < 0) {
17566                alc_free(codec);
17567                return err;
17568        }
17569
17570        if (board_config != ALC662_AUTO)
17571                setup_preset(codec, &alc662_presets[board_config]);
17572
17573        spec->stream_analog_playback = &alc662_pcm_analog_playback;
17574        spec->stream_analog_capture = &alc662_pcm_analog_capture;
17575
17576        spec->stream_digital_playback = &alc662_pcm_digital_playback;
17577        spec->stream_digital_capture = &alc662_pcm_digital_capture;
17578
17579        if (!spec->adc_nids) {
17580                spec->adc_nids = alc662_adc_nids;
17581                spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17582        }
17583        if (!spec->capsrc_nids)
17584                spec->capsrc_nids = alc662_capsrc_nids;
17585
17586        if (!spec->cap_mixer)
17587                set_capture_mixer(codec);
17588        if (codec->vendor_id == 0x10ec0662)
17589                set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17590        else
17591                set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17592
17593        spec->vmaster_nid = 0x02;
17594
17595        codec->patch_ops = alc_patch_ops;
17596        if (board_config == ALC662_AUTO)
17597                spec->init_hook = alc662_auto_init;
17598#ifdef CONFIG_SND_HDA_POWER_SAVE
17599        if (!spec->loopback.amplist)
17600                spec->loopback.amplist = alc662_loopbacks;
17601#endif
17602        codec->proc_widget_hook = print_realtek_coef;
17603
17604        return 0;
17605}
17606
17607/*
17608 * patch entries
17609 */
17610static struct hda_codec_preset snd_hda_preset_realtek[] = {
17611        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17612        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17613        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17614        { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17615        { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17616        { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17617        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17618          .patch = patch_alc861 },
17619        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17620        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17621        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17622        { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17623          .patch = patch_alc882 },
17624        { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17625          .patch = patch_alc662 },
17626        { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17627        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17628        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17629        { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17630        { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17631          .patch = patch_alc882 },
17632        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17633          .patch = patch_alc882 },
17634        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17635        { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17636        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17637          .patch = patch_alc882 },
17638        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17639        { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17640        {} /* terminator */
17641};
17642
17643MODULE_ALIAS("snd-hda-codec-id:10ec*");
17644
17645MODULE_LICENSE("GPL");
17646MODULE_DESCRIPTION("Realtek HD-audio codec");
17647
17648static struct hda_codec_preset_list realtek_list = {
17649        .preset = snd_hda_preset_realtek,
17650        .owner = THIS_MODULE,
17651};
17652
17653static int __init patch_realtek_init(void)
17654{
17655        return snd_hda_add_codec_preset(&realtek_list);
17656}
17657
17658static void __exit patch_realtek_exit(void)
17659{
17660        snd_hda_delete_codec_preset(&realtek_list);
17661}
17662
17663module_init(patch_realtek_init)
17664module_exit(patch_realtek_exit)
17665