Showing error 1908

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: sound/pci/hda/patch_realtek.c
Line in file: 2752
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-11 08:47:26 UTC


Source:

    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_patch.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#ifdef CONFIG_SND_DEBUG
   82        ALC260_TEST,
   83#endif
   84        ALC260_AUTO,
   85        ALC260_MODEL_LAST /* last tag */
   86};
   87
   88/* ALC262 models */
   89enum {
   90        ALC262_BASIC,
   91        ALC262_HIPPO,
   92        ALC262_HIPPO_1,
   93        ALC262_FUJITSU,
   94        ALC262_HP_BPC,
   95        ALC262_HP_BPC_D7000_WL,
   96        ALC262_HP_BPC_D7000_WF,
   97        ALC262_HP_TC_T5735,
   98        ALC262_HP_RP5700,
   99        ALC262_BENQ_ED8,
  100        ALC262_SONY_ASSAMD,
  101        ALC262_BENQ_T31,
  102        ALC262_ULTRA,
  103        ALC262_LENOVO_3000,
  104        ALC262_NEC,
  105        ALC262_TOSHIBA_S06,
  106        ALC262_TOSHIBA_RX1,
  107        ALC262_AUTO,
  108        ALC262_MODEL_LAST /* last tag */
  109};
  110
  111/* ALC268 models */
  112enum {
  113        ALC267_QUANTA_IL1,
  114        ALC268_3ST,
  115        ALC268_TOSHIBA,
  116        ALC268_ACER,
  117        ALC268_ACER_ASPIRE_ONE,
  118        ALC268_DELL,
  119        ALC268_ZEPTO,
  120#ifdef CONFIG_SND_DEBUG
  121        ALC268_TEST,
  122#endif
  123        ALC268_AUTO,
  124        ALC268_MODEL_LAST /* last tag */
  125};
  126
  127/* ALC269 models */
  128enum {
  129        ALC269_BASIC,
  130        ALC269_QUANTA_FL1,
  131        ALC269_ASUS_EEEPC_P703,
  132        ALC269_ASUS_EEEPC_P901,
  133        ALC269_AUTO,
  134        ALC269_MODEL_LAST /* last tag */
  135};
  136
  137/* ALC861 models */
  138enum {
  139        ALC861_3ST,
  140        ALC660_3ST,
  141        ALC861_3ST_DIG,
  142        ALC861_6ST_DIG,
  143        ALC861_UNIWILL_M31,
  144        ALC861_TOSHIBA,
  145        ALC861_ASUS,
  146        ALC861_ASUS_LAPTOP,
  147        ALC861_AUTO,
  148        ALC861_MODEL_LAST,
  149};
  150
  151/* ALC861-VD models */
  152enum {
  153        ALC660VD_3ST,
  154        ALC660VD_3ST_DIG,
  155        ALC861VD_3ST,
  156        ALC861VD_3ST_DIG,
  157        ALC861VD_6ST_DIG,
  158        ALC861VD_LENOVO,
  159        ALC861VD_DALLAS,
  160        ALC861VD_HP,
  161        ALC861VD_AUTO,
  162        ALC861VD_MODEL_LAST,
  163};
  164
  165/* ALC662 models */
  166enum {
  167        ALC662_3ST_2ch_DIG,
  168        ALC662_3ST_6ch_DIG,
  169        ALC662_3ST_6ch,
  170        ALC662_5ST_DIG,
  171        ALC662_LENOVO_101E,
  172        ALC662_ASUS_EEEPC_P701,
  173        ALC662_ASUS_EEEPC_EP20,
  174        ALC663_ASUS_M51VA,
  175        ALC663_ASUS_G71V,
  176        ALC663_ASUS_H13,
  177        ALC663_ASUS_G50V,
  178        ALC662_ECS,
  179        ALC663_ASUS_MODE1,
  180        ALC662_ASUS_MODE2,
  181        ALC663_ASUS_MODE3,
  182        ALC663_ASUS_MODE4,
  183        ALC663_ASUS_MODE5,
  184        ALC663_ASUS_MODE6,
  185        ALC662_AUTO,
  186        ALC662_MODEL_LAST,
  187};
  188
  189/* ALC882 models */
  190enum {
  191        ALC882_3ST_DIG,
  192        ALC882_6ST_DIG,
  193        ALC882_ARIMA,
  194        ALC882_W2JC,
  195        ALC882_TARGA,
  196        ALC882_ASUS_A7J,
  197        ALC882_ASUS_A7M,
  198        ALC885_MACPRO,
  199        ALC885_MBP3,
  200        ALC885_IMAC24,
  201        ALC882_AUTO,
  202        ALC882_MODEL_LAST,
  203};
  204
  205/* ALC883 models */
  206enum {
  207        ALC883_3ST_2ch_DIG,
  208        ALC883_3ST_6ch_DIG,
  209        ALC883_3ST_6ch,
  210        ALC883_6ST_DIG,
  211        ALC883_TARGA_DIG,
  212        ALC883_TARGA_2ch_DIG,
  213        ALC883_ACER,
  214        ALC883_ACER_ASPIRE,
  215        ALC883_MEDION,
  216        ALC883_MEDION_MD2,
  217        ALC883_LAPTOP_EAPD,
  218        ALC883_LENOVO_101E_2ch,
  219        ALC883_LENOVO_NB0763,
  220        ALC888_LENOVO_MS7195_DIG,
  221        ALC888_LENOVO_SKY,
  222        ALC883_HAIER_W66,
  223        ALC888_3ST_HP,
  224        ALC888_6ST_DELL,
  225        ALC883_MITAC,
  226        ALC883_CLEVO_M720,
  227        ALC883_FUJITSU_PI2515,
  228        ALC883_3ST_6ch_INTEL,
  229        ALC888_ASUS_M90V,
  230        ALC888_ASUS_EEE1601,
  231        ALC883_AUTO,
  232        ALC883_MODEL_LAST,
  233};
  234
  235/* for GPIO Poll */
  236#define GPIO_MASK        0x03
  237
  238struct alc_spec {
  239        /* codec parameterization */
  240        struct snd_kcontrol_new *mixers[5];        /* mixer arrays */
  241        unsigned int num_mixers;
  242
  243        const struct hda_verb *init_verbs[5];        /* initialization verbs
  244                                                 * don't forget NULL
  245                                                 * termination!
  246                                                 */
  247        unsigned int num_init_verbs;
  248
  249        char *stream_name_analog;        /* analog PCM stream */
  250        struct hda_pcm_stream *stream_analog_playback;
  251        struct hda_pcm_stream *stream_analog_capture;
  252        struct hda_pcm_stream *stream_analog_alt_playback;
  253        struct hda_pcm_stream *stream_analog_alt_capture;
  254
  255        char *stream_name_digital;        /* digital PCM stream */
  256        struct hda_pcm_stream *stream_digital_playback;
  257        struct hda_pcm_stream *stream_digital_capture;
  258
  259        /* playback */
  260        struct hda_multi_out multiout;        /* playback set-up
  261                                         * max_channels, dacs must be set
  262                                         * dig_out_nid and hp_nid are optional
  263                                         */
  264        hda_nid_t alt_dac_nid;
  265
  266        /* capture */
  267        unsigned int num_adc_nids;
  268        hda_nid_t *adc_nids;
  269        hda_nid_t *capsrc_nids;
  270        hda_nid_t dig_in_nid;                /* digital-in NID; optional */
  271
  272        /* capture source */
  273        unsigned int num_mux_defs;
  274        const struct hda_input_mux *input_mux;
  275        unsigned int cur_mux[3];
  276
  277        /* channel model */
  278        const struct hda_channel_mode *channel_mode;
  279        int num_channel_mode;
  280        int need_dac_fix;
  281
  282        /* PCM information */
  283        struct hda_pcm pcm_rec[3];        /* used in alc_build_pcms() */
  284
  285        /* dynamic controls, init_verbs and input_mux */
  286        struct auto_pin_cfg autocfg;
  287        unsigned int num_kctl_alloc, num_kctl_used;
  288        struct snd_kcontrol_new *kctl_alloc;
  289        struct hda_input_mux private_imux;
  290        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  291
  292        /* hooks */
  293        void (*init_hook)(struct hda_codec *codec);
  294        void (*unsol_event)(struct hda_codec *codec, unsigned int res);
  295
  296        /* for pin sensing */
  297        unsigned int sense_updated: 1;
  298        unsigned int jack_present: 1;
  299        unsigned int master_sw: 1;
  300
  301        /* for virtual master */
  302        hda_nid_t vmaster_nid;
  303#ifdef CONFIG_SND_HDA_POWER_SAVE
  304        struct hda_loopback_check loopback;
  305#endif
  306
  307        /* for PLL fix */
  308        hda_nid_t pll_nid;
  309        unsigned int pll_coef_idx, pll_coef_bit;
  310
  311#ifdef SND_HDA_NEEDS_RESUME
  312#define ALC_MAX_PINS        16
  313        unsigned int num_pins;
  314        hda_nid_t pin_nids[ALC_MAX_PINS];
  315        unsigned int pin_cfgs[ALC_MAX_PINS];
  316#endif
  317};
  318
  319/*
  320 * configuration template - to be copied to the spec instance
  321 */
  322struct alc_config_preset {
  323        struct snd_kcontrol_new *mixers[5]; /* should be identical size
  324                                             * with spec
  325                                             */
  326        const struct hda_verb *init_verbs[5];
  327        unsigned int num_dacs;
  328        hda_nid_t *dac_nids;
  329        hda_nid_t dig_out_nid;                /* optional */
  330        hda_nid_t hp_nid;                /* optional */
  331        unsigned int num_adc_nids;
  332        hda_nid_t *adc_nids;
  333        hda_nid_t *capsrc_nids;
  334        hda_nid_t dig_in_nid;
  335        unsigned int num_channel_mode;
  336        const struct hda_channel_mode *channel_mode;
  337        int need_dac_fix;
  338        unsigned int num_mux_defs;
  339        const struct hda_input_mux *input_mux;
  340        void (*unsol_event)(struct hda_codec *, unsigned int);
  341        void (*init_hook)(struct hda_codec *);
  342#ifdef CONFIG_SND_HDA_POWER_SAVE
  343        struct hda_amp_list *loopbacks;
  344#endif
  345};
  346
  347
  348/*
  349 * input MUX handling
  350 */
  351static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
  352                             struct snd_ctl_elem_info *uinfo)
  353{
  354        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  355        struct alc_spec *spec = codec->spec;
  356        unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
  357        if (mux_idx >= spec->num_mux_defs)
  358                mux_idx = 0;
  359        return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
  360}
  361
  362static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
  363                            struct snd_ctl_elem_value *ucontrol)
  364{
  365        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  366        struct alc_spec *spec = codec->spec;
  367        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  368
  369        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
  370        return 0;
  371}
  372
  373static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
  374                            struct snd_ctl_elem_value *ucontrol)
  375{
  376        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  377        struct alc_spec *spec = codec->spec;
  378        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
  379        unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
  380        hda_nid_t nid = spec->capsrc_nids ?
  381                spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
  382        return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
  383                                     nid, &spec->cur_mux[adc_idx]);
  384}
  385
  386
  387/*
  388 * channel mode setting
  389 */
  390static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
  391                            struct snd_ctl_elem_info *uinfo)
  392{
  393        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  394        struct alc_spec *spec = codec->spec;
  395        return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
  396                                    spec->num_channel_mode);
  397}
  398
  399static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
  400                           struct snd_ctl_elem_value *ucontrol)
  401{
  402        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  403        struct alc_spec *spec = codec->spec;
  404        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
  405                                   spec->num_channel_mode,
  406                                   spec->multiout.max_channels);
  407}
  408
  409static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
  410                           struct snd_ctl_elem_value *ucontrol)
  411{
  412        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  413        struct alc_spec *spec = codec->spec;
  414        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
  415                                      spec->num_channel_mode,
  416                                      &spec->multiout.max_channels);
  417        if (err >= 0 && spec->need_dac_fix)
  418                spec->multiout.num_dacs = spec->multiout.max_channels / 2;
  419        return err;
  420}
  421
  422/*
  423 * Control the mode of pin widget settings via the mixer.  "pc" is used
  424 * instead of "%" to avoid consequences of accidently treating the % as
  425 * being part of a format specifier.  Maximum allowed length of a value is
  426 * 63 characters plus NULL terminator.
  427 *
  428 * Note: some retasking pin complexes seem to ignore requests for input
  429 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
  430 * are requested.  Therefore order this list so that this behaviour will not
  431 * cause problems when mixer clients move through the enum sequentially.
  432 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
  433 * March 2006.
  434 */
  435static char *alc_pin_mode_names[] = {
  436        "Mic 50pc bias", "Mic 80pc bias",
  437        "Line in", "Line out", "Headphone out",
  438};
  439static unsigned char alc_pin_mode_values[] = {
  440        PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
  441};
  442/* The control can present all 5 options, or it can limit the options based
  443 * in the pin being assumed to be exclusively an input or an output pin.  In
  444 * addition, "input" pins may or may not process the mic bias option
  445 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
  446 * accept requests for bias as of chip versions up to March 2006) and/or
  447 * wiring in the computer.
  448 */
  449#define ALC_PIN_DIR_IN              0x00
  450#define ALC_PIN_DIR_OUT             0x01
  451#define ALC_PIN_DIR_INOUT           0x02
  452#define ALC_PIN_DIR_IN_NOMICBIAS    0x03
  453#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
  454
  455/* Info about the pin modes supported by the different pin direction modes.
  456 * For each direction the minimum and maximum values are given.
  457 */
  458static signed char alc_pin_mode_dir_info[5][2] = {
  459        { 0, 2 },    /* ALC_PIN_DIR_IN */
  460        { 3, 4 },    /* ALC_PIN_DIR_OUT */
  461        { 0, 4 },    /* ALC_PIN_DIR_INOUT */
  462        { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
  463        { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
  464};
  465#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
  466#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
  467#define alc_pin_mode_n_items(_dir) \
  468        (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
  469
  470static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
  471                             struct snd_ctl_elem_info *uinfo)
  472{
  473        unsigned int item_num = uinfo->value.enumerated.item;
  474        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  475
  476        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  477        uinfo->count = 1;
  478        uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
  479
  480        if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
  481                item_num = alc_pin_mode_min(dir);
  482        strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
  483        return 0;
  484}
  485
  486static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
  487                            struct snd_ctl_elem_value *ucontrol)
  488{
  489        unsigned int i;
  490        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  491        hda_nid_t nid = kcontrol->private_value & 0xffff;
  492        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  493        long *valp = ucontrol->value.integer.value;
  494        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  495                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
  496                                                 0x00);
  497
  498        /* Find enumerated value for current pinctl setting */
  499        i = alc_pin_mode_min(dir);
  500        while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
  501                i++;
  502        *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
  503        return 0;
  504}
  505
  506static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
  507                            struct snd_ctl_elem_value *ucontrol)
  508{
  509        signed int change;
  510        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  511        hda_nid_t nid = kcontrol->private_value & 0xffff;
  512        unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
  513        long val = *ucontrol->value.integer.value;
  514        unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
  515                                                 AC_VERB_GET_PIN_WIDGET_CONTROL,
  516                                                 0x00);
  517
  518        if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
  519                val = alc_pin_mode_min(dir);
  520
  521        change = pinctl != alc_pin_mode_values[val];
  522        if (change) {
  523                /* Set pin mode to that requested */
  524                snd_hda_codec_write_cache(codec, nid, 0,
  525                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
  526                                          alc_pin_mode_values[val]);
  527
  528                /* Also enable the retasking pin's input/output as required
  529                 * for the requested pin mode.  Enum values of 2 or less are
  530                 * input modes.
  531                 *
  532                 * Dynamically switching the input/output buffers probably
  533                 * reduces noise slightly (particularly on input) so we'll
  534                 * do it.  However, having both input and output buffers
  535                 * enabled simultaneously doesn't seem to be problematic if
  536                 * this turns out to be necessary in the future.
  537                 */
  538                if (val <= 2) {
  539                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  540                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
  541                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  542                                                 HDA_AMP_MUTE, 0);
  543                } else {
  544                        snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
  545                                                 HDA_AMP_MUTE, HDA_AMP_MUTE);
  546                        snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
  547                                                 HDA_AMP_MUTE, 0);
  548                }
  549        }
  550        return change;
  551}
  552
  553#define ALC_PIN_MODE(xname, nid, dir) \
  554        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
  555          .info = alc_pin_mode_info, \
  556          .get = alc_pin_mode_get, \
  557          .put = alc_pin_mode_put, \
  558          .private_value = nid | (dir<<16) }
  559
  560/* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
  561 * together using a mask with more than one bit set.  This control is
  562 * currently used only by the ALC260 test model.  At this stage they are not
  563 * needed for any "production" models.
  564 */
  565#ifdef CONFIG_SND_DEBUG
  566#define alc_gpio_data_info        snd_ctl_boolean_mono_info
  567
  568static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
  569                             struct snd_ctl_elem_value *ucontrol)
  570{
  571        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  572        hda_nid_t nid = kcontrol->private_value & 0xffff;
  573        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  574        long *valp = ucontrol->value.integer.value;
  575        unsigned int val = snd_hda_codec_read(codec, nid, 0,
  576                                              AC_VERB_GET_GPIO_DATA, 0x00);
  577
  578        *valp = (val & mask) != 0;
  579        return 0;
  580}
  581static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
  582                             struct snd_ctl_elem_value *ucontrol)
  583{
  584        signed int change;
  585        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  586        hda_nid_t nid = kcontrol->private_value & 0xffff;
  587        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  588        long val = *ucontrol->value.integer.value;
  589        unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
  590                                                    AC_VERB_GET_GPIO_DATA,
  591                                                    0x00);
  592
  593        /* Set/unset the masked GPIO bit(s) as needed */
  594        change = (val == 0 ? 0 : mask) != (gpio_data & mask);
  595        if (val == 0)
  596                gpio_data &= ~mask;
  597        else
  598                gpio_data |= mask;
  599        snd_hda_codec_write_cache(codec, nid, 0,
  600                                  AC_VERB_SET_GPIO_DATA, gpio_data);
  601
  602        return change;
  603}
  604#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
  605        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
  606          .info = alc_gpio_data_info, \
  607          .get = alc_gpio_data_get, \
  608          .put = alc_gpio_data_put, \
  609          .private_value = nid | (mask<<16) }
  610#endif   /* CONFIG_SND_DEBUG */
  611
  612/* A switch control to allow the enabling of the digital IO pins on the
  613 * ALC260.  This is incredibly simplistic; the intention of this control is
  614 * to provide something in the test model allowing digital outputs to be
  615 * identified if present.  If models are found which can utilise these
  616 * outputs a more complete mixer control can be devised for those models if
  617 * necessary.
  618 */
  619#ifdef CONFIG_SND_DEBUG
  620#define alc_spdif_ctrl_info        snd_ctl_boolean_mono_info
  621
  622static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
  623                              struct snd_ctl_elem_value *ucontrol)
  624{
  625        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  626        hda_nid_t nid = kcontrol->private_value & 0xffff;
  627        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  628        long *valp = ucontrol->value.integer.value;
  629        unsigned int val = snd_hda_codec_read(codec, nid, 0,
  630                                              AC_VERB_GET_DIGI_CONVERT_1, 0x00);
  631
  632        *valp = (val & mask) != 0;
  633        return 0;
  634}
  635static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
  636                              struct snd_ctl_elem_value *ucontrol)
  637{
  638        signed int change;
  639        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  640        hda_nid_t nid = kcontrol->private_value & 0xffff;
  641        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  642        long val = *ucontrol->value.integer.value;
  643        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  644                                                    AC_VERB_GET_DIGI_CONVERT_1,
  645                                                    0x00);
  646
  647        /* Set/unset the masked control bit(s) as needed */
  648        change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
  649        if (val==0)
  650                ctrl_data &= ~mask;
  651        else
  652                ctrl_data |= mask;
  653        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
  654                                  ctrl_data);
  655
  656        return change;
  657}
  658#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
  659        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
  660          .info = alc_spdif_ctrl_info, \
  661          .get = alc_spdif_ctrl_get, \
  662          .put = alc_spdif_ctrl_put, \
  663          .private_value = nid | (mask<<16) }
  664#endif   /* CONFIG_SND_DEBUG */
  665
  666/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
  667 * Again, this is only used in the ALC26x test models to help identify when
  668 * the EAPD line must be asserted for features to work.
  669 */
  670#ifdef CONFIG_SND_DEBUG
  671#define alc_eapd_ctrl_info        snd_ctl_boolean_mono_info
  672
  673static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
  674                              struct snd_ctl_elem_value *ucontrol)
  675{
  676        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  677        hda_nid_t nid = kcontrol->private_value & 0xffff;
  678        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  679        long *valp = ucontrol->value.integer.value;
  680        unsigned int val = snd_hda_codec_read(codec, nid, 0,
  681                                              AC_VERB_GET_EAPD_BTLENABLE, 0x00);
  682
  683        *valp = (val & mask) != 0;
  684        return 0;
  685}
  686
  687static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
  688                              struct snd_ctl_elem_value *ucontrol)
  689{
  690        int change;
  691        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  692        hda_nid_t nid = kcontrol->private_value & 0xffff;
  693        unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
  694        long val = *ucontrol->value.integer.value;
  695        unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
  696                                                    AC_VERB_GET_EAPD_BTLENABLE,
  697                                                    0x00);
  698
  699        /* Set/unset the masked control bit(s) as needed */
  700        change = (!val ? 0 : mask) != (ctrl_data & mask);
  701        if (!val)
  702                ctrl_data &= ~mask;
  703        else
  704                ctrl_data |= mask;
  705        snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
  706                                  ctrl_data);
  707
  708        return change;
  709}
  710
  711#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
  712        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
  713          .info = alc_eapd_ctrl_info, \
  714          .get = alc_eapd_ctrl_get, \
  715          .put = alc_eapd_ctrl_put, \
  716          .private_value = nid | (mask<<16) }
  717#endif   /* CONFIG_SND_DEBUG */
  718
  719/*
  720 * set up from the preset table
  721 */
  722static void setup_preset(struct alc_spec *spec,
  723                         const struct alc_config_preset *preset)
  724{
  725        int i;
  726
  727        for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
  728                spec->mixers[spec->num_mixers++] = preset->mixers[i];
  729        for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
  730             i++)
  731                spec->init_verbs[spec->num_init_verbs++] =
  732                        preset->init_verbs[i];
  733
  734        spec->channel_mode = preset->channel_mode;
  735        spec->num_channel_mode = preset->num_channel_mode;
  736        spec->need_dac_fix = preset->need_dac_fix;
  737
  738        spec->multiout.max_channels = spec->channel_mode[0].channels;
  739
  740        spec->multiout.num_dacs = preset->num_dacs;
  741        spec->multiout.dac_nids = preset->dac_nids;
  742        spec->multiout.dig_out_nid = preset->dig_out_nid;
  743        spec->multiout.hp_nid = preset->hp_nid;
  744
  745        spec->num_mux_defs = preset->num_mux_defs;
  746        if (!spec->num_mux_defs)
  747                spec->num_mux_defs = 1;
  748        spec->input_mux = preset->input_mux;
  749
  750        spec->num_adc_nids = preset->num_adc_nids;
  751        spec->adc_nids = preset->adc_nids;
  752        spec->capsrc_nids = preset->capsrc_nids;
  753        spec->dig_in_nid = preset->dig_in_nid;
  754
  755        spec->unsol_event = preset->unsol_event;
  756        spec->init_hook = preset->init_hook;
  757#ifdef CONFIG_SND_HDA_POWER_SAVE
  758        spec->loopback.amplist = preset->loopbacks;
  759#endif
  760}
  761
  762/* Enable GPIO mask and set output */
  763static struct hda_verb alc_gpio1_init_verbs[] = {
  764        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
  765        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
  766        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
  767        { }
  768};
  769
  770static struct hda_verb alc_gpio2_init_verbs[] = {
  771        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
  772        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
  773        {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
  774        { }
  775};
  776
  777static struct hda_verb alc_gpio3_init_verbs[] = {
  778        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
  779        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
  780        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
  781        { }
  782};
  783
  784/*
  785 * Fix hardware PLL issue
  786 * On some codecs, the analog PLL gating control must be off while
  787 * the default value is 1.
  788 */
  789static void alc_fix_pll(struct hda_codec *codec)
  790{
  791        struct alc_spec *spec = codec->spec;
  792        unsigned int val;
  793
  794        if (!spec->pll_nid)
  795                return;
  796        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
  797                            spec->pll_coef_idx);
  798        val = snd_hda_codec_read(codec, spec->pll_nid, 0,
  799                                 AC_VERB_GET_PROC_COEF, 0);
  800        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
  801                            spec->pll_coef_idx);
  802        snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
  803                            val & ~(1 << spec->pll_coef_bit));
  804}
  805
  806static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
  807                             unsigned int coef_idx, unsigned int coef_bit)
  808{
  809        struct alc_spec *spec = codec->spec;
  810        spec->pll_nid = nid;
  811        spec->pll_coef_idx = coef_idx;
  812        spec->pll_coef_bit = coef_bit;
  813        alc_fix_pll(codec);
  814}
  815
  816static void alc_sku_automute(struct hda_codec *codec)
  817{
  818        struct alc_spec *spec = codec->spec;
  819        unsigned int present;
  820        unsigned int hp_nid = spec->autocfg.hp_pins[0];
  821        unsigned int sp_nid = spec->autocfg.speaker_pins[0];
  822
  823        /* need to execute and sync at first */
  824        snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
  825        present = snd_hda_codec_read(codec, hp_nid, 0,
  826                                     AC_VERB_GET_PIN_SENSE, 0);
  827        spec->jack_present = (present & 0x80000000) != 0;
  828        snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
  829                            spec->jack_present ? 0 : PIN_OUT);
  830}
  831
  832#if 0 /* it's broken in some acses -- temporarily disabled */
  833static void alc_mic_automute(struct hda_codec *codec)
  834{
  835        struct alc_spec *spec = codec->spec;
  836        unsigned int present;
  837        unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
  838        unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
  839        unsigned int mix_nid = spec->capsrc_nids[0];
  840        unsigned int capsrc_idx_mic, capsrc_idx_fmic;
  841
  842        capsrc_idx_mic = mic_nid - 0x18;
  843        capsrc_idx_fmic = fmic_nid - 0x18;
  844        present = snd_hda_codec_read(codec, mic_nid, 0,
  845                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
  846        snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  847                    0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
  848        snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
  849                    0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
  850        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
  851                         HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
  852}
  853#else
  854#define alc_mic_automute(codec) /* NOP */
  855#endif /* disabled */
  856
  857/* unsolicited event for HP jack sensing */
  858static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
  859{
  860        if (codec->vendor_id == 0x10ec0880)
  861                res >>= 28;
  862        else
  863                res >>= 26;
  864        if (res == ALC880_HP_EVENT)
  865                alc_sku_automute(codec);
  866
  867        if (res == ALC880_MIC_EVENT)
  868                alc_mic_automute(codec);
  869}
  870
  871static void alc_inithook(struct hda_codec *codec)
  872{
  873        alc_sku_automute(codec);
  874        alc_mic_automute(codec);
  875}
  876
  877/* additional initialization for ALC888 variants */
  878static void alc888_coef_init(struct hda_codec *codec)
  879{
  880        unsigned int tmp;
  881
  882        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
  883        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
  884        snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
  885        if ((tmp & 0xf0) == 2)
  886                /* alc888S-VC */
  887                snd_hda_codec_read(codec, 0x20, 0,
  888                                   AC_VERB_SET_PROC_COEF, 0x830);
  889         else
  890                 /* alc888-VB */
  891                 snd_hda_codec_read(codec, 0x20, 0,
  892                                    AC_VERB_SET_PROC_COEF, 0x3030);
  893}
  894
  895/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
  896 *        31 ~ 16 :        Manufacture ID
  897 *        15 ~ 8        :        SKU ID
  898 *        7  ~ 0        :        Assembly ID
  899 *        port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
  900 */
  901static void alc_subsystem_id(struct hda_codec *codec,
  902                             unsigned int porta, unsigned int porte,
  903                             unsigned int portd)
  904{
  905        unsigned int ass, tmp, i;
  906        unsigned nid;
  907        struct alc_spec *spec = codec->spec;
  908
  909        ass = codec->subsystem_id & 0xffff;
  910        if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
  911                goto do_sku;
  912
  913        /*
  914         * 31~30        : port conetcivity
  915         * 29~21        : reserve
  916         * 20                : PCBEEP input
  917         * 19~16        : Check sum (15:1)
  918         * 15~1                : Custom
  919         * 0                : override
  920        */
  921        nid = 0x1d;
  922        if (codec->vendor_id == 0x10ec0260)
  923                nid = 0x17;
  924        ass = snd_hda_codec_read(codec, nid, 0,
  925                                 AC_VERB_GET_CONFIG_DEFAULT, 0);
  926        if (!(ass & 1) && !(ass & 0x100000))
  927                return;
  928        if ((ass >> 30) != 1)        /* no physical connection */
  929                return;
  930
  931        /* check sum */
  932        tmp = 0;
  933        for (i = 1; i < 16; i++) {
  934                if ((ass >> i) & 1)
  935                        tmp++;
  936        }
  937        if (((ass >> 16) & 0xf) != tmp)
  938                return;
  939do_sku:
  940        /*
  941         * 0 : override
  942         * 1 :        Swap Jack
  943         * 2 : 0 --> Desktop, 1 --> Laptop
  944         * 3~5 : External Amplifier control
  945         * 7~6 : Reserved
  946        */
  947        tmp = (ass & 0x38) >> 3;        /* external Amp control */
  948        switch (tmp) {
  949        case 1:
  950                snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
  951                break;
  952        case 3:
  953                snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
  954                break;
  955        case 7:
  956                snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
  957                break;
  958        case 5:        /* set EAPD output high */
  959                switch (codec->vendor_id) {
  960                case 0x10ec0260:
  961                        snd_hda_codec_write(codec, 0x0f, 0,
  962                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
  963                        snd_hda_codec_write(codec, 0x10, 0,
  964                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
  965                        break;
  966                case 0x10ec0262:
  967                case 0x10ec0267:
  968                case 0x10ec0268:
  969                case 0x10ec0269:
  970                case 0x10ec0660:
  971                case 0x10ec0662:
  972                case 0x10ec0663:
  973                case 0x10ec0862:
  974                case 0x10ec0889:
  975                        snd_hda_codec_write(codec, 0x14, 0,
  976                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
  977                        snd_hda_codec_write(codec, 0x15, 0,
  978                                            AC_VERB_SET_EAPD_BTLENABLE, 2);
  979                        break;
  980                }
  981                switch (codec->vendor_id) {
  982                case 0x10ec0260:
  983                        snd_hda_codec_write(codec, 0x1a, 0,
  984                                            AC_VERB_SET_COEF_INDEX, 7);
  985                        tmp = snd_hda_codec_read(codec, 0x1a, 0,
  986                                                 AC_VERB_GET_PROC_COEF, 0);
  987                        snd_hda_codec_write(codec, 0x1a, 0,
  988                                            AC_VERB_SET_COEF_INDEX, 7);
  989                        snd_hda_codec_write(codec, 0x1a, 0,
  990                                            AC_VERB_SET_PROC_COEF,
  991                                            tmp | 0x2010);
  992                        break;
  993                case 0x10ec0262:
  994                case 0x10ec0880:
  995                case 0x10ec0882:
  996                case 0x10ec0883:
  997                case 0x10ec0885:
  998                case 0x10ec0889:
  999                        snd_hda_codec_write(codec, 0x20, 0,
 1000                                            AC_VERB_SET_COEF_INDEX, 7);
 1001                        tmp = snd_hda_codec_read(codec, 0x20, 0,
 1002                                                 AC_VERB_GET_PROC_COEF, 0);
 1003                        snd_hda_codec_write(codec, 0x20, 0,
 1004                                            AC_VERB_SET_COEF_INDEX, 7);
 1005                        snd_hda_codec_write(codec, 0x20, 0,
 1006                                            AC_VERB_SET_PROC_COEF,
 1007                                            tmp | 0x2010);
 1008                        break;
 1009                case 0x10ec0888:
 1010                        /*alc888_coef_init(codec);*/ /* called in alc_init() */
 1011                        break;
 1012                case 0x10ec0267:
 1013                case 0x10ec0268:
 1014                        snd_hda_codec_write(codec, 0x20, 0,
 1015                                            AC_VERB_SET_COEF_INDEX, 7);
 1016                        tmp = snd_hda_codec_read(codec, 0x20, 0,
 1017                                                 AC_VERB_GET_PROC_COEF, 0);
 1018                        snd_hda_codec_write(codec, 0x20, 0,
 1019                                            AC_VERB_SET_COEF_INDEX, 7);
 1020                        snd_hda_codec_write(codec, 0x20, 0,
 1021                                            AC_VERB_SET_PROC_COEF,
 1022                                            tmp | 0x3000);
 1023                        break;
 1024                }
 1025        default:
 1026                break;
 1027        }
 1028
 1029        /* is laptop or Desktop and enable the function "Mute internal speaker
 1030         * when the external headphone out jack is plugged"
 1031         */
 1032        if (!(ass & 0x8000))
 1033                return;
 1034        /*
 1035         * 10~8 : Jack location
 1036         * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
 1037         * 14~13: Resvered
 1038         * 15   : 1 --> enable the function "Mute internal speaker
 1039         *                when the external headphone out jack is plugged"
 1040         */
 1041        if (!spec->autocfg.speaker_pins[0]) {
 1042                if (spec->autocfg.line_out_pins[0])
 1043                        spec->autocfg.speaker_pins[0] =
 1044                                spec->autocfg.line_out_pins[0];
 1045                else
 1046                        return;
 1047        }
 1048
 1049        if (!spec->autocfg.hp_pins[0]) {
 1050                tmp = (ass >> 11) & 0x3;        /* HP to chassis */
 1051                if (tmp == 0)
 1052                        spec->autocfg.hp_pins[0] = porta;
 1053                else if (tmp == 1)
 1054                        spec->autocfg.hp_pins[0] = porte;
 1055                else if (tmp == 2)
 1056                        spec->autocfg.hp_pins[0] = portd;
 1057                else
 1058                        return;
 1059        }
 1060        if (spec->autocfg.hp_pins[0])
 1061                snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
 1062                        AC_VERB_SET_UNSOLICITED_ENABLE,
 1063                        AC_USRSP_EN | ALC880_HP_EVENT);
 1064
 1065#if 0 /* it's broken in some acses -- temporarily disabled */
 1066        if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
 1067                spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
 1068                snd_hda_codec_write(codec,
 1069                        spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
 1070                        AC_VERB_SET_UNSOLICITED_ENABLE,
 1071                        AC_USRSP_EN | ALC880_MIC_EVENT);
 1072#endif /* disabled */
 1073
 1074        spec->unsol_event = alc_sku_unsol_event;
 1075}
 1076
 1077/*
 1078 * Fix-up pin default configurations
 1079 */
 1080
 1081struct alc_pincfg {
 1082        hda_nid_t nid;
 1083        u32 val;
 1084};
 1085
 1086static void alc_fix_pincfg(struct hda_codec *codec,
 1087                           const struct snd_pci_quirk *quirk,
 1088                           const struct alc_pincfg **pinfix)
 1089{
 1090        const struct alc_pincfg *cfg;
 1091
 1092        quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
 1093        if (!quirk)
 1094                return;
 1095
 1096        cfg = pinfix[quirk->value];
 1097        for (; cfg->nid; cfg++) {
 1098                int i;
 1099                u32 val = cfg->val;
 1100                for (i = 0; i < 4; i++) {
 1101                        snd_hda_codec_write(codec, cfg->nid, 0,
 1102                                    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
 1103                                    val & 0xff);
 1104                        val >>= 8;
 1105                }
 1106        }
 1107}
 1108
 1109/*
 1110 * ALC880 3-stack model
 1111 *
 1112 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
 1113 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
 1114 *                 F-Mic = 0x1b, HP = 0x19
 1115 */
 1116
 1117static hda_nid_t alc880_dac_nids[4] = {
 1118        /* front, rear, clfe, rear_surr */
 1119        0x02, 0x05, 0x04, 0x03
 1120};
 1121
 1122static hda_nid_t alc880_adc_nids[3] = {
 1123        /* ADC0-2 */
 1124        0x07, 0x08, 0x09,
 1125};
 1126
 1127/* The datasheet says the node 0x07 is connected from inputs,
 1128 * but it shows zero connection in the real implementation on some devices.
 1129 * Note: this is a 915GAV bug, fixed on 915GLV
 1130 */
 1131static hda_nid_t alc880_adc_nids_alt[2] = {
 1132        /* ADC1-2 */
 1133        0x08, 0x09,
 1134};
 1135
 1136#define ALC880_DIGOUT_NID        0x06
 1137#define ALC880_DIGIN_NID        0x0a
 1138
 1139static struct hda_input_mux alc880_capture_source = {
 1140        .num_items = 4,
 1141        .items = {
 1142                { "Mic", 0x0 },
 1143                { "Front Mic", 0x3 },
 1144                { "Line", 0x2 },
 1145                { "CD", 0x4 },
 1146        },
 1147};
 1148
 1149/* channel source setting (2/6 channel selection for 3-stack) */
 1150/* 2ch mode */
 1151static struct hda_verb alc880_threestack_ch2_init[] = {
 1152        /* set line-in to input, mute it */
 1153        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 1154        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 1155        /* set mic-in to input vref 80%, mute it */
 1156        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 1157        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 1158        { } /* end */
 1159};
 1160
 1161/* 6ch mode */
 1162static struct hda_verb alc880_threestack_ch6_init[] = {
 1163        /* set line-in to output, unmute it */
 1164        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 1165        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 1166        /* set mic-in to output, unmute it */
 1167        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 1168        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 1169        { } /* end */
 1170};
 1171
 1172static struct hda_channel_mode alc880_threestack_modes[2] = {
 1173        { 2, alc880_threestack_ch2_init },
 1174        { 6, alc880_threestack_ch6_init },
 1175};
 1176
 1177static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
 1178        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1179        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 1180        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 1181        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
 1182        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 1183        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 1184        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 1185        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 1186        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1187        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1188        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 1189        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 1190        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1191        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1192        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
 1193        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
 1194        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 1195        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 1196        HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
 1197        {
 1198                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1199                .name = "Channel Mode",
 1200                .info = alc_ch_mode_info,
 1201                .get = alc_ch_mode_get,
 1202                .put = alc_ch_mode_put,
 1203        },
 1204        { } /* end */
 1205};
 1206
 1207/* capture mixer elements */
 1208static struct snd_kcontrol_new alc880_capture_mixer[] = {
 1209        HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
 1210        HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
 1211        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
 1212        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
 1213        HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
 1214        HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
 1215        {
 1216                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1217                /* The multiple "Capture Source" controls confuse alsamixer
 1218                 * So call somewhat different..
 1219                 */
 1220                /* .name = "Capture Source", */
 1221                .name = "Input Source",
 1222                .count = 3,
 1223                .info = alc_mux_enum_info,
 1224                .get = alc_mux_enum_get,
 1225                .put = alc_mux_enum_put,
 1226        },
 1227        { } /* end */
 1228};
 1229
 1230/* capture mixer elements (in case NID 0x07 not available) */
 1231static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
 1232        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 1233        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 1234        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 1235        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 1236        {
 1237                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1238                /* The multiple "Capture Source" controls confuse alsamixer
 1239                 * So call somewhat different..
 1240                 */
 1241                /* .name = "Capture Source", */
 1242                .name = "Input Source",
 1243                .count = 2,
 1244                .info = alc_mux_enum_info,
 1245                .get = alc_mux_enum_get,
 1246                .put = alc_mux_enum_put,
 1247        },
 1248        { } /* end */
 1249};
 1250
 1251
 1252
 1253/*
 1254 * ALC880 5-stack model
 1255 *
 1256 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
 1257 *      Side = 0x02 (0xd)
 1258 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
 1259 *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
 1260 */
 1261
 1262/* additional mixers to alc880_three_stack_mixer */
 1263static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
 1264        HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1265        HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
 1266        { } /* end */
 1267};
 1268
 1269/* channel source setting (6/8 channel selection for 5-stack) */
 1270/* 6ch mode */
 1271static struct hda_verb alc880_fivestack_ch6_init[] = {
 1272        /* set line-in to input, mute it */
 1273        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 1274        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 1275        { } /* end */
 1276};
 1277
 1278/* 8ch mode */
 1279static struct hda_verb alc880_fivestack_ch8_init[] = {
 1280        /* set line-in to output, unmute it */
 1281        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 1282        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 1283        { } /* end */
 1284};
 1285
 1286static struct hda_channel_mode alc880_fivestack_modes[2] = {
 1287        { 6, alc880_fivestack_ch6_init },
 1288        { 8, alc880_fivestack_ch8_init },
 1289};
 1290
 1291
 1292/*
 1293 * ALC880 6-stack model
 1294 *
 1295 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
 1296 *      Side = 0x05 (0x0f)
 1297 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
 1298 *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
 1299 */
 1300
 1301static hda_nid_t alc880_6st_dac_nids[4] = {
 1302        /* front, rear, clfe, rear_surr */
 1303        0x02, 0x03, 0x04, 0x05
 1304};
 1305
 1306static struct hda_input_mux alc880_6stack_capture_source = {
 1307        .num_items = 4,
 1308        .items = {
 1309                { "Mic", 0x0 },
 1310                { "Front Mic", 0x1 },
 1311                { "Line", 0x2 },
 1312                { "CD", 0x4 },
 1313        },
 1314};
 1315
 1316/* fixed 8-channels */
 1317static struct hda_channel_mode alc880_sixstack_modes[1] = {
 1318        { 8, NULL },
 1319};
 1320
 1321static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
 1322        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1323        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 1324        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1325        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 1326        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 1327        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 1328        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 1329        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 1330        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 1331        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 1332        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1333        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1334        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 1335        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 1336        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1337        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1338        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 1339        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 1340        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 1341        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 1342        {
 1343                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1344                .name = "Channel Mode",
 1345                .info = alc_ch_mode_info,
 1346                .get = alc_ch_mode_get,
 1347                .put = alc_ch_mode_put,
 1348        },
 1349        { } /* end */
 1350};
 1351
 1352
 1353/*
 1354 * ALC880 W810 model
 1355 *
 1356 * W810 has rear IO for:
 1357 * Front (DAC 02)
 1358 * Surround (DAC 03)
 1359 * Center/LFE (DAC 04)
 1360 * Digital out (06)
 1361 *
 1362 * The system also has a pair of internal speakers, and a headphone jack.
 1363 * These are both connected to Line2 on the codec, hence to DAC 02.
 1364 *
 1365 * There is a variable resistor to control the speaker or headphone
 1366 * volume. This is a hardware-only device without a software API.
 1367 *
 1368 * Plugging headphones in will disable the internal speakers. This is
 1369 * implemented in hardware, not via the driver using jack sense. In
 1370 * a similar fashion, plugging into the rear socket marked "front" will
 1371 * disable both the speakers and headphones.
 1372 *
 1373 * For input, there's a microphone jack, and an "audio in" jack.
 1374 * These may not do anything useful with this driver yet, because I
 1375 * haven't setup any initialization verbs for these yet...
 1376 */
 1377
 1378static hda_nid_t alc880_w810_dac_nids[3] = {
 1379        /* front, rear/surround, clfe */
 1380        0x02, 0x03, 0x04
 1381};
 1382
 1383/* fixed 6 channels */
 1384static struct hda_channel_mode alc880_w810_modes[1] = {
 1385        { 6, NULL }
 1386};
 1387
 1388/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
 1389static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
 1390        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1391        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 1392        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1393        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 1394        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 1395        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 1396        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 1397        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 1398        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 1399        { } /* end */
 1400};
 1401
 1402
 1403/*
 1404 * Z710V model
 1405 *
 1406 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
 1407 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
 1408 *                 Line = 0x1a
 1409 */
 1410
 1411static hda_nid_t alc880_z71v_dac_nids[1] = {
 1412        0x02
 1413};
 1414#define ALC880_Z71V_HP_DAC        0x03
 1415
 1416/* fixed 2 channels */
 1417static struct hda_channel_mode alc880_2_jack_modes[1] = {
 1418        { 2, NULL }
 1419};
 1420
 1421static struct snd_kcontrol_new alc880_z71v_mixer[] = {
 1422        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1423        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 1424        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1425        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
 1426        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1427        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1428        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1429        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1430        { } /* end */
 1431};
 1432
 1433
 1434/*
 1435 * ALC880 F1734 model
 1436 *
 1437 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
 1438 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
 1439 */
 1440
 1441static hda_nid_t alc880_f1734_dac_nids[1] = {
 1442        0x03
 1443};
 1444#define ALC880_F1734_HP_DAC        0x02
 1445
 1446static struct snd_kcontrol_new alc880_f1734_mixer[] = {
 1447        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1448        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 1449        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1450        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 1451        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1452        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1453        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 1454        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 1455        { } /* end */
 1456};
 1457
 1458static struct hda_input_mux alc880_f1734_capture_source = {
 1459        .num_items = 2,
 1460        .items = {
 1461                { "Mic", 0x1 },
 1462                { "CD", 0x4 },
 1463        },
 1464};
 1465
 1466
 1467/*
 1468 * ALC880 ASUS model
 1469 *
 1470 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
 1471 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
 1472 *  Mic = 0x18, Line = 0x1a
 1473 */
 1474
 1475#define alc880_asus_dac_nids        alc880_w810_dac_nids        /* identical with w810 */
 1476#define alc880_asus_modes        alc880_threestack_modes        /* 2/6 channel mode */
 1477
 1478static struct snd_kcontrol_new alc880_asus_mixer[] = {
 1479        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1480        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 1481        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1482        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 1483        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 1484        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 1485        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 1486        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 1487        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1488        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1489        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 1490        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 1491        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1492        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1493        {
 1494                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1495                .name = "Channel Mode",
 1496                .info = alc_ch_mode_info,
 1497                .get = alc_ch_mode_get,
 1498                .put = alc_ch_mode_put,
 1499        },
 1500        { } /* end */
 1501};
 1502
 1503/*
 1504 * ALC880 ASUS W1V model
 1505 *
 1506 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
 1507 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
 1508 *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
 1509 */
 1510
 1511/* additional mixers to alc880_asus_mixer */
 1512static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
 1513        HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
 1514        HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
 1515        { } /* end */
 1516};
 1517
 1518/* additional mixers to alc880_asus_mixer */
 1519static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
 1520        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 1521        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 1522        { } /* end */
 1523};
 1524
 1525/* TCL S700 */
 1526static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
 1527        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1528        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 1529        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 1530        HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
 1531        HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
 1532        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
 1533        HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
 1534        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 1535        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 1536        {
 1537                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1538                /* The multiple "Capture Source" controls confuse alsamixer
 1539                 * So call somewhat different..
 1540                 */
 1541                /* .name = "Capture Source", */
 1542                .name = "Input Source",
 1543                .count = 1,
 1544                .info = alc_mux_enum_info,
 1545                .get = alc_mux_enum_get,
 1546                .put = alc_mux_enum_put,
 1547        },
 1548        { } /* end */
 1549};
 1550
 1551/* Uniwill */
 1552static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
 1553        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1554        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 1555        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1556        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 1557        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 1558        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 1559        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 1560        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 1561        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1562        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1563        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 1564        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 1565        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1566        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1567        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 1568        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 1569        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 1570        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 1571        {
 1572                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 1573                .name = "Channel Mode",
 1574                .info = alc_ch_mode_info,
 1575                .get = alc_ch_mode_get,
 1576                .put = alc_ch_mode_put,
 1577        },
 1578        { } /* end */
 1579};
 1580
 1581static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
 1582        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1583        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 1584        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1585        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 1586        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 1587        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 1588        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1589        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1590        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 1591        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 1592        { } /* end */
 1593};
 1594
 1595static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
 1596        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 1597        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 1598        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 1599        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 1600        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 1601        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 1602        { } /* end */
 1603};
 1604
 1605/*
 1606 * virtual master controls
 1607 */
 1608
 1609/*
 1610 * slave controls for virtual master
 1611 */
 1612static const char *alc_slave_vols[] = {
 1613        "Front Playback Volume",
 1614        "Surround Playback Volume",
 1615        "Center Playback Volume",
 1616        "LFE Playback Volume",
 1617        "Side Playback Volume",
 1618        "Headphone Playback Volume",
 1619        "Speaker Playback Volume",
 1620        "Mono Playback Volume",
 1621        "Line-Out Playback Volume",
 1622        NULL,
 1623};
 1624
 1625static const char *alc_slave_sws[] = {
 1626        "Front Playback Switch",
 1627        "Surround Playback Switch",
 1628        "Center Playback Switch",
 1629        "LFE Playback Switch",
 1630        "Side Playback Switch",
 1631        "Headphone Playback Switch",
 1632        "Speaker Playback Switch",
 1633        "Mono Playback Switch",
 1634        "IEC958 Playback Switch",
 1635        NULL,
 1636};
 1637
 1638/*
 1639 * build control elements
 1640 */
 1641static int alc_build_controls(struct hda_codec *codec)
 1642{
 1643        struct alc_spec *spec = codec->spec;
 1644        int err;
 1645        int i;
 1646
 1647        for (i = 0; i < spec->num_mixers; i++) {
 1648                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
 1649                if (err < 0)
 1650                        return err;
 1651        }
 1652
 1653        if (spec->multiout.dig_out_nid) {
 1654                err = snd_hda_create_spdif_out_ctls(codec,
 1655                                                    spec->multiout.dig_out_nid);
 1656                if (err < 0)
 1657                        return err;
 1658                err = snd_hda_create_spdif_share_sw(codec,
 1659                                                    &spec->multiout);
 1660                if (err < 0)
 1661                        return err;
 1662                spec->multiout.share_spdif = 1;
 1663        }
 1664        if (spec->dig_in_nid) {
 1665                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
 1666                if (err < 0)
 1667                        return err;
 1668        }
 1669
 1670        /* if we have no master control, let's create it */
 1671        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
 1672                unsigned int vmaster_tlv[4];
 1673                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 1674                                        HDA_OUTPUT, vmaster_tlv);
 1675                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
 1676                                          vmaster_tlv, alc_slave_vols);
 1677                if (err < 0)
 1678                        return err;
 1679        }
 1680        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 1681                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
 1682                                          NULL, alc_slave_sws);
 1683                if (err < 0)
 1684                        return err;
 1685        }
 1686
 1687        return 0;
 1688}
 1689
 1690
 1691/*
 1692 * initialize the codec volumes, etc
 1693 */
 1694
 1695/*
 1696 * generic initialization of ADC, input mixers and output mixers
 1697 */
 1698static struct hda_verb alc880_volume_init_verbs[] = {
 1699        /*
 1700         * Unmute ADC0-2 and set the default input to mic-in
 1701         */
 1702        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 1703        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 1704        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 1705        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 1706        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 1707        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 1708
 1709        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 1710         * mixer widget
 1711         * Note: PASD motherboards uses the Line In 2 as the input for front
 1712         * panel mic (mic 2)
 1713         */
 1714        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 1715        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 1716        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 1717        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 1718        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 1719        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 1720        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
 1721        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
 1722
 1723        /*
 1724         * Set up output mixers (0x0c - 0x0f)
 1725         */
 1726        /* set vol=0 to output mixers */
 1727        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 1728        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 1729        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 1730        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 1731        /* set up input amps for analog loopback */
 1732        /* Amp Indices: DAC = 0, mixer = 1 */
 1733        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 1734        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 1735        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 1736        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 1737        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 1738        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 1739        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 1740        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 1741
 1742        { }
 1743};
 1744
 1745/*
 1746 * 3-stack pin configuration:
 1747 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
 1748 */
 1749static struct hda_verb alc880_pin_3stack_init_verbs[] = {
 1750        /*
 1751         * preset connection lists of input pins
 1752         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
 1753         */
 1754        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 1755        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 1756        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
 1757
 1758        /*
 1759         * Set pin mode and muting
 1760         */
 1761        /* set front pin widgets 0x14 for output */
 1762        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1763        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1764        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 1765        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1766        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1767        /* Mic2 (as headphone out) for HP output */
 1768        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1769        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1770        /* Line In pin widget for input */
 1771        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1772        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1773        /* Line2 (as front mic) pin widget for input and vref at 80% */
 1774        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1775        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1776        /* CD pin widget for input */
 1777        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1778
 1779        { }
 1780};
 1781
 1782/*
 1783 * 5-stack pin configuration:
 1784 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
 1785 * line-in/side = 0x1a, f-mic = 0x1b
 1786 */
 1787static struct hda_verb alc880_pin_5stack_init_verbs[] = {
 1788        /*
 1789         * preset connection lists of input pins
 1790         * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
 1791         */
 1792        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 1793        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
 1794
 1795        /*
 1796         * Set pin mode and muting
 1797         */
 1798        /* set pin widgets 0x14-0x17 for output */
 1799        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1800        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1801        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1802        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1803        /* unmute pins for output (no gain on this amp) */
 1804        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1805        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1806        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1807        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1808
 1809        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 1810        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1811        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1812        /* Mic2 (as headphone out) for HP output */
 1813        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1814        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1815        /* Line In pin widget for input */
 1816        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1817        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1818        /* Line2 (as front mic) pin widget for input and vref at 80% */
 1819        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1820        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1821        /* CD pin widget for input */
 1822        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1823
 1824        { }
 1825};
 1826
 1827/*
 1828 * W810 pin configuration:
 1829 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
 1830 */
 1831static struct hda_verb alc880_pin_w810_init_verbs[] = {
 1832        /* hphone/speaker input selector: front DAC */
 1833        {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
 1834
 1835        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1836        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1837        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1838        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1839        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1840        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1841
 1842        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1843        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1844
 1845        { }
 1846};
 1847
 1848/*
 1849 * Z71V pin configuration:
 1850 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
 1851 */
 1852static struct hda_verb alc880_pin_z71v_init_verbs[] = {
 1853        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1854        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1855        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1856        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1857
 1858        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1859        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1860        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1861        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1862
 1863        { }
 1864};
 1865
 1866/*
 1867 * 6-stack pin configuration:
 1868 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
 1869 * f-mic = 0x19, line = 0x1a, HP = 0x1b
 1870 */
 1871static struct hda_verb alc880_pin_6stack_init_verbs[] = {
 1872        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 1873
 1874        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1875        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1876        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1877        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1878        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1879        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1880        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1881        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1882
 1883        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1884        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1885        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1886        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1887        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1888        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1889        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1890        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1891        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1892
 1893        { }
 1894};
 1895
 1896/*
 1897 * Uniwill pin configuration:
 1898 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
 1899 * line = 0x1a
 1900 */
 1901static struct hda_verb alc880_uniwill_init_verbs[] = {
 1902        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 1903
 1904        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1905        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1906        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1907        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1908        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1909        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1910        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 1911        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1912        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1913        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1914        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1915        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1916        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1917        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1918
 1919        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1920        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1921        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1922        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1923        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1924        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1925        /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
 1926        /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
 1927        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1928
 1929        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 1930        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
 1931
 1932        { }
 1933};
 1934
 1935/*
 1936* Uniwill P53
 1937* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
 1938 */
 1939static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
 1940        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 1941
 1942        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1943        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1944        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1945        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1946        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 1947        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 1948        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1949        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1950        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1951        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1952        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 1953        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 1954
 1955        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1956        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1957        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 1958        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1959        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 1960        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 1961
 1962        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 1963        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
 1964
 1965        { }
 1966};
 1967
 1968static struct hda_verb alc880_beep_init_verbs[] = {
 1969        { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
 1970        { }
 1971};
 1972
 1973/* toggle speaker-output according to the hp-jack state */
 1974static void alc880_uniwill_hp_automute(struct hda_codec *codec)
 1975{
 1976         unsigned int present;
 1977        unsigned char bits;
 1978
 1979         present = snd_hda_codec_read(codec, 0x14, 0,
 1980                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 1981        bits = present ? HDA_AMP_MUTE : 0;
 1982        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 1983                                 HDA_AMP_MUTE, bits);
 1984        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 1985                                 HDA_AMP_MUTE, bits);
 1986}
 1987
 1988/* auto-toggle front mic */
 1989static void alc880_uniwill_mic_automute(struct hda_codec *codec)
 1990{
 1991         unsigned int present;
 1992        unsigned char bits;
 1993
 1994        present = snd_hda_codec_read(codec, 0x18, 0,
 1995                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 1996        bits = present ? HDA_AMP_MUTE : 0;
 1997        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
 1998}
 1999
 2000static void alc880_uniwill_automute(struct hda_codec *codec)
 2001{
 2002        alc880_uniwill_hp_automute(codec);
 2003        alc880_uniwill_mic_automute(codec);
 2004}
 2005
 2006static void alc880_uniwill_unsol_event(struct hda_codec *codec,
 2007                                       unsigned int res)
 2008{
 2009        /* Looks like the unsol event is incompatible with the standard
 2010         * definition.  4bit tag is placed at 28 bit!
 2011         */
 2012        switch (res >> 28) {
 2013        case ALC880_HP_EVENT:
 2014                alc880_uniwill_hp_automute(codec);
 2015                break;
 2016        case ALC880_MIC_EVENT:
 2017                alc880_uniwill_mic_automute(codec);
 2018                break;
 2019        }
 2020}
 2021
 2022static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
 2023{
 2024         unsigned int present;
 2025        unsigned char bits;
 2026
 2027         present = snd_hda_codec_read(codec, 0x14, 0,
 2028                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 2029        bits = present ? HDA_AMP_MUTE : 0;
 2030        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
 2031}
 2032
 2033static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
 2034{
 2035        unsigned int present;
 2036
 2037        present = snd_hda_codec_read(codec, 0x21, 0,
 2038                                     AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 2039        present &= HDA_AMP_VOLMASK;
 2040        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
 2041                                 HDA_AMP_VOLMASK, present);
 2042        snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
 2043                                 HDA_AMP_VOLMASK, present);
 2044}
 2045
 2046static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
 2047                                           unsigned int res)
 2048{
 2049        /* Looks like the unsol event is incompatible with the standard
 2050         * definition.  4bit tag is placed at 28 bit!
 2051         */
 2052        if ((res >> 28) == ALC880_HP_EVENT)
 2053                alc880_uniwill_p53_hp_automute(codec);
 2054        if ((res >> 28) == ALC880_DCVOL_EVENT)
 2055                alc880_uniwill_p53_dcvol_automute(codec);
 2056}
 2057
 2058/*
 2059 * F1734 pin configuration:
 2060 * HP = 0x14, speaker-out = 0x15, mic = 0x18
 2061 */
 2062static struct hda_verb alc880_pin_f1734_init_verbs[] = {
 2063        {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
 2064        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
 2065        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
 2066        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
 2067        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
 2068
 2069        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2070        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2071        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2072        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2073
 2074        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2075        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2076        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
 2077        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2078        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2079        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2080        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2081        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2082        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2083
 2084        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
 2085        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
 2086
 2087        { }
 2088};
 2089
 2090/*
 2091 * ASUS pin configuration:
 2092 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
 2093 */
 2094static struct hda_verb alc880_pin_asus_init_verbs[] = {
 2095        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
 2096        {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
 2097        {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
 2098        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
 2099
 2100        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2101        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2102        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2103        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2104        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2105        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2106        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2107        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2108
 2109        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2110        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2111        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2112        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2113        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2114        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2115        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2116        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2117        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2118
 2119        { }
 2120};
 2121
 2122/* Enable GPIO mask and set output */
 2123#define alc880_gpio1_init_verbs        alc_gpio1_init_verbs
 2124#define alc880_gpio2_init_verbs        alc_gpio2_init_verbs
 2125
 2126/* Clevo m520g init */
 2127static struct hda_verb alc880_pin_clevo_init_verbs[] = {
 2128        /* headphone output */
 2129        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
 2130        /* line-out */
 2131        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2132        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2133        /* Line-in */
 2134        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2135        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2136        /* CD */
 2137        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2138        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2139        /* Mic1 (rear panel) */
 2140        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2141        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2142        /* Mic2 (front panel) */
 2143        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2144        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2145        /* headphone */
 2146        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2147        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2148        /* change to EAPD mode */
 2149        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 2150        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
 2151
 2152        { }
 2153};
 2154
 2155static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
 2156        /* change to EAPD mode */
 2157        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 2158        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
 2159
 2160        /* Headphone output */
 2161        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2162        /* Front output*/
 2163        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2164        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 2165
 2166        /* Line In pin widget for input */
 2167        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2168        /* CD pin widget for input */
 2169        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2170        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 2171        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2172
 2173        /* change to EAPD mode */
 2174        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 2175        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
 2176
 2177        { }
 2178};
 2179
 2180/*
 2181 * LG m1 express dual
 2182 *
 2183 * Pin assignment:
 2184 *   Rear Line-In/Out (blue): 0x14
 2185 *   Build-in Mic-In: 0x15
 2186 *   Speaker-out: 0x17
 2187 *   HP-Out (green): 0x1b
 2188 *   Mic-In/Out (red): 0x19
 2189 *   SPDIF-Out: 0x1e
 2190 */
 2191
 2192/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
 2193static hda_nid_t alc880_lg_dac_nids[3] = {
 2194        0x05, 0x02, 0x03
 2195};
 2196
 2197/* seems analog CD is not working */
 2198static struct hda_input_mux alc880_lg_capture_source = {
 2199        .num_items = 3,
 2200        .items = {
 2201                { "Mic", 0x1 },
 2202                { "Line", 0x5 },
 2203                { "Internal Mic", 0x6 },
 2204        },
 2205};
 2206
 2207/* 2,4,6 channel modes */
 2208static struct hda_verb alc880_lg_ch2_init[] = {
 2209        /* set line-in and mic-in to input */
 2210        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 2211        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 2212        { }
 2213};
 2214
 2215static struct hda_verb alc880_lg_ch4_init[] = {
 2216        /* set line-in to out and mic-in to input */
 2217        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 2218        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 2219        { }
 2220};
 2221
 2222static struct hda_verb alc880_lg_ch6_init[] = {
 2223        /* set line-in and mic-in to output */
 2224        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 2225        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
 2226        { }
 2227};
 2228
 2229static struct hda_channel_mode alc880_lg_ch_modes[3] = {
 2230        { 2, alc880_lg_ch2_init },
 2231        { 4, alc880_lg_ch4_init },
 2232        { 6, alc880_lg_ch6_init },
 2233};
 2234
 2235static struct snd_kcontrol_new alc880_lg_mixer[] = {
 2236        HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 2237        HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
 2238        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 2239        HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
 2240        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
 2241        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
 2242        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
 2243        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
 2244        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 2245        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 2246        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
 2247        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
 2248        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
 2249        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
 2250        {
 2251                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 2252                .name = "Channel Mode",
 2253                .info = alc_ch_mode_info,
 2254                .get = alc_ch_mode_get,
 2255                .put = alc_ch_mode_put,
 2256        },
 2257        { } /* end */
 2258};
 2259
 2260static struct hda_verb alc880_lg_init_verbs[] = {
 2261        /* set capture source to mic-in */
 2262        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 2263        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 2264        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 2265        /* mute all amp mixer inputs */
 2266        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
 2267        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
 2268        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
 2269        /* line-in to input */
 2270        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 2271        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2272        /* built-in mic */
 2273        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2274        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2275        /* speaker-out */
 2276        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2277        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2278        /* mic-in to input */
 2279        {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
 2280        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2281        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2282        /* HP-out */
 2283        {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
 2284        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2285        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2286        /* jack sense */
 2287        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
 2288        { }
 2289};
 2290
 2291/* toggle speaker-output according to the hp-jack state */
 2292static void alc880_lg_automute(struct hda_codec *codec)
 2293{
 2294        unsigned int present;
 2295        unsigned char bits;
 2296
 2297        present = snd_hda_codec_read(codec, 0x1b, 0,
 2298                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 2299        bits = present ? HDA_AMP_MUTE : 0;
 2300        snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
 2301                                 HDA_AMP_MUTE, bits);
 2302}
 2303
 2304static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
 2305{
 2306        /* Looks like the unsol event is incompatible with the standard
 2307         * definition.  4bit tag is placed at 28 bit!
 2308         */
 2309        if ((res >> 28) == 0x01)
 2310                alc880_lg_automute(codec);
 2311}
 2312
 2313/*
 2314 * LG LW20
 2315 *
 2316 * Pin assignment:
 2317 *   Speaker-out: 0x14
 2318 *   Mic-In: 0x18
 2319 *   Built-in Mic-In: 0x19
 2320 *   Line-In: 0x1b
 2321 *   HP-Out: 0x1a
 2322 *   SPDIF-Out: 0x1e
 2323 */
 2324
 2325static struct hda_input_mux alc880_lg_lw_capture_source = {
 2326        .num_items = 3,
 2327        .items = {
 2328                { "Mic", 0x0 },
 2329                { "Internal Mic", 0x1 },
 2330                { "Line In", 0x2 },
 2331        },
 2332};
 2333
 2334#define alc880_lg_lw_modes alc880_threestack_modes
 2335
 2336static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
 2337        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 2338        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 2339        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 2340        HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
 2341        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 2342        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 2343        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 2344        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 2345        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 2346        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 2347        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 2348        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 2349        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 2350        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 2351        {
 2352                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 2353                .name = "Channel Mode",
 2354                .info = alc_ch_mode_info,
 2355                .get = alc_ch_mode_get,
 2356                .put = alc_ch_mode_put,
 2357        },
 2358        { } /* end */
 2359};
 2360
 2361static struct hda_verb alc880_lg_lw_init_verbs[] = {
 2362        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 2363        {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 2364        {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
 2365
 2366        /* set capture source to mic-in */
 2367        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 2368        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 2369        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 2370        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
 2371        /* speaker-out */
 2372        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2373        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2374        /* HP-out */
 2375        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2376        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2377        /* mic-in to input */
 2378        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2379        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2380        /* built-in mic */
 2381        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2382        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2383        /* jack sense */
 2384        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
 2385        { }
 2386};
 2387
 2388/* toggle speaker-output according to the hp-jack state */
 2389static void alc880_lg_lw_automute(struct hda_codec *codec)
 2390{
 2391        unsigned int present;
 2392        unsigned char bits;
 2393
 2394        present = snd_hda_codec_read(codec, 0x1b, 0,
 2395                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 2396        bits = present ? HDA_AMP_MUTE : 0;
 2397        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 2398                                 HDA_AMP_MUTE, bits);
 2399}
 2400
 2401static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
 2402{
 2403        /* Looks like the unsol event is incompatible with the standard
 2404         * definition.  4bit tag is placed at 28 bit!
 2405         */
 2406        if ((res >> 28) == 0x01)
 2407                alc880_lg_lw_automute(codec);
 2408}
 2409
 2410static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
 2411        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 2412        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
 2413        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 2414        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 2415        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 2416        HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
 2417        { } /* end */
 2418};
 2419
 2420static struct hda_input_mux alc880_medion_rim_capture_source = {
 2421        .num_items = 2,
 2422        .items = {
 2423                { "Mic", 0x0 },
 2424                { "Internal Mic", 0x1 },
 2425        },
 2426};
 2427
 2428static struct hda_verb alc880_medion_rim_init_verbs[] = {
 2429        {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 2430
 2431        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2432        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2433
 2434        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 2435        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 2436        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2437        /* Mic2 (as headphone out) for HP output */
 2438        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 2439        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 2440        /* Internal Speaker */
 2441        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 2442        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 2443
 2444        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 2445        {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
 2446
 2447        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 2448        { }
 2449};
 2450
 2451/* toggle speaker-output according to the hp-jack state */
 2452static void alc880_medion_rim_automute(struct hda_codec *codec)
 2453{
 2454        unsigned int present;
 2455        unsigned char bits;
 2456
 2457        present = snd_hda_codec_read(codec, 0x14, 0,
 2458                                     AC_VERB_GET_PIN_SENSE, 0)
 2459                & AC_PINSENSE_PRESENCE;
 2460        bits = present ? HDA_AMP_MUTE : 0;
 2461        snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 2462                                 HDA_AMP_MUTE, bits);
 2463        if (present)
 2464                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
 2465        else
 2466                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
 2467}
 2468
 2469static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
 2470                                          unsigned int res)
 2471{
 2472        /* Looks like the unsol event is incompatible with the standard
 2473         * definition.  4bit tag is placed at 28 bit!
 2474         */
 2475        if ((res >> 28) == ALC880_HP_EVENT)
 2476                alc880_medion_rim_automute(codec);
 2477}
 2478
 2479#ifdef CONFIG_SND_HDA_POWER_SAVE
 2480static struct hda_amp_list alc880_loopbacks[] = {
 2481        { 0x0b, HDA_INPUT, 0 },
 2482        { 0x0b, HDA_INPUT, 1 },
 2483        { 0x0b, HDA_INPUT, 2 },
 2484        { 0x0b, HDA_INPUT, 3 },
 2485        { 0x0b, HDA_INPUT, 4 },
 2486        { } /* end */
 2487};
 2488
 2489static struct hda_amp_list alc880_lg_loopbacks[] = {
 2490        { 0x0b, HDA_INPUT, 1 },
 2491        { 0x0b, HDA_INPUT, 6 },
 2492        { 0x0b, HDA_INPUT, 7 },
 2493        { } /* end */
 2494};
 2495#endif
 2496
 2497/*
 2498 * Common callbacks
 2499 */
 2500
 2501static int alc_init(struct hda_codec *codec)
 2502{
 2503        struct alc_spec *spec = codec->spec;
 2504        unsigned int i;
 2505
 2506        alc_fix_pll(codec);
 2507        if (codec->vendor_id == 0x10ec0888)
 2508                alc888_coef_init(codec);
 2509
 2510        for (i = 0; i < spec->num_init_verbs; i++)
 2511                snd_hda_sequence_write(codec, spec->init_verbs[i]);
 2512
 2513        if (spec->init_hook)
 2514                spec->init_hook(codec);
 2515
 2516        return 0;
 2517}
 2518
 2519static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
 2520{
 2521        struct alc_spec *spec = codec->spec;
 2522
 2523        if (spec->unsol_event)
 2524                spec->unsol_event(codec, res);
 2525}
 2526
 2527#ifdef CONFIG_SND_HDA_POWER_SAVE
 2528static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 2529{
 2530        struct alc_spec *spec = codec->spec;
 2531        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
 2532}
 2533#endif
 2534
 2535/*
 2536 * Analog playback callbacks
 2537 */
 2538static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
 2539                                    struct hda_codec *codec,
 2540                                    struct snd_pcm_substream *substream)
 2541{
 2542        struct alc_spec *spec = codec->spec;
 2543        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
 2544                                             hinfo);
 2545}
 2546
 2547static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 2548                                       struct hda_codec *codec,
 2549                                       unsigned int stream_tag,
 2550                                       unsigned int format,
 2551                                       struct snd_pcm_substream *substream)
 2552{
 2553        struct alc_spec *spec = codec->spec;
 2554        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
 2555                                                stream_tag, format, substream);
 2556}
 2557
 2558static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 2559                                       struct hda_codec *codec,
 2560                                       struct snd_pcm_substream *substream)
 2561{
 2562        struct alc_spec *spec = codec->spec;
 2563        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 2564}
 2565
 2566/*
 2567 * Digital out
 2568 */
 2569static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 2570                                        struct hda_codec *codec,
 2571                                        struct snd_pcm_substream *substream)
 2572{
 2573        struct alc_spec *spec = codec->spec;
 2574        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 2575}
 2576
 2577static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 2578                                           struct hda_codec *codec,
 2579                                           unsigned int stream_tag,
 2580                                           unsigned int format,
 2581                                           struct snd_pcm_substream *substream)
 2582{
 2583        struct alc_spec *spec = codec->spec;
 2584        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
 2585                                             stream_tag, format, substream);
 2586}
 2587
 2588static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 2589                                         struct hda_codec *codec,
 2590                                         struct snd_pcm_substream *substream)
 2591{
 2592        struct alc_spec *spec = codec->spec;
 2593        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 2594}
 2595
 2596/*
 2597 * Analog capture
 2598 */
 2599static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 2600                                      struct hda_codec *codec,
 2601                                      unsigned int stream_tag,
 2602                                      unsigned int format,
 2603                                      struct snd_pcm_substream *substream)
 2604{
 2605        struct alc_spec *spec = codec->spec;
 2606
 2607        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
 2608                                   stream_tag, 0, format);
 2609        return 0;
 2610}
 2611
 2612static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 2613                                      struct hda_codec *codec,
 2614                                      struct snd_pcm_substream *substream)
 2615{
 2616        struct alc_spec *spec = codec->spec;
 2617
 2618        snd_hda_codec_cleanup_stream(codec,
 2619                                     spec->adc_nids[substream->number + 1]);
 2620        return 0;
 2621}
 2622
 2623
 2624/*
 2625 */
 2626static struct hda_pcm_stream alc880_pcm_analog_playback = {
 2627        .substreams = 1,
 2628        .channels_min = 2,
 2629        .channels_max = 8,
 2630        /* NID is set in alc_build_pcms */
 2631        .ops = {
 2632                .open = alc880_playback_pcm_open,
 2633                .prepare = alc880_playback_pcm_prepare,
 2634                .cleanup = alc880_playback_pcm_cleanup
 2635        },
 2636};
 2637
 2638static struct hda_pcm_stream alc880_pcm_analog_capture = {
 2639        .substreams = 1,
 2640        .channels_min = 2,
 2641        .channels_max = 2,
 2642        /* NID is set in alc_build_pcms */
 2643};
 2644
 2645static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
 2646        .substreams = 1,
 2647        .channels_min = 2,
 2648        .channels_max = 2,
 2649        /* NID is set in alc_build_pcms */
 2650};
 2651
 2652static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
 2653        .substreams = 2, /* can be overridden */
 2654        .channels_min = 2,
 2655        .channels_max = 2,
 2656        /* NID is set in alc_build_pcms */
 2657        .ops = {
 2658                .prepare = alc880_alt_capture_pcm_prepare,
 2659                .cleanup = alc880_alt_capture_pcm_cleanup
 2660        },
 2661};
 2662
 2663static struct hda_pcm_stream alc880_pcm_digital_playback = {
 2664        .substreams = 1,
 2665        .channels_min = 2,
 2666        .channels_max = 2,
 2667        /* NID is set in alc_build_pcms */
 2668        .ops = {
 2669                .open = alc880_dig_playback_pcm_open,
 2670                .close = alc880_dig_playback_pcm_close,
 2671                .prepare = alc880_dig_playback_pcm_prepare
 2672        },
 2673};
 2674
 2675static struct hda_pcm_stream alc880_pcm_digital_capture = {
 2676        .substreams = 1,
 2677        .channels_min = 2,
 2678        .channels_max = 2,
 2679        /* NID is set in alc_build_pcms */
 2680};
 2681
 2682/* Used by alc_build_pcms to flag that a PCM has no playback stream */
 2683static struct hda_pcm_stream alc_pcm_null_stream = {
 2684        .substreams = 0,
 2685        .channels_min = 0,
 2686        .channels_max = 0,
 2687};
 2688
 2689static int alc_build_pcms(struct hda_codec *codec)
 2690{
 2691        struct alc_spec *spec = codec->spec;
 2692        struct hda_pcm *info = spec->pcm_rec;
 2693        int i;
 2694
 2695        codec->num_pcms = 1;
 2696        codec->pcm_info = info;
 2697
 2698        info->name = spec->stream_name_analog;
 2699        if (spec->stream_analog_playback) {
 2700                if (snd_BUG_ON(!spec->multiout.dac_nids))
 2701                        return -EINVAL;
 2702                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
 2703                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
 2704        }
 2705        if (spec->stream_analog_capture) {
 2706                if (snd_BUG_ON(!spec->adc_nids))
 2707                        return -EINVAL;
 2708                info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
 2709                info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 2710        }
 2711
 2712        if (spec->channel_mode) {
 2713                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
 2714                for (i = 0; i < spec->num_channel_mode; i++) {
 2715                        if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
 2716                                info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
 2717                        }
 2718                }
 2719        }
 2720
 2721        /* SPDIF for stream index #1 */
 2722        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
 2723                codec->num_pcms = 2;
 2724                info = spec->pcm_rec + 1;
 2725                info->name = spec->stream_name_digital;
 2726                info->pcm_type = HDA_PCM_TYPE_SPDIF;
 2727                if (spec->multiout.dig_out_nid &&
 2728                    spec->stream_digital_playback) {
 2729                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
 2730                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
 2731                }
 2732                if (spec->dig_in_nid &&
 2733                    spec->stream_digital_capture) {
 2734                        info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
 2735                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 2736                }
 2737                /* FIXME: do we need this for all Realtek codec models? */
 2738                codec->spdif_status_reset = 1;
 2739        }
 2740
 2741        /* If the use of more than one ADC is requested for the current
 2742         * model, configure a second analog capture-only PCM.
 2743         */
 2744        /* Additional Analaog capture for index #2 */
 2745        if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
 2746            (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
 2747                codec->num_pcms = 3;
 2748                info = spec->pcm_rec + 2;
 2749                info->name = spec->stream_name_analog;
 2750                if (spec->alt_dac_nid) {
 2751                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
 2752                                *spec->stream_analog_alt_playback;
 2753                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 2754                                spec->alt_dac_nid;
 2755                } else {
 2756                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
 2757                                alc_pcm_null_stream;
 2758                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
 2759                }
 2760                if (spec->num_adc_nids > 1) {
 2761                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 2762                                *spec->stream_analog_alt_capture;
 2763                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
 2764                                spec->adc_nids[1];
 2765                        info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
 2766                                spec->num_adc_nids - 1;
 2767                } else {
 2768                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 2769                                alc_pcm_null_stream;
 2770                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
 2771                }
 2772        }
 2773
 2774        return 0;
 2775}
 2776
 2777static void alc_free(struct hda_codec *codec)
 2778{
 2779        struct alc_spec *spec = codec->spec;
 2780        unsigned int i;
 2781
 2782        if (!spec)
 2783                return;
 2784
 2785        if (spec->kctl_alloc) {
 2786                for (i = 0; i < spec->num_kctl_used; i++)
 2787                        kfree(spec->kctl_alloc[i].name);
 2788                kfree(spec->kctl_alloc);
 2789        }
 2790        kfree(spec);
 2791        codec->spec = NULL; /* to be sure */
 2792}
 2793
 2794#ifdef SND_HDA_NEEDS_RESUME
 2795static void store_pin_configs(struct hda_codec *codec)
 2796{
 2797        struct alc_spec *spec = codec->spec;
 2798        hda_nid_t nid, end_nid;
 2799
 2800        end_nid = codec->start_nid + codec->num_nodes;
 2801        for (nid = codec->start_nid; nid < end_nid; nid++) {
 2802                unsigned int wid_caps = get_wcaps(codec, nid);
 2803                unsigned int wid_type =
 2804                        (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 2805                if (wid_type != AC_WID_PIN)
 2806                        continue;
 2807                if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
 2808                        break;
 2809                spec->pin_nids[spec->num_pins] = nid;
 2810                spec->pin_cfgs[spec->num_pins] =
 2811                        snd_hda_codec_read(codec, nid, 0,
 2812                                           AC_VERB_GET_CONFIG_DEFAULT, 0);
 2813                spec->num_pins++;
 2814        }
 2815}
 2816
 2817static void resume_pin_configs(struct hda_codec *codec)
 2818{
 2819        struct alc_spec *spec = codec->spec;
 2820        int i;
 2821
 2822        for (i = 0; i < spec->num_pins; i++) {
 2823                hda_nid_t pin_nid = spec->pin_nids[i];
 2824                unsigned int pin_config = spec->pin_cfgs[i];
 2825                snd_hda_codec_write(codec, pin_nid, 0,
 2826                                    AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
 2827                                    pin_config & 0x000000ff);
 2828                snd_hda_codec_write(codec, pin_nid, 0,
 2829                                    AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
 2830                                    (pin_config & 0x0000ff00) >> 8);
 2831                snd_hda_codec_write(codec, pin_nid, 0,
 2832                                    AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
 2833                                    (pin_config & 0x00ff0000) >> 16);
 2834                snd_hda_codec_write(codec, pin_nid, 0,
 2835                                    AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
 2836                                    pin_config >> 24);
 2837        }
 2838}
 2839
 2840static int alc_resume(struct hda_codec *codec)
 2841{
 2842        resume_pin_configs(codec);
 2843        codec->patch_ops.init(codec);
 2844        snd_hda_codec_resume_amp(codec);
 2845        snd_hda_codec_resume_cache(codec);
 2846        return 0;
 2847}
 2848#else
 2849#define store_pin_configs(codec)
 2850#endif
 2851
 2852/*
 2853 */
 2854static struct hda_codec_ops alc_patch_ops = {
 2855        .build_controls = alc_build_controls,
 2856        .build_pcms = alc_build_pcms,
 2857        .init = alc_init,
 2858        .free = alc_free,
 2859        .unsol_event = alc_unsol_event,
 2860#ifdef SND_HDA_NEEDS_RESUME
 2861        .resume = alc_resume,
 2862#endif
 2863#ifdef CONFIG_SND_HDA_POWER_SAVE
 2864        .check_power_status = alc_check_power_status,
 2865#endif
 2866};
 2867
 2868
 2869/*
 2870 * Test configuration for debugging
 2871 *
 2872 * Almost all inputs/outputs are enabled.  I/O pins can be configured via
 2873 * enum controls.
 2874 */
 2875#ifdef CONFIG_SND_DEBUG
 2876static hda_nid_t alc880_test_dac_nids[4] = {
 2877        0x02, 0x03, 0x04, 0x05
 2878};
 2879
 2880static struct hda_input_mux alc880_test_capture_source = {
 2881        .num_items = 7,
 2882        .items = {
 2883                { "In-1", 0x0 },
 2884                { "In-2", 0x1 },
 2885                { "In-3", 0x2 },
 2886                { "In-4", 0x3 },
 2887                { "CD", 0x4 },
 2888                { "Front", 0x5 },
 2889                { "Surround", 0x6 },
 2890        },
 2891};
 2892
 2893static struct hda_channel_mode alc880_test_modes[4] = {
 2894        { 2, NULL },
 2895        { 4, NULL },
 2896        { 6, NULL },
 2897        { 8, NULL },
 2898};
 2899
 2900static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
 2901                                 struct snd_ctl_elem_info *uinfo)
 2902{
 2903        static char *texts[] = {
 2904                "N/A", "Line Out", "HP Out",
 2905                "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
 2906        };
 2907        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 2908        uinfo->count = 1;
 2909        uinfo->value.enumerated.items = 8;
 2910        if (uinfo->value.enumerated.item >= 8)
 2911                uinfo->value.enumerated.item = 7;
 2912        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 2913        return 0;
 2914}
 2915
 2916static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
 2917                                struct snd_ctl_elem_value *ucontrol)
 2918{
 2919        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 2920        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
 2921        unsigned int pin_ctl, item = 0;
 2922
 2923        pin_ctl = snd_hda_codec_read(codec, nid, 0,
 2924                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
 2925        if (pin_ctl & AC_PINCTL_OUT_EN) {
 2926                if (pin_ctl & AC_PINCTL_HP_EN)
 2927                        item = 2;
 2928                else
 2929                        item = 1;
 2930        } else if (pin_ctl & AC_PINCTL_IN_EN) {
 2931                switch (pin_ctl & AC_PINCTL_VREFEN) {
 2932                case AC_PINCTL_VREF_HIZ: item = 3; break;
 2933                case AC_PINCTL_VREF_50:  item = 4; break;
 2934                case AC_PINCTL_VREF_GRD: item = 5; break;
 2935                case AC_PINCTL_VREF_80:  item = 6; break;
 2936                case AC_PINCTL_VREF_100: item = 7; break;
 2937                }
 2938        }
 2939        ucontrol->value.enumerated.item[0] = item;
 2940        return 0;
 2941}
 2942
 2943static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
 2944                                struct snd_ctl_elem_value *ucontrol)
 2945{
 2946        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 2947        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
 2948        static unsigned int ctls[] = {
 2949                0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
 2950                AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
 2951                AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
 2952                AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
 2953                AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
 2954                AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
 2955        };
 2956        unsigned int old_ctl, new_ctl;
 2957
 2958        old_ctl = snd_hda_codec_read(codec, nid, 0,
 2959                                     AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
 2960        new_ctl = ctls[ucontrol->value.enumerated.item[0]];
 2961        if (old_ctl != new_ctl) {
 2962                int val;
 2963                snd_hda_codec_write_cache(codec, nid, 0,
 2964                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
 2965                                          new_ctl);
 2966                val = ucontrol->value.enumerated.item[0] >= 3 ?
 2967                        HDA_AMP_MUTE : 0;
 2968                snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
 2969                                         HDA_AMP_MUTE, val);
 2970                return 1;
 2971        }
 2972        return 0;
 2973}
 2974
 2975static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
 2976                                 struct snd_ctl_elem_info *uinfo)
 2977{
 2978        static char *texts[] = {
 2979                "Front", "Surround", "CLFE", "Side"
 2980        };
 2981        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 2982        uinfo->count = 1;
 2983        uinfo->value.enumerated.items = 4;
 2984        if (uinfo->value.enumerated.item >= 4)
 2985                uinfo->value.enumerated.item = 3;
 2986        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 2987        return 0;
 2988}
 2989
 2990static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
 2991                                struct snd_ctl_elem_value *ucontrol)
 2992{
 2993        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 2994        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
 2995        unsigned int sel;
 2996
 2997        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
 2998        ucontrol->value.enumerated.item[0] = sel & 3;
 2999        return 0;
 3000}
 3001
 3002static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
 3003                                struct snd_ctl_elem_value *ucontrol)
 3004{
 3005        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 3006        hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
 3007        unsigned int sel;
 3008
 3009        sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
 3010        if (ucontrol->value.enumerated.item[0] != sel) {
 3011                sel = ucontrol->value.enumerated.item[0] & 3;
 3012                snd_hda_codec_write_cache(codec, nid, 0,
 3013                                          AC_VERB_SET_CONNECT_SEL, sel);
 3014                return 1;
 3015        }
 3016        return 0;
 3017}
 3018
 3019#define PIN_CTL_TEST(xname,nid) {                        \
 3020                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,        \
 3021                        .name = xname,                       \
 3022                        .info = alc_test_pin_ctl_info, \
 3023                        .get = alc_test_pin_ctl_get,   \
 3024                        .put = alc_test_pin_ctl_put,   \
 3025                        .private_value = nid               \
 3026                        }
 3027
 3028#define PIN_SRC_TEST(xname,nid) {                        \
 3029                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,        \
 3030                        .name = xname,                       \
 3031                        .info = alc_test_pin_src_info, \
 3032                        .get = alc_test_pin_src_get,   \
 3033                        .put = alc_test_pin_src_put,   \
 3034                        .private_value = nid               \
 3035                        }
 3036
 3037static struct snd_kcontrol_new alc880_test_mixer[] = {
 3038        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 3039        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 3040        HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
 3041        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 3042        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 3043        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 3044        HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
 3045        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 3046        PIN_CTL_TEST("Front Pin Mode", 0x14),
 3047        PIN_CTL_TEST("Surround Pin Mode", 0x15),
 3048        PIN_CTL_TEST("CLFE Pin Mode", 0x16),
 3049        PIN_CTL_TEST("Side Pin Mode", 0x17),
 3050        PIN_CTL_TEST("In-1 Pin Mode", 0x18),
 3051        PIN_CTL_TEST("In-2 Pin Mode", 0x19),
 3052        PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
 3053        PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
 3054        PIN_SRC_TEST("In-1 Pin Source", 0x18),
 3055        PIN_SRC_TEST("In-2 Pin Source", 0x19),
 3056        PIN_SRC_TEST("In-3 Pin Source", 0x1a),
 3057        PIN_SRC_TEST("In-4 Pin Source", 0x1b),
 3058        HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
 3059        HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
 3060        HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
 3061        HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
 3062        HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
 3063        HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
 3064        HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
 3065        HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
 3066        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
 3067        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
 3068        {
 3069                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 3070                .name = "Channel Mode",
 3071                .info = alc_ch_mode_info,
 3072                .get = alc_ch_mode_get,
 3073                .put = alc_ch_mode_put,
 3074        },
 3075        { } /* end */
 3076};
 3077
 3078static struct hda_verb alc880_test_init_verbs[] = {
 3079        /* Unmute inputs of 0x0c - 0x0f */
 3080        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 3081        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 3082        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 3083        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 3084        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 3085        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 3086        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 3087        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 3088        /* Vol output for 0x0c-0x0f */
 3089        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 3090        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 3091        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 3092        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 3093        /* Set output pins 0x14-0x17 */
 3094        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 3095        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 3096        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 3097        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 3098        /* Unmute output pins 0x14-0x17 */
 3099        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 3100        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 3101        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 3102        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 3103        /* Set input pins 0x18-0x1c */
 3104        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 3105        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 3106        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 3107        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 3108        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 3109        /* Mute input pins 0x18-0x1b */
 3110        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 3111        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 3112        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 3113        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 3114        /* ADC set up */
 3115        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 3116        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 3117        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 3118        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 3119        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 3120        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 3121        /* Analog input/passthru */
 3122        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 3123        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 3124        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 3125        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 3126        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 3127        { }
 3128};
 3129#endif
 3130
 3131/*
 3132 */
 3133
 3134static const char *alc880_models[ALC880_MODEL_LAST] = {
 3135        [ALC880_3ST]                = "3stack",
 3136        [ALC880_TCL_S700]        = "tcl",
 3137        [ALC880_3ST_DIG]        = "3stack-digout",
 3138        [ALC880_CLEVO]                = "clevo",
 3139        [ALC880_5ST]                = "5stack",
 3140        [ALC880_5ST_DIG]        = "5stack-digout",
 3141        [ALC880_W810]                = "w810",
 3142        [ALC880_Z71V]                = "z71v",
 3143        [ALC880_6ST]                = "6stack",
 3144        [ALC880_6ST_DIG]        = "6stack-digout",
 3145        [ALC880_ASUS]                = "asus",
 3146        [ALC880_ASUS_W1V]        = "asus-w1v",
 3147        [ALC880_ASUS_DIG]        = "asus-dig",
 3148        [ALC880_ASUS_DIG2]        = "asus-dig2",
 3149        [ALC880_UNIWILL_DIG]        = "uniwill",
 3150        [ALC880_UNIWILL_P53]        = "uniwill-p53",
 3151        [ALC880_FUJITSU]        = "fujitsu",
 3152        [ALC880_F1734]                = "F1734",
 3153        [ALC880_LG]                = "lg",
 3154        [ALC880_LG_LW]                = "lg-lw",
 3155        [ALC880_MEDION_RIM]        = "medion",
 3156#ifdef CONFIG_SND_DEBUG
 3157        [ALC880_TEST]                = "test",
 3158#endif
 3159        [ALC880_AUTO]                = "auto",
 3160};
 3161
 3162static struct snd_pci_quirk alc880_cfg_tbl[] = {
 3163        SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
 3164        SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
 3165        SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
 3166        SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
 3167        SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
 3168        SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
 3169        SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
 3170        SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
 3171        SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
 3172        SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
 3173        SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
 3174        SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
 3175        SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
 3176        SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
 3177        SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
 3178        SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
 3179        SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
 3180        SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
 3181        /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
 3182        SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
 3183        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
 3184        SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
 3185        SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
 3186        SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
 3187        SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
 3188        SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
 3189        SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
 3190        SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
 3191        SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
 3192        SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
 3193        SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
 3194        SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
 3195        SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
 3196        SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
 3197        SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
 3198        SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
 3199        SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
 3200        SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
 3201        SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
 3202        SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
 3203        SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
 3204        SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
 3205        SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
 3206        SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
 3207        SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
 3208        SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
 3209        SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
 3210        SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
 3211        SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
 3212        SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
 3213        SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
 3214        SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
 3215        SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
 3216        SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
 3217        SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
 3218        SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
 3219        SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
 3220        SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
 3221        SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
 3222        SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
 3223        SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
 3224        SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
 3225        SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
 3226        SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
 3227        SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
 3228        SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
 3229        SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
 3230        SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
 3231        SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
 3232        SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
 3233        SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
 3234        {}
 3235};
 3236
 3237/*
 3238 * ALC880 codec presets
 3239 */
 3240static struct alc_config_preset alc880_presets[] = {
 3241        [ALC880_3ST] = {
 3242                .mixers = { alc880_three_stack_mixer },
 3243                .init_verbs = { alc880_volume_init_verbs,
 3244                                alc880_pin_3stack_init_verbs },
 3245                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3246                .dac_nids = alc880_dac_nids,
 3247                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 3248                .channel_mode = alc880_threestack_modes,
 3249                .need_dac_fix = 1,
 3250                .input_mux = &alc880_capture_source,
 3251        },
 3252        [ALC880_3ST_DIG] = {
 3253                .mixers = { alc880_three_stack_mixer },
 3254                .init_verbs = { alc880_volume_init_verbs,
 3255                                alc880_pin_3stack_init_verbs },
 3256                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3257                .dac_nids = alc880_dac_nids,
 3258                .dig_out_nid = ALC880_DIGOUT_NID,
 3259                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 3260                .channel_mode = alc880_threestack_modes,
 3261                .need_dac_fix = 1,
 3262                .input_mux = &alc880_capture_source,
 3263        },
 3264        [ALC880_TCL_S700] = {
 3265                .mixers = { alc880_tcl_s700_mixer },
 3266                .init_verbs = { alc880_volume_init_verbs,
 3267                                alc880_pin_tcl_S700_init_verbs,
 3268                                alc880_gpio2_init_verbs },
 3269                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3270                .dac_nids = alc880_dac_nids,
 3271                .hp_nid = 0x03,
 3272                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
 3273                .channel_mode = alc880_2_jack_modes,
 3274                .input_mux = &alc880_capture_source,
 3275        },
 3276        [ALC880_5ST] = {
 3277                .mixers = { alc880_three_stack_mixer,
 3278                            alc880_five_stack_mixer},
 3279                .init_verbs = { alc880_volume_init_verbs,
 3280                                alc880_pin_5stack_init_verbs },
 3281                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3282                .dac_nids = alc880_dac_nids,
 3283                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
 3284                .channel_mode = alc880_fivestack_modes,
 3285                .input_mux = &alc880_capture_source,
 3286        },
 3287        [ALC880_5ST_DIG] = {
 3288                .mixers = { alc880_three_stack_mixer,
 3289                            alc880_five_stack_mixer },
 3290                .init_verbs = { alc880_volume_init_verbs,
 3291                                alc880_pin_5stack_init_verbs },
 3292                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3293                .dac_nids = alc880_dac_nids,
 3294                .dig_out_nid = ALC880_DIGOUT_NID,
 3295                .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
 3296                .channel_mode = alc880_fivestack_modes,
 3297                .input_mux = &alc880_capture_source,
 3298        },
 3299        [ALC880_6ST] = {
 3300                .mixers = { alc880_six_stack_mixer },
 3301                .init_verbs = { alc880_volume_init_verbs,
 3302                                alc880_pin_6stack_init_verbs },
 3303                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
 3304                .dac_nids = alc880_6st_dac_nids,
 3305                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
 3306                .channel_mode = alc880_sixstack_modes,
 3307                .input_mux = &alc880_6stack_capture_source,
 3308        },
 3309        [ALC880_6ST_DIG] = {
 3310                .mixers = { alc880_six_stack_mixer },
 3311                .init_verbs = { alc880_volume_init_verbs,
 3312                                alc880_pin_6stack_init_verbs },
 3313                .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
 3314                .dac_nids = alc880_6st_dac_nids,
 3315                .dig_out_nid = ALC880_DIGOUT_NID,
 3316                .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
 3317                .channel_mode = alc880_sixstack_modes,
 3318                .input_mux = &alc880_6stack_capture_source,
 3319        },
 3320        [ALC880_W810] = {
 3321                .mixers = { alc880_w810_base_mixer },
 3322                .init_verbs = { alc880_volume_init_verbs,
 3323                                alc880_pin_w810_init_verbs,
 3324                                alc880_gpio2_init_verbs },
 3325                .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
 3326                .dac_nids = alc880_w810_dac_nids,
 3327                .dig_out_nid = ALC880_DIGOUT_NID,
 3328                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
 3329                .channel_mode = alc880_w810_modes,
 3330                .input_mux = &alc880_capture_source,
 3331        },
 3332        [ALC880_Z71V] = {
 3333                .mixers = { alc880_z71v_mixer },
 3334                .init_verbs = { alc880_volume_init_verbs,
 3335                                alc880_pin_z71v_init_verbs },
 3336                .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
 3337                .dac_nids = alc880_z71v_dac_nids,
 3338                .dig_out_nid = ALC880_DIGOUT_NID,
 3339                .hp_nid = 0x03,
 3340                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
 3341                .channel_mode = alc880_2_jack_modes,
 3342                .input_mux = &alc880_capture_source,
 3343        },
 3344        [ALC880_F1734] = {
 3345                .mixers = { alc880_f1734_mixer },
 3346                .init_verbs = { alc880_volume_init_verbs,
 3347                                alc880_pin_f1734_init_verbs },
 3348                .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
 3349                .dac_nids = alc880_f1734_dac_nids,
 3350                .hp_nid = 0x02,
 3351                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
 3352                .channel_mode = alc880_2_jack_modes,
 3353                .input_mux = &alc880_f1734_capture_source,
 3354                .unsol_event = alc880_uniwill_p53_unsol_event,
 3355                .init_hook = alc880_uniwill_p53_hp_automute,
 3356        },
 3357        [ALC880_ASUS] = {
 3358                .mixers = { alc880_asus_mixer },
 3359                .init_verbs = { alc880_volume_init_verbs,
 3360                                alc880_pin_asus_init_verbs,
 3361                                alc880_gpio1_init_verbs },
 3362                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3363                .dac_nids = alc880_asus_dac_nids,
 3364                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
 3365                .channel_mode = alc880_asus_modes,
 3366                .need_dac_fix = 1,
 3367                .input_mux = &alc880_capture_source,
 3368        },
 3369        [ALC880_ASUS_DIG] = {
 3370                .mixers = { alc880_asus_mixer },
 3371                .init_verbs = { alc880_volume_init_verbs,
 3372                                alc880_pin_asus_init_verbs,
 3373                                alc880_gpio1_init_verbs },
 3374                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3375                .dac_nids = alc880_asus_dac_nids,
 3376                .dig_out_nid = ALC880_DIGOUT_NID,
 3377                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
 3378                .channel_mode = alc880_asus_modes,
 3379                .need_dac_fix = 1,
 3380                .input_mux = &alc880_capture_source,
 3381        },
 3382        [ALC880_ASUS_DIG2] = {
 3383                .mixers = { alc880_asus_mixer },
 3384                .init_verbs = { alc880_volume_init_verbs,
 3385                                alc880_pin_asus_init_verbs,
 3386                                alc880_gpio2_init_verbs }, /* use GPIO2 */
 3387                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3388                .dac_nids = alc880_asus_dac_nids,
 3389                .dig_out_nid = ALC880_DIGOUT_NID,
 3390                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
 3391                .channel_mode = alc880_asus_modes,
 3392                .need_dac_fix = 1,
 3393                .input_mux = &alc880_capture_source,
 3394        },
 3395        [ALC880_ASUS_W1V] = {
 3396                .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
 3397                .init_verbs = { alc880_volume_init_verbs,
 3398                                alc880_pin_asus_init_verbs,
 3399                                alc880_gpio1_init_verbs },
 3400                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3401                .dac_nids = alc880_asus_dac_nids,
 3402                .dig_out_nid = ALC880_DIGOUT_NID,
 3403                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
 3404                .channel_mode = alc880_asus_modes,
 3405                .need_dac_fix = 1,
 3406                .input_mux = &alc880_capture_source,
 3407        },
 3408        [ALC880_UNIWILL_DIG] = {
 3409                .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
 3410                .init_verbs = { alc880_volume_init_verbs,
 3411                                alc880_pin_asus_init_verbs },
 3412                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3413                .dac_nids = alc880_asus_dac_nids,
 3414                .dig_out_nid = ALC880_DIGOUT_NID,
 3415                .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
 3416                .channel_mode = alc880_asus_modes,
 3417                .need_dac_fix = 1,
 3418                .input_mux = &alc880_capture_source,
 3419        },
 3420        [ALC880_UNIWILL] = {
 3421                .mixers = { alc880_uniwill_mixer },
 3422                .init_verbs = { alc880_volume_init_verbs,
 3423                                alc880_uniwill_init_verbs },
 3424                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3425                .dac_nids = alc880_asus_dac_nids,
 3426                .dig_out_nid = ALC880_DIGOUT_NID,
 3427                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 3428                .channel_mode = alc880_threestack_modes,
 3429                .need_dac_fix = 1,
 3430                .input_mux = &alc880_capture_source,
 3431                .unsol_event = alc880_uniwill_unsol_event,
 3432                .init_hook = alc880_uniwill_automute,
 3433        },
 3434        [ALC880_UNIWILL_P53] = {
 3435                .mixers = { alc880_uniwill_p53_mixer },
 3436                .init_verbs = { alc880_volume_init_verbs,
 3437                                alc880_uniwill_p53_init_verbs },
 3438                .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
 3439                .dac_nids = alc880_asus_dac_nids,
 3440                .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
 3441                .channel_mode = alc880_threestack_modes,
 3442                .input_mux = &alc880_capture_source,
 3443                .unsol_event = alc880_uniwill_p53_unsol_event,
 3444                .init_hook = alc880_uniwill_p53_hp_automute,
 3445        },
 3446        [ALC880_FUJITSU] = {
 3447                .mixers = { alc880_fujitsu_mixer,
 3448                            alc880_pcbeep_mixer, },
 3449                .init_verbs = { alc880_volume_init_verbs,
 3450                                alc880_uniwill_p53_init_verbs,
 3451                                       alc880_beep_init_verbs },
 3452                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3453                .dac_nids = alc880_dac_nids,
 3454                .dig_out_nid = ALC880_DIGOUT_NID,
 3455                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
 3456                .channel_mode = alc880_2_jack_modes,
 3457                .input_mux = &alc880_capture_source,
 3458                .unsol_event = alc880_uniwill_p53_unsol_event,
 3459                .init_hook = alc880_uniwill_p53_hp_automute,
 3460        },
 3461        [ALC880_CLEVO] = {
 3462                .mixers = { alc880_three_stack_mixer },
 3463                .init_verbs = { alc880_volume_init_verbs,
 3464                                alc880_pin_clevo_init_verbs },
 3465                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3466                .dac_nids = alc880_dac_nids,
 3467                .hp_nid = 0x03,
 3468                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 3469                .channel_mode = alc880_threestack_modes,
 3470                .need_dac_fix = 1,
 3471                .input_mux = &alc880_capture_source,
 3472        },
 3473        [ALC880_LG] = {
 3474                .mixers = { alc880_lg_mixer },
 3475                .init_verbs = { alc880_volume_init_verbs,
 3476                                alc880_lg_init_verbs },
 3477                .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
 3478                .dac_nids = alc880_lg_dac_nids,
 3479                .dig_out_nid = ALC880_DIGOUT_NID,
 3480                .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
 3481                .channel_mode = alc880_lg_ch_modes,
 3482                .need_dac_fix = 1,
 3483                .input_mux = &alc880_lg_capture_source,
 3484                .unsol_event = alc880_lg_unsol_event,
 3485                .init_hook = alc880_lg_automute,
 3486#ifdef CONFIG_SND_HDA_POWER_SAVE
 3487                .loopbacks = alc880_lg_loopbacks,
 3488#endif
 3489        },
 3490        [ALC880_LG_LW] = {
 3491                .mixers = { alc880_lg_lw_mixer },
 3492                .init_verbs = { alc880_volume_init_verbs,
 3493                                alc880_lg_lw_init_verbs },
 3494                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3495                .dac_nids = alc880_dac_nids,
 3496                .dig_out_nid = ALC880_DIGOUT_NID,
 3497                .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
 3498                .channel_mode = alc880_lg_lw_modes,
 3499                .input_mux = &alc880_lg_lw_capture_source,
 3500                .unsol_event = alc880_lg_lw_unsol_event,
 3501                .init_hook = alc880_lg_lw_automute,
 3502        },
 3503        [ALC880_MEDION_RIM] = {
 3504                .mixers = { alc880_medion_rim_mixer },
 3505                .init_verbs = { alc880_volume_init_verbs,
 3506                                alc880_medion_rim_init_verbs,
 3507                                alc_gpio2_init_verbs },
 3508                .num_dacs = ARRAY_SIZE(alc880_dac_nids),
 3509                .dac_nids = alc880_dac_nids,
 3510                .dig_out_nid = ALC880_DIGOUT_NID,
 3511                .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
 3512                .channel_mode = alc880_2_jack_modes,
 3513                .input_mux = &alc880_medion_rim_capture_source,
 3514                .unsol_event = alc880_medion_rim_unsol_event,
 3515                .init_hook = alc880_medion_rim_automute,
 3516        },
 3517#ifdef CONFIG_SND_DEBUG
 3518        [ALC880_TEST] = {
 3519                .mixers = { alc880_test_mixer },
 3520                .init_verbs = { alc880_test_init_verbs },
 3521                .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
 3522                .dac_nids = alc880_test_dac_nids,
 3523                .dig_out_nid = ALC880_DIGOUT_NID,
 3524                .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
 3525                .channel_mode = alc880_test_modes,
 3526                .input_mux = &alc880_test_capture_source,
 3527        },
 3528#endif
 3529};
 3530
 3531/*
 3532 * Automatic parse of I/O pins from the BIOS configuration
 3533 */
 3534
 3535#define NUM_CONTROL_ALLOC        32
 3536#define NUM_VERB_ALLOC                32
 3537
 3538enum {
 3539        ALC_CTL_WIDGET_VOL,
 3540        ALC_CTL_WIDGET_MUTE,
 3541        ALC_CTL_BIND_MUTE,
 3542};
 3543static struct snd_kcontrol_new alc880_control_templates[] = {
 3544        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 3545        HDA_CODEC_MUTE(NULL, 0, 0, 0),
 3546        HDA_BIND_MUTE(NULL, 0, 0, 0),
 3547};
 3548
 3549/* add dynamic controls */
 3550static int add_control(struct alc_spec *spec, int type, const char *name,
 3551                       unsigned long val)
 3552{
 3553        struct snd_kcontrol_new *knew;
 3554
 3555        if (spec->num_kctl_used >= spec->num_kctl_alloc) {
 3556                int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
 3557
 3558                /* array + terminator */
 3559                knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
 3560                if (!knew)
 3561                        return -ENOMEM;
 3562                if (spec->kctl_alloc) {
 3563                        memcpy(knew, spec->kctl_alloc,
 3564                               sizeof(*knew) * spec->num_kctl_alloc);
 3565                        kfree(spec->kctl_alloc);
 3566                }
 3567                spec->kctl_alloc = knew;
 3568                spec->num_kctl_alloc = num;
 3569        }
 3570
 3571        knew = &spec->kctl_alloc[spec->num_kctl_used];
 3572        *knew = alc880_control_templates[type];
 3573        knew->name = kstrdup(name, GFP_KERNEL);
 3574        if (!knew->name)
 3575                return -ENOMEM;
 3576        knew->private_value = val;
 3577        spec->num_kctl_used++;
 3578        return 0;
 3579}
 3580
 3581#define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
 3582#define alc880_fixed_pin_idx(nid)        ((nid) - 0x14)
 3583#define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
 3584#define alc880_multi_pin_idx(nid)        ((nid) - 0x18)
 3585#define alc880_is_input_pin(nid)        ((nid) >= 0x18)
 3586#define alc880_input_pin_idx(nid)        ((nid) - 0x18)
 3587#define alc880_idx_to_dac(nid)                ((nid) + 0x02)
 3588#define alc880_dac_to_idx(nid)                ((nid) - 0x02)
 3589#define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
 3590#define alc880_idx_to_selector(nid)        ((nid) + 0x10)
 3591#define ALC880_PIN_CD_NID                0x1c
 3592
 3593/* fill in the dac_nids table from the parsed pin configuration */
 3594static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
 3595                                     const struct auto_pin_cfg *cfg)
 3596{
 3597        hda_nid_t nid;
 3598        int assigned[4];
 3599        int i, j;
 3600
 3601        memset(assigned, 0, sizeof(assigned));
 3602        spec->multiout.dac_nids = spec->private_dac_nids;
 3603
 3604        /* check the pins hardwired to audio widget */
 3605        for (i = 0; i < cfg->line_outs; i++) {
 3606                nid = cfg->line_out_pins[i];
 3607                if (alc880_is_fixed_pin(nid)) {
 3608                        int idx = alc880_fixed_pin_idx(nid);
 3609                        spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
 3610                        assigned[idx] = 1;
 3611                }
 3612        }
 3613        /* left pins can be connect to any audio widget */
 3614        for (i = 0; i < cfg->line_outs; i++) {
 3615                nid = cfg->line_out_pins[i];
 3616                if (alc880_is_fixed_pin(nid))
 3617                        continue;
 3618                /* search for an empty channel */
 3619                for (j = 0; j < cfg->line_outs; j++) {
 3620                        if (!assigned[j]) {
 3621                                spec->multiout.dac_nids[i] =
 3622                                        alc880_idx_to_dac(j);
 3623                                assigned[j] = 1;
 3624                                break;
 3625                        }
 3626                }
 3627        }
 3628        spec->multiout.num_dacs = cfg->line_outs;
 3629        return 0;
 3630}
 3631
 3632/* add playback controls from the parsed DAC table */
 3633static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
 3634                                             const struct auto_pin_cfg *cfg)
 3635{
 3636        char name[32];
 3637        static const char *chname[4] = {
 3638                "Front", "Surround", NULL /*CLFE*/, "Side"
 3639        };
 3640        hda_nid_t nid;
 3641        int i, err;
 3642
 3643        for (i = 0; i < cfg->line_outs; i++) {
 3644                if (!spec->multiout.dac_nids[i])
 3645                        continue;
 3646                nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
 3647                if (i == 2) {
 3648                        /* Center/LFE */
 3649                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
 3650                                          "Center Playback Volume",
 3651                                          HDA_COMPOSE_AMP_VAL(nid, 1, 0,
 3652                                                              HDA_OUTPUT));
 3653                        if (err < 0)
 3654                                return err;
 3655                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
 3656                                          "LFE Playback Volume",
 3657                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
 3658                                                              HDA_OUTPUT));
 3659                        if (err < 0)
 3660                                return err;
 3661                        err = add_control(spec, ALC_CTL_BIND_MUTE,
 3662                                          "Center Playback Switch",
 3663                                          HDA_COMPOSE_AMP_VAL(nid, 1, 2,
 3664                                                              HDA_INPUT));
 3665                        if (err < 0)
 3666                                return err;
 3667                        err = add_control(spec, ALC_CTL_BIND_MUTE,
 3668                                          "LFE Playback Switch",
 3669                                          HDA_COMPOSE_AMP_VAL(nid, 2, 2,
 3670                                                              HDA_INPUT));
 3671                        if (err < 0)
 3672                                return err;
 3673                } else {
 3674                        sprintf(name, "%s Playback Volume", chname[i]);
 3675                        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
 3676                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
 3677                                                              HDA_OUTPUT));
 3678                        if (err < 0)
 3679                                return err;
 3680                        sprintf(name, "%s Playback Switch", chname[i]);
 3681                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
 3682                                          HDA_COMPOSE_AMP_VAL(nid, 3, 2,
 3683                                                              HDA_INPUT));
 3684                        if (err < 0)
 3685                                return err;
 3686                }
 3687        }
 3688        return 0;
 3689}
 3690
 3691/* add playback controls for speaker and HP outputs */
 3692static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
 3693                                        const char *pfx)
 3694{
 3695        hda_nid_t nid;
 3696        int err;
 3697        char name[32];
 3698
 3699        if (!pin)
 3700                return 0;
 3701
 3702        if (alc880_is_fixed_pin(pin)) {
 3703                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
 3704                /* specify the DAC as the extra output */
 3705                if (!spec->multiout.hp_nid)
 3706                        spec->multiout.hp_nid = nid;
 3707                else
 3708                        spec->multiout.extra_out_nid[0] = nid;
 3709                /* control HP volume/switch on the output mixer amp */
 3710                nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
 3711                sprintf(name, "%s Playback Volume", pfx);
 3712                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
 3713                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
 3714                if (err < 0)
 3715                        return err;
 3716                sprintf(name, "%s Playback Switch", pfx);
 3717                err = add_control(spec, ALC_CTL_BIND_MUTE, name,
 3718                                  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
 3719                if (err < 0)
 3720                        return err;
 3721        } else if (alc880_is_multi_pin(pin)) {
 3722                /* set manual connection */
 3723                /* we have only a switch on HP-out PIN */
 3724                sprintf(name, "%s Playback Switch", pfx);
 3725                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
 3726                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
 3727                if (err < 0)
 3728                        return err;
 3729        }
 3730        return 0;
 3731}
 3732
 3733/* create input playback/capture controls for the given pin */
 3734static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
 3735                            const char *ctlname,
 3736                            int idx, hda_nid_t mix_nid)
 3737{
 3738        char name[32];
 3739        int err;
 3740
 3741        sprintf(name, "%s Playback Volume", ctlname);
 3742        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
 3743                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 3744        if (err < 0)
 3745                return err;
 3746        sprintf(name, "%s Playback Switch", ctlname);
 3747        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
 3748                          HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 3749        if (err < 0)
 3750                return err;
 3751        return 0;
 3752}
 3753
 3754/* create playback/capture controls for input pins */
 3755static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
 3756                                                const struct auto_pin_cfg *cfg)
 3757{
 3758        struct hda_input_mux *imux = &spec->private_imux;
 3759        int i, err, idx;
 3760
 3761        for (i = 0; i < AUTO_PIN_LAST; i++) {
 3762                if (alc880_is_input_pin(cfg->input_pins[i])) {
 3763                        idx = alc880_input_pin_idx(cfg->input_pins[i]);
 3764                        err = new_analog_input(spec, cfg->input_pins[i],
 3765                                               auto_pin_cfg_labels[i],
 3766                                               idx, 0x0b);
 3767                        if (err < 0)
 3768                                return err;
 3769                        imux->items[imux->num_items].label =
 3770                                auto_pin_cfg_labels[i];
 3771                        imux->items[imux->num_items].index =
 3772                                alc880_input_pin_idx(cfg->input_pins[i]);
 3773                        imux->num_items++;
 3774                }
 3775        }
 3776        return 0;
 3777}
 3778
 3779static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
 3780                               unsigned int pin_type)
 3781{
 3782        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 3783                            pin_type);
 3784        /* unmute pin */
 3785        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 3786                            AMP_OUT_UNMUTE);
 3787}
 3788
 3789static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
 3790                                              hda_nid_t nid, int pin_type,
 3791                                              int dac_idx)
 3792{
 3793        alc_set_pin_output(codec, nid, pin_type);
 3794        /* need the manual connection? */
 3795        if (alc880_is_multi_pin(nid)) {
 3796                struct alc_spec *spec = codec->spec;
 3797                int idx = alc880_multi_pin_idx(nid);
 3798                snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
 3799                                    AC_VERB_SET_CONNECT_SEL,
 3800                                    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
 3801        }
 3802}
 3803
 3804static int get_pin_type(int line_out_type)
 3805{
 3806        if (line_out_type == AUTO_PIN_HP_OUT)
 3807                return PIN_HP;
 3808        else
 3809                return PIN_OUT;
 3810}
 3811
 3812static void alc880_auto_init_multi_out(struct hda_codec *codec)
 3813{
 3814        struct alc_spec *spec = codec->spec;
 3815        int i;
 3816
 3817        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 3818        for (i = 0; i < spec->autocfg.line_outs; i++) {
 3819                hda_nid_t nid = spec->autocfg.line_out_pins[i];
 3820                int pin_type = get_pin_type(spec->autocfg.line_out_type);
 3821                alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
 3822        }
 3823}
 3824
 3825static void alc880_auto_init_extra_out(struct hda_codec *codec)
 3826{
 3827        struct alc_spec *spec = codec->spec;
 3828        hda_nid_t pin;
 3829
 3830        pin = spec->autocfg.speaker_pins[0];
 3831        if (pin) /* connect to front */
 3832                alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 3833        pin = spec->autocfg.hp_pins[0];
 3834        if (pin) /* connect to front */
 3835                alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 3836}
 3837
 3838static void alc880_auto_init_analog_input(struct hda_codec *codec)
 3839{
 3840        struct alc_spec *spec = codec->spec;
 3841        int i;
 3842
 3843        for (i = 0; i < AUTO_PIN_LAST; i++) {
 3844                hda_nid_t nid = spec->autocfg.input_pins[i];
 3845                if (alc880_is_input_pin(nid)) {
 3846                        snd_hda_codec_write(codec, nid, 0,
 3847                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
 3848                                            i <= AUTO_PIN_FRONT_MIC ?
 3849                                            PIN_VREF80 : PIN_IN);
 3850                        if (nid != ALC880_PIN_CD_NID)
 3851                                snd_hda_codec_write(codec, nid, 0,
 3852                                                    AC_VERB_SET_AMP_GAIN_MUTE,
 3853                                                    AMP_OUT_MUTE);
 3854                }
 3855        }
 3856}
 3857
 3858/* parse the BIOS configuration and set up the alc_spec */
 3859/* return 1 if successful, 0 if the proper config is not found,
 3860 * or a negative error code
 3861 */
 3862static int alc880_parse_auto_config(struct hda_codec *codec)
 3863{
 3864        struct alc_spec *spec = codec->spec;
 3865        int err;
 3866        static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
 3867
 3868        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
 3869                                           alc880_ignore);
 3870        if (err < 0)
 3871                return err;
 3872        if (!spec->autocfg.line_outs)
 3873                return 0; /* can't find valid BIOS pin config */
 3874
 3875        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
 3876        if (err < 0)
 3877                return err;
 3878        err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
 3879        if (err < 0)
 3880                return err;
 3881        err = alc880_auto_create_extra_out(spec,
 3882                                           spec->autocfg.speaker_pins[0],
 3883                                           "Speaker");
 3884        if (err < 0)
 3885                return err;
 3886        err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
 3887                                           "Headphone");
 3888        if (err < 0)
 3889                return err;
 3890        err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
 3891        if (err < 0)
 3892                return err;
 3893
 3894        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
 3895
 3896        if (spec->autocfg.dig_out_pin)
 3897                spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
 3898        if (spec->autocfg.dig_in_pin)
 3899                spec->dig_in_nid = ALC880_DIGIN_NID;
 3900
 3901        if (spec->kctl_alloc)
 3902                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
 3903
 3904        spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
 3905
 3906        spec->num_mux_defs = 1;
 3907        spec->input_mux = &spec->private_imux;
 3908
 3909        store_pin_configs(codec);
 3910        return 1;
 3911}
 3912
 3913/* additional initialization for auto-configuration model */
 3914static void alc880_auto_init(struct hda_codec *codec)
 3915{
 3916        struct alc_spec *spec = codec->spec;
 3917        alc880_auto_init_multi_out(codec);
 3918        alc880_auto_init_extra_out(codec);
 3919        alc880_auto_init_analog_input(codec);
 3920        if (spec->unsol_event)
 3921                alc_inithook(codec);
 3922}
 3923
 3924/*
 3925 * OK, here we have finally the patch for ALC880
 3926 */
 3927
 3928static int patch_alc880(struct hda_codec *codec)
 3929{
 3930        struct alc_spec *spec;
 3931        int board_config;
 3932        int err;
 3933
 3934        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 3935        if (spec == NULL)
 3936                return -ENOMEM;
 3937
 3938        codec->spec = spec;
 3939
 3940        board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
 3941                                                  alc880_models,
 3942                                                  alc880_cfg_tbl);
 3943        if (board_config < 0) {
 3944                printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
 3945                       "trying auto-probe from BIOS...\n");
 3946                board_config = ALC880_AUTO;
 3947        }
 3948
 3949        if (board_config == ALC880_AUTO) {
 3950                /* automatic parse from the BIOS config */
 3951                err = alc880_parse_auto_config(codec);
 3952                if (err < 0) {
 3953                        alc_free(codec);
 3954                        return err;
 3955                } else if (!err) {
 3956                        printk(KERN_INFO
 3957                               "hda_codec: Cannot set up configuration "
 3958                               "from BIOS.  Using 3-stack mode...\n");
 3959                        board_config = ALC880_3ST;
 3960                }
 3961        }
 3962
 3963        if (board_config != ALC880_AUTO)
 3964                setup_preset(spec, &alc880_presets[board_config]);
 3965
 3966        spec->stream_name_analog = "ALC880 Analog";
 3967        spec->stream_analog_playback = &alc880_pcm_analog_playback;
 3968        spec->stream_analog_capture = &alc880_pcm_analog_capture;
 3969        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 3970
 3971        spec->stream_name_digital = "ALC880 Digital";
 3972        spec->stream_digital_playback = &alc880_pcm_digital_playback;
 3973        spec->stream_digital_capture = &alc880_pcm_digital_capture;
 3974
 3975        if (!spec->adc_nids && spec->input_mux) {
 3976                /* check whether NID 0x07 is valid */
 3977                unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
 3978                /* get type */
 3979                wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 3980                if (wcap != AC_WID_AUD_IN) {
 3981                        spec->adc_nids = alc880_adc_nids_alt;
 3982                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
 3983                        spec->mixers[spec->num_mixers] =
 3984                                alc880_capture_alt_mixer;
 3985                        spec->num_mixers++;
 3986                } else {
 3987                        spec->adc_nids = alc880_adc_nids;
 3988                        spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
 3989                        spec->mixers[spec->num_mixers] = alc880_capture_mixer;
 3990                        spec->num_mixers++;
 3991                }
 3992        }
 3993
 3994        spec->vmaster_nid = 0x0c;
 3995
 3996        codec->patch_ops = alc_patch_ops;
 3997        if (board_config == ALC880_AUTO)
 3998                spec->init_hook = alc880_auto_init;
 3999#ifdef CONFIG_SND_HDA_POWER_SAVE
 4000        if (!spec->loopback.amplist)
 4001                spec->loopback.amplist = alc880_loopbacks;
 4002#endif
 4003
 4004        return 0;
 4005}
 4006
 4007
 4008/*
 4009 * ALC260 support
 4010 */
 4011
 4012static hda_nid_t alc260_dac_nids[1] = {
 4013        /* front */
 4014        0x02,
 4015};
 4016
 4017static hda_nid_t alc260_adc_nids[1] = {
 4018        /* ADC0 */
 4019        0x04,
 4020};
 4021
 4022static hda_nid_t alc260_adc_nids_alt[1] = {
 4023        /* ADC1 */
 4024        0x05,
 4025};
 4026
 4027static hda_nid_t alc260_hp_adc_nids[2] = {
 4028        /* ADC1, 0 */
 4029        0x05, 0x04
 4030};
 4031
 4032/* NIDs used when simultaneous access to both ADCs makes sense.  Note that
 4033 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
 4034 */
 4035static hda_nid_t alc260_dual_adc_nids[2] = {
 4036        /* ADC0, ADC1 */
 4037        0x04, 0x05
 4038};
 4039
 4040#define ALC260_DIGOUT_NID        0x03
 4041#define ALC260_DIGIN_NID        0x06
 4042
 4043static struct hda_input_mux alc260_capture_source = {
 4044        .num_items = 4,
 4045        .items = {
 4046                { "Mic", 0x0 },
 4047                { "Front Mic", 0x1 },
 4048                { "Line", 0x2 },
 4049                { "CD", 0x4 },
 4050        },
 4051};
 4052
 4053/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
 4054 * headphone jack and the internal CD lines since these are the only pins at
 4055 * which audio can appear.  For flexibility, also allow the option of
 4056 * recording the mixer output on the second ADC (ADC0 doesn't have a
 4057 * connection to the mixer output).
 4058 */
 4059static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
 4060        {
 4061                .num_items = 3,
 4062                .items = {
 4063                        { "Mic/Line", 0x0 },
 4064                        { "CD", 0x4 },
 4065                        { "Headphone", 0x2 },
 4066                },
 4067        },
 4068        {
 4069                .num_items = 4,
 4070                .items = {
 4071                        { "Mic/Line", 0x0 },
 4072                        { "CD", 0x4 },
 4073                        { "Headphone", 0x2 },
 4074                        { "Mixer", 0x5 },
 4075                },
 4076        },
 4077
 4078};
 4079
 4080/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
 4081 * the Fujitsu S702x, but jacks are marked differently.
 4082 */
 4083static struct hda_input_mux alc260_acer_capture_sources[2] = {
 4084        {
 4085                .num_items = 4,
 4086                .items = {
 4087                        { "Mic", 0x0 },
 4088                        { "Line", 0x2 },
 4089                        { "CD", 0x4 },
 4090                        { "Headphone", 0x5 },
 4091                },
 4092        },
 4093        {
 4094                .num_items = 5,
 4095                .items = {
 4096                        { "Mic", 0x0 },
 4097                        { "Line", 0x2 },
 4098                        { "CD", 0x4 },
 4099                        { "Headphone", 0x6 },
 4100                        { "Mixer", 0x5 },
 4101                },
 4102        },
 4103};
 4104/*
 4105 * This is just place-holder, so there's something for alc_build_pcms to look
 4106 * at when it calculates the maximum number of channels. ALC260 has no mixer
 4107 * element which allows changing the channel mode, so the verb list is
 4108 * never used.
 4109 */
 4110static struct hda_channel_mode alc260_modes[1] = {
 4111        { 2, NULL },
 4112};
 4113
 4114
 4115/* Mixer combinations
 4116 *
 4117 * basic: base_output + input + pc_beep + capture
 4118 * HP: base_output + input + capture_alt
 4119 * HP_3013: hp_3013 + input + capture
 4120 * fujitsu: fujitsu + capture
 4121 * acer: acer + capture
 4122 */
 4123
 4124static struct snd_kcontrol_new alc260_base_output_mixer[] = {
 4125        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4126        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 4127        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 4128        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 4129        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
 4130        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 4131        { } /* end */
 4132};
 4133
 4134static struct snd_kcontrol_new alc260_input_mixer[] = {
 4135        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 4136        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 4137        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
 4138        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
 4139        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
 4140        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
 4141        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
 4142        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
 4143        { } /* end */
 4144};
 4145
 4146static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
 4147        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
 4148        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
 4149        { } /* end */
 4150};
 4151
 4152/* update HP, line and mono out pins according to the master switch */
 4153static void alc260_hp_master_update(struct hda_codec *codec,
 4154                                    hda_nid_t hp, hda_nid_t line,
 4155                                    hda_nid_t mono)
 4156{
 4157        struct alc_spec *spec = codec->spec;
 4158        unsigned int val = spec->master_sw ? PIN_HP : 0;
 4159        /* change HP and line-out pins */
 4160        snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4161                            val);
 4162        snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4163                            val);
 4164        /* mono (speaker) depending on the HP jack sense */
 4165        val = (val && !spec->jack_present) ? PIN_OUT : 0;
 4166        snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4167                            val);
 4168}
 4169
 4170static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
 4171                                   struct snd_ctl_elem_value *ucontrol)
 4172{
 4173        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 4174        struct alc_spec *spec = codec->spec;
 4175        *ucontrol->value.integer.value = spec->master_sw;
 4176        return 0;
 4177}
 4178
 4179static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 4180                                   struct snd_ctl_elem_value *ucontrol)
 4181{
 4182        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 4183        struct alc_spec *spec = codec->spec;
 4184        int val = !!*ucontrol->value.integer.value;
 4185        hda_nid_t hp, line, mono;
 4186
 4187        if (val == spec->master_sw)
 4188                return 0;
 4189        spec->master_sw = val;
 4190        hp = (kcontrol->private_value >> 16) & 0xff;
 4191        line = (kcontrol->private_value >> 8) & 0xff;
 4192        mono = kcontrol->private_value & 0xff;
 4193        alc260_hp_master_update(codec, hp, line, mono);
 4194        return 1;
 4195}
 4196
 4197static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
 4198        {
 4199                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 4200                .name = "Master Playback Switch",
 4201                .info = snd_ctl_boolean_mono_info,
 4202                .get = alc260_hp_master_sw_get,
 4203                .put = alc260_hp_master_sw_put,
 4204                .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
 4205        },
 4206        HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4207        HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
 4208        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 4209        HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
 4210        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
 4211                              HDA_OUTPUT),
 4212        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 4213        { } /* end */
 4214};
 4215
 4216static struct hda_verb alc260_hp_unsol_verbs[] = {
 4217        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4218        {},
 4219};
 4220
 4221static void alc260_hp_automute(struct hda_codec *codec)
 4222{
 4223        struct alc_spec *spec = codec->spec;
 4224        unsigned int present;
 4225
 4226        present = snd_hda_codec_read(codec, 0x10, 0,
 4227                                     AC_VERB_GET_PIN_SENSE, 0);
 4228        spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
 4229        alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
 4230}
 4231
 4232static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
 4233{
 4234        if ((res >> 26) == ALC880_HP_EVENT)
 4235                alc260_hp_automute(codec);
 4236}
 4237
 4238static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
 4239        {
 4240                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 4241                .name = "Master Playback Switch",
 4242                .info = snd_ctl_boolean_mono_info,
 4243                .get = alc260_hp_master_sw_get,
 4244                .put = alc260_hp_master_sw_put,
 4245                .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
 4246        },
 4247        HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 4248        HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
 4249        HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
 4250        HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
 4251        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4252        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 4253        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
 4254        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
 4255        { } /* end */
 4256};
 4257
 4258static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
 4259        .ops = &snd_hda_bind_vol,
 4260        .values = {
 4261                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
 4262                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
 4263                HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
 4264                0
 4265        },
 4266};
 4267
 4268static struct hda_bind_ctls alc260_dc7600_bind_switch = {
 4269        .ops = &snd_hda_bind_sw,
 4270        .values = {
 4271                HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
 4272                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
 4273                0
 4274        },
 4275};
 4276
 4277static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
 4278        HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
 4279        HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
 4280        HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
 4281        HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
 4282        { } /* end */
 4283};
 4284
 4285static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
 4286        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4287        {},
 4288};
 4289
 4290static void alc260_hp_3013_automute(struct hda_codec *codec)
 4291{
 4292        struct alc_spec *spec = codec->spec;
 4293        unsigned int present;
 4294
 4295        present = snd_hda_codec_read(codec, 0x15, 0,
 4296                                     AC_VERB_GET_PIN_SENSE, 0);
 4297        spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
 4298        alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
 4299}
 4300
 4301static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
 4302                                       unsigned int res)
 4303{
 4304        if ((res >> 26) == ALC880_HP_EVENT)
 4305                alc260_hp_3013_automute(codec);
 4306}
 4307
 4308static void alc260_hp_3012_automute(struct hda_codec *codec)
 4309{
 4310        unsigned int present, bits;
 4311
 4312        present = snd_hda_codec_read(codec, 0x10, 0,
 4313                        AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
 4314
 4315        bits = present ? 0 : PIN_OUT;
 4316        snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4317                            bits);
 4318        snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4319                            bits);
 4320        snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 4321                            bits);
 4322}
 4323
 4324static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
 4325                                       unsigned int res)
 4326{
 4327        if ((res >> 26) == ALC880_HP_EVENT)
 4328                alc260_hp_3012_automute(codec);
 4329}
 4330
 4331/* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12,
 4332 * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
 4333 */
 4334static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
 4335        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4336        HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
 4337        ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
 4338        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 4339        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 4340        HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
 4341        HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
 4342        ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
 4343        HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
 4344        HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
 4345        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 4346        HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
 4347        { } /* end */
 4348};
 4349
 4350/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
 4351 * versions of the ALC260 don't act on requests to enable mic bias from NID
 4352 * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
 4353 * datasheet doesn't mention this restriction.  At this stage it's not clear
 4354 * whether this behaviour is intentional or is a hardware bug in chip
 4355 * revisions available in early 2006.  Therefore for now allow the
 4356 * "Headphone Jack Mode" control to span all choices, but if it turns out
 4357 * that the lack of mic bias for this NID is intentional we could change the
 4358 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
 4359 *
 4360 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
 4361 * don't appear to make the mic bias available from the "line" jack, even
 4362 * though the NID used for this jack (0x14) can supply it.  The theory is
 4363 * that perhaps Acer have included blocking capacitors between the ALC260
 4364 * and the output jack.  If this turns out to be the case for all such
 4365 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
 4366 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
 4367 *
 4368 * The C20x Tablet series have a mono internal speaker which is controlled
 4369 * via the chip's Mono sum widget and pin complex, so include the necessary
 4370 * controls for such models.  On models without a "mono speaker" the control
 4371 * won't do anything.
 4372 */
 4373static struct snd_kcontrol_new alc260_acer_mixer[] = {
 4374        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4375        HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
 4376        ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
 4377        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
 4378                              HDA_OUTPUT),
 4379        HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
 4380                           HDA_INPUT),
 4381        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 4382        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 4383        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
 4384        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
 4385        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
 4386        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
 4387        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
 4388        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
 4389        HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
 4390        HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
 4391        { } /* end */
 4392};
 4393
 4394/* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
 4395 * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
 4396 */
 4397static struct snd_kcontrol_new alc260_will_mixer[] = {
 4398        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4399        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
 4400        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
 4401        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
 4402        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
 4403        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
 4404        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
 4405        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
 4406        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 4407        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 4408        HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
 4409        HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
 4410        { } /* end */
 4411};
 4412
 4413/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
 4414 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
 4415 */
 4416static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
 4417        HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4418        HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
 4419        HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
 4420        HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
 4421        ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
 4422        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
 4423        HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
 4424        HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
 4425        HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
 4426        ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
 4427        { } /* end */
 4428};
 4429
 4430/* capture mixer elements */
 4431static struct snd_kcontrol_new alc260_capture_mixer[] = {
 4432        HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 4433        HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
 4434        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
 4435        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
 4436        {
 4437                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 4438                /* The multiple "Capture Source" controls confuse alsamixer
 4439                 * So call somewhat different..
 4440                 */
 4441                /* .name = "Capture Source", */
 4442                .name = "Input Source",
 4443                .count = 2,
 4444                .info = alc_mux_enum_info,
 4445                .get = alc_mux_enum_get,
 4446                .put = alc_mux_enum_put,
 4447        },
 4448        { } /* end */
 4449};
 4450
 4451static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
 4452        HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
 4453        HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
 4454        {
 4455                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 4456                /* The multiple "Capture Source" controls confuse alsamixer
 4457                 * So call somewhat different..
 4458                 */
 4459                /* .name = "Capture Source", */
 4460                .name = "Input Source",
 4461                .count = 1,
 4462                .info = alc_mux_enum_info,
 4463                .get = alc_mux_enum_get,
 4464                .put = alc_mux_enum_put,
 4465        },
 4466        { } /* end */
 4467};
 4468
 4469/*
 4470 * initialization verbs
 4471 */
 4472static struct hda_verb alc260_init_verbs[] = {
 4473        /* Line In pin widget for input */
 4474        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 4475        /* CD pin widget for input */
 4476        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 4477        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 4478        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 4479        /* Mic2 (front panel) pin widget for input and vref at 80% */
 4480        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 4481        /* LINE-2 is used for line-out in rear */
 4482        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4483        /* select line-out */
 4484        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
 4485        /* LINE-OUT pin */
 4486        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4487        /* enable HP */
 4488        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4489        /* enable Mono */
 4490        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4491        /* mute capture amp left and right */
 4492        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 4493        /* set connection select to line in (default select for this ADC) */
 4494        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
 4495        /* mute capture amp left and right */
 4496        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 4497        /* set connection select to line in (default select for this ADC) */
 4498        {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
 4499        /* set vol=0 Line-Out mixer amp left and right */
 4500        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4501        /* unmute pin widget amp left and right (no gain on this amp) */
 4502        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4503        /* set vol=0 HP mixer amp left and right */
 4504        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4505        /* unmute pin widget amp left and right (no gain on this amp) */
 4506        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4507        /* set vol=0 Mono mixer amp left and right */
 4508        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4509        /* unmute pin widget amp left and right (no gain on this amp) */
 4510        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4511        /* unmute LINE-2 out pin */
 4512        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4513        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
 4514         * Line In 2 = 0x03
 4515         */
 4516        /* mute analog inputs */
 4517        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4518        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4519        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 4520        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 4521        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 4522        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
 4523        /* mute Front out path */
 4524        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4525        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4526        /* mute Headphone out path */
 4527        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4528        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4529        /* mute Mono out path */
 4530        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4531        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4532        { }
 4533};
 4534
 4535#if 0 /* should be identical with alc260_init_verbs? */
 4536static struct hda_verb alc260_hp_init_verbs[] = {
 4537        /* Headphone and output */
 4538        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
 4539        /* mono output */
 4540        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 4541        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 4542        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 4543        /* Mic2 (front panel) pin widget for input and vref at 80% */
 4544        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 4545        /* Line In pin widget for input */
 4546        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 4547        /* Line-2 pin widget for output */
 4548        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 4549        /* CD pin widget for input */
 4550        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 4551        /* unmute amp left and right */
 4552        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
 4553        /* set connection select to line in (default select for this ADC) */
 4554        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
 4555        /* unmute Line-Out mixer amp left and right (volume = 0) */
 4556        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 4557        /* mute pin widget amp left and right (no gain on this amp) */
 4558        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 4559        /* unmute HP mixer amp left and right (volume = 0) */
 4560        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 4561        /* mute pin widget amp left and right (no gain on this amp) */
 4562        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 4563        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
 4564         * Line In 2 = 0x03
 4565         */
 4566        /* mute analog inputs */
 4567        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4568        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4569        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 4570        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 4571        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 4572        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
 4573        /* Unmute Front out path */
 4574        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4575        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4576        /* Unmute Headphone out path */
 4577        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4578        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4579        /* Unmute Mono out path */
 4580        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4581        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4582        { }
 4583};
 4584#endif
 4585
 4586static struct hda_verb alc260_hp_3013_init_verbs[] = {
 4587        /* Line out and output */
 4588        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 4589        /* mono output */
 4590        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 4591        /* Mic1 (rear panel) pin widget for input and vref at 80% */
 4592        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 4593        /* Mic2 (front panel) pin widget for input and vref at 80% */
 4594        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 4595        /* Line In pin widget for input */
 4596        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 4597        /* Headphone pin widget for output */
 4598        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
 4599        /* CD pin widget for input */
 4600        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 4601        /* unmute amp left and right */
 4602        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
 4603        /* set connection select to line in (default select for this ADC) */
 4604        {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
 4605        /* unmute Line-Out mixer amp left and right (volume = 0) */
 4606        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 4607        /* mute pin widget amp left and right (no gain on this amp) */
 4608        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 4609        /* unmute HP mixer amp left and right (volume = 0) */
 4610        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 4611        /* mute pin widget amp left and right (no gain on this amp) */
 4612        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 4613        /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
 4614         * Line In 2 = 0x03
 4615         */
 4616        /* mute analog inputs */
 4617        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4618        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4619        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 4620        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 4621        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 4622        /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
 4623        /* Unmute Front out path */
 4624        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4625        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4626        /* Unmute Headphone out path */
 4627        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4628        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4629        /* Unmute Mono out path */
 4630        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 4631        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 4632        { }
 4633};
 4634
 4635/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
 4636 * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
 4637 * audio = 0x16, internal speaker = 0x10.
 4638 */
 4639static struct hda_verb alc260_fujitsu_init_verbs[] = {
 4640        /* Disable all GPIOs */
 4641        {0x01, AC_VERB_SET_GPIO_MASK, 0},
 4642        /* Internal speaker is connected to headphone pin */
 4643        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4644        /* Headphone/Line-out jack connects to Line1 pin; make it an output */
 4645        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4646        /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
 4647        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 4648        /* Ensure all other unused pins are disabled and muted. */
 4649        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4650        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4651        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4652        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4653        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4654        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4655        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4656        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4657
 4658        /* Disable digital (SPDIF) pins */
 4659        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
 4660        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
 4661
 4662        /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
 4663         * when acting as an output.
 4664         */
 4665        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
 4666
 4667        /* Start with output sum widgets muted and their output gains at min */
 4668        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4669        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4670        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4671        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4672        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4673        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4674        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4675        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4676        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4677
 4678        /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
 4679        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4680        /* Unmute Line1 pin widget output buffer since it starts as an output.
 4681         * If the pin mode is changed by the user the pin mode control will
 4682         * take care of enabling the pin's input/output buffers as needed.
 4683         * Therefore there's no need to enable the input buffer at this
 4684         * stage.
 4685         */
 4686        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4687        /* Unmute input buffer of pin widget used for Line-in (no equiv
 4688         * mixer ctrl)
 4689         */
 4690        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 4691
 4692        /* Mute capture amp left and right */
 4693        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4694        /* Set ADC connection select to match default mixer setting - line
 4695         * in (on mic1 pin)
 4696         */
 4697        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
 4698
 4699        /* Do the same for the second ADC: mute capture input amp and
 4700         * set ADC connection to line in (on mic1 pin)
 4701         */
 4702        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4703        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
 4704
 4705        /* Mute all inputs to mixer widget (even unconnected ones) */
 4706        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
 4707        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
 4708        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
 4709        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
 4710        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
 4711        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
 4712        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
 4713        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
 4714
 4715        { }
 4716};
 4717
 4718/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
 4719 * similar laptops (adapted from Fujitsu init verbs).
 4720 */
 4721static struct hda_verb alc260_acer_init_verbs[] = {
 4722        /* On TravelMate laptops, GPIO 0 enables the internal speaker and
 4723         * the headphone jack.  Turn this on and rely on the standard mute
 4724         * methods whenever the user wants to turn these outputs off.
 4725         */
 4726        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 4727        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 4728        {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
 4729        /* Internal speaker/Headphone jack is connected to Line-out pin */
 4730        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4731        /* Internal microphone/Mic jack is connected to Mic1 pin */
 4732        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
 4733        /* Line In jack is connected to Line1 pin */
 4734        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 4735        /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
 4736        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4737        /* Ensure all other unused pins are disabled and muted. */
 4738        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4739        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4740        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4741        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4742        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
 4743        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4744        /* Disable digital (SPDIF) pins */
 4745        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
 4746        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
 4747
 4748        /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
 4749         * bus when acting as outputs.
 4750         */
 4751        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
 4752        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
 4753
 4754        /* Start with output sum widgets muted and their output gains at min */
 4755        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4756        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4757        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4758        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4759        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4760        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4761        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4762        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 4763        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 4764
 4765        /* Unmute Line-out pin widget amp left and right
 4766         * (no equiv mixer ctrl)
 4767         */
 4768        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4769        /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
 4770        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 4771        /* Unmute Mic1 and Line1 pin widget input buffers since they start as
 4772         * inputs. If the pin mode is changed by the user the pin mode control
 4773         * will take care of enabling the pin's input/output buffers as needed.
 4774         * Therefore there's no need to enable the input buffer at this
 4775         * stage.
 4776         */
 4777        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 4778        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 4779
 4780        /* Mute capture amp left and right */
 4781        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4782        /* Set ADC connection select to match default mixer setting - mic
 4783         * (on mic1 pin)
 4784         */
 4785        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
 4786
 4787        /* Do similar with the second ADC: mute capture input amp and
 4788         * set ADC connection to mic to match ALSA's default state.
 4789         */
 4790        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 4791        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
 4792
 4793        /* Mute all inputs to mixer widget (even unconnected ones) */
 4794        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
 4795        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
 4796        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
 4797        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
 4798        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
 4799        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
 4800        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
 4801        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
 4802
 4803        { }
 4804};
 4805
 4806static struct hda_verb alc260_will_verbs[] = {
 4807        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4808        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
 4809        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
 4810        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
 4811        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
 4812        {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
 4813        {}
 4814};
 4815
 4816static struct hda_verb alc260_replacer_672v_verbs[] = {
 4817        {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
 4818        {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
 4819        {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
 4820
 4821        {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 4822        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 4823        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
 4824
 4825        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4826        {}
 4827};
 4828
 4829/* toggle speaker-output according to the hp-jack state */
 4830static void alc260_replacer_672v_automute(struct hda_codec *codec)
 4831{
 4832        unsigned int present;
 4833
 4834        /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
 4835        present = snd_hda_codec_read(codec, 0x0f, 0,
 4836                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 4837        if (present) {
 4838                snd_hda_codec_write_cache(codec, 0x01, 0,
 4839                                          AC_VERB_SET_GPIO_DATA, 1);
 4840                snd_hda_codec_write_cache(codec, 0x0f, 0,
 4841                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
 4842                                          PIN_HP);
 4843        } else {
 4844                snd_hda_codec_write_cache(codec, 0x01, 0,
 4845                                          AC_VERB_SET_GPIO_DATA, 0);
 4846                snd_hda_codec_write_cache(codec, 0x0f, 0,
 4847                                          AC_VERB_SET_PIN_WIDGET_CONTROL,
 4848                                          PIN_OUT);
 4849        }
 4850}
 4851
 4852static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
 4853                                       unsigned int res)
 4854{
 4855        if ((res >> 26) == ALC880_HP_EVENT)
 4856                alc260_replacer_672v_automute(codec);
 4857}
 4858
 4859static struct hda_verb alc260_hp_dc7600_verbs[] = {
 4860        {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
 4861        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
 4862        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4863        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 4864        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4865        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4866        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 4867        {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4868        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4869        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 4870        {}
 4871};
 4872
 4873/* Test configuration for debugging, modelled after the ALC880 test
 4874 * configuration.
 4875 */
 4876#ifdef CONFIG_SND_DEBUG
 4877static hda_nid_t alc260_test_dac_nids[1] = {
 4878        0x02,
 4879};
 4880static hda_nid_t alc260_test_adc_nids[2] = {
 4881        0x04, 0x05,
 4882};
 4883/* For testing the ALC260, each input MUX needs its own definition since
 4884 * the signal assignments are different.  This assumes that the first ADC
 4885 * is NID 0x04.
 4886 */
 4887static struct hda_input_mux alc260_test_capture_sources[2] = {
 4888        {
 4889                .num_items = 7,
 4890                .items = {
 4891                        { "MIC1 pin", 0x0 },
 4892                        { "MIC2 pin", 0x1 },
 4893                        { "LINE1 pin", 0x2 },
 4894                        { "LINE2 pin", 0x3 },
 4895                        { "CD pin", 0x4 },
 4896                        { "LINE-OUT pin", 0x5 },
 4897                        { "HP-OUT pin", 0x6 },
 4898                },
 4899        },
 4900        {
 4901                .num_items = 8,
 4902                .items = {
 4903                        { "MIC1 pin", 0x0 },
 4904                        { "MIC2 pin", 0x1 },
 4905                        { "LINE1 pin", 0x2 },
 4906                        { "LINE2 pin", 0x3 },
 4907                        { "CD pin", 0x4 },
 4908                        { "Mixer", 0x5 },
 4909                        { "LINE-OUT pin", 0x6 },
 4910                        { "HP-OUT pin", 0x7 },
 4911                },
 4912        },
 4913};
 4914static struct snd_kcontrol_new alc260_test_mixer[] = {
 4915        /* Output driver widgets */
 4916        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
 4917        HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
 4918        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 4919        HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
 4920        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 4921        HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
 4922
 4923        /* Modes for retasking pin widgets
 4924         * Note: the ALC260 doesn't seem to act on requests to enable mic
 4925         * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
 4926         * mention this restriction.  At this stage it's not clear whether
 4927         * this behaviour is intentional or is a hardware bug in chip
 4928         * revisions available at least up until early 2006.  Therefore for
 4929         * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
 4930         * choices, but if it turns out that the lack of mic bias for these
 4931         * NIDs is intentional we could change their modes from
 4932         * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
 4933         */
 4934        ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
 4935        ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
 4936        ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
 4937        ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
 4938        ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
 4939        ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
 4940
 4941        /* Loopback mixer controls */
 4942        HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
 4943        HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
 4944        HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
 4945        HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
 4946        HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
 4947        HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
 4948        HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
 4949        HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
 4950        HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 4951        HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 4952        HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
 4953        HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
 4954        HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
 4955        HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
 4956        HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
 4957        HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
 4958
 4959        /* Controls for GPIO pins, assuming they are configured as outputs */
 4960        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
 4961        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
 4962        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
 4963        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
 4964
 4965        /* Switches to allow the digital IO pins to be enabled.  The datasheet
 4966         * is ambigious as to which NID is which; testing on laptops which
 4967         * make this output available should provide clarification.
 4968         */
 4969        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
 4970        ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
 4971
 4972        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
 4973         * this output to turn on an external amplifier.
 4974         */
 4975        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
 4976        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
 4977
 4978        { } /* end */
 4979};
 4980static struct hda_verb alc260_test_init_verbs[] = {
 4981        /* Enable all GPIOs as outputs with an initial value of 0 */
 4982        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
 4983        {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
 4984        {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
 4985
 4986        /* Enable retasking pins as output, initially without power amp */
 4987        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4988        {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4989        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4990        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4991        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4992        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 4993
 4994        /* Disable digital (SPDIF) pins initially, but users can enable
 4995         * them via a mixer switch.  In the case of SPDIF-out, this initverb
 4996         * payload also sets the generation to 0, output to be in "consumer"
 4997         * PCM format, copyright asserted, no pre-emphasis and no validity
 4998         * control.
 4999         */
 5000        {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
 5001        {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
 5002
 5003        /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
 5004         * OUT1 sum bus when acting as an output.
 5005         */
 5006        {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
 5007        {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
 5008        {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
 5009        {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
 5010
 5011        /* Start with output sum widgets muted and their output gains at min */
 5012        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5013        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5014        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5015        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5016        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5017        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5018        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5019        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5020        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5021
 5022        /* Unmute retasking pin widget output buffers since the default
 5023         * state appears to be output.  As the pin mode is changed by the
 5024         * user the pin mode control will take care of enabling the pin's
 5025         * input/output buffers as needed.
 5026         */
 5027        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5028        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5029        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5030        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5031        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5032        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5033        /* Also unmute the mono-out pin widget */
 5034        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5035
 5036        /* Mute capture amp left and right */
 5037        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5038        /* Set ADC connection select to match default mixer setting (mic1
 5039         * pin)
 5040         */
 5041        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
 5042
 5043        /* Do the same for the second ADC: mute capture input amp and
 5044         * set ADC connection to mic1 pin
 5045         */
 5046        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5047        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
 5048
 5049        /* Mute all inputs to mixer widget (even unconnected ones) */
 5050        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
 5051        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
 5052        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
 5053        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
 5054        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
 5055        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
 5056        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
 5057        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
 5058
 5059        { }
 5060};
 5061#endif
 5062
 5063#define alc260_pcm_analog_playback        alc880_pcm_analog_alt_playback
 5064#define alc260_pcm_analog_capture        alc880_pcm_analog_capture
 5065
 5066#define alc260_pcm_digital_playback        alc880_pcm_digital_playback
 5067#define alc260_pcm_digital_capture        alc880_pcm_digital_capture
 5068
 5069/*
 5070 * for BIOS auto-configuration
 5071 */
 5072
 5073static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
 5074                                        const char *pfx, int *vol_bits)
 5075{
 5076        hda_nid_t nid_vol;
 5077        unsigned long vol_val, sw_val;
 5078        char name[32];
 5079        int err;
 5080
 5081        if (nid >= 0x0f && nid < 0x11) {
 5082                nid_vol = nid - 0x7;
 5083                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
 5084                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
 5085        } else if (nid == 0x11) {
 5086                nid_vol = nid - 0x7;
 5087                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
 5088                sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
 5089        } else if (nid >= 0x12 && nid <= 0x15) {
 5090                nid_vol = 0x08;
 5091                vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
 5092                sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
 5093        } else
 5094                return 0; /* N/A */
 5095
 5096        if (!(*vol_bits & (1 << nid_vol))) {
 5097                /* first control for the volume widget */
 5098                snprintf(name, sizeof(name), "%s Playback Volume", pfx);
 5099                err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
 5100                if (err < 0)
 5101                        return err;
 5102                *vol_bits |= (1 << nid_vol);
 5103        }
 5104        snprintf(name, sizeof(name), "%s Playback Switch", pfx);
 5105        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
 5106        if (err < 0)
 5107                return err;
 5108        return 1;
 5109}
 5110
 5111/* add playback controls from the parsed DAC table */
 5112static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
 5113                                             const struct auto_pin_cfg *cfg)
 5114{
 5115        hda_nid_t nid;
 5116        int err;
 5117        int vols = 0;
 5118
 5119        spec->multiout.num_dacs = 1;
 5120        spec->multiout.dac_nids = spec->private_dac_nids;
 5121        spec->multiout.dac_nids[0] = 0x02;
 5122
 5123        nid = cfg->line_out_pins[0];
 5124        if (nid) {
 5125                err = alc260_add_playback_controls(spec, nid, "Front", &vols);
 5126                if (err < 0)
 5127                        return err;
 5128        }
 5129
 5130        nid = cfg->speaker_pins[0];
 5131        if (nid) {
 5132                err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
 5133                if (err < 0)
 5134                        return err;
 5135        }
 5136
 5137        nid = cfg->hp_pins[0];
 5138        if (nid) {
 5139                err = alc260_add_playback_controls(spec, nid, "Headphone",
 5140                                                   &vols);
 5141                if (err < 0)
 5142                        return err;
 5143        }
 5144        return 0;
 5145}
 5146
 5147/* create playback/capture controls for input pins */
 5148static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
 5149                                                const struct auto_pin_cfg *cfg)
 5150{
 5151        struct hda_input_mux *imux = &spec->private_imux;
 5152        int i, err, idx;
 5153
 5154        for (i = 0; i < AUTO_PIN_LAST; i++) {
 5155                if (cfg->input_pins[i] >= 0x12) {
 5156                        idx = cfg->input_pins[i] - 0x12;
 5157                        err = new_analog_input(spec, cfg->input_pins[i],
 5158                                               auto_pin_cfg_labels[i], idx,
 5159                                               0x07);
 5160                        if (err < 0)
 5161                                return err;
 5162                        imux->items[imux->num_items].label =
 5163                                auto_pin_cfg_labels[i];
 5164                        imux->items[imux->num_items].index = idx;
 5165                        imux->num_items++;
 5166                }
 5167                if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
 5168                        idx = cfg->input_pins[i] - 0x09;
 5169                        err = new_analog_input(spec, cfg->input_pins[i],
 5170                                               auto_pin_cfg_labels[i], idx,
 5171                                               0x07);
 5172                        if (err < 0)
 5173                                return err;
 5174                        imux->items[imux->num_items].label =
 5175                                auto_pin_cfg_labels[i];
 5176                        imux->items[imux->num_items].index = idx;
 5177                        imux->num_items++;
 5178                }
 5179        }
 5180        return 0;
 5181}
 5182
 5183static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
 5184                                              hda_nid_t nid, int pin_type,
 5185                                              int sel_idx)
 5186{
 5187        alc_set_pin_output(codec, nid, pin_type);
 5188        /* need the manual connection? */
 5189        if (nid >= 0x12) {
 5190                int idx = nid - 0x12;
 5191                snd_hda_codec_write(codec, idx + 0x0b, 0,
 5192                                    AC_VERB_SET_CONNECT_SEL, sel_idx);
 5193        }
 5194}
 5195
 5196static void alc260_auto_init_multi_out(struct hda_codec *codec)
 5197{
 5198        struct alc_spec *spec = codec->spec;
 5199        hda_nid_t nid;
 5200
 5201        alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
 5202        nid = spec->autocfg.line_out_pins[0];
 5203        if (nid) {
 5204                int pin_type = get_pin_type(spec->autocfg.line_out_type);
 5205                alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
 5206        }
 5207
 5208        nid = spec->autocfg.speaker_pins[0];
 5209        if (nid)
 5210                alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
 5211
 5212        nid = spec->autocfg.hp_pins[0];
 5213        if (nid)
 5214                alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
 5215}
 5216
 5217#define ALC260_PIN_CD_NID                0x16
 5218static void alc260_auto_init_analog_input(struct hda_codec *codec)
 5219{
 5220        struct alc_spec *spec = codec->spec;
 5221        int i;
 5222
 5223        for (i = 0; i < AUTO_PIN_LAST; i++) {
 5224                hda_nid_t nid = spec->autocfg.input_pins[i];
 5225                if (nid >= 0x12) {
 5226                        snd_hda_codec_write(codec, nid, 0,
 5227                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
 5228                                            i <= AUTO_PIN_FRONT_MIC ?
 5229                                            PIN_VREF80 : PIN_IN);
 5230                        if (nid != ALC260_PIN_CD_NID)
 5231                                snd_hda_codec_write(codec, nid, 0,
 5232                                                    AC_VERB_SET_AMP_GAIN_MUTE,
 5233                                                    AMP_OUT_MUTE);
 5234                }
 5235        }
 5236}
 5237
 5238/*
 5239 * generic initialization of ADC, input mixers and output mixers
 5240 */
 5241static struct hda_verb alc260_volume_init_verbs[] = {
 5242        /*
 5243         * Unmute ADC0-1 and set the default input to mic-in
 5244         */
 5245        {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
 5246        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5247        {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
 5248        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5249
 5250        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 5251         * mixer widget
 5252         * Note: PASD motherboards uses the Line In 2 as the input for
 5253         * front panel mic (mic 2)
 5254         */
 5255        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 5256        /* mute analog inputs */
 5257        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5258        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5259        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5260        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5261        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 5262
 5263        /*
 5264         * Set up output mixers (0x08 - 0x0a)
 5265         */
 5266        /* set vol=0 to output mixers */
 5267        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5268        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5269        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5270        /* set up input amps for analog loopback */
 5271        /* Amp Indices: DAC = 0, mixer = 1 */
 5272        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5273        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 5274        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5275        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 5276        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5277        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 5278
 5279        { }
 5280};
 5281
 5282static int alc260_parse_auto_config(struct hda_codec *codec)
 5283{
 5284        struct alc_spec *spec = codec->spec;
 5285        unsigned int wcap;
 5286        int err;
 5287        static hda_nid_t alc260_ignore[] = { 0x17, 0 };
 5288
 5289        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
 5290                                           alc260_ignore);
 5291        if (err < 0)
 5292                return err;
 5293        err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
 5294        if (err < 0)
 5295                return err;
 5296        if (!spec->kctl_alloc)
 5297                return 0; /* can't find valid BIOS pin config */
 5298        err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
 5299        if (err < 0)
 5300                return err;
 5301
 5302        spec->multiout.max_channels = 2;
 5303
 5304        if (spec->autocfg.dig_out_pin)
 5305                spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
 5306        if (spec->kctl_alloc)
 5307                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
 5308
 5309        spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
 5310
 5311        spec->num_mux_defs = 1;
 5312        spec->input_mux = &spec->private_imux;
 5313
 5314        /* check whether NID 0x04 is valid */
 5315        wcap = get_wcaps(codec, 0x04);
 5316        wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
 5317        if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
 5318                spec->adc_nids = alc260_adc_nids_alt;
 5319                spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
 5320                spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
 5321        } else {
 5322                spec->adc_nids = alc260_adc_nids;
 5323                spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
 5324                spec->mixers[spec->num_mixers] = alc260_capture_mixer;
 5325        }
 5326        spec->num_mixers++;
 5327
 5328        store_pin_configs(codec);
 5329        return 1;
 5330}
 5331
 5332/* additional initialization for auto-configuration model */
 5333static void alc260_auto_init(struct hda_codec *codec)
 5334{
 5335        struct alc_spec *spec = codec->spec;
 5336        alc260_auto_init_multi_out(codec);
 5337        alc260_auto_init_analog_input(codec);
 5338        if (spec->unsol_event)
 5339                alc_inithook(codec);
 5340}
 5341
 5342#ifdef CONFIG_SND_HDA_POWER_SAVE
 5343static struct hda_amp_list alc260_loopbacks[] = {
 5344        { 0x07, HDA_INPUT, 0 },
 5345        { 0x07, HDA_INPUT, 1 },
 5346        { 0x07, HDA_INPUT, 2 },
 5347        { 0x07, HDA_INPUT, 3 },
 5348        { 0x07, HDA_INPUT, 4 },
 5349        { } /* end */
 5350};
 5351#endif
 5352
 5353/*
 5354 * ALC260 configurations
 5355 */
 5356static const char *alc260_models[ALC260_MODEL_LAST] = {
 5357        [ALC260_BASIC]                = "basic",
 5358        [ALC260_HP]                = "hp",
 5359        [ALC260_HP_3013]        = "hp-3013",
 5360        [ALC260_HP_DC7600]        = "hp-dc7600",
 5361        [ALC260_FUJITSU_S702X]        = "fujitsu",
 5362        [ALC260_ACER]                = "acer",
 5363        [ALC260_WILL]                = "will",
 5364        [ALC260_REPLACER_672V]        = "replacer",
 5365#ifdef CONFIG_SND_DEBUG
 5366        [ALC260_TEST]                = "test",
 5367#endif
 5368        [ALC260_AUTO]                = "auto",
 5369};
 5370
 5371static struct snd_pci_quirk alc260_cfg_tbl[] = {
 5372        SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
 5373        SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
 5374        SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
 5375        SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
 5376        SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
 5377        SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
 5378        SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
 5379        SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
 5380        SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
 5381        SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
 5382        SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
 5383        SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
 5384        SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
 5385        SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
 5386        SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
 5387        SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
 5388        SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
 5389        SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
 5390        {}
 5391};
 5392
 5393static struct alc_config_preset alc260_presets[] = {
 5394        [ALC260_BASIC] = {
 5395                .mixers = { alc260_base_output_mixer,
 5396                            alc260_input_mixer,
 5397                            alc260_pc_beep_mixer,
 5398                            alc260_capture_mixer },
 5399                .init_verbs = { alc260_init_verbs },
 5400                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5401                .dac_nids = alc260_dac_nids,
 5402                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
 5403                .adc_nids = alc260_adc_nids,
 5404                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5405                .channel_mode = alc260_modes,
 5406                .input_mux = &alc260_capture_source,
 5407        },
 5408        [ALC260_HP] = {
 5409                .mixers = { alc260_hp_output_mixer,
 5410                            alc260_input_mixer,
 5411                            alc260_capture_alt_mixer },
 5412                .init_verbs = { alc260_init_verbs,
 5413                                alc260_hp_unsol_verbs },
 5414                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5415                .dac_nids = alc260_dac_nids,
 5416                .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
 5417                .adc_nids = alc260_hp_adc_nids,
 5418                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5419                .channel_mode = alc260_modes,
 5420                .input_mux = &alc260_capture_source,
 5421                .unsol_event = alc260_hp_unsol_event,
 5422                .init_hook = alc260_hp_automute,
 5423        },
 5424        [ALC260_HP_DC7600] = {
 5425                .mixers = { alc260_hp_dc7600_mixer,
 5426                            alc260_input_mixer,
 5427                            alc260_capture_alt_mixer },
 5428                .init_verbs = { alc260_init_verbs,
 5429                                alc260_hp_dc7600_verbs },
 5430                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5431                .dac_nids = alc260_dac_nids,
 5432                .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
 5433                .adc_nids = alc260_hp_adc_nids,
 5434                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5435                .channel_mode = alc260_modes,
 5436                .input_mux = &alc260_capture_source,
 5437                .unsol_event = alc260_hp_3012_unsol_event,
 5438                .init_hook = alc260_hp_3012_automute,
 5439        },
 5440        [ALC260_HP_3013] = {
 5441                .mixers = { alc260_hp_3013_mixer,
 5442                            alc260_input_mixer,
 5443                            alc260_capture_alt_mixer },
 5444                .init_verbs = { alc260_hp_3013_init_verbs,
 5445                                alc260_hp_3013_unsol_verbs },
 5446                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5447                .dac_nids = alc260_dac_nids,
 5448                .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
 5449                .adc_nids = alc260_hp_adc_nids,
 5450                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5451                .channel_mode = alc260_modes,
 5452                .input_mux = &alc260_capture_source,
 5453                .unsol_event = alc260_hp_3013_unsol_event,
 5454                .init_hook = alc260_hp_3013_automute,
 5455        },
 5456        [ALC260_FUJITSU_S702X] = {
 5457                .mixers = { alc260_fujitsu_mixer,
 5458                            alc260_capture_mixer },
 5459                .init_verbs = { alc260_fujitsu_init_verbs },
 5460                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5461                .dac_nids = alc260_dac_nids,
 5462                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
 5463                .adc_nids = alc260_dual_adc_nids,
 5464                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5465                .channel_mode = alc260_modes,
 5466                .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
 5467                .input_mux = alc260_fujitsu_capture_sources,
 5468        },
 5469        [ALC260_ACER] = {
 5470                .mixers = { alc260_acer_mixer,
 5471                            alc260_capture_mixer },
 5472                .init_verbs = { alc260_acer_init_verbs },
 5473                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5474                .dac_nids = alc260_dac_nids,
 5475                .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
 5476                .adc_nids = alc260_dual_adc_nids,
 5477                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5478                .channel_mode = alc260_modes,
 5479                .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
 5480                .input_mux = alc260_acer_capture_sources,
 5481        },
 5482        [ALC260_WILL] = {
 5483                .mixers = { alc260_will_mixer,
 5484                            alc260_capture_mixer },
 5485                .init_verbs = { alc260_init_verbs, alc260_will_verbs },
 5486                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5487                .dac_nids = alc260_dac_nids,
 5488                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
 5489                .adc_nids = alc260_adc_nids,
 5490                .dig_out_nid = ALC260_DIGOUT_NID,
 5491                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5492                .channel_mode = alc260_modes,
 5493                .input_mux = &alc260_capture_source,
 5494        },
 5495        [ALC260_REPLACER_672V] = {
 5496                .mixers = { alc260_replacer_672v_mixer,
 5497                            alc260_capture_mixer },
 5498                .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
 5499                .num_dacs = ARRAY_SIZE(alc260_dac_nids),
 5500                .dac_nids = alc260_dac_nids,
 5501                .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
 5502                .adc_nids = alc260_adc_nids,
 5503                .dig_out_nid = ALC260_DIGOUT_NID,
 5504                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5505                .channel_mode = alc260_modes,
 5506                .input_mux = &alc260_capture_source,
 5507                .unsol_event = alc260_replacer_672v_unsol_event,
 5508                .init_hook = alc260_replacer_672v_automute,
 5509        },
 5510#ifdef CONFIG_SND_DEBUG
 5511        [ALC260_TEST] = {
 5512                .mixers = { alc260_test_mixer,
 5513                            alc260_capture_mixer },
 5514                .init_verbs = { alc260_test_init_verbs },
 5515                .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
 5516                .dac_nids = alc260_test_dac_nids,
 5517                .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
 5518                .adc_nids = alc260_test_adc_nids,
 5519                .num_channel_mode = ARRAY_SIZE(alc260_modes),
 5520                .channel_mode = alc260_modes,
 5521                .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
 5522                .input_mux = alc260_test_capture_sources,
 5523        },
 5524#endif
 5525};
 5526
 5527static int patch_alc260(struct hda_codec *codec)
 5528{
 5529        struct alc_spec *spec;
 5530        int err, board_config;
 5531
 5532        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 5533        if (spec == NULL)
 5534                return -ENOMEM;
 5535
 5536        codec->spec = spec;
 5537
 5538        board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
 5539                                                  alc260_models,
 5540                                                  alc260_cfg_tbl);
 5541        if (board_config < 0) {
 5542                snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
 5543                           "trying auto-probe from BIOS...\n");
 5544                board_config = ALC260_AUTO;
 5545        }
 5546
 5547        if (board_config == ALC260_AUTO) {
 5548                /* automatic parse from the BIOS config */
 5549                err = alc260_parse_auto_config(codec);
 5550                if (err < 0) {
 5551                        alc_free(codec);
 5552                        return err;
 5553                } else if (!err) {
 5554                        printk(KERN_INFO
 5555                               "hda_codec: Cannot set up configuration "
 5556                               "from BIOS.  Using base mode...\n");
 5557                        board_config = ALC260_BASIC;
 5558                }
 5559        }
 5560
 5561        if (board_config != ALC260_AUTO)
 5562                setup_preset(spec, &alc260_presets[board_config]);
 5563
 5564        spec->stream_name_analog = "ALC260 Analog";
 5565        spec->stream_analog_playback = &alc260_pcm_analog_playback;
 5566        spec->stream_analog_capture = &alc260_pcm_analog_capture;
 5567
 5568        spec->stream_name_digital = "ALC260 Digital";
 5569        spec->stream_digital_playback = &alc260_pcm_digital_playback;
 5570        spec->stream_digital_capture = &alc260_pcm_digital_capture;
 5571
 5572        spec->vmaster_nid = 0x08;
 5573
 5574        codec->patch_ops = alc_patch_ops;
 5575        if (board_config == ALC260_AUTO)
 5576                spec->init_hook = alc260_auto_init;
 5577#ifdef CONFIG_SND_HDA_POWER_SAVE
 5578        if (!spec->loopback.amplist)
 5579                spec->loopback.amplist = alc260_loopbacks;
 5580#endif
 5581
 5582        return 0;
 5583}
 5584
 5585
 5586/*
 5587 * ALC882 support
 5588 *
 5589 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
 5590 * configuration.  Each pin widget can choose any input DACs and a mixer.
 5591 * Each ADC is connected from a mixer of all inputs.  This makes possible
 5592 * 6-channel independent captures.
 5593 *
 5594 * In addition, an independent DAC for the multi-playback (not used in this
 5595 * driver yet).
 5596 */
 5597#define ALC882_DIGOUT_NID        0x06
 5598#define ALC882_DIGIN_NID        0x0a
 5599
 5600static struct hda_channel_mode alc882_ch_modes[1] = {
 5601        { 8, NULL }
 5602};
 5603
 5604static hda_nid_t alc882_dac_nids[4] = {
 5605        /* front, rear, clfe, rear_surr */
 5606        0x02, 0x03, 0x04, 0x05
 5607};
 5608
 5609/* identical with ALC880 */
 5610#define alc882_adc_nids                alc880_adc_nids
 5611#define alc882_adc_nids_alt        alc880_adc_nids_alt
 5612
 5613static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
 5614static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
 5615
 5616/* input MUX */
 5617/* FIXME: should be a matrix-type input source selection */
 5618
 5619static struct hda_input_mux alc882_capture_source = {
 5620        .num_items = 4,
 5621        .items = {
 5622                { "Mic", 0x0 },
 5623                { "Front Mic", 0x1 },
 5624                { "Line", 0x2 },
 5625                { "CD", 0x4 },
 5626        },
 5627};
 5628#define alc882_mux_enum_info alc_mux_enum_info
 5629#define alc882_mux_enum_get alc_mux_enum_get
 5630
 5631static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
 5632                               struct snd_ctl_elem_value *ucontrol)
 5633{
 5634        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 5635        struct alc_spec *spec = codec->spec;
 5636        const struct hda_input_mux *imux = spec->input_mux;
 5637        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 5638        hda_nid_t nid = spec->capsrc_nids ?
 5639                spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
 5640        unsigned int *cur_val = &spec->cur_mux[adc_idx];
 5641        unsigned int i, idx;
 5642
 5643        idx = ucontrol->value.enumerated.item[0];
 5644        if (idx >= imux->num_items)
 5645                idx = imux->num_items - 1;
 5646        if (*cur_val == idx)
 5647                return 0;
 5648        for (i = 0; i < imux->num_items; i++) {
 5649                unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
 5650                snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
 5651                                         imux->items[i].index,
 5652                                         HDA_AMP_MUTE, v);
 5653        }
 5654        *cur_val = idx;
 5655        return 1;
 5656}
 5657
 5658/*
 5659 * 2ch mode
 5660 */
 5661static struct hda_verb alc882_3ST_ch2_init[] = {
 5662        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 5663        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 5664        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 5665        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 5666        { } /* end */
 5667};
 5668
 5669/*
 5670 * 6ch mode
 5671 */
 5672static struct hda_verb alc882_3ST_ch6_init[] = {
 5673        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5674        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 5675        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
 5676        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5677        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 5678        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 5679        { } /* end */
 5680};
 5681
 5682static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
 5683        { 2, alc882_3ST_ch2_init },
 5684        { 6, alc882_3ST_ch6_init },
 5685};
 5686
 5687/*
 5688 * 6ch mode
 5689 */
 5690static struct hda_verb alc882_sixstack_ch6_init[] = {
 5691        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
 5692        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5693        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5694        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5695        { } /* end */
 5696};
 5697
 5698/*
 5699 * 8ch mode
 5700 */
 5701static struct hda_verb alc882_sixstack_ch8_init[] = {
 5702        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5703        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5704        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5705        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5706        { } /* end */
 5707};
 5708
 5709static struct hda_channel_mode alc882_sixstack_modes[2] = {
 5710        { 6, alc882_sixstack_ch6_init },
 5711        { 8, alc882_sixstack_ch8_init },
 5712};
 5713
 5714/*
 5715 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
 5716 */
 5717
 5718/*
 5719 * 2ch mode
 5720 */
 5721static struct hda_verb alc885_mbp_ch2_init[] = {
 5722        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 5723        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5724        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5725        { } /* end */
 5726};
 5727
 5728/*
 5729 * 6ch mode
 5730 */
 5731static struct hda_verb alc885_mbp_ch6_init[] = {
 5732        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 5733        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5734        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 5735        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5736        { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 5737        { } /* end */
 5738};
 5739
 5740static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
 5741        { 2, alc885_mbp_ch2_init },
 5742        { 6, alc885_mbp_ch6_init },
 5743};
 5744
 5745
 5746/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
 5747 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
 5748 */
 5749static struct snd_kcontrol_new alc882_base_mixer[] = {
 5750        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5751        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 5752        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 5753        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 5754        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 5755        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 5756        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 5757        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 5758        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 5759        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 5760        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 5761        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 5762        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 5763        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5764        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5765        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 5766        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 5767        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 5768        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 5769        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 5770        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 5771        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 5772        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 5773        { } /* end */
 5774};
 5775
 5776static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
 5777        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
 5778        HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
 5779        HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
 5780        HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
 5781        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5782        HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5783        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
 5784        HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
 5785        HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
 5786        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
 5787        { } /* end */
 5788};
 5789static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
 5790        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5791        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 5792        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 5793        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 5794        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5795        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5796        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 5797        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 5798        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 5799        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 5800        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 5801        { } /* end */
 5802};
 5803
 5804static struct snd_kcontrol_new alc882_targa_mixer[] = {
 5805        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5806        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 5807        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 5808        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 5809        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 5810        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5811        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5812        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 5813        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 5814        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 5815        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 5816        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 5817        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 5818        { } /* end */
 5819};
 5820
 5821/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
 5822 *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
 5823 */
 5824static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
 5825        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5826        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 5827        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 5828        HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
 5829        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 5830        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 5831        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5832        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5833        HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
 5834        HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
 5835        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 5836        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 5837        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 5838        { } /* end */
 5839};
 5840
 5841static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
 5842        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5843        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 5844        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 5845        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 5846        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 5847        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5848        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5849        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 5850        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 5851        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 5852        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 5853        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 5854        { } /* end */
 5855};
 5856
 5857static struct snd_kcontrol_new alc882_chmode_mixer[] = {
 5858        {
 5859                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 5860                .name = "Channel Mode",
 5861                .info = alc_ch_mode_info,
 5862                .get = alc_ch_mode_get,
 5863                .put = alc_ch_mode_put,
 5864        },
 5865        { } /* end */
 5866};
 5867
 5868static struct hda_verb alc882_init_verbs[] = {
 5869        /* Front mixer: unmute input/output amp left and right (volume = 0) */
 5870        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5871        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5872        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5873        /* Rear mixer */
 5874        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5875        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5876        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5877        /* CLFE mixer */
 5878        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5879        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5880        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5881        /* Side mixer */
 5882        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5883        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5884        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5885
 5886        /* Front Pin: output 0 (0x0c) */
 5887        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5888        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5889        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 5890        /* Rear Pin: output 1 (0x0d) */
 5891        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5892        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5893        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
 5894        /* CLFE Pin: output 2 (0x0e) */
 5895        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5896        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5897        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
 5898        /* Side Pin: output 3 (0x0f) */
 5899        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5900        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5901        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
 5902        /* Mic (rear) pin: input vref at 80% */
 5903        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 5904        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 5905        /* Front Mic pin: input vref at 80% */
 5906        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 5907        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 5908        /* Line In pin: input */
 5909        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 5910        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 5911        /* Line-2 In: Headphone output (output 0 - 0x0c) */
 5912        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 5913        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5914        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 5915        /* CD pin widget for input */
 5916        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 5917
 5918        /* FIXME: use matrix-type input source selection */
 5919        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 5920        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 5921        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5922        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5923        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5924        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 5925        /* Input mixer2 */
 5926        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5927        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5928        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5929        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 5930        /* Input mixer3 */
 5931        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5932        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5933        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5934        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 5935        /* ADC1: mute amp left and right */
 5936        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5937        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 5938        /* ADC2: mute amp left and right */
 5939        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5940        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 5941        /* ADC3: mute amp left and right */
 5942        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5943        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 5944
 5945        { }
 5946};
 5947
 5948static struct hda_verb alc882_eapd_verbs[] = {
 5949        /* change to EAPD mode */
 5950        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 5951        {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
 5952        { }
 5953};
 5954
 5955/* Mac Pro test */
 5956static struct snd_kcontrol_new alc882_macpro_mixer[] = {
 5957        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 5958        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 5959        HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
 5960        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
 5961        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
 5962        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
 5963        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
 5964        { } /* end */
 5965};
 5966
 5967static struct hda_verb alc882_macpro_init_verbs[] = {
 5968        /* Front mixer: unmute input/output amp left and right (volume = 0) */
 5969        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 5970        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 5971        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 5972        /* Front Pin: output 0 (0x0c) */
 5973        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5974        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5975        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 5976        /* Front Mic pin: input vref at 80% */
 5977        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 5978        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 5979        /* Speaker:  output */
 5980        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 5981        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5982        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
 5983        /* Headphone output (output 0 - 0x0c) */
 5984        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 5985        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 5986        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
 5987
 5988        /* FIXME: use matrix-type input source selection */
 5989        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 5990        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 5991        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5992        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5993        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5994        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 5995        /* Input mixer2 */
 5996        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 5997        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 5998        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 5999        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6000        /* Input mixer3 */
 6001        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6002        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 6003        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 6004        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6005        /* ADC1: mute amp left and right */
 6006        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6007        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 6008        /* ADC2: mute amp left and right */
 6009        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6010        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 6011        /* ADC3: mute amp left and right */
 6012        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6013        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 6014
 6015        { }
 6016};
 6017
 6018/* Macbook Pro rev3 */
 6019static struct hda_verb alc885_mbp3_init_verbs[] = {
 6020        /* Front mixer: unmute input/output amp left and right (volume = 0) */
 6021        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6022        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6023        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 6024        /* Rear mixer */
 6025        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6026        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6027        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 6028        /* Front Pin: output 0 (0x0c) */
 6029        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6030        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 6031        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 6032        /* HP Pin: output 0 (0x0d) */
 6033        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
 6034        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 6035        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 6036        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 6037        /* Mic (rear) pin: input vref at 80% */
 6038        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 6039        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 6040        /* Front Mic pin: input vref at 80% */
 6041        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 6042        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 6043        /* Line In pin: use output 1 when in LineOut mode */
 6044        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 6045        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 6046        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
 6047
 6048        /* FIXME: use matrix-type input source selection */
 6049        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 6050        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 6051        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6052        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 6053        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 6054        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6055        /* Input mixer2 */
 6056        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6057        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 6058        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 6059        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6060        /* Input mixer3 */
 6061        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6062        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 6063        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 6064        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6065        /* ADC1: mute amp left and right */
 6066        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6067        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 6068        /* ADC2: mute amp left and right */
 6069        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6070        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 6071        /* ADC3: mute amp left and right */
 6072        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6073        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 6074
 6075        { }
 6076};
 6077
 6078/* iMac 24 mixer. */
 6079static struct snd_kcontrol_new alc885_imac24_mixer[] = {
 6080        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
 6081        HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
 6082        { } /* end */
 6083};
 6084
 6085/* iMac 24 init verbs. */
 6086static struct hda_verb alc885_imac24_init_verbs[] = {
 6087        /* Internal speakers: output 0 (0x0c) */
 6088        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6089        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 6090        {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
 6091        /* Internal speakers: output 0 (0x0c) */
 6092        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6093        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 6094        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
 6095        /* Headphone: output 0 (0x0c) */
 6096        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 6097        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 6098        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 6099        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 6100        /* Front Mic: input vref at 80% */
 6101        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 6102        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 6103        { }
 6104};
 6105
 6106/* Toggle speaker-output according to the hp-jack state */
 6107static void alc885_imac24_automute(struct hda_codec *codec)
 6108{
 6109         unsigned int present;
 6110
 6111         present = snd_hda_codec_read(codec, 0x14, 0,
 6112                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 6113        snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
 6114                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 6115        snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
 6116                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 6117}
 6118
 6119/* Processes unsolicited events. */
 6120static void alc885_imac24_unsol_event(struct hda_codec *codec,
 6121                                      unsigned int res)
 6122{
 6123        /* Headphone insertion or removal. */
 6124        if ((res >> 26) == ALC880_HP_EVENT)
 6125                alc885_imac24_automute(codec);
 6126}
 6127
 6128static void alc885_mbp3_automute(struct hda_codec *codec)
 6129{
 6130         unsigned int present;
 6131
 6132         present = snd_hda_codec_read(codec, 0x15, 0,
 6133                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 6134        snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
 6135                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 6136        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 6137                                 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
 6138
 6139}
 6140static void alc885_mbp3_unsol_event(struct hda_codec *codec,
 6141                                    unsigned int res)
 6142{
 6143        /* Headphone insertion or removal. */
 6144        if ((res >> 26) == ALC880_HP_EVENT)
 6145                alc885_mbp3_automute(codec);
 6146}
 6147
 6148
 6149static struct hda_verb alc882_targa_verbs[] = {
 6150        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6151        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6152
 6153        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 6154        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6155
 6156        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 6157        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
 6158        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 6159
 6160        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 6161        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 6162        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 6163        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 6164        { } /* end */
 6165};
 6166
 6167/* toggle speaker-output according to the hp-jack state */
 6168static void alc882_targa_automute(struct hda_codec *codec)
 6169{
 6170         unsigned int present;
 6171
 6172         present = snd_hda_codec_read(codec, 0x14, 0,
 6173                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 6174        snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 6175                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 6176        snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
 6177                                  present ? 1 : 3);
 6178}
 6179
 6180static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
 6181{
 6182        /* Looks like the unsol event is incompatible with the standard
 6183         * definition.  4bit tag is placed at 26 bit!
 6184         */
 6185        if (((res >> 26) == ALC880_HP_EVENT)) {
 6186                alc882_targa_automute(codec);
 6187        }
 6188}
 6189
 6190static struct hda_verb alc882_asus_a7j_verbs[] = {
 6191        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6192        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6193
 6194        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 6195        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6196        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6197
 6198        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
 6199        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 6200        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
 6201
 6202        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 6203        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
 6204        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 6205        { } /* end */
 6206};
 6207
 6208static struct hda_verb alc882_asus_a7m_verbs[] = {
 6209        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6210        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6211
 6212        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 6213        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6214        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 6215
 6216        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
 6217        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 6218        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
 6219
 6220        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 6221        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
 6222        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 6223         { } /* end */
 6224};
 6225
 6226static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
 6227{
 6228        unsigned int gpiostate, gpiomask, gpiodir;
 6229
 6230        gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
 6231                                       AC_VERB_GET_GPIO_DATA, 0);
 6232
 6233        if (!muted)
 6234                gpiostate |= (1 << pin);
 6235        else
 6236                gpiostate &= ~(1 << pin);
 6237
 6238        gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
 6239                                      AC_VERB_GET_GPIO_MASK, 0);
 6240        gpiomask |= (1 << pin);
 6241
 6242        gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
 6243                                     AC_VERB_GET_GPIO_DIRECTION, 0);
 6244        gpiodir |= (1 << pin);
 6245
 6246
 6247        snd_hda_codec_write(codec, codec->afg, 0,
 6248                            AC_VERB_SET_GPIO_MASK, gpiomask);
 6249        snd_hda_codec_write(codec, codec->afg, 0,
 6250                            AC_VERB_SET_GPIO_DIRECTION, gpiodir);
 6251
 6252        msleep(1);
 6253
 6254        snd_hda_codec_write(codec, codec->afg, 0,
 6255                            AC_VERB_SET_GPIO_DATA, gpiostate);
 6256}
 6257
 6258/* set up GPIO at initialization */
 6259static void alc885_macpro_init_hook(struct hda_codec *codec)
 6260{
 6261        alc882_gpio_mute(codec, 0, 0);
 6262        alc882_gpio_mute(codec, 1, 0);
 6263}
 6264
 6265/* set up GPIO and update auto-muting at initialization */
 6266static void alc885_imac24_init_hook(struct hda_codec *codec)
 6267{
 6268        alc885_macpro_init_hook(codec);
 6269        alc885_imac24_automute(codec);
 6270}
 6271
 6272/*
 6273 * generic initialization of ADC, input mixers and output mixers
 6274 */
 6275static struct hda_verb alc882_auto_init_verbs[] = {
 6276        /*
 6277         * Unmute ADC0-2 and set the default input to mic-in
 6278         */
 6279        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 6280        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6281        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 6282        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6283        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 6284        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6285
 6286        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 6287         * mixer widget
 6288         * Note: PASD motherboards uses the Line In 2 as the input for
 6289         * front panel mic (mic 2)
 6290         */
 6291        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 6292        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 6293        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 6294        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 6295        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 6296        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 6297
 6298        /*
 6299         * Set up output mixers (0x0c - 0x0f)
 6300         */
 6301        /* set vol=0 to output mixers */
 6302        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6303        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6304        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6305        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 6306        /* set up input amps for analog loopback */
 6307        /* Amp Indices: DAC = 0, mixer = 1 */
 6308        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6309        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6310        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6311        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6312        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6313        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6314        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6315        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6316        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 6317        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 6318
 6319        /* FIXME: use matrix-type input source selection */
 6320        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 6321        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 6322        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 6323        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 6324        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 6325        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 6326        /* Input mixer2 */
 6327        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 6328        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 6329        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 6330        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 6331        /* Input mixer3 */
 6332        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 6333        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 6334        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 6335        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 6336
 6337        { }
 6338};
 6339
 6340/* capture mixer elements */
 6341static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
 6342        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 6343        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 6344        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 6345        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 6346        {
 6347                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 6348                /* The multiple "Capture Source" controls confuse alsamixer
 6349                 * So call somewhat different..
 6350                 */
 6351                /* .name = "Capture Source", */
 6352                .name = "Input Source",
 6353                .count = 2,
 6354                .info = alc882_mux_enum_info,
 6355                .get = alc882_mux_enum_get,
 6356                .put = alc882_mux_enum_put,
 6357        },
 6358        { } /* end */
 6359};
 6360
 6361static struct snd_kcontrol_new alc882_capture_mixer[] = {
 6362        HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
 6363        HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
 6364        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
 6365        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
 6366        HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
 6367        HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
 6368        {
 6369                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 6370                /* The multiple "Capture Source" controls confuse alsamixer
 6371                 * So call somewhat different..
 6372                 */
 6373                /* .name = "Capture Source", */
 6374                .name = "Input Source",
 6375                .count = 3,
 6376                .info = alc882_mux_enum_info,
 6377                .get = alc882_mux_enum_get,
 6378                .put = alc882_mux_enum_put,
 6379        },
 6380        { } /* end */
 6381};
 6382
 6383#ifdef CONFIG_SND_HDA_POWER_SAVE
 6384#define alc882_loopbacks        alc880_loopbacks
 6385#endif
 6386
 6387/* pcm configuration: identiacal with ALC880 */
 6388#define alc882_pcm_analog_playback        alc880_pcm_analog_playback
 6389#define alc882_pcm_analog_capture        alc880_pcm_analog_capture
 6390#define alc882_pcm_digital_playback        alc880_pcm_digital_playback
 6391#define alc882_pcm_digital_capture        alc880_pcm_digital_capture
 6392
 6393/*
 6394 * configuration and preset
 6395 */
 6396static const char *alc882_models[ALC882_MODEL_LAST] = {
 6397        [ALC882_3ST_DIG]        = "3stack-dig",
 6398        [ALC882_6ST_DIG]        = "6stack-dig",
 6399        [ALC882_ARIMA]                = "arima",
 6400        [ALC882_W2JC]                = "w2jc",
 6401        [ALC882_TARGA]                = "targa",
 6402        [ALC882_ASUS_A7J]        = "asus-a7j",
 6403        [ALC882_ASUS_A7M]        = "asus-a7m",
 6404        [ALC885_MACPRO]                = "macpro",
 6405        [ALC885_MBP3]                = "mbp3",
 6406        [ALC885_IMAC24]                = "imac24",
 6407        [ALC882_AUTO]                = "auto",
 6408};
 6409
 6410static struct snd_pci_quirk alc882_cfg_tbl[] = {
 6411        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
 6412        SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
 6413        SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
 6414        SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
 6415        SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
 6416        SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
 6417        SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
 6418        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
 6419        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
 6420        SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
 6421        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
 6422        SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
 6423        {}
 6424};
 6425
 6426static struct alc_config_preset alc882_presets[] = {
 6427        [ALC882_3ST_DIG] = {
 6428                .mixers = { alc882_base_mixer },
 6429                .init_verbs = { alc882_init_verbs },
 6430                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6431                .dac_nids = alc882_dac_nids,
 6432                .dig_out_nid = ALC882_DIGOUT_NID,
 6433                .dig_in_nid = ALC882_DIGIN_NID,
 6434                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 6435                .channel_mode = alc882_ch_modes,
 6436                .need_dac_fix = 1,
 6437                .input_mux = &alc882_capture_source,
 6438        },
 6439        [ALC882_6ST_DIG] = {
 6440                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 6441                .init_verbs = { alc882_init_verbs },
 6442                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6443                .dac_nids = alc882_dac_nids,
 6444                .dig_out_nid = ALC882_DIGOUT_NID,
 6445                .dig_in_nid = ALC882_DIGIN_NID,
 6446                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 6447                .channel_mode = alc882_sixstack_modes,
 6448                .input_mux = &alc882_capture_source,
 6449        },
 6450        [ALC882_ARIMA] = {
 6451                .mixers = { alc882_base_mixer, alc882_chmode_mixer },
 6452                .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
 6453                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6454                .dac_nids = alc882_dac_nids,
 6455                .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
 6456                .channel_mode = alc882_sixstack_modes,
 6457                .input_mux = &alc882_capture_source,
 6458        },
 6459        [ALC882_W2JC] = {
 6460                .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
 6461                .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
 6462                                alc880_gpio1_init_verbs },
 6463                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6464                .dac_nids = alc882_dac_nids,
 6465                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 6466                .channel_mode = alc880_threestack_modes,
 6467                .need_dac_fix = 1,
 6468                .input_mux = &alc882_capture_source,
 6469                .dig_out_nid = ALC882_DIGOUT_NID,
 6470        },
 6471        [ALC885_MBP3] = {
 6472                .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
 6473                .init_verbs = { alc885_mbp3_init_verbs,
 6474                                alc880_gpio1_init_verbs },
 6475                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6476                .dac_nids = alc882_dac_nids,
 6477                .channel_mode = alc885_mbp_6ch_modes,
 6478                .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
 6479                .input_mux = &alc882_capture_source,
 6480                .dig_out_nid = ALC882_DIGOUT_NID,
 6481                .dig_in_nid = ALC882_DIGIN_NID,
 6482                .unsol_event = alc885_mbp3_unsol_event,
 6483                .init_hook = alc885_mbp3_automute,
 6484        },
 6485        [ALC885_MACPRO] = {
 6486                .mixers = { alc882_macpro_mixer },
 6487                .init_verbs = { alc882_macpro_init_verbs },
 6488                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6489                .dac_nids = alc882_dac_nids,
 6490                .dig_out_nid = ALC882_DIGOUT_NID,
 6491                .dig_in_nid = ALC882_DIGIN_NID,
 6492                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 6493                .channel_mode = alc882_ch_modes,
 6494                .input_mux = &alc882_capture_source,
 6495                .init_hook = alc885_macpro_init_hook,
 6496        },
 6497        [ALC885_IMAC24] = {
 6498                .mixers = { alc885_imac24_mixer },
 6499                .init_verbs = { alc885_imac24_init_verbs },
 6500                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6501                .dac_nids = alc882_dac_nids,
 6502                .dig_out_nid = ALC882_DIGOUT_NID,
 6503                .dig_in_nid = ALC882_DIGIN_NID,
 6504                .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
 6505                .channel_mode = alc882_ch_modes,
 6506                .input_mux = &alc882_capture_source,
 6507                .unsol_event = alc885_imac24_unsol_event,
 6508                .init_hook = alc885_imac24_init_hook,
 6509        },
 6510        [ALC882_TARGA] = {
 6511                .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
 6512                            alc882_capture_mixer },
 6513                .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
 6514                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6515                .dac_nids = alc882_dac_nids,
 6516                .dig_out_nid = ALC882_DIGOUT_NID,
 6517                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
 6518                .adc_nids = alc882_adc_nids,
 6519                .capsrc_nids = alc882_capsrc_nids,
 6520                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
 6521                .channel_mode = alc882_3ST_6ch_modes,
 6522                .need_dac_fix = 1,
 6523                .input_mux = &alc882_capture_source,
 6524                .unsol_event = alc882_targa_unsol_event,
 6525                .init_hook = alc882_targa_automute,
 6526        },
 6527        [ALC882_ASUS_A7J] = {
 6528                .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
 6529                            alc882_capture_mixer },
 6530                .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
 6531                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6532                .dac_nids = alc882_dac_nids,
 6533                .dig_out_nid = ALC882_DIGOUT_NID,
 6534                .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
 6535                .adc_nids = alc882_adc_nids,
 6536                .capsrc_nids = alc882_capsrc_nids,
 6537                .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
 6538                .channel_mode = alc882_3ST_6ch_modes,
 6539                .need_dac_fix = 1,
 6540                .input_mux = &alc882_capture_source,
 6541        },
 6542        [ALC882_ASUS_A7M] = {
 6543                .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
 6544                .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
 6545                                alc880_gpio1_init_verbs,
 6546                                alc882_asus_a7m_verbs },
 6547                .num_dacs = ARRAY_SIZE(alc882_dac_nids),
 6548                .dac_nids = alc882_dac_nids,
 6549                .dig_out_nid = ALC882_DIGOUT_NID,
 6550                .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
 6551                .channel_mode = alc880_threestack_modes,
 6552                .need_dac_fix = 1,
 6553                .input_mux = &alc882_capture_source,
 6554        },
 6555};
 6556
 6557
 6558/*
 6559 * Pin config fixes
 6560 */
 6561enum {
 6562        PINFIX_ABIT_AW9D_MAX
 6563};
 6564
 6565static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
 6566        { 0x15, 0x01080104 }, /* side */
 6567        { 0x16, 0x01011012 }, /* rear */
 6568        { 0x17, 0x01016011 }, /* clfe */
 6569        { }
 6570};
 6571
 6572static const struct alc_pincfg *alc882_pin_fixes[] = {
 6573        [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
 6574};
 6575
 6576static struct snd_pci_quirk alc882_pinfix_tbl[] = {
 6577        SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
 6578        {}
 6579};
 6580
 6581/*
 6582 * BIOS auto configuration
 6583 */
 6584static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
 6585                                              hda_nid_t nid, int pin_type,
 6586                                              int dac_idx)
 6587{
 6588        /* set as output */
 6589        struct alc_spec *spec = codec->spec;
 6590        int idx;
 6591
 6592        alc_set_pin_output(codec, nid, pin_type);
 6593        if (spec->multiout.dac_nids[dac_idx] == 0x25)
 6594                idx = 4;
 6595        else
 6596                idx = spec->multiout.dac_nids[dac_idx] - 2;
 6597        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
 6598
 6599}
 6600
 6601static void alc882_auto_init_multi_out(struct hda_codec *codec)
 6602{
 6603        struct alc_spec *spec = codec->spec;
 6604        int i;
 6605
 6606        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 6607        for (i = 0; i <= HDA_SIDE; i++) {
 6608                hda_nid_t nid = spec->autocfg.line_out_pins[i];
 6609                int pin_type = get_pin_type(spec->autocfg.line_out_type);
 6610                if (nid)
 6611                        alc882_auto_set_output_and_unmute(codec, nid, pin_type,
 6612                                                          i);
 6613        }
 6614}
 6615
 6616static void alc882_auto_init_hp_out(struct hda_codec *codec)
 6617{
 6618        struct alc_spec *spec = codec->spec;
 6619        hda_nid_t pin;
 6620
 6621        pin = spec->autocfg.hp_pins[0];
 6622        if (pin) /* connect to front */
 6623                /* use dac 0 */
 6624                alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 6625        pin = spec->autocfg.speaker_pins[0];
 6626        if (pin)
 6627                alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 6628}
 6629
 6630#define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
 6631#define ALC882_PIN_CD_NID                ALC880_PIN_CD_NID
 6632
 6633static void alc882_auto_init_analog_input(struct hda_codec *codec)
 6634{
 6635        struct alc_spec *spec = codec->spec;
 6636        int i;
 6637
 6638        for (i = 0; i < AUTO_PIN_LAST; i++) {
 6639                hda_nid_t nid = spec->autocfg.input_pins[i];
 6640                unsigned int vref;
 6641                if (!nid)
 6642                        continue;
 6643                vref = PIN_IN;
 6644                if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
 6645                        unsigned int pincap;
 6646                        pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
 6647                        if ((pincap >> AC_PINCAP_VREF_SHIFT) &
 6648                            AC_PINCAP_VREF_80)
 6649                                vref = PIN_VREF80;
 6650                }
 6651                snd_hda_codec_write(codec, nid, 0,
 6652                                    AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
 6653                if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
 6654                        snd_hda_codec_write(codec, nid, 0,
 6655                                            AC_VERB_SET_AMP_GAIN_MUTE,
 6656                                            AMP_OUT_MUTE);
 6657        }
 6658}
 6659
 6660static void alc882_auto_init_input_src(struct hda_codec *codec)
 6661{
 6662        struct alc_spec *spec = codec->spec;
 6663        const struct hda_input_mux *imux = spec->input_mux;
 6664        int c;
 6665
 6666        for (c = 0; c < spec->num_adc_nids; c++) {
 6667                hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
 6668                hda_nid_t nid = spec->capsrc_nids[c];
 6669                int conns, mute, idx, item;
 6670
 6671                conns = snd_hda_get_connections(codec, nid, conn_list,
 6672                                                ARRAY_SIZE(conn_list));
 6673                if (conns < 0)
 6674                        continue;
 6675                for (idx = 0; idx < conns; idx++) {
 6676                        /* if the current connection is the selected one,
 6677                         * unmute it as default - otherwise mute it
 6678                         */
 6679                        mute = AMP_IN_MUTE(idx);
 6680                        for (item = 0; item < imux->num_items; item++) {
 6681                                if (imux->items[item].index == idx) {
 6682                                        if (spec->cur_mux[c] == item)
 6683                                                mute = AMP_IN_UNMUTE(idx);
 6684                                        break;
 6685                                }
 6686                        }
 6687                        snd_hda_codec_write(codec, nid, 0,
 6688                                            AC_VERB_SET_AMP_GAIN_MUTE, mute);
 6689                }
 6690        }
 6691}
 6692
 6693/* add mic boosts if needed */
 6694static int alc_auto_add_mic_boost(struct hda_codec *codec)
 6695{
 6696        struct alc_spec *spec = codec->spec;
 6697        int err;
 6698        hda_nid_t nid;
 6699
 6700        nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
 6701        if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 6702                err = add_control(spec, ALC_CTL_WIDGET_VOL,
 6703                                  "Mic Boost",
 6704                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 6705                if (err < 0)
 6706                        return err;
 6707        }
 6708        nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
 6709        if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
 6710                err = add_control(spec, ALC_CTL_WIDGET_VOL,
 6711                                  "Front Mic Boost",
 6712                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
 6713                if (err < 0)
 6714                        return err;
 6715        }
 6716        return 0;
 6717}
 6718
 6719/* almost identical with ALC880 parser... */
 6720static int alc882_parse_auto_config(struct hda_codec *codec)
 6721{
 6722        struct alc_spec *spec = codec->spec;
 6723        int err = alc880_parse_auto_config(codec);
 6724
 6725        if (err < 0)
 6726                return err;
 6727        else if (!err)
 6728                return 0; /* no config found */
 6729
 6730        err = alc_auto_add_mic_boost(codec);
 6731        if (err < 0)
 6732                return err;
 6733
 6734        /* hack - override the init verbs */
 6735        spec->init_verbs[0] = alc882_auto_init_verbs;
 6736
 6737        return 1; /* config found */
 6738}
 6739
 6740/* additional initialization for auto-configuration model */
 6741static void alc882_auto_init(struct hda_codec *codec)
 6742{
 6743        struct alc_spec *spec = codec->spec;
 6744        alc882_auto_init_multi_out(codec);
 6745        alc882_auto_init_hp_out(codec);
 6746        alc882_auto_init_analog_input(codec);
 6747        alc882_auto_init_input_src(codec);
 6748        if (spec->unsol_event)
 6749                alc_inithook(codec);
 6750}
 6751
 6752static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
 6753
 6754static int patch_alc882(struct hda_codec *codec)
 6755{
 6756        struct alc_spec *spec;
 6757        int err, board_config;
 6758
 6759        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 6760        if (spec == NULL)
 6761                return -ENOMEM;
 6762
 6763        codec->spec = spec;
 6764
 6765        board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
 6766                                                  alc882_models,
 6767                                                  alc882_cfg_tbl);
 6768
 6769        if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
 6770                /* Pick up systems that don't supply PCI SSID */
 6771                switch (codec->subsystem_id) {
 6772                case 0x106b0c00: /* Mac Pro */
 6773                        board_config = ALC885_MACPRO;
 6774                        break;
 6775                case 0x106b1000: /* iMac 24 */
 6776                case 0x106b2800: /* AppleTV */
 6777                        board_config = ALC885_IMAC24;
 6778                        break;
 6779                case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
 6780                case 0x106b00a4: /* MacbookPro4,1 */
 6781                case 0x106b2c00: /* Macbook Pro rev3 */
 6782                case 0x106b3600: /* Macbook 3.1 */
 6783                        board_config = ALC885_MBP3;
 6784                        break;
 6785                default:
 6786                        /* ALC889A is handled better as ALC888-compatible */
 6787                        if (codec->revision_id == 0x100101 ||
 6788                            codec->revision_id == 0x100103) {
 6789                                alc_free(codec);
 6790                                return patch_alc883(codec);
 6791                        }
 6792                        printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
 6793                                                "trying auto-probe from BIOS...\n");
 6794                        board_config = ALC882_AUTO;
 6795                }
 6796        }
 6797
 6798        alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
 6799
 6800        if (board_config == ALC882_AUTO) {
 6801                /* automatic parse from the BIOS config */
 6802                err = alc882_parse_auto_config(codec);
 6803                if (err < 0) {
 6804                        alc_free(codec);
 6805                        return err;
 6806                } else if (!err) {
 6807                        printk(KERN_INFO
 6808                               "hda_codec: Cannot set up configuration "
 6809                               "from BIOS.  Using base mode...\n");
 6810                        board_config = ALC882_3ST_DIG;
 6811                }
 6812        }
 6813
 6814        if (board_config != ALC882_AUTO)
 6815                setup_preset(spec, &alc882_presets[board_config]);
 6816
 6817        if (codec->vendor_id == 0x10ec0885) {
 6818                spec->stream_name_analog = "ALC885 Analog";
 6819                spec->stream_name_digital = "ALC885 Digital";
 6820        } else {
 6821                spec->stream_name_analog = "ALC882 Analog";
 6822                spec->stream_name_digital = "ALC882 Digital";
 6823        }
 6824
 6825        spec->stream_analog_playback = &alc882_pcm_analog_playback;
 6826        spec->stream_analog_capture = &alc882_pcm_analog_capture;
 6827        /* FIXME: setup DAC5 */
 6828        /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
 6829        spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
 6830
 6831        spec->stream_digital_playback = &alc882_pcm_digital_playback;
 6832        spec->stream_digital_capture = &alc882_pcm_digital_capture;
 6833
 6834        if (!spec->adc_nids && spec->input_mux) {
 6835                /* check whether NID 0x07 is valid */
 6836                unsigned int wcap = get_wcaps(codec, 0x07);
 6837                /* get type */
 6838                wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 6839                if (wcap != AC_WID_AUD_IN) {
 6840                        spec->adc_nids = alc882_adc_nids_alt;
 6841                        spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
 6842                        spec->capsrc_nids = alc882_capsrc_nids_alt;
 6843                        spec->mixers[spec->num_mixers] =
 6844                                alc882_capture_alt_mixer;
 6845                        spec->num_mixers++;
 6846                } else {
 6847                        spec->adc_nids = alc882_adc_nids;
 6848                        spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
 6849                        spec->capsrc_nids = alc882_capsrc_nids;
 6850                        spec->mixers[spec->num_mixers] = alc882_capture_mixer;
 6851                        spec->num_mixers++;
 6852                }
 6853        }
 6854
 6855        spec->vmaster_nid = 0x0c;
 6856
 6857        codec->patch_ops = alc_patch_ops;
 6858        if (board_config == ALC882_AUTO)
 6859                spec->init_hook = alc882_auto_init;
 6860#ifdef CONFIG_SND_HDA_POWER_SAVE
 6861        if (!spec->loopback.amplist)
 6862                spec->loopback.amplist = alc882_loopbacks;
 6863#endif
 6864
 6865        return 0;
 6866}
 6867
 6868/*
 6869 * ALC883 support
 6870 *
 6871 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
 6872 * configuration.  Each pin widget can choose any input DACs and a mixer.
 6873 * Each ADC is connected from a mixer of all inputs.  This makes possible
 6874 * 6-channel independent captures.
 6875 *
 6876 * In addition, an independent DAC for the multi-playback (not used in this
 6877 * driver yet).
 6878 */
 6879#define ALC883_DIGOUT_NID        0x06
 6880#define ALC883_DIGIN_NID        0x0a
 6881
 6882static hda_nid_t alc883_dac_nids[4] = {
 6883        /* front, rear, clfe, rear_surr */
 6884        0x02, 0x03, 0x04, 0x05
 6885};
 6886
 6887static hda_nid_t alc883_adc_nids[2] = {
 6888        /* ADC1-2 */
 6889        0x08, 0x09,
 6890};
 6891
 6892static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
 6893
 6894/* input MUX */
 6895/* FIXME: should be a matrix-type input source selection */
 6896
 6897static struct hda_input_mux alc883_capture_source = {
 6898        .num_items = 4,
 6899        .items = {
 6900                { "Mic", 0x0 },
 6901                { "Front Mic", 0x1 },
 6902                { "Line", 0x2 },
 6903                { "CD", 0x4 },
 6904        },
 6905};
 6906
 6907static struct hda_input_mux alc883_3stack_6ch_intel = {
 6908        .num_items = 4,
 6909        .items = {
 6910                { "Mic", 0x1 },
 6911                { "Front Mic", 0x0 },
 6912                { "Line", 0x2 },
 6913                { "CD", 0x4 },
 6914        },
 6915};
 6916
 6917static struct hda_input_mux alc883_lenovo_101e_capture_source = {
 6918        .num_items = 2,
 6919        .items = {
 6920                { "Mic", 0x1 },
 6921                { "Line", 0x2 },
 6922        },
 6923};
 6924
 6925static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
 6926        .num_items = 4,
 6927        .items = {
 6928                { "Mic", 0x0 },
 6929                { "iMic", 0x1 },
 6930                { "Line", 0x2 },
 6931                { "CD", 0x4 },
 6932        },
 6933};
 6934
 6935static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
 6936        .num_items = 2,
 6937        .items = {
 6938                { "Mic", 0x0 },
 6939                { "Int Mic", 0x1 },
 6940        },
 6941};
 6942
 6943static struct hda_input_mux alc883_lenovo_sky_capture_source = {
 6944        .num_items = 3,
 6945        .items = {
 6946                { "Mic", 0x0 },
 6947                { "Front Mic", 0x1 },
 6948                { "Line", 0x4 },
 6949        },
 6950};
 6951
 6952static struct hda_input_mux alc883_asus_eee1601_capture_source = {
 6953        .num_items = 2,
 6954        .items = {
 6955                { "Mic", 0x0 },
 6956                { "Line", 0x2 },
 6957        },
 6958};
 6959
 6960#define alc883_mux_enum_info alc_mux_enum_info
 6961#define alc883_mux_enum_get alc_mux_enum_get
 6962/* ALC883 has the ALC882-type input selection */
 6963#define alc883_mux_enum_put alc882_mux_enum_put
 6964
 6965/*
 6966 * 2ch mode
 6967 */
 6968static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
 6969        { 2, NULL }
 6970};
 6971
 6972/*
 6973 * 2ch mode
 6974 */
 6975static struct hda_verb alc883_3ST_ch2_init[] = {
 6976        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 6977        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 6978        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 6979        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 6980        { } /* end */
 6981};
 6982
 6983/*
 6984 * 4ch mode
 6985 */
 6986static struct hda_verb alc883_3ST_ch4_init[] = {
 6987        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 6988        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 6989        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 6990        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 6991        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 6992        { } /* end */
 6993};
 6994
 6995/*
 6996 * 6ch mode
 6997 */
 6998static struct hda_verb alc883_3ST_ch6_init[] = {
 6999        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7000        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7001        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
 7002        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7003        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7004        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 7005        { } /* end */
 7006};
 7007
 7008static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
 7009        { 2, alc883_3ST_ch2_init },
 7010        { 4, alc883_3ST_ch4_init },
 7011        { 6, alc883_3ST_ch6_init },
 7012};
 7013
 7014/*
 7015 * 2ch mode
 7016 */
 7017static struct hda_verb alc883_3ST_ch2_intel_init[] = {
 7018        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 7019        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 7020        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 7021        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 7022        { } /* end */
 7023};
 7024
 7025/*
 7026 * 4ch mode
 7027 */
 7028static struct hda_verb alc883_3ST_ch4_intel_init[] = {
 7029        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 7030        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 7031        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7032        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7033        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 7034        { } /* end */
 7035};
 7036
 7037/*
 7038 * 6ch mode
 7039 */
 7040static struct hda_verb alc883_3ST_ch6_intel_init[] = {
 7041        { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7042        { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7043        { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
 7044        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7045        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7046        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
 7047        { } /* end */
 7048};
 7049
 7050static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
 7051        { 2, alc883_3ST_ch2_intel_init },
 7052        { 4, alc883_3ST_ch4_intel_init },
 7053        { 6, alc883_3ST_ch6_intel_init },
 7054};
 7055
 7056/*
 7057 * 6ch mode
 7058 */
 7059static struct hda_verb alc883_sixstack_ch6_init[] = {
 7060        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
 7061        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7062        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7063        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7064        { } /* end */
 7065};
 7066
 7067/*
 7068 * 8ch mode
 7069 */
 7070static struct hda_verb alc883_sixstack_ch8_init[] = {
 7071        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7072        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7073        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7074        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7075        { } /* end */
 7076};
 7077
 7078static struct hda_channel_mode alc883_sixstack_modes[2] = {
 7079        { 6, alc883_sixstack_ch6_init },
 7080        { 8, alc883_sixstack_ch8_init },
 7081};
 7082
 7083static struct hda_verb alc883_medion_eapd_verbs[] = {
 7084        /* eanable EAPD on medion laptop */
 7085        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 7086        {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
 7087        { }
 7088};
 7089
 7090/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
 7091 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
 7092 */
 7093
 7094static struct snd_kcontrol_new alc883_base_mixer[] = {
 7095        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7096        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7097        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7098        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 7099        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 7100        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7101        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7102        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7103        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 7104        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 7105        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7106        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7107        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7108        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7109        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7110        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7111        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7112        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7113        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7114        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7115        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7116        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 7117        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 7118        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7119        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7120        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7121        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7122        {
 7123                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7124                /* .name = "Capture Source", */
 7125                .name = "Input Source",
 7126                .count = 2,
 7127                .info = alc883_mux_enum_info,
 7128                .get = alc883_mux_enum_get,
 7129                .put = alc883_mux_enum_put,
 7130        },
 7131        { } /* end */
 7132};
 7133
 7134static struct snd_kcontrol_new alc883_mitac_mixer[] = {
 7135        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7136        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7137        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 7138        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7139        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7140        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7141        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 7142        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7143        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7144        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7145        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7146        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7147        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7148        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7149        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7150        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7151        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7152        {
 7153                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7154                /* .name = "Capture Source", */
 7155                .name = "Input Source",
 7156                .count = 2,
 7157                .info = alc883_mux_enum_info,
 7158                .get = alc883_mux_enum_get,
 7159                .put = alc883_mux_enum_put,
 7160        },
 7161        { } /* end */
 7162};
 7163
 7164static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
 7165        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7166        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 7167        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7168        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 7169        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7170        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7171        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7172        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7173        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
 7174        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7175        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7176        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7177        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7178        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7179        {
 7180                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7181                /* .name = "Capture Source", */
 7182                .name = "Input Source",
 7183                .count = 2,
 7184                .info = alc883_mux_enum_info,
 7185                .get = alc883_mux_enum_get,
 7186                .put = alc883_mux_enum_put,
 7187        },
 7188        { } /* end */
 7189};
 7190
 7191static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
 7192        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7193        HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 7194        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7195        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 7196        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7197        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7198        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7199        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7200        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
 7201        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7202        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7203        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7204        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7205        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7206        {
 7207                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7208                /* .name = "Capture Source", */
 7209                .name = "Input Source",
 7210                .count = 2,
 7211                .info = alc883_mux_enum_info,
 7212                .get = alc883_mux_enum_get,
 7213                .put = alc883_mux_enum_put,
 7214        },
 7215        { } /* end */
 7216};
 7217
 7218static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
 7219        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7220        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7221        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7222        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7223        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7224        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7225        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7226        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7227        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7228        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7229        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7230        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7231        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7232        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 7233        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 7234        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7235        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7236        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7237        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7238        {
 7239                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7240                /* .name = "Capture Source", */
 7241                .name = "Input Source",
 7242                .count = 2,
 7243                .info = alc883_mux_enum_info,
 7244                .get = alc883_mux_enum_get,
 7245                .put = alc883_mux_enum_put,
 7246        },
 7247        { } /* end */
 7248};
 7249
 7250static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
 7251        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7252        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7253        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7254        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 7255        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 7256        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7257        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7258        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7259        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7260        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7261        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7262        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7263        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7264        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7265        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7266        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7267        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7268        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7269        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7270        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 7271        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 7272        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7273        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7274        {
 7275                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7276                /* .name = "Capture Source", */
 7277                .name = "Input Source",
 7278                .count = 1,
 7279                .info = alc883_mux_enum_info,
 7280                .get = alc883_mux_enum_get,
 7281                .put = alc883_mux_enum_put,
 7282        },
 7283        { } /* end */
 7284};
 7285
 7286static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
 7287        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7288        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7289        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7290        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 7291        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
 7292                              HDA_OUTPUT),
 7293        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7294        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7295        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7296        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 7297        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7298        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7299        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7300        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7301        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7302        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
 7303        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7304        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7305        HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
 7306        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7307        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 7308        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 7309        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7310        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7311        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7312        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7313        {
 7314                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7315                /* .name = "Capture Source", */
 7316                .name = "Input Source",
 7317                .count = 2,
 7318                .info = alc883_mux_enum_info,
 7319                .get = alc883_mux_enum_get,
 7320                .put = alc883_mux_enum_put,
 7321        },
 7322        { } /* end */
 7323};
 7324
 7325static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
 7326        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7327        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7328        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7329        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 7330        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 7331        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7332        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7333        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7334        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7335        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7336        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7337        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7338        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7339        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7340        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7341        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7342        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7343        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7344        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7345        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 7346        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 7347        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7348        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7349
 7350        {
 7351                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7352                /* .name = "Capture Source", */
 7353                .name = "Input Source",
 7354                .count = 1,
 7355                .info = alc883_mux_enum_info,
 7356                .get = alc883_mux_enum_get,
 7357                .put = alc883_mux_enum_put,
 7358        },
 7359        { } /* end */
 7360};
 7361
 7362static struct snd_kcontrol_new alc883_tagra_mixer[] = {
 7363        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7364        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7365        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7366        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7367        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
 7368        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 7369        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 7370        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
 7371        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
 7372        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7373        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7374        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7375        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7376        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7377        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7378        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7379        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7380        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7381        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7382        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7383        {
 7384                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7385                /* .name = "Capture Source", */
 7386                .name = "Input Source",
 7387                .count = 2,
 7388                .info = alc883_mux_enum_info,
 7389                .get = alc883_mux_enum_get,
 7390                .put = alc883_mux_enum_put,
 7391        },
 7392        { } /* end */
 7393};
 7394
 7395static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
 7396        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7397        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7398        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7399        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7400        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7401        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7402        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7403        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7404        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7405        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
 7406        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7407        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7408        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7409        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7410        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7411        {
 7412                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7413                /* .name = "Capture Source", */
 7414                .name = "Input Source",
 7415                .count = 2,
 7416                .info = alc883_mux_enum_info,
 7417                .get = alc883_mux_enum_get,
 7418                .put = alc883_mux_enum_put,
 7419        },
 7420        { } /* end */
 7421};
 7422
 7423static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
 7424        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7425        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7426        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 7427        HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
 7428        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7429        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7430        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7431        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7432        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7433        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7434        {
 7435                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7436                /* .name = "Capture Source", */
 7437                .name = "Input Source",
 7438                .count = 1,
 7439                .info = alc883_mux_enum_info,
 7440                .get = alc883_mux_enum_get,
 7441                .put = alc883_mux_enum_put,
 7442        },
 7443        { } /* end */
 7444};
 7445
 7446static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
 7447        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7448        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
 7449        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7450        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7451        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7452        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7453        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7454        HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7455        HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7456        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7457        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7458        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7459        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7460        {
 7461                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7462                /* .name = "Capture Source", */
 7463                .name = "Input Source",
 7464                .count = 2,
 7465                .info = alc883_mux_enum_info,
 7466                .get = alc883_mux_enum_get,
 7467                .put = alc883_mux_enum_put,
 7468        },
 7469        { } /* end */
 7470};
 7471
 7472static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
 7473        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7474        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7475        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 7476        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7477        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7478        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7479        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7480        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7481        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7482        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7483        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7484        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7485        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7486        {
 7487                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7488                /* .name = "Capture Source", */
 7489                .name = "Input Source",
 7490                .count = 2,
 7491                .info = alc883_mux_enum_info,
 7492                .get = alc883_mux_enum_get,
 7493                .put = alc883_mux_enum_put,
 7494        },
 7495        { } /* end */
 7496};
 7497
 7498static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
 7499        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7500        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7501        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7502        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7503        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7504        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7505        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7506        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7507        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7508        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7509        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7510        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7511        {
 7512                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7513                /* .name = "Capture Source", */
 7514                .name = "Input Source",
 7515                .count = 2,
 7516                .info = alc883_mux_enum_info,
 7517                .get = alc883_mux_enum_get,
 7518                .put = alc883_mux_enum_put,
 7519        },
 7520        { } /* end */
 7521};
 7522
 7523static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
 7524        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7525        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7526        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
 7527        HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
 7528        HDA_CODEC_VOLUME_MONO("Center Playback Volume",
 7529                                                0x0d, 1, 0x0, HDA_OUTPUT),
 7530        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
 7531        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
 7532        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
 7533        HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
 7534        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
 7535        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 7536        HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
 7537        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 7538        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 7539        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7540        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7541        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7542        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7543        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7544        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 7545        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 7546        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 7547        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 7548        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 7549        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 7550        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 7551        {
 7552                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7553                /* .name = "Capture Source", */
 7554                .name = "Input Source",
 7555                .count = 2,
 7556                .info = alc883_mux_enum_info,
 7557                .get = alc883_mux_enum_get,
 7558                .put = alc883_mux_enum_put,
 7559        },
 7560        { } /* end */
 7561};
 7562
 7563static struct hda_bind_ctls alc883_bind_cap_vol = {
 7564        .ops = &snd_hda_bind_vol,
 7565        .values = {
 7566                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
 7567                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
 7568                0
 7569        },
 7570};
 7571
 7572static struct hda_bind_ctls alc883_bind_cap_switch = {
 7573        .ops = &snd_hda_bind_sw,
 7574        .values = {
 7575                HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
 7576                HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
 7577                0
 7578        },
 7579};
 7580
 7581static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
 7582        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 7583        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 7584        HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 7585        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 7586        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 7587        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 7588        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 7589        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 7590        HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
 7591        HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
 7592        {
 7593                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7594                /* .name = "Capture Source", */
 7595                .name = "Input Source",
 7596                .count = 1,
 7597                .info = alc883_mux_enum_info,
 7598                .get = alc883_mux_enum_get,
 7599                .put = alc883_mux_enum_put,
 7600        },
 7601        { } /* end */
 7602};
 7603
 7604static struct snd_kcontrol_new alc883_chmode_mixer[] = {
 7605        {
 7606                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 7607                .name = "Channel Mode",
 7608                .info = alc_ch_mode_info,
 7609                .get = alc_ch_mode_get,
 7610                .put = alc_ch_mode_put,
 7611        },
 7612        { } /* end */
 7613};
 7614
 7615static struct hda_verb alc883_init_verbs[] = {
 7616        /* ADC1: mute amp left and right */
 7617        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7618        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 7619        /* ADC2: mute amp left and right */
 7620        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7621        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 7622        /* Front mixer: unmute input/output amp left and right (volume = 0) */
 7623        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 7624        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7625        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7626        /* Rear mixer */
 7627        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 7628        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7629        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7630        /* CLFE mixer */
 7631        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 7632        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7633        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7634        /* Side mixer */
 7635        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 7636        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7637        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7638
 7639        /* mute analog input loopbacks */
 7640        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 7641        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7642        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 7643        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 7644        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 7645
 7646        /* Front Pin: output 0 (0x0c) */
 7647        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7648        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 7649        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 7650        /* Rear Pin: output 1 (0x0d) */
 7651        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7652        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 7653        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
 7654        /* CLFE Pin: output 2 (0x0e) */
 7655        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7656        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 7657        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
 7658        /* Side Pin: output 3 (0x0f) */
 7659        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7660        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 7661        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
 7662        /* Mic (rear) pin: input vref at 80% */
 7663        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 7664        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 7665        /* Front Mic pin: input vref at 80% */
 7666        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 7667        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 7668        /* Line In pin: input */
 7669        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 7670        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 7671        /* Line-2 In: Headphone output (output 0 - 0x0c) */
 7672        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7673        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 7674        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 7675        /* CD pin widget for input */
 7676        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 7677
 7678        /* FIXME: use matrix-type input source selection */
 7679        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 7680        /* Input mixer2 */
 7681        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7682        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7683        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 7684        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 7685        /* Input mixer3 */
 7686        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7687        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 7688        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 7689        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 7690        { }
 7691};
 7692
 7693/* toggle speaker-output according to the hp-jack state */
 7694static void alc883_mitac_hp_automute(struct hda_codec *codec)
 7695{
 7696        unsigned int present;
 7697
 7698        present = snd_hda_codec_read(codec, 0x15, 0,
 7699                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7700        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 7701                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7702        snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
 7703                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7704}
 7705
 7706/* auto-toggle front mic */
 7707/*
 7708static void alc883_mitac_mic_automute(struct hda_codec *codec)
 7709{
 7710        unsigned int present;
 7711        unsigned char bits;
 7712
 7713        present = snd_hda_codec_read(codec, 0x18, 0,
 7714                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7715        bits = present ? HDA_AMP_MUTE : 0;
 7716        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
 7717}
 7718*/
 7719
 7720static void alc883_mitac_automute(struct hda_codec *codec)
 7721{
 7722        alc883_mitac_hp_automute(codec);
 7723        /* alc883_mitac_mic_automute(codec); */
 7724}
 7725
 7726static void alc883_mitac_unsol_event(struct hda_codec *codec,
 7727                                           unsigned int res)
 7728{
 7729        switch (res >> 26) {
 7730        case ALC880_HP_EVENT:
 7731                alc883_mitac_hp_automute(codec);
 7732                break;
 7733        case ALC880_MIC_EVENT:
 7734                /* alc883_mitac_mic_automute(codec); */
 7735                break;
 7736        }
 7737}
 7738
 7739static struct hda_verb alc883_mitac_verbs[] = {
 7740        /* HP */
 7741        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 7742        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7743        /* Subwoofer */
 7744        {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
 7745        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7746
 7747        /* enable unsolicited event */
 7748        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7749        /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
 7750
 7751        { } /* end */
 7752};
 7753
 7754static struct hda_verb alc883_clevo_m720_verbs[] = {
 7755        /* HP */
 7756        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 7757        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7758        /* Int speaker */
 7759        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
 7760        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7761
 7762        /* enable unsolicited event */
 7763        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7764        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
 7765
 7766        { } /* end */
 7767};
 7768
 7769static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
 7770        /* HP */
 7771        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 7772        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7773        /* Subwoofer */
 7774        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
 7775        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7776
 7777        /* enable unsolicited event */
 7778        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7779
 7780        { } /* end */
 7781};
 7782
 7783static struct hda_verb alc883_tagra_verbs[] = {
 7784        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7785        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 7786
 7787        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7788        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7789
 7790        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
 7791        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
 7792        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
 7793
 7794        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7795        {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
 7796        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
 7797        {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
 7798
 7799        { } /* end */
 7800};
 7801
 7802static struct hda_verb alc883_lenovo_101e_verbs[] = {
 7803        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 7804        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
 7805        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
 7806        { } /* end */
 7807};
 7808
 7809static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
 7810        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 7811        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7812        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7813        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7814        { } /* end */
 7815};
 7816
 7817static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
 7818        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7819        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 7820        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 7821        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
 7822        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
 7823        { } /* end */
 7824};
 7825
 7826static struct hda_verb alc883_haier_w66_verbs[] = {
 7827        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7828        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 7829
 7830        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7831
 7832        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 7833        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7834        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7835        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7836        { } /* end */
 7837};
 7838
 7839static struct hda_verb alc888_lenovo_sky_verbs[] = {
 7840        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7841        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 7842        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7843        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7844        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7845        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 7846        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
 7847        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7848        { } /* end */
 7849};
 7850
 7851static struct hda_verb alc888_3st_hp_verbs[] = {
 7852        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},        /* Front: output 0 (0x0c) */
 7853        {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Rear : output 1 (0x0d) */
 7854        {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},        /* CLFE : output 2 (0x0e) */
 7855        { }
 7856};
 7857
 7858static struct hda_verb alc888_6st_dell_verbs[] = {
 7859        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7860        { }
 7861};
 7862
 7863static struct hda_verb alc888_3st_hp_2ch_init[] = {
 7864        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
 7865        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 7866        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
 7867        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
 7868        { }
 7869};
 7870
 7871static struct hda_verb alc888_3st_hp_6ch_init[] = {
 7872        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7873        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7874        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 7875        { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
 7876        { }
 7877};
 7878
 7879static struct hda_channel_mode alc888_3st_hp_modes[2] = {
 7880        { 2, alc888_3st_hp_2ch_init },
 7881        { 6, alc888_3st_hp_6ch_init },
 7882};
 7883
 7884/* toggle front-jack and RCA according to the hp-jack state */
 7885static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
 7886{
 7887         unsigned int present;
 7888
 7889         present = snd_hda_codec_read(codec, 0x1b, 0,
 7890                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7891        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 7892                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7893        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 7894                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7895}
 7896
 7897/* toggle RCA according to the front-jack state */
 7898static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
 7899{
 7900         unsigned int present;
 7901
 7902         present = snd_hda_codec_read(codec, 0x14, 0,
 7903                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7904        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 7905                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7906}
 7907
 7908static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
 7909                                             unsigned int res)
 7910{
 7911        if ((res >> 26) == ALC880_HP_EVENT)
 7912                alc888_lenovo_ms7195_front_automute(codec);
 7913        if ((res >> 26) == ALC880_FRONT_EVENT)
 7914                alc888_lenovo_ms7195_rca_automute(codec);
 7915}
 7916
 7917static struct hda_verb alc883_medion_md2_verbs[] = {
 7918        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 7919        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 7920
 7921        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 7922
 7923        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 7924        { } /* end */
 7925};
 7926
 7927/* toggle speaker-output according to the hp-jack state */
 7928static void alc883_medion_md2_automute(struct hda_codec *codec)
 7929{
 7930         unsigned int present;
 7931
 7932         present = snd_hda_codec_read(codec, 0x14, 0,
 7933                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7934        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 7935                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7936}
 7937
 7938static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
 7939                                          unsigned int res)
 7940{
 7941        if ((res >> 26) == ALC880_HP_EVENT)
 7942                alc883_medion_md2_automute(codec);
 7943}
 7944
 7945/* toggle speaker-output according to the hp-jack state */
 7946static void alc883_tagra_automute(struct hda_codec *codec)
 7947{
 7948         unsigned int present;
 7949        unsigned char bits;
 7950
 7951         present = snd_hda_codec_read(codec, 0x14, 0,
 7952                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7953        bits = present ? HDA_AMP_MUTE : 0;
 7954        snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 7955                                 HDA_AMP_MUTE, bits);
 7956        snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
 7957                                  present ? 1 : 3);
 7958}
 7959
 7960static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
 7961{
 7962        if ((res >> 26) == ALC880_HP_EVENT)
 7963                alc883_tagra_automute(codec);
 7964}
 7965
 7966/* toggle speaker-output according to the hp-jack state */
 7967static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
 7968{
 7969        unsigned int present;
 7970        unsigned char bits;
 7971
 7972        present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
 7973                & AC_PINSENSE_PRESENCE;
 7974        bits = present ? HDA_AMP_MUTE : 0;
 7975        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 7976                                 HDA_AMP_MUTE, bits);
 7977}
 7978
 7979static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
 7980{
 7981        unsigned int present;
 7982
 7983        present = snd_hda_codec_read(codec, 0x18, 0,
 7984                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 7985        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
 7986                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 7987}
 7988
 7989static void alc883_clevo_m720_automute(struct hda_codec *codec)
 7990{
 7991        alc883_clevo_m720_hp_automute(codec);
 7992        alc883_clevo_m720_mic_automute(codec);
 7993}
 7994
 7995static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
 7996                                           unsigned int res)
 7997{
 7998        switch (res >> 26) {
 7999        case ALC880_HP_EVENT:
 8000                alc883_clevo_m720_hp_automute(codec);
 8001                break;
 8002        case ALC880_MIC_EVENT:
 8003                alc883_clevo_m720_mic_automute(codec);
 8004                break;
 8005        }
 8006}
 8007
 8008/* toggle speaker-output according to the hp-jack state */
 8009static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
 8010{
 8011         unsigned int present;
 8012        unsigned char bits;
 8013
 8014         present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
 8015                & AC_PINSENSE_PRESENCE;
 8016        bits = present ? HDA_AMP_MUTE : 0;
 8017        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8018                                 HDA_AMP_MUTE, bits);
 8019}
 8020
 8021static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
 8022                                                  unsigned int res)
 8023{
 8024        if ((res >> 26) == ALC880_HP_EVENT)
 8025                alc883_2ch_fujitsu_pi2515_automute(codec);
 8026}
 8027
 8028static void alc883_haier_w66_automute(struct hda_codec *codec)
 8029{
 8030        unsigned int present;
 8031        unsigned char bits;
 8032
 8033        present = snd_hda_codec_read(codec, 0x1b, 0,
 8034                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8035        bits = present ? 0x80 : 0;
 8036        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 8037                                 0x80, bits);
 8038}
 8039
 8040static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
 8041                                         unsigned int res)
 8042{
 8043        if ((res >> 26) == ALC880_HP_EVENT)
 8044                alc883_haier_w66_automute(codec);
 8045}
 8046
 8047static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
 8048{
 8049         unsigned int present;
 8050        unsigned char bits;
 8051
 8052         present = snd_hda_codec_read(codec, 0x14, 0,
 8053                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8054        bits = present ? HDA_AMP_MUTE : 0;
 8055        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8056                                 HDA_AMP_MUTE, bits);
 8057}
 8058
 8059static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
 8060{
 8061         unsigned int present;
 8062        unsigned char bits;
 8063
 8064         present = snd_hda_codec_read(codec, 0x1b, 0,
 8065                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8066        bits = present ? HDA_AMP_MUTE : 0;
 8067        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8068                                 HDA_AMP_MUTE, bits);
 8069        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 8070                                 HDA_AMP_MUTE, bits);
 8071}
 8072
 8073static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
 8074                                           unsigned int res)
 8075{
 8076        if ((res >> 26) == ALC880_HP_EVENT)
 8077                alc883_lenovo_101e_all_automute(codec);
 8078        if ((res >> 26) == ALC880_FRONT_EVENT)
 8079                alc883_lenovo_101e_ispeaker_automute(codec);
 8080}
 8081
 8082/* toggle speaker-output according to the hp-jack state */
 8083static void alc883_acer_aspire_automute(struct hda_codec *codec)
 8084{
 8085         unsigned int present;
 8086
 8087         present = snd_hda_codec_read(codec, 0x14, 0,
 8088                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8089        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8090                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8091        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 8092                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8093}
 8094
 8095static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
 8096                                           unsigned int res)
 8097{
 8098        if ((res >> 26) == ALC880_HP_EVENT)
 8099                alc883_acer_aspire_automute(codec);
 8100}
 8101
 8102static struct hda_verb alc883_acer_eapd_verbs[] = {
 8103        /* HP Pin: output 0 (0x0c) */
 8104        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 8105        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 8106        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 8107        /* Front Pin: output 0 (0x0c) */
 8108        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 8109        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 8110        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 8111        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
 8112        /* eanable EAPD on medion laptop */
 8113        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 8114        {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
 8115        /* enable unsolicited event */
 8116        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 8117        { }
 8118};
 8119
 8120static void alc888_6st_dell_front_automute(struct hda_codec *codec)
 8121{
 8122         unsigned int present;
 8123
 8124         present = snd_hda_codec_read(codec, 0x1b, 0,
 8125                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8126        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 8127                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8128        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8129                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8130        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 8131                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8132        snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
 8133                                HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
 8134}
 8135
 8136static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
 8137                                             unsigned int res)
 8138{
 8139        switch (res >> 26) {
 8140        case ALC880_HP_EVENT:
 8141                printk("hp_event\n");
 8142                alc888_6st_dell_front_automute(codec);
 8143                break;
 8144        }
 8145}
 8146
 8147static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
 8148{
 8149        unsigned int mute;
 8150        unsigned int present;
 8151
 8152        snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
 8153        present = snd_hda_codec_read(codec, 0x1b, 0,
 8154                                     AC_VERB_GET_PIN_SENSE, 0);
 8155        present = (present & 0x80000000) != 0;
 8156        if (present) {
 8157                /* mute internal speaker */
 8158                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 8159                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 8160                snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8161                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 8162                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 8163                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 8164                snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
 8165                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 8166                snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
 8167                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 8168        } else {
 8169                /* unmute internal speaker if necessary */
 8170                mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
 8171                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 8172                                         HDA_AMP_MUTE, mute);
 8173                snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 8174                                         HDA_AMP_MUTE, mute);
 8175                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 8176                                         HDA_AMP_MUTE, mute);
 8177                snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
 8178                                         HDA_AMP_MUTE, mute);
 8179                snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
 8180                                         HDA_AMP_MUTE, mute);
 8181        }
 8182}
 8183
 8184static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
 8185                                             unsigned int res)
 8186{
 8187        if ((res >> 26) == ALC880_HP_EVENT)
 8188                alc888_lenovo_sky_front_automute(codec);
 8189}
 8190
 8191/*
 8192 * generic initialization of ADC, input mixers and output mixers
 8193 */
 8194static struct hda_verb alc883_auto_init_verbs[] = {
 8195        /*
 8196         * Unmute ADC0-2 and set the default input to mic-in
 8197         */
 8198        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 8199        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8200        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 8201        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8202
 8203        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 8204         * mixer widget
 8205         * Note: PASD motherboards uses the Line In 2 as the input for
 8206         * front panel mic (mic 2)
 8207         */
 8208        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 8209        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 8210        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 8211        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 8212        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 8213        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 8214
 8215        /*
 8216         * Set up output mixers (0x0c - 0x0f)
 8217         */
 8218        /* set vol=0 to output mixers */
 8219        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 8220        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 8221        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 8222        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 8223        /* set up input amps for analog loopback */
 8224        /* Amp Indices: DAC = 0, mixer = 1 */
 8225        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8226        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8227        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8228        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8229        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8230        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8231        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8232        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8233        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8234        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8235
 8236        /* FIXME: use matrix-type input source selection */
 8237        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 8238        /* Input mixer1 */
 8239        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8240        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8241        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 8242        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
 8243        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 8244        /* Input mixer2 */
 8245        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8246        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8247        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
 8248        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
 8249        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
 8250
 8251        { }
 8252};
 8253
 8254/* capture mixer elements */
 8255static struct snd_kcontrol_new alc883_capture_mixer[] = {
 8256        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 8257        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 8258        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
 8259        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
 8260        {
 8261                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 8262                /* The multiple "Capture Source" controls confuse alsamixer
 8263                 * So call somewhat different..
 8264                 */
 8265                /* .name = "Capture Source", */
 8266                .name = "Input Source",
 8267                .count = 2,
 8268                .info = alc882_mux_enum_info,
 8269                .get = alc882_mux_enum_get,
 8270                .put = alc882_mux_enum_put,
 8271        },
 8272        { } /* end */
 8273};
 8274
 8275static struct hda_verb alc888_asus_m90v_verbs[] = {
 8276        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 8277        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 8278        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 8279        /* enable unsolicited event */
 8280        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 8281        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
 8282        { } /* end */
 8283};
 8284
 8285static void alc883_nb_mic_automute(struct hda_codec *codec)
 8286{
 8287        unsigned int present;
 8288
 8289        present = snd_hda_codec_read(codec, 0x18, 0,
 8290                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 8291        snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 8292                            0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
 8293        snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 8294                            0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
 8295}
 8296
 8297static void alc883_M90V_speaker_automute(struct hda_codec *codec)
 8298{
 8299        unsigned int present;
 8300        unsigned char bits;
 8301
 8302        present = snd_hda_codec_read(codec, 0x1b, 0,
 8303                                     AC_VERB_GET_PIN_SENSE, 0)
 8304                & AC_PINSENSE_PRESENCE;
 8305        bits = present ? 0 : PIN_OUT;
 8306        snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 8307                            bits);
 8308        snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 8309                            bits);
 8310        snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 8311                            bits);
 8312}
 8313
 8314static void alc883_mode2_unsol_event(struct hda_codec *codec,
 8315                                           unsigned int res)
 8316{
 8317        switch (res >> 26) {
 8318        case ALC880_HP_EVENT:
 8319                alc883_M90V_speaker_automute(codec);
 8320                break;
 8321        case ALC880_MIC_EVENT:
 8322                alc883_nb_mic_automute(codec);
 8323                break;
 8324        }
 8325}
 8326
 8327static void alc883_mode2_inithook(struct hda_codec *codec)
 8328{
 8329        alc883_M90V_speaker_automute(codec);
 8330        alc883_nb_mic_automute(codec);
 8331}
 8332
 8333static struct hda_verb alc888_asus_eee1601_verbs[] = {
 8334        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 8335        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 8336        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 8337        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 8338        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 8339        {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
 8340        {0x20, AC_VERB_SET_PROC_COEF,  0x0838},
 8341        /* enable unsolicited event */
 8342        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 8343        { } /* end */
 8344};
 8345
 8346static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
 8347{
 8348        unsigned int present;
 8349        unsigned char bits;
 8350
 8351        present = snd_hda_codec_read(codec, 0x14, 0,
 8352                                     AC_VERB_GET_PIN_SENSE, 0)
 8353                & AC_PINSENSE_PRESENCE;
 8354        bits = present ? 0 : PIN_OUT;
 8355        snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 8356                            bits);
 8357}
 8358
 8359static void alc883_eee1601_unsol_event(struct hda_codec *codec,
 8360                                           unsigned int res)
 8361{
 8362        switch (res >> 26) {
 8363        case ALC880_HP_EVENT:
 8364                alc883_eee1601_speaker_automute(codec);
 8365                break;
 8366        }
 8367}
 8368
 8369static void alc883_eee1601_inithook(struct hda_codec *codec)
 8370{
 8371        alc883_eee1601_speaker_automute(codec);
 8372}
 8373
 8374#ifdef CONFIG_SND_HDA_POWER_SAVE
 8375#define alc883_loopbacks        alc880_loopbacks
 8376#endif
 8377
 8378/* pcm configuration: identiacal with ALC880 */
 8379#define alc883_pcm_analog_playback        alc880_pcm_analog_playback
 8380#define alc883_pcm_analog_capture        alc880_pcm_analog_capture
 8381#define alc883_pcm_analog_alt_capture        alc880_pcm_analog_alt_capture
 8382#define alc883_pcm_digital_playback        alc880_pcm_digital_playback
 8383#define alc883_pcm_digital_capture        alc880_pcm_digital_capture
 8384
 8385/*
 8386 * configuration and preset
 8387 */
 8388static const char *alc883_models[ALC883_MODEL_LAST] = {
 8389        [ALC883_3ST_2ch_DIG]        = "3stack-dig",
 8390        [ALC883_3ST_6ch_DIG]        = "3stack-6ch-dig",
 8391        [ALC883_3ST_6ch]        = "3stack-6ch",
 8392        [ALC883_6ST_DIG]        = "6stack-dig",
 8393        [ALC883_TARGA_DIG]        = "targa-dig",
 8394        [ALC883_TARGA_2ch_DIG]        = "targa-2ch-dig",
 8395        [ALC883_ACER]                = "acer",
 8396        [ALC883_ACER_ASPIRE]        = "acer-aspire",
 8397        [ALC883_MEDION]                = "medion",
 8398        [ALC883_MEDION_MD2]        = "medion-md2",
 8399        [ALC883_LAPTOP_EAPD]        = "laptop-eapd",
 8400        [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
 8401        [ALC883_LENOVO_NB0763]        = "lenovo-nb0763",
 8402        [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
 8403        [ALC888_LENOVO_SKY] = "lenovo-sky",
 8404        [ALC883_HAIER_W66]         = "haier-w66",
 8405        [ALC888_3ST_HP]                = "3stack-hp",
 8406        [ALC888_6ST_DELL]        = "6stack-dell",
 8407        [ALC883_MITAC]                = "mitac",
 8408        [ALC883_CLEVO_M720]        = "clevo-m720",
 8409        [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
 8410        [ALC883_3ST_6ch_INTEL]        = "3stack-6ch-intel",
 8411        [ALC883_AUTO]                = "auto",
 8412};
 8413
 8414static struct snd_pci_quirk alc883_cfg_tbl[] = {
 8415        SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
 8416        SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
 8417        SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
 8418        SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
 8419        SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
 8420        SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
 8421        SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
 8422        SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
 8423        SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
 8424        SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
 8425        SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
 8426        SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
 8427        SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
 8428        SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
 8429        SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
 8430        SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
 8431        SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
 8432        SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
 8433        SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
 8434        SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
 8435        SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
 8436        SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
 8437        SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
 8438        SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
 8439        SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
 8440        SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
 8441        SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
 8442        SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
 8443        SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
 8444        SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
 8445        SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
 8446        SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
 8447        SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
 8448        SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
 8449        SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
 8450        SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
 8451        SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
 8452        SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
 8453        SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
 8454        SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
 8455        SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
 8456        SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
 8457        SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
 8458        SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
 8459        SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
 8460        SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
 8461        SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
 8462        SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
 8463        SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
 8464        SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
 8465        SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
 8466        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
 8467        SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
 8468        SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
 8469        SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
 8470        SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
 8471        SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
 8472        SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
 8473        SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
 8474        SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
 8475        SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
 8476        SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
 8477        SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
 8478        {}
 8479};
 8480
 8481static struct alc_config_preset alc883_presets[] = {
 8482        [ALC883_3ST_2ch_DIG] = {
 8483                .mixers = { alc883_3ST_2ch_mixer },
 8484                .init_verbs = { alc883_init_verbs },
 8485                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8486                .dac_nids = alc883_dac_nids,
 8487                .dig_out_nid = ALC883_DIGOUT_NID,
 8488                .dig_in_nid = ALC883_DIGIN_NID,
 8489                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8490                .channel_mode = alc883_3ST_2ch_modes,
 8491                .input_mux = &alc883_capture_source,
 8492        },
 8493        [ALC883_3ST_6ch_DIG] = {
 8494                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 8495                .init_verbs = { alc883_init_verbs },
 8496                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8497                .dac_nids = alc883_dac_nids,
 8498                .dig_out_nid = ALC883_DIGOUT_NID,
 8499                .dig_in_nid = ALC883_DIGIN_NID,
 8500                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
 8501                .channel_mode = alc883_3ST_6ch_modes,
 8502                .need_dac_fix = 1,
 8503                .input_mux = &alc883_capture_source,
 8504        },
 8505        [ALC883_3ST_6ch] = {
 8506                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 8507                .init_verbs = { alc883_init_verbs },
 8508                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8509                .dac_nids = alc883_dac_nids,
 8510                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
 8511                .channel_mode = alc883_3ST_6ch_modes,
 8512                .need_dac_fix = 1,
 8513                .input_mux = &alc883_capture_source,
 8514        },
 8515        [ALC883_3ST_6ch_INTEL] = {
 8516                .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
 8517                .init_verbs = { alc883_init_verbs },
 8518                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8519                .dac_nids = alc883_dac_nids,
 8520                .dig_out_nid = ALC883_DIGOUT_NID,
 8521                .dig_in_nid = ALC883_DIGIN_NID,
 8522                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
 8523                .channel_mode = alc883_3ST_6ch_intel_modes,
 8524                .need_dac_fix = 1,
 8525                .input_mux = &alc883_3stack_6ch_intel,
 8526        },
 8527        [ALC883_6ST_DIG] = {
 8528                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
 8529                .init_verbs = { alc883_init_verbs },
 8530                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8531                .dac_nids = alc883_dac_nids,
 8532                .dig_out_nid = ALC883_DIGOUT_NID,
 8533                .dig_in_nid = ALC883_DIGIN_NID,
 8534                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
 8535                .channel_mode = alc883_sixstack_modes,
 8536                .input_mux = &alc883_capture_source,
 8537        },
 8538        [ALC883_TARGA_DIG] = {
 8539                .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
 8540                .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
 8541                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8542                .dac_nids = alc883_dac_nids,
 8543                .dig_out_nid = ALC883_DIGOUT_NID,
 8544                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
 8545                .channel_mode = alc883_3ST_6ch_modes,
 8546                .need_dac_fix = 1,
 8547                .input_mux = &alc883_capture_source,
 8548                .unsol_event = alc883_tagra_unsol_event,
 8549                .init_hook = alc883_tagra_automute,
 8550        },
 8551        [ALC883_TARGA_2ch_DIG] = {
 8552                .mixers = { alc883_tagra_2ch_mixer},
 8553                .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
 8554                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8555                .dac_nids = alc883_dac_nids,
 8556                .dig_out_nid = ALC883_DIGOUT_NID,
 8557                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8558                .channel_mode = alc883_3ST_2ch_modes,
 8559                .input_mux = &alc883_capture_source,
 8560                .unsol_event = alc883_tagra_unsol_event,
 8561                .init_hook = alc883_tagra_automute,
 8562        },
 8563        [ALC883_ACER] = {
 8564                .mixers = { alc883_base_mixer },
 8565                /* On TravelMate laptops, GPIO 0 enables the internal speaker
 8566                 * and the headphone jack.  Turn this on and rely on the
 8567                 * standard mute methods whenever the user wants to turn
 8568                 * these outputs off.
 8569                 */
 8570                .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
 8571                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8572                .dac_nids = alc883_dac_nids,
 8573                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8574                .channel_mode = alc883_3ST_2ch_modes,
 8575                .input_mux = &alc883_capture_source,
 8576        },
 8577        [ALC883_ACER_ASPIRE] = {
 8578                .mixers = { alc883_acer_aspire_mixer },
 8579                .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
 8580                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8581                .dac_nids = alc883_dac_nids,
 8582                .dig_out_nid = ALC883_DIGOUT_NID,
 8583                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8584                .channel_mode = alc883_3ST_2ch_modes,
 8585                .input_mux = &alc883_capture_source,
 8586                .unsol_event = alc883_acer_aspire_unsol_event,
 8587                .init_hook = alc883_acer_aspire_automute,
 8588        },
 8589        [ALC883_MEDION] = {
 8590                .mixers = { alc883_fivestack_mixer,
 8591                            alc883_chmode_mixer },
 8592                .init_verbs = { alc883_init_verbs,
 8593                                alc883_medion_eapd_verbs },
 8594                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8595                .dac_nids = alc883_dac_nids,
 8596                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
 8597                .channel_mode = alc883_sixstack_modes,
 8598                .input_mux = &alc883_capture_source,
 8599        },
 8600        [ALC883_MEDION_MD2] = {
 8601                .mixers = { alc883_medion_md2_mixer},
 8602                .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
 8603                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8604                .dac_nids = alc883_dac_nids,
 8605                .dig_out_nid = ALC883_DIGOUT_NID,
 8606                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8607                .channel_mode = alc883_3ST_2ch_modes,
 8608                .input_mux = &alc883_capture_source,
 8609                .unsol_event = alc883_medion_md2_unsol_event,
 8610                .init_hook = alc883_medion_md2_automute,
 8611        },
 8612        [ALC883_LAPTOP_EAPD] = {
 8613                .mixers = { alc883_base_mixer },
 8614                .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
 8615                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8616                .dac_nids = alc883_dac_nids,
 8617                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8618                .channel_mode = alc883_3ST_2ch_modes,
 8619                .input_mux = &alc883_capture_source,
 8620        },
 8621        [ALC883_CLEVO_M720] = {
 8622                .mixers = { alc883_clevo_m720_mixer },
 8623                .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
 8624                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8625                .dac_nids = alc883_dac_nids,
 8626                .dig_out_nid = ALC883_DIGOUT_NID,
 8627                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8628                .channel_mode = alc883_3ST_2ch_modes,
 8629                .input_mux = &alc883_capture_source,
 8630                .unsol_event = alc883_clevo_m720_unsol_event,
 8631                .init_hook = alc883_clevo_m720_automute,
 8632        },
 8633        [ALC883_LENOVO_101E_2ch] = {
 8634                .mixers = { alc883_lenovo_101e_2ch_mixer},
 8635                .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
 8636                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8637                .dac_nids = alc883_dac_nids,
 8638                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8639                .channel_mode = alc883_3ST_2ch_modes,
 8640                .input_mux = &alc883_lenovo_101e_capture_source,
 8641                .unsol_event = alc883_lenovo_101e_unsol_event,
 8642                .init_hook = alc883_lenovo_101e_all_automute,
 8643        },
 8644        [ALC883_LENOVO_NB0763] = {
 8645                .mixers = { alc883_lenovo_nb0763_mixer },
 8646                .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
 8647                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8648                .dac_nids = alc883_dac_nids,
 8649                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8650                .channel_mode = alc883_3ST_2ch_modes,
 8651                .need_dac_fix = 1,
 8652                .input_mux = &alc883_lenovo_nb0763_capture_source,
 8653                .unsol_event = alc883_medion_md2_unsol_event,
 8654                .init_hook = alc883_medion_md2_automute,
 8655        },
 8656        [ALC888_LENOVO_MS7195_DIG] = {
 8657                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 8658                .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
 8659                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8660                .dac_nids = alc883_dac_nids,
 8661                .dig_out_nid = ALC883_DIGOUT_NID,
 8662                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
 8663                .channel_mode = alc883_3ST_6ch_modes,
 8664                .need_dac_fix = 1,
 8665                .input_mux = &alc883_capture_source,
 8666                .unsol_event = alc883_lenovo_ms7195_unsol_event,
 8667                .init_hook = alc888_lenovo_ms7195_front_automute,
 8668        },
 8669        [ALC883_HAIER_W66] = {
 8670                .mixers = { alc883_tagra_2ch_mixer},
 8671                .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
 8672                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8673                .dac_nids = alc883_dac_nids,
 8674                .dig_out_nid = ALC883_DIGOUT_NID,
 8675                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8676                .channel_mode = alc883_3ST_2ch_modes,
 8677                .input_mux = &alc883_capture_source,
 8678                .unsol_event = alc883_haier_w66_unsol_event,
 8679                .init_hook = alc883_haier_w66_automute,
 8680        },
 8681        [ALC888_3ST_HP] = {
 8682                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 8683                .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
 8684                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8685                .dac_nids = alc883_dac_nids,
 8686                .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
 8687                .channel_mode = alc888_3st_hp_modes,
 8688                .need_dac_fix = 1,
 8689                .input_mux = &alc883_capture_source,
 8690        },
 8691        [ALC888_6ST_DELL] = {
 8692                .mixers = { alc883_base_mixer, alc883_chmode_mixer },
 8693                .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
 8694                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8695                .dac_nids = alc883_dac_nids,
 8696                .dig_out_nid = ALC883_DIGOUT_NID,
 8697                .dig_in_nid = ALC883_DIGIN_NID,
 8698                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
 8699                .channel_mode = alc883_sixstack_modes,
 8700                .input_mux = &alc883_capture_source,
 8701                .unsol_event = alc888_6st_dell_unsol_event,
 8702                .init_hook = alc888_6st_dell_front_automute,
 8703        },
 8704        [ALC883_MITAC] = {
 8705                .mixers = { alc883_mitac_mixer },
 8706                .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
 8707                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8708                .dac_nids = alc883_dac_nids,
 8709                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8710                .channel_mode = alc883_3ST_2ch_modes,
 8711                .input_mux = &alc883_capture_source,
 8712                .unsol_event = alc883_mitac_unsol_event,
 8713                .init_hook = alc883_mitac_automute,
 8714        },
 8715        [ALC883_FUJITSU_PI2515] = {
 8716                .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
 8717                .init_verbs = { alc883_init_verbs,
 8718                                alc883_2ch_fujitsu_pi2515_verbs},
 8719                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8720                .dac_nids = alc883_dac_nids,
 8721                .dig_out_nid = ALC883_DIGOUT_NID,
 8722                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8723                .channel_mode = alc883_3ST_2ch_modes,
 8724                .input_mux = &alc883_fujitsu_pi2515_capture_source,
 8725                .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
 8726                .init_hook = alc883_2ch_fujitsu_pi2515_automute,
 8727        },
 8728        [ALC888_LENOVO_SKY] = {
 8729                .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
 8730                .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
 8731                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8732                .dac_nids = alc883_dac_nids,
 8733                .dig_out_nid = ALC883_DIGOUT_NID,
 8734                .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
 8735                .adc_nids = alc883_adc_nids,
 8736                .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
 8737                .channel_mode = alc883_sixstack_modes,
 8738                .need_dac_fix = 1,
 8739                .input_mux = &alc883_lenovo_sky_capture_source,
 8740                .unsol_event = alc883_lenovo_sky_unsol_event,
 8741                .init_hook = alc888_lenovo_sky_front_automute,
 8742        },
 8743        [ALC888_ASUS_M90V] = {
 8744                .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
 8745                .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
 8746                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8747                .dac_nids = alc883_dac_nids,
 8748                .dig_out_nid = ALC883_DIGOUT_NID,
 8749                .dig_in_nid = ALC883_DIGIN_NID,
 8750                .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
 8751                .channel_mode = alc883_3ST_6ch_modes,
 8752                .need_dac_fix = 1,
 8753                .input_mux = &alc883_fujitsu_pi2515_capture_source,
 8754                .unsol_event = alc883_mode2_unsol_event,
 8755                .init_hook = alc883_mode2_inithook,
 8756        },
 8757        [ALC888_ASUS_EEE1601] = {
 8758                .mixers = { alc883_asus_eee1601_mixer },
 8759                .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
 8760                .num_dacs = ARRAY_SIZE(alc883_dac_nids),
 8761                .dac_nids = alc883_dac_nids,
 8762                .dig_out_nid = ALC883_DIGOUT_NID,
 8763                .dig_in_nid = ALC883_DIGIN_NID,
 8764                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
 8765                .channel_mode = alc883_3ST_2ch_modes,
 8766                .need_dac_fix = 1,
 8767                .input_mux = &alc883_asus_eee1601_capture_source,
 8768                .unsol_event = alc883_eee1601_unsol_event,
 8769                .init_hook = alc883_eee1601_inithook,
 8770        },
 8771};
 8772
 8773
 8774/*
 8775 * BIOS auto configuration
 8776 */
 8777static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
 8778                                              hda_nid_t nid, int pin_type,
 8779                                              int dac_idx)
 8780{
 8781        /* set as output */
 8782        struct alc_spec *spec = codec->spec;
 8783        int idx;
 8784
 8785        alc_set_pin_output(codec, nid, pin_type);
 8786        if (spec->multiout.dac_nids[dac_idx] == 0x25)
 8787                idx = 4;
 8788        else
 8789                idx = spec->multiout.dac_nids[dac_idx] - 2;
 8790        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
 8791
 8792}
 8793
 8794static void alc883_auto_init_multi_out(struct hda_codec *codec)
 8795{
 8796        struct alc_spec *spec = codec->spec;
 8797        int i;
 8798
 8799        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
 8800        for (i = 0; i <= HDA_SIDE; i++) {
 8801                hda_nid_t nid = spec->autocfg.line_out_pins[i];
 8802                int pin_type = get_pin_type(spec->autocfg.line_out_type);
 8803                if (nid)
 8804                        alc883_auto_set_output_and_unmute(codec, nid, pin_type,
 8805                                                          i);
 8806        }
 8807}
 8808
 8809static void alc883_auto_init_hp_out(struct hda_codec *codec)
 8810{
 8811        struct alc_spec *spec = codec->spec;
 8812        hda_nid_t pin;
 8813
 8814        pin = spec->autocfg.hp_pins[0];
 8815        if (pin) /* connect to front */
 8816                /* use dac 0 */
 8817                alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 8818        pin = spec->autocfg.speaker_pins[0];
 8819        if (pin)
 8820                alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 8821}
 8822
 8823#define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
 8824#define ALC883_PIN_CD_NID                ALC880_PIN_CD_NID
 8825
 8826static void alc883_auto_init_analog_input(struct hda_codec *codec)
 8827{
 8828        struct alc_spec *spec = codec->spec;
 8829        int i;
 8830
 8831        for (i = 0; i < AUTO_PIN_LAST; i++) {
 8832                hda_nid_t nid = spec->autocfg.input_pins[i];
 8833                if (alc883_is_input_pin(nid)) {
 8834                        snd_hda_codec_write(codec, nid, 0,
 8835                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
 8836                                            (i <= AUTO_PIN_FRONT_MIC ?
 8837                                             PIN_VREF80 : PIN_IN));
 8838                        if (nid != ALC883_PIN_CD_NID)
 8839                                snd_hda_codec_write(codec, nid, 0,
 8840                                                    AC_VERB_SET_AMP_GAIN_MUTE,
 8841                                                    AMP_OUT_MUTE);
 8842                }
 8843        }
 8844}
 8845
 8846#define alc883_auto_init_input_src        alc882_auto_init_input_src
 8847
 8848/* almost identical with ALC880 parser... */
 8849static int alc883_parse_auto_config(struct hda_codec *codec)
 8850{
 8851        struct alc_spec *spec = codec->spec;
 8852        int err = alc880_parse_auto_config(codec);
 8853
 8854        if (err < 0)
 8855                return err;
 8856        else if (!err)
 8857                return 0; /* no config found */
 8858
 8859        err = alc_auto_add_mic_boost(codec);
 8860        if (err < 0)
 8861                return err;
 8862
 8863        /* hack - override the init verbs */
 8864        spec->init_verbs[0] = alc883_auto_init_verbs;
 8865        spec->mixers[spec->num_mixers] = alc883_capture_mixer;
 8866        spec->num_mixers++;
 8867
 8868        return 1; /* config found */
 8869}
 8870
 8871/* additional initialization for auto-configuration model */
 8872static void alc883_auto_init(struct hda_codec *codec)
 8873{
 8874        struct alc_spec *spec = codec->spec;
 8875        alc883_auto_init_multi_out(codec);
 8876        alc883_auto_init_hp_out(codec);
 8877        alc883_auto_init_analog_input(codec);
 8878        alc883_auto_init_input_src(codec);
 8879        if (spec->unsol_event)
 8880                alc_inithook(codec);
 8881}
 8882
 8883static int patch_alc883(struct hda_codec *codec)
 8884{
 8885        struct alc_spec *spec;
 8886        int err, board_config;
 8887
 8888        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 8889        if (spec == NULL)
 8890                return -ENOMEM;
 8891
 8892        codec->spec = spec;
 8893
 8894        alc_fix_pll_init(codec, 0x20, 0x0a, 10);
 8895
 8896        board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
 8897                                                  alc883_models,
 8898                                                  alc883_cfg_tbl);
 8899        if (board_config < 0) {
 8900                printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
 8901                       "trying auto-probe from BIOS...\n");
 8902                board_config = ALC883_AUTO;
 8903        }
 8904
 8905        if (board_config == ALC883_AUTO) {
 8906                /* automatic parse from the BIOS config */
 8907                err = alc883_parse_auto_config(codec);
 8908                if (err < 0) {
 8909                        alc_free(codec);
 8910                        return err;
 8911                } else if (!err) {
 8912                        printk(KERN_INFO
 8913                               "hda_codec: Cannot set up configuration "
 8914                               "from BIOS.  Using base mode...\n");
 8915                        board_config = ALC883_3ST_2ch_DIG;
 8916                }
 8917        }
 8918
 8919        if (board_config != ALC883_AUTO)
 8920                setup_preset(spec, &alc883_presets[board_config]);
 8921
 8922        switch (codec->vendor_id) {
 8923        case 0x10ec0888:
 8924                if (codec->revision_id == 0x100101) {
 8925                        spec->stream_name_analog = "ALC1200 Analog";
 8926                        spec->stream_name_digital = "ALC1200 Digital";
 8927                } else {
 8928                        spec->stream_name_analog = "ALC888 Analog";
 8929                        spec->stream_name_digital = "ALC888 Digital";
 8930                }
 8931                break;
 8932        case 0x10ec0889:
 8933                spec->stream_name_analog = "ALC889 Analog";
 8934                spec->stream_name_digital = "ALC889 Digital";
 8935                break;
 8936        default:
 8937                spec->stream_name_analog = "ALC883 Analog";
 8938                spec->stream_name_digital = "ALC883 Digital";
 8939                break;
 8940        }
 8941
 8942        spec->stream_analog_playback = &alc883_pcm_analog_playback;
 8943        spec->stream_analog_capture = &alc883_pcm_analog_capture;
 8944        spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
 8945
 8946        spec->stream_digital_playback = &alc883_pcm_digital_playback;
 8947        spec->stream_digital_capture = &alc883_pcm_digital_capture;
 8948
 8949        spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
 8950        spec->adc_nids = alc883_adc_nids;
 8951        spec->capsrc_nids = alc883_capsrc_nids;
 8952
 8953        spec->vmaster_nid = 0x0c;
 8954
 8955        codec->patch_ops = alc_patch_ops;
 8956        if (board_config == ALC883_AUTO)
 8957                spec->init_hook = alc883_auto_init;
 8958
 8959#ifdef CONFIG_SND_HDA_POWER_SAVE
 8960        if (!spec->loopback.amplist)
 8961                spec->loopback.amplist = alc883_loopbacks;
 8962#endif
 8963
 8964        return 0;
 8965}
 8966
 8967/*
 8968 * ALC262 support
 8969 */
 8970
 8971#define ALC262_DIGOUT_NID        ALC880_DIGOUT_NID
 8972#define ALC262_DIGIN_NID        ALC880_DIGIN_NID
 8973
 8974#define alc262_dac_nids                alc260_dac_nids
 8975#define alc262_adc_nids                alc882_adc_nids
 8976#define alc262_adc_nids_alt        alc882_adc_nids_alt
 8977#define alc262_capsrc_nids        alc882_capsrc_nids
 8978#define alc262_capsrc_nids_alt        alc882_capsrc_nids_alt
 8979
 8980#define alc262_modes                alc260_modes
 8981#define alc262_capture_source        alc882_capture_source
 8982
 8983static hda_nid_t alc262_dmic_adc_nids[1] = {
 8984        /* ADC0 */
 8985        0x09
 8986};
 8987
 8988static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
 8989
 8990static struct snd_kcontrol_new alc262_base_mixer[] = {
 8991        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 8992        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 8993        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 8994        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 8995        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 8996        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 8997        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 8998        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 8999        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9000        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9001        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9002        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 9003        /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
 9004           HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
 9005        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
 9006        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9007        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
 9008        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
 9009        { } /* end */
 9010};
 9011
 9012static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
 9013        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9014        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 9015        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 9016        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 9017        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 9018        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 9019        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9020        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9021        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9022        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9023        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9024        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 9025        /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
 9026           HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
 9027        /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
 9028        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 9029        { } /* end */
 9030};
 9031
 9032/* update HP, line and mono-out pins according to the master switch */
 9033static void alc262_hp_master_update(struct hda_codec *codec)
 9034{
 9035        struct alc_spec *spec = codec->spec;
 9036        int val = spec->master_sw;
 9037
 9038        /* HP & line-out */
 9039        snd_hda_codec_write_cache(codec, 0x1b, 0,
 9040                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
 9041                                  val ? PIN_HP : 0);
 9042        snd_hda_codec_write_cache(codec, 0x15, 0,
 9043                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
 9044                                  val ? PIN_HP : 0);
 9045        /* mono (speaker) depending on the HP jack sense */
 9046        val = val && !spec->jack_present;
 9047        snd_hda_codec_write_cache(codec, 0x16, 0,
 9048                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
 9049                                  val ? PIN_OUT : 0);
 9050}
 9051
 9052static void alc262_hp_bpc_automute(struct hda_codec *codec)
 9053{
 9054        struct alc_spec *spec = codec->spec;
 9055        unsigned int presence;
 9056        presence = snd_hda_codec_read(codec, 0x1b, 0,
 9057                                      AC_VERB_GET_PIN_SENSE, 0);
 9058        spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
 9059        alc262_hp_master_update(codec);
 9060}
 9061
 9062static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
 9063{
 9064        if ((res >> 26) != ALC880_HP_EVENT)
 9065                return;
 9066        alc262_hp_bpc_automute(codec);
 9067}
 9068
 9069static void alc262_hp_wildwest_automute(struct hda_codec *codec)
 9070{
 9071        struct alc_spec *spec = codec->spec;
 9072        unsigned int presence;
 9073        presence = snd_hda_codec_read(codec, 0x15, 0,
 9074                                      AC_VERB_GET_PIN_SENSE, 0);
 9075        spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
 9076        alc262_hp_master_update(codec);
 9077}
 9078
 9079static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
 9080                                           unsigned int res)
 9081{
 9082        if ((res >> 26) != ALC880_HP_EVENT)
 9083                return;
 9084        alc262_hp_wildwest_automute(codec);
 9085}
 9086
 9087static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
 9088                                   struct snd_ctl_elem_value *ucontrol)
 9089{
 9090        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9091        struct alc_spec *spec = codec->spec;
 9092        *ucontrol->value.integer.value = spec->master_sw;
 9093        return 0;
 9094}
 9095
 9096static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 9097                                   struct snd_ctl_elem_value *ucontrol)
 9098{
 9099        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9100        struct alc_spec *spec = codec->spec;
 9101        int val = !!*ucontrol->value.integer.value;
 9102
 9103        if (val == spec->master_sw)
 9104                return 0;
 9105        spec->master_sw = val;
 9106        alc262_hp_master_update(codec);
 9107        return 1;
 9108}
 9109
 9110static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
 9111        {
 9112                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9113                .name = "Master Playback Switch",
 9114                .info = snd_ctl_boolean_mono_info,
 9115                .get = alc262_hp_master_sw_get,
 9116                .put = alc262_hp_master_sw_put,
 9117        },
 9118        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9119        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9120        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 9121        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
 9122                              HDA_OUTPUT),
 9123        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
 9124                            HDA_OUTPUT),
 9125        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9126        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9127        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9128        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9129        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9130        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 9131        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 9132        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 9133        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 9134        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 9135        HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
 9136        HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
 9137        HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
 9138        HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
 9139        { } /* end */
 9140};
 9141
 9142static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
 9143        {
 9144                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9145                .name = "Master Playback Switch",
 9146                .info = snd_ctl_boolean_mono_info,
 9147                .get = alc262_hp_master_sw_get,
 9148                .put = alc262_hp_master_sw_put,
 9149        },
 9150        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9151        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 9152        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 9153        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9154        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
 9155                              HDA_OUTPUT),
 9156        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
 9157                            HDA_OUTPUT),
 9158        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
 9159        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
 9160        HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
 9161        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9162        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9163        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 9164        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 9165        HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
 9166        HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
 9167        { } /* end */
 9168};
 9169
 9170static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
 9171        HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9172        HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9173        HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
 9174        { } /* end */
 9175};
 9176
 9177/* mute/unmute internal speaker according to the hp jack and mute state */
 9178static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
 9179{
 9180        struct alc_spec *spec = codec->spec;
 9181
 9182        if (force || !spec->sense_updated) {
 9183                unsigned int present;
 9184                present = snd_hda_codec_read(codec, 0x15, 0,
 9185                                             AC_VERB_GET_PIN_SENSE, 0);
 9186                spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
 9187                spec->sense_updated = 1;
 9188        }
 9189        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 9190                                 spec->jack_present ? HDA_AMP_MUTE : 0);
 9191}
 9192
 9193static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
 9194                                        unsigned int res)
 9195{
 9196        if ((res >> 26) != ALC880_HP_EVENT)
 9197                return;
 9198        alc262_hp_t5735_automute(codec, 1);
 9199}
 9200
 9201static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
 9202{
 9203        alc262_hp_t5735_automute(codec, 1);
 9204}
 9205
 9206static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
 9207        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9208        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 9209        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 9210        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9211        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9212        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9213        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9214        { } /* end */
 9215};
 9216
 9217static struct hda_verb alc262_hp_t5735_verbs[] = {
 9218        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9219        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9220
 9221        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 9222        { }
 9223};
 9224
 9225static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
 9226        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9227        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 9228        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
 9229        HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
 9230        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9231        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9232        { } /* end */
 9233};
 9234
 9235static struct hda_verb alc262_hp_rp5700_verbs[] = {
 9236        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 9237        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 9238        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9239        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9240        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 9241        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 9242        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 9243        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
 9244        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
 9245        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
 9246        {}
 9247};
 9248
 9249static struct hda_input_mux alc262_hp_rp5700_capture_source = {
 9250        .num_items = 1,
 9251        .items = {
 9252                { "Line", 0x1 },
 9253        },
 9254};
 9255
 9256/* bind hp and internal speaker mute (with plug check) */
 9257static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
 9258                                     struct snd_ctl_elem_value *ucontrol)
 9259{
 9260        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9261        long *valp = ucontrol->value.integer.value;
 9262        int change;
 9263
 9264        /* change hp mute */
 9265        change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
 9266                                          HDA_AMP_MUTE,
 9267                                          valp[0] ? 0 : HDA_AMP_MUTE);
 9268        change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
 9269                                           HDA_AMP_MUTE,
 9270                                           valp[1] ? 0 : HDA_AMP_MUTE);
 9271        if (change) {
 9272                /* change speaker according to HP jack state */
 9273                struct alc_spec *spec = codec->spec;
 9274                unsigned int mute;
 9275                if (spec->jack_present)
 9276                        mute = HDA_AMP_MUTE;
 9277                else
 9278                        mute = snd_hda_codec_amp_read(codec, 0x15, 0,
 9279                                                      HDA_OUTPUT, 0);
 9280                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9281                                         HDA_AMP_MUTE, mute);
 9282        }
 9283        return change;
 9284}
 9285
 9286static struct snd_kcontrol_new alc262_sony_mixer[] = {
 9287        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9288        {
 9289                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9290                .name = "Master Playback Switch",
 9291                .info = snd_hda_mixer_amp_switch_info,
 9292                .get = snd_hda_mixer_amp_switch_get,
 9293                .put = alc262_sony_master_sw_put,
 9294                .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
 9295        },
 9296        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9297        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9298        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9299        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9300        { } /* end */
 9301};
 9302
 9303static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
 9304        HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9305        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 9306        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9307        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9308        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9309        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9310        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9311        { } /* end */
 9312};
 9313
 9314#define alc262_capture_mixer                alc882_capture_mixer
 9315#define alc262_capture_alt_mixer        alc882_capture_alt_mixer
 9316
 9317/*
 9318 * generic initialization of ADC, input mixers and output mixers
 9319 */
 9320static struct hda_verb alc262_init_verbs[] = {
 9321        /*
 9322         * Unmute ADC0-2 and set the default input to mic-in
 9323         */
 9324        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
 9325        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9326        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
 9327        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9328        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
 9329        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9330
 9331        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
 9332         * mixer widget
 9333         * Note: PASD motherboards uses the Line In 2 as the input for
 9334         * front panel mic (mic 2)
 9335         */
 9336        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
 9337        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 9338        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 9339        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 9340        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 9341        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 9342
 9343        /*
 9344         * Set up output mixers (0x0c - 0x0e)
 9345         */
 9346        /* set vol=0 to output mixers */
 9347        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 9348        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 9349        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 9350        /* set up input amps for analog loopback */
 9351        /* Amp Indices: DAC = 0, mixer = 1 */
 9352        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9353        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9354        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9355        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9356        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9357        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9358
 9359        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 9360        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
 9361        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
 9362        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 9363        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 9364        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
 9365
 9366        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9367        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9368        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9369        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9370        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9371
 9372        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 9373        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
 9374
 9375        /* FIXME: use matrix-type input source selection */
 9376        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
 9377        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
 9378        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 9379        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 9380        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 9381        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 9382        /* Input mixer2 */
 9383        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 9384        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 9385        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 9386        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 9387        /* Input mixer3 */
 9388        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
 9389        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
 9390        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
 9391        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
 9392
 9393        { }
 9394};
 9395
 9396static struct hda_verb alc262_eapd_verbs[] = {
 9397        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
 9398        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
 9399        { }
 9400};
 9401
 9402static struct hda_verb alc262_hippo_unsol_verbs[] = {
 9403        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9404        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9405        {}
 9406};
 9407
 9408static struct hda_verb alc262_hippo1_unsol_verbs[] = {
 9409        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
 9410        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
 9411        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
 9412
 9413        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9414        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9415        {}
 9416};
 9417
 9418static struct hda_verb alc262_sony_unsol_verbs[] = {
 9419        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
 9420        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 9421        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},        // Front Mic
 9422
 9423        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9424        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9425        {}
 9426};
 9427
 9428static struct hda_input_mux alc262_dmic_capture_source = {
 9429        .num_items = 2,
 9430        .items = {
 9431                { "Int DMic", 0x9 },
 9432                { "Mic", 0x0 },
 9433        },
 9434};
 9435
 9436static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
 9437        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9438        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
 9439        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9440        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9441        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9442        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
 9443        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
 9444        {
 9445                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9446                /* The multiple "Capture Source" controls confuse alsamixer
 9447                 * So call somewhat different..
 9448                 */
 9449                /* .name = "Capture Source", */
 9450                .name = "Input Source",
 9451                .count = 1,
 9452                .info = alc_mux_enum_info,
 9453                .get = alc_mux_enum_get,
 9454                .put = alc_mux_enum_put,
 9455        },
 9456        { } /* end */
 9457};
 9458
 9459static struct hda_verb alc262_toshiba_s06_verbs[] = {
 9460        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 9461        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9462        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9463        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 9464        {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
 9465        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 9466        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
 9467        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9468        {}
 9469};
 9470
 9471static void alc262_dmic_automute(struct hda_codec *codec)
 9472{
 9473        unsigned int present;
 9474
 9475        present = snd_hda_codec_read(codec, 0x18, 0,
 9476                                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 9477        snd_hda_codec_write(codec, 0x22, 0,
 9478                                AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
 9479}
 9480
 9481/* toggle speaker-output according to the hp-jack state */
 9482static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
 9483{
 9484        unsigned int present;
 9485        unsigned char bits;
 9486
 9487        present = snd_hda_codec_read(codec, 0x15, 0,
 9488                                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 9489        bits = present ? 0 : PIN_OUT;
 9490        snd_hda_codec_write(codec, 0x14, 0,
 9491                                        AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
 9492}
 9493
 9494
 9495
 9496/* unsolicited event for HP jack sensing */
 9497static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
 9498                                       unsigned int res)
 9499{
 9500        if ((res >> 26) == ALC880_HP_EVENT)
 9501                alc262_toshiba_s06_speaker_automute(codec);
 9502        if ((res >> 26) == ALC880_MIC_EVENT)
 9503                alc262_dmic_automute(codec);
 9504
 9505}
 9506
 9507static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
 9508{
 9509        alc262_toshiba_s06_speaker_automute(codec);
 9510        alc262_dmic_automute(codec);
 9511}
 9512
 9513/* mute/unmute internal speaker according to the hp jack and mute state */
 9514static void alc262_hippo_automute(struct hda_codec *codec)
 9515{
 9516        struct alc_spec *spec = codec->spec;
 9517        unsigned int mute;
 9518        unsigned int present;
 9519
 9520        /* need to execute and sync at first */
 9521        snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
 9522        present = snd_hda_codec_read(codec, 0x15, 0,
 9523                                     AC_VERB_GET_PIN_SENSE, 0);
 9524        spec->jack_present = (present & 0x80000000) != 0;
 9525        if (spec->jack_present) {
 9526                /* mute internal speaker */
 9527                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9528                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 9529        } else {
 9530                /* unmute internal speaker if necessary */
 9531                mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
 9532                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9533                                         HDA_AMP_MUTE, mute);
 9534        }
 9535}
 9536
 9537/* unsolicited event for HP jack sensing */
 9538static void alc262_hippo_unsol_event(struct hda_codec *codec,
 9539                                       unsigned int res)
 9540{
 9541        if ((res >> 26) != ALC880_HP_EVENT)
 9542                return;
 9543        alc262_hippo_automute(codec);
 9544}
 9545
 9546static void alc262_hippo1_automute(struct hda_codec *codec)
 9547{
 9548        unsigned int mute;
 9549        unsigned int present;
 9550
 9551        snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
 9552        present = snd_hda_codec_read(codec, 0x1b, 0,
 9553                                     AC_VERB_GET_PIN_SENSE, 0);
 9554        present = (present & 0x80000000) != 0;
 9555        if (present) {
 9556                /* mute internal speaker */
 9557                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9558                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 9559        } else {
 9560                /* unmute internal speaker if necessary */
 9561                mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
 9562                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9563                                         HDA_AMP_MUTE, mute);
 9564        }
 9565}
 9566
 9567/* unsolicited event for HP jack sensing */
 9568static void alc262_hippo1_unsol_event(struct hda_codec *codec,
 9569                                       unsigned int res)
 9570{
 9571        if ((res >> 26) != ALC880_HP_EVENT)
 9572                return;
 9573        alc262_hippo1_automute(codec);
 9574}
 9575
 9576/*
 9577 * nec model
 9578 *  0x15 = headphone
 9579 *  0x16 = internal speaker
 9580 *  0x18 = external mic
 9581 */
 9582
 9583static struct snd_kcontrol_new alc262_nec_mixer[] = {
 9584        HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
 9585        HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
 9586
 9587        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9588        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9589        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9590
 9591        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 9592        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 9593        { } /* end */
 9594};
 9595
 9596static struct hda_verb alc262_nec_verbs[] = {
 9597        /* Unmute Speaker */
 9598        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 9599
 9600        /* Headphone */
 9601        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9602        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9603
 9604        /* External mic to headphone */
 9605        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9606        /* External mic to speaker */
 9607        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9608        {}
 9609};
 9610
 9611/*
 9612 * fujitsu model
 9613 *  0x14 = headphone/spdif-out, 0x15 = internal speaker,
 9614 *  0x1b = port replicator headphone out
 9615 */
 9616
 9617#define ALC_HP_EVENT        0x37
 9618
 9619static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
 9620        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
 9621        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9622        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
 9623        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9624        {}
 9625};
 9626
 9627static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
 9628        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
 9629        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9630        {}
 9631};
 9632
 9633static struct hda_input_mux alc262_fujitsu_capture_source = {
 9634        .num_items = 3,
 9635        .items = {
 9636                { "Mic", 0x0 },
 9637                { "Int Mic", 0x1 },
 9638                { "CD", 0x4 },
 9639        },
 9640};
 9641
 9642static struct hda_input_mux alc262_HP_capture_source = {
 9643        .num_items = 5,
 9644        .items = {
 9645                { "Mic", 0x0 },
 9646                { "Front Mic", 0x1 },
 9647                { "Line", 0x2 },
 9648                { "CD", 0x4 },
 9649                { "AUX IN", 0x6 },
 9650        },
 9651};
 9652
 9653static struct hda_input_mux alc262_HP_D7000_capture_source = {
 9654        .num_items = 4,
 9655        .items = {
 9656                { "Mic", 0x0 },
 9657                { "Front Mic", 0x2 },
 9658                { "Line", 0x1 },
 9659                { "CD", 0x4 },
 9660        },
 9661};
 9662
 9663/* mute/unmute internal speaker according to the hp jacks and mute state */
 9664static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
 9665{
 9666        struct alc_spec *spec = codec->spec;
 9667        unsigned int mute;
 9668
 9669        if (force || !spec->sense_updated) {
 9670                unsigned int present;
 9671                /* need to execute and sync at first */
 9672                snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
 9673                /* check laptop HP jack */
 9674                present = snd_hda_codec_read(codec, 0x14, 0,
 9675                                             AC_VERB_GET_PIN_SENSE, 0);
 9676                /* need to execute and sync at first */
 9677                snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
 9678                /* check docking HP jack */
 9679                present |= snd_hda_codec_read(codec, 0x1b, 0,
 9680                                              AC_VERB_GET_PIN_SENSE, 0);
 9681                if (present & AC_PINSENSE_PRESENCE)
 9682                        spec->jack_present = 1;
 9683                else
 9684                        spec->jack_present = 0;
 9685                spec->sense_updated = 1;
 9686        }
 9687        /* unmute internal speaker only if both HPs are unplugged and
 9688         * master switch is on
 9689         */
 9690        if (spec->jack_present)
 9691                mute = HDA_AMP_MUTE;
 9692        else
 9693                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
 9694        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 9695                                 HDA_AMP_MUTE, mute);
 9696}
 9697
 9698/* unsolicited event for HP jack sensing */
 9699static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
 9700                                       unsigned int res)
 9701{
 9702        if ((res >> 26) != ALC_HP_EVENT)
 9703                return;
 9704        alc262_fujitsu_automute(codec, 1);
 9705}
 9706
 9707static void alc262_fujitsu_init_hook(struct hda_codec *codec)
 9708{
 9709        alc262_fujitsu_automute(codec, 1);
 9710}
 9711
 9712/* bind volumes of both NID 0x0c and 0x0d */
 9713static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
 9714        .ops = &snd_hda_bind_vol,
 9715        .values = {
 9716                HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
 9717                HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
 9718                0
 9719        },
 9720};
 9721
 9722/* mute/unmute internal speaker according to the hp jack and mute state */
 9723static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
 9724{
 9725        struct alc_spec *spec = codec->spec;
 9726        unsigned int mute;
 9727
 9728        if (force || !spec->sense_updated) {
 9729                unsigned int present_int_hp;
 9730                /* need to execute and sync at first */
 9731                snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
 9732                present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
 9733                                        AC_VERB_GET_PIN_SENSE, 0);
 9734                spec->jack_present = (present_int_hp & 0x80000000) != 0;
 9735                spec->sense_updated = 1;
 9736        }
 9737        if (spec->jack_present) {
 9738                /* mute internal speaker */
 9739                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9740                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 9741                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 9742                                         HDA_AMP_MUTE, HDA_AMP_MUTE);
 9743        } else {
 9744                /* unmute internal speaker if necessary */
 9745                mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
 9746                snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9747                                         HDA_AMP_MUTE, mute);
 9748                snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
 9749                                         HDA_AMP_MUTE, mute);
 9750        }
 9751}
 9752
 9753/* unsolicited event for HP jack sensing */
 9754static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
 9755                                       unsigned int res)
 9756{
 9757        if ((res >> 26) != ALC_HP_EVENT)
 9758                return;
 9759        alc262_lenovo_3000_automute(codec, 1);
 9760}
 9761
 9762/* bind hp and internal speaker mute (with plug check) */
 9763static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
 9764                                         struct snd_ctl_elem_value *ucontrol)
 9765{
 9766        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9767        long *valp = ucontrol->value.integer.value;
 9768        int change;
 9769
 9770        change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9771                                                 HDA_AMP_MUTE,
 9772                                                 valp ? 0 : HDA_AMP_MUTE);
 9773        change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 9774                                                 HDA_AMP_MUTE,
 9775                                                 valp ? 0 : HDA_AMP_MUTE);
 9776
 9777        if (change)
 9778                alc262_fujitsu_automute(codec, 0);
 9779        return change;
 9780}
 9781
 9782static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
 9783        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
 9784        {
 9785                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9786                .name = "Master Playback Switch",
 9787                .info = snd_hda_mixer_amp_switch_info,
 9788                .get = snd_hda_mixer_amp_switch_get,
 9789                .put = alc262_fujitsu_master_sw_put,
 9790                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
 9791        },
 9792        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 9793        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 9794        HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
 9795        HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
 9796        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9797        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9798        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9799        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
 9800        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 9801        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 9802        { } /* end */
 9803};
 9804
 9805/* bind hp and internal speaker mute (with plug check) */
 9806static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
 9807                                         struct snd_ctl_elem_value *ucontrol)
 9808{
 9809        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9810        long *valp = ucontrol->value.integer.value;
 9811        int change;
 9812
 9813        change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 9814                                                 HDA_AMP_MUTE,
 9815                                                 valp ? 0 : HDA_AMP_MUTE);
 9816
 9817        if (change)
 9818                alc262_lenovo_3000_automute(codec, 0);
 9819        return change;
 9820}
 9821
 9822static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
 9823        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
 9824        {
 9825                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9826                .name = "Master Playback Switch",
 9827                .info = snd_hda_mixer_amp_switch_info,
 9828                .get = snd_hda_mixer_amp_switch_get,
 9829                .put = alc262_lenovo_3000_master_sw_put,
 9830                .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
 9831        },
 9832        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
 9833        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
 9834        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9835        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9836        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9837        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
 9838        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
 9839        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
 9840        { } /* end */
 9841};
 9842
 9843static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
 9844        HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
 9845        {
 9846                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9847                .name = "Master Playback Switch",
 9848                .info = snd_hda_mixer_amp_switch_info,
 9849                .get = snd_hda_mixer_amp_switch_get,
 9850                .put = alc262_sony_master_sw_put,
 9851                .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
 9852        },
 9853        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
 9854        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
 9855        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
 9856        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9857        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9858        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
 9859        { } /* end */
 9860};
 9861
 9862/* additional init verbs for Benq laptops */
 9863static struct hda_verb alc262_EAPD_verbs[] = {
 9864        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 9865        {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
 9866        {}
 9867};
 9868
 9869static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
 9870        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 9871        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
 9872
 9873        {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
 9874        {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
 9875        {}
 9876};
 9877
 9878/* Samsung Q1 Ultra Vista model setup */
 9879static struct snd_kcontrol_new alc262_ultra_mixer[] = {
 9880        HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 9881        HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
 9882        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
 9883        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
 9884        HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
 9885        HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
 9886        { } /* end */
 9887};
 9888
 9889static struct hda_verb alc262_ultra_verbs[] = {
 9890        /* output mixer */
 9891        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 9892        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 9893        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 9894        /* speaker */
 9895        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 9896        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 9897        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9898        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
 9899        /* HP */
 9900        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 9901        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
 9902        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
 9903        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
 9904        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
 9905        /* internal mic */
 9906        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
 9907        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 9908        /* ADC, choose mic */
 9909        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 9910        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 9911        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
 9912        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 9913        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 9914        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 9915        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
 9916        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
 9917        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
 9918        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
 9919        {}
 9920};
 9921
 9922/* mute/unmute internal speaker according to the hp jack and mute state */
 9923static void alc262_ultra_automute(struct hda_codec *codec)
 9924{
 9925        struct alc_spec *spec = codec->spec;
 9926        unsigned int mute;
 9927
 9928        mute = 0;
 9929        /* auto-mute only when HP is used as HP */
 9930        if (!spec->cur_mux[0]) {
 9931                unsigned int present;
 9932                /* need to execute and sync at first */
 9933                snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
 9934                present = snd_hda_codec_read(codec, 0x15, 0,
 9935                                             AC_VERB_GET_PIN_SENSE, 0);
 9936                spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
 9937                if (spec->jack_present)
 9938                        mute = HDA_AMP_MUTE;
 9939        }
 9940        /* mute/unmute internal speaker */
 9941        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
 9942                                 HDA_AMP_MUTE, mute);
 9943        /* mute/unmute HP */
 9944        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
 9945                                 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
 9946}
 9947
 9948/* unsolicited event for HP jack sensing */
 9949static void alc262_ultra_unsol_event(struct hda_codec *codec,
 9950                                       unsigned int res)
 9951{
 9952        if ((res >> 26) != ALC880_HP_EVENT)
 9953                return;
 9954        alc262_ultra_automute(codec);
 9955}
 9956
 9957static struct hda_input_mux alc262_ultra_capture_source = {
 9958        .num_items = 2,
 9959        .items = {
 9960                { "Mic", 0x1 },
 9961                { "Headphone", 0x7 },
 9962        },
 9963};
 9964
 9965static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
 9966                                     struct snd_ctl_elem_value *ucontrol)
 9967{
 9968        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 9969        struct alc_spec *spec = codec->spec;
 9970        int ret;
 9971
 9972        ret = alc882_mux_enum_put(kcontrol, ucontrol);
 9973        if (!ret)
 9974                return 0;
 9975        /* reprogram the HP pin as mic or HP according to the input source */
 9976        snd_hda_codec_write_cache(codec, 0x15, 0,
 9977                                  AC_VERB_SET_PIN_WIDGET_CONTROL,
 9978                                  spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
 9979        alc262_ultra_automute(codec); /* mute/unmute HP */
 9980        return ret;
 9981}
 9982
 9983static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
 9984        HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
 9985        HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
 9986        {
 9987                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 9988                .name = "Capture Source",
 9989                .info = alc882_mux_enum_info,
 9990                .get = alc882_mux_enum_get,
 9991                .put = alc262_ultra_mux_enum_put,
 9992        },
 9993        { } /* end */
 9994};
 9995
 9996/* add playback controls from the parsed DAC table */
 9997static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
 9998                                             const struct auto_pin_cfg *cfg)
 9999{
10000        hda_nid_t nid;
10001        int err;
10002
10003        spec->multiout.num_dacs = 1;        /* only use one dac */
10004        spec->multiout.dac_nids = spec->private_dac_nids;
10005        spec->multiout.dac_nids[0] = 2;
10006
10007        nid = cfg->line_out_pins[0];
10008        if (nid) {
10009                err = add_control(spec, ALC_CTL_WIDGET_VOL,
10010                                  "Front Playback Volume",
10011                                  HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10012                if (err < 0)
10013                        return err;
10014                err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10015                                  "Front Playback Switch",
10016                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10017                if (err < 0)
10018                        return err;
10019        }
10020
10021        nid = cfg->speaker_pins[0];
10022        if (nid) {
10023                if (nid == 0x16) {
10024                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
10025                                          "Speaker Playback Volume",
10026                                          HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10027                                                              HDA_OUTPUT));
10028                        if (err < 0)
10029                                return err;
10030                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10031                                          "Speaker Playback Switch",
10032                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10033                                                              HDA_OUTPUT));
10034                        if (err < 0)
10035                                return err;
10036                } else {
10037                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10038                                          "Speaker Playback Switch",
10039                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10040                                                              HDA_OUTPUT));
10041                        if (err < 0)
10042                                return err;
10043                }
10044        }
10045        nid = cfg->hp_pins[0];
10046        if (nid) {
10047                /* spec->multiout.hp_nid = 2; */
10048                if (nid == 0x16) {
10049                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
10050                                          "Headphone Playback Volume",
10051                                          HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10052                                                              HDA_OUTPUT));
10053                        if (err < 0)
10054                                return err;
10055                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10056                                          "Headphone Playback Switch",
10057                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10058                                                              HDA_OUTPUT));
10059                        if (err < 0)
10060                                return err;
10061                } else {
10062                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10063                                          "Headphone Playback Switch",
10064                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10065                                                              HDA_OUTPUT));
10066                        if (err < 0)
10067                                return err;
10068                }
10069        }
10070        return 0;
10071}
10072
10073/* identical with ALC880 */
10074#define alc262_auto_create_analog_input_ctls \
10075        alc880_auto_create_analog_input_ctls
10076
10077/*
10078 * generic initialization of ADC, input mixers and output mixers
10079 */
10080static struct hda_verb alc262_volume_init_verbs[] = {
10081        /*
10082         * Unmute ADC0-2 and set the default input to mic-in
10083         */
10084        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10085        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10087        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10089        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10090
10091        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10092         * mixer widget
10093         * Note: PASD motherboards uses the Line In 2 as the input for
10094         * front panel mic (mic 2)
10095         */
10096        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10097        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10098        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10099        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10100        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10101        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10102
10103        /*
10104         * Set up output mixers (0x0c - 0x0f)
10105         */
10106        /* set vol=0 to output mixers */
10107        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10108        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10109        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10110
10111        /* set up input amps for analog loopback */
10112        /* Amp Indices: DAC = 0, mixer = 1 */
10113        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10114        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10115        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10116        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10117        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10118        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10119
10120        /* FIXME: use matrix-type input source selection */
10121        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10122        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10123        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10124        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10125        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10126        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10127        /* Input mixer2 */
10128        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10129        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10130        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10131        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10132        /* Input mixer3 */
10133        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10134        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10135        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10136        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10137
10138        { }
10139};
10140
10141static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10142        /*
10143         * Unmute ADC0-2 and set the default input to mic-in
10144         */
10145        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10146        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10148        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10150        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10151
10152        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10153         * mixer widget
10154         * Note: PASD motherboards uses the Line In 2 as the input for
10155         * front panel mic (mic 2)
10156         */
10157        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10158        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10159        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10160        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10161        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10162        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10163        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10164        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10165
10166        /*
10167         * Set up output mixers (0x0c - 0x0e)
10168         */
10169        /* set vol=0 to output mixers */
10170        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10171        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10172        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10173
10174        /* set up input amps for analog loopback */
10175        /* Amp Indices: DAC = 0, mixer = 1 */
10176        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10178        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10179        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10180        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10181        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10182
10183        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10184        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10185        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10186
10187        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10188        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10189
10190        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10191        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10192
10193        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10194        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10195        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10196        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10197        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10198
10199        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10200        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10201        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10202        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10203        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10204        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10205
10206
10207        /* FIXME: use matrix-type input source selection */
10208        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10209        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10210        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10211        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10212        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10213        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10214        /* Input mixer2 */
10215        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10216        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10217        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10218        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10219        /* Input mixer3 */
10220        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10221        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10222        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10223        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10224
10225        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10226
10227        { }
10228};
10229
10230static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10231        /*
10232         * Unmute ADC0-2 and set the default input to mic-in
10233         */
10234        {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10235        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10236        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10237        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10238        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10239        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10240
10241        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10242         * mixer widget
10243         * Note: PASD motherboards uses the Line In 2 as the input for front
10244         * panel mic (mic 2)
10245         */
10246        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10247        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10248        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10249        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10250        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10251        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10252        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10253        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10254        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10255        /*
10256         * Set up output mixers (0x0c - 0x0e)
10257         */
10258        /* set vol=0 to output mixers */
10259        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10260        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10261        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10262
10263        /* set up input amps for analog loopback */
10264        /* Amp Indices: DAC = 0, mixer = 1 */
10265        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10266        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10267        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10268        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10269        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10270        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10271
10272
10273        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
10274        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },        /* Mono */
10275        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },        /* rear MIC */
10276        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
10277        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },        /* Front MIC */
10278        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },        /* Line out */
10279        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
10280
10281        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10282        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10283
10284        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10285        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10286
10287        /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10288        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10289        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10290        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10291        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10292        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10293
10294        /* FIXME: use matrix-type input source selection */
10295        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10296        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10297        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10298        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10299        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10300        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10301        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10302        /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
10303        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10304        /* Input mixer2 */
10305        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10306        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10307        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10308        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10309        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10310        /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10311        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10312        /* Input mixer3 */
10313        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10314        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10315        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10316        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10317        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10318        /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10319        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10320
10321        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10322
10323        { }
10324};
10325
10326static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10327
10328        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },        /* Front Speaker */
10329        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10330        {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10331
10332        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },        /* MIC jack */
10333        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },        /* Front MIC */
10334        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10335        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10336
10337        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP  jack */
10338        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10339        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10340        {}
10341};
10342
10343
10344#ifdef CONFIG_SND_HDA_POWER_SAVE
10345#define alc262_loopbacks        alc880_loopbacks
10346#endif
10347
10348/* pcm configuration: identiacal with ALC880 */
10349#define alc262_pcm_analog_playback        alc880_pcm_analog_playback
10350#define alc262_pcm_analog_capture        alc880_pcm_analog_capture
10351#define alc262_pcm_digital_playback        alc880_pcm_digital_playback
10352#define alc262_pcm_digital_capture        alc880_pcm_digital_capture
10353
10354/*
10355 * BIOS auto configuration
10356 */
10357static int alc262_parse_auto_config(struct hda_codec *codec)
10358{
10359        struct alc_spec *spec = codec->spec;
10360        int err;
10361        static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10362
10363        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10364                                           alc262_ignore);
10365        if (err < 0)
10366                return err;
10367        if (!spec->autocfg.line_outs)
10368                return 0; /* can't find valid BIOS pin config */
10369        err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10370        if (err < 0)
10371                return err;
10372        err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10373        if (err < 0)
10374                return err;
10375
10376        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10377
10378        if (spec->autocfg.dig_out_pin)
10379                spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10380        if (spec->autocfg.dig_in_pin)
10381                spec->dig_in_nid = ALC262_DIGIN_NID;
10382
10383        if (spec->kctl_alloc)
10384                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10385
10386        spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
10387        spec->num_mux_defs = 1;
10388        spec->input_mux = &spec->private_imux;
10389
10390        err = alc_auto_add_mic_boost(codec);
10391        if (err < 0)
10392                return err;
10393
10394        store_pin_configs(codec);
10395        return 1;
10396}
10397
10398#define alc262_auto_init_multi_out        alc882_auto_init_multi_out
10399#define alc262_auto_init_hp_out                alc882_auto_init_hp_out
10400#define alc262_auto_init_analog_input        alc882_auto_init_analog_input
10401#define alc262_auto_init_input_src        alc882_auto_init_input_src
10402
10403
10404/* init callback for auto-configuration model -- overriding the default init */
10405static void alc262_auto_init(struct hda_codec *codec)
10406{
10407        struct alc_spec *spec = codec->spec;
10408        alc262_auto_init_multi_out(codec);
10409        alc262_auto_init_hp_out(codec);
10410        alc262_auto_init_analog_input(codec);
10411        alc262_auto_init_input_src(codec);
10412        if (spec->unsol_event)
10413                alc_inithook(codec);
10414}
10415
10416/*
10417 * configuration and preset
10418 */
10419static const char *alc262_models[ALC262_MODEL_LAST] = {
10420        [ALC262_BASIC]                = "basic",
10421        [ALC262_HIPPO]                = "hippo",
10422        [ALC262_HIPPO_1]        = "hippo_1",
10423        [ALC262_FUJITSU]        = "fujitsu",
10424        [ALC262_HP_BPC]                = "hp-bpc",
10425        [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10426        [ALC262_HP_TC_T5735]        = "hp-tc-t5735",
10427        [ALC262_HP_RP5700]        = "hp-rp5700",
10428        [ALC262_BENQ_ED8]        = "benq",
10429        [ALC262_BENQ_T31]        = "benq-t31",
10430        [ALC262_SONY_ASSAMD]        = "sony-assamd",
10431        [ALC262_TOSHIBA_S06]        = "toshiba-s06",
10432        [ALC262_TOSHIBA_RX1]        = "toshiba-rx1",
10433        [ALC262_ULTRA]                = "ultra",
10434        [ALC262_LENOVO_3000]        = "lenovo-3000",
10435        [ALC262_NEC]                = "nec",
10436        [ALC262_AUTO]                = "auto",
10437};
10438
10439static struct snd_pci_quirk alc262_cfg_tbl[] = {
10440        SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10441        SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10442        SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10443        SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10444        SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10445        SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10446        SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10447        SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10448        SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10449        SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10450        SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10451        SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10452        SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10453        SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10454        SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10455        SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10456        SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10457        SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10458        SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10459        SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10460        SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10461        SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10462                      ALC262_HP_TC_T5735),
10463        SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10464        SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10465        SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10466        SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10467        SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10468        SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10469        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10470                      ALC262_TOSHIBA_RX1),
10471        SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10472        SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10473        SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10474        SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10475        SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10476        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10477        SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10478        SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10479        SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10480        {}
10481};
10482
10483static struct alc_config_preset alc262_presets[] = {
10484        [ALC262_BASIC] = {
10485                .mixers = { alc262_base_mixer },
10486                .init_verbs = { alc262_init_verbs },
10487                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10488                .dac_nids = alc262_dac_nids,
10489                .hp_nid = 0x03,
10490                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10491                .channel_mode = alc262_modes,
10492                .input_mux = &alc262_capture_source,
10493        },
10494        [ALC262_HIPPO] = {
10495                .mixers = { alc262_base_mixer },
10496                .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10497                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10498                .dac_nids = alc262_dac_nids,
10499                .hp_nid = 0x03,
10500                .dig_out_nid = ALC262_DIGOUT_NID,
10501                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10502                .channel_mode = alc262_modes,
10503                .input_mux = &alc262_capture_source,
10504                .unsol_event = alc262_hippo_unsol_event,
10505                .init_hook = alc262_hippo_automute,
10506        },
10507        [ALC262_HIPPO_1] = {
10508                .mixers = { alc262_hippo1_mixer },
10509                .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10510                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10511                .dac_nids = alc262_dac_nids,
10512                .hp_nid = 0x02,
10513                .dig_out_nid = ALC262_DIGOUT_NID,
10514                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10515                .channel_mode = alc262_modes,
10516                .input_mux = &alc262_capture_source,
10517                .unsol_event = alc262_hippo1_unsol_event,
10518                .init_hook = alc262_hippo1_automute,
10519        },
10520        [ALC262_FUJITSU] = {
10521                .mixers = { alc262_fujitsu_mixer },
10522                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10523                                alc262_fujitsu_unsol_verbs },
10524                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10525                .dac_nids = alc262_dac_nids,
10526                .hp_nid = 0x03,
10527                .dig_out_nid = ALC262_DIGOUT_NID,
10528                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10529                .channel_mode = alc262_modes,
10530                .input_mux = &alc262_fujitsu_capture_source,
10531                .unsol_event = alc262_fujitsu_unsol_event,
10532                .init_hook = alc262_fujitsu_init_hook,
10533        },
10534        [ALC262_HP_BPC] = {
10535                .mixers = { alc262_HP_BPC_mixer },
10536                .init_verbs = { alc262_HP_BPC_init_verbs },
10537                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10538                .dac_nids = alc262_dac_nids,
10539                .hp_nid = 0x03,
10540                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10541                .channel_mode = alc262_modes,
10542                .input_mux = &alc262_HP_capture_source,
10543                .unsol_event = alc262_hp_bpc_unsol_event,
10544                .init_hook = alc262_hp_bpc_automute,
10545        },
10546        [ALC262_HP_BPC_D7000_WF] = {
10547                .mixers = { alc262_HP_BPC_WildWest_mixer },
10548                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10549                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10550                .dac_nids = alc262_dac_nids,
10551                .hp_nid = 0x03,
10552                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10553                .channel_mode = alc262_modes,
10554                .input_mux = &alc262_HP_D7000_capture_source,
10555                .unsol_event = alc262_hp_wildwest_unsol_event,
10556                .init_hook = alc262_hp_wildwest_automute,
10557        },
10558        [ALC262_HP_BPC_D7000_WL] = {
10559                .mixers = { alc262_HP_BPC_WildWest_mixer,
10560                            alc262_HP_BPC_WildWest_option_mixer },
10561                .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10562                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10563                .dac_nids = alc262_dac_nids,
10564                .hp_nid = 0x03,
10565                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10566                .channel_mode = alc262_modes,
10567                .input_mux = &alc262_HP_D7000_capture_source,
10568                .unsol_event = alc262_hp_wildwest_unsol_event,
10569                .init_hook = alc262_hp_wildwest_automute,
10570        },
10571        [ALC262_HP_TC_T5735] = {
10572                .mixers = { alc262_hp_t5735_mixer },
10573                .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10574                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10575                .dac_nids = alc262_dac_nids,
10576                .hp_nid = 0x03,
10577                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10578                .channel_mode = alc262_modes,
10579                .input_mux = &alc262_capture_source,
10580                .unsol_event = alc262_hp_t5735_unsol_event,
10581                .init_hook = alc262_hp_t5735_init_hook,
10582        },
10583        [ALC262_HP_RP5700] = {
10584                .mixers = { alc262_hp_rp5700_mixer },
10585                .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10586                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10587                .dac_nids = alc262_dac_nids,
10588                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10589                .channel_mode = alc262_modes,
10590                .input_mux = &alc262_hp_rp5700_capture_source,
10591        },
10592        [ALC262_BENQ_ED8] = {
10593                .mixers = { alc262_base_mixer },
10594                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10595                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10596                .dac_nids = alc262_dac_nids,
10597                .hp_nid = 0x03,
10598                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10599                .channel_mode = alc262_modes,
10600                .input_mux = &alc262_capture_source,
10601        },
10602        [ALC262_SONY_ASSAMD] = {
10603                .mixers = { alc262_sony_mixer },
10604                .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10605                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10606                .dac_nids = alc262_dac_nids,
10607                .hp_nid = 0x02,
10608                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10609                .channel_mode = alc262_modes,
10610                .input_mux = &alc262_capture_source,
10611                .unsol_event = alc262_hippo_unsol_event,
10612                .init_hook = alc262_hippo_automute,
10613        },
10614        [ALC262_BENQ_T31] = {
10615                .mixers = { alc262_benq_t31_mixer },
10616                .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10617                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10618                .dac_nids = alc262_dac_nids,
10619                .hp_nid = 0x03,
10620                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10621                .channel_mode = alc262_modes,
10622                .input_mux = &alc262_capture_source,
10623                .unsol_event = alc262_hippo_unsol_event,
10624                .init_hook = alc262_hippo_automute,
10625        },
10626        [ALC262_ULTRA] = {
10627                .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10628                .init_verbs = { alc262_ultra_verbs },
10629                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10630                .dac_nids = alc262_dac_nids,
10631                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10632                .channel_mode = alc262_modes,
10633                .input_mux = &alc262_ultra_capture_source,
10634                .adc_nids = alc262_adc_nids, /* ADC0 */
10635                .capsrc_nids = alc262_capsrc_nids,
10636                .num_adc_nids = 1, /* single ADC */
10637                .unsol_event = alc262_ultra_unsol_event,
10638                .init_hook = alc262_ultra_automute,
10639        },
10640        [ALC262_LENOVO_3000] = {
10641                .mixers = { alc262_lenovo_3000_mixer },
10642                .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10643                                alc262_lenovo_3000_unsol_verbs },
10644                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10645                .dac_nids = alc262_dac_nids,
10646                .hp_nid = 0x03,
10647                .dig_out_nid = ALC262_DIGOUT_NID,
10648                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10649                .channel_mode = alc262_modes,
10650                .input_mux = &alc262_fujitsu_capture_source,
10651                .unsol_event = alc262_lenovo_3000_unsol_event,
10652        },
10653        [ALC262_NEC] = {
10654                .mixers = { alc262_nec_mixer },
10655                .init_verbs = { alc262_nec_verbs },
10656                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10657                .dac_nids = alc262_dac_nids,
10658                .hp_nid = 0x03,
10659                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10660                .channel_mode = alc262_modes,
10661                .input_mux = &alc262_capture_source,
10662        },
10663        [ALC262_TOSHIBA_S06] = {
10664                .mixers = { alc262_toshiba_s06_mixer },
10665                .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10666                                                        alc262_eapd_verbs },
10667                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10668                .capsrc_nids = alc262_dmic_capsrc_nids,
10669                .dac_nids = alc262_dac_nids,
10670                .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10671                .dig_out_nid = ALC262_DIGOUT_NID,
10672                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10673                .channel_mode = alc262_modes,
10674                .input_mux = &alc262_dmic_capture_source,
10675                .unsol_event = alc262_toshiba_s06_unsol_event,
10676                .init_hook = alc262_toshiba_s06_init_hook,
10677        },
10678        [ALC262_TOSHIBA_RX1] = {
10679                .mixers = { alc262_toshiba_rx1_mixer },
10680                .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10681                .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10682                .dac_nids = alc262_dac_nids,
10683                .hp_nid = 0x03,
10684                .num_channel_mode = ARRAY_SIZE(alc262_modes),
10685                .channel_mode = alc262_modes,
10686                .input_mux = &alc262_capture_source,
10687                .unsol_event = alc262_hippo_unsol_event,
10688                .init_hook = alc262_hippo_automute,
10689        },
10690};
10691
10692static int patch_alc262(struct hda_codec *codec)
10693{
10694        struct alc_spec *spec;
10695        int board_config;
10696        int err;
10697
10698        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10699        if (spec == NULL)
10700                return -ENOMEM;
10701
10702        codec->spec = spec;
10703#if 0
10704        /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
10705         * under-run
10706         */
10707        {
10708        int tmp;
10709        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10710        tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10711        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10712        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10713        }
10714#endif
10715
10716        alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10717
10718        board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10719                                                  alc262_models,
10720                                                  alc262_cfg_tbl);
10721
10722        if (board_config < 0) {
10723                printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10724                       "trying auto-probe from BIOS...\n");
10725                board_config = ALC262_AUTO;
10726        }
10727
10728        if (board_config == ALC262_AUTO) {
10729                /* automatic parse from the BIOS config */
10730                err = alc262_parse_auto_config(codec);
10731                if (err < 0) {
10732                        alc_free(codec);
10733                        return err;
10734                } else if (!err) {
10735                        printk(KERN_INFO
10736                               "hda_codec: Cannot set up configuration "
10737                               "from BIOS.  Using base mode...\n");
10738                        board_config = ALC262_BASIC;
10739                }
10740        }
10741
10742        if (board_config != ALC262_AUTO)
10743                setup_preset(spec, &alc262_presets[board_config]);
10744
10745        spec->stream_name_analog = "ALC262 Analog";
10746        spec->stream_analog_playback = &alc262_pcm_analog_playback;
10747        spec->stream_analog_capture = &alc262_pcm_analog_capture;
10748
10749        spec->stream_name_digital = "ALC262 Digital";
10750        spec->stream_digital_playback = &alc262_pcm_digital_playback;
10751        spec->stream_digital_capture = &alc262_pcm_digital_capture;
10752
10753        if (!spec->adc_nids && spec->input_mux) {
10754                /* check whether NID 0x07 is valid */
10755                unsigned int wcap = get_wcaps(codec, 0x07);
10756
10757                /* get type */
10758                wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10759                if (wcap != AC_WID_AUD_IN) {
10760                        spec->adc_nids = alc262_adc_nids_alt;
10761                        spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10762                        spec->capsrc_nids = alc262_capsrc_nids_alt;
10763                        spec->mixers[spec->num_mixers] =
10764                                alc262_capture_alt_mixer;
10765                        spec->num_mixers++;
10766                } else {
10767                        spec->adc_nids = alc262_adc_nids;
10768                        spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10769                        spec->capsrc_nids = alc262_capsrc_nids;
10770                        spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10771                        spec->num_mixers++;
10772                }
10773        }
10774
10775        spec->vmaster_nid = 0x0c;
10776
10777        codec->patch_ops = alc_patch_ops;
10778        if (board_config == ALC262_AUTO)
10779                spec->init_hook = alc262_auto_init;
10780#ifdef CONFIG_SND_HDA_POWER_SAVE
10781        if (!spec->loopback.amplist)
10782                spec->loopback.amplist = alc262_loopbacks;
10783#endif
10784
10785        return 0;
10786}
10787
10788/*
10789 *  ALC268 channel source setting (2 channel)
10790 */
10791#define ALC268_DIGOUT_NID        ALC880_DIGOUT_NID
10792#define alc268_modes                alc260_modes
10793
10794static hda_nid_t alc268_dac_nids[2] = {
10795        /* front, hp */
10796        0x02, 0x03
10797};
10798
10799static hda_nid_t alc268_adc_nids[2] = {
10800        /* ADC0-1 */
10801        0x08, 0x07
10802};
10803
10804static hda_nid_t alc268_adc_nids_alt[1] = {
10805        /* ADC0 */
10806        0x08
10807};
10808
10809static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10810
10811static struct snd_kcontrol_new alc268_base_mixer[] = {
10812        /* output mixer control */
10813        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10814        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10815        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10816        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10817        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10818        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10819        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10820        { }
10821};
10822
10823/* bind Beep switches of both NID 0x0f and 0x10 */
10824static struct hda_bind_ctls alc268_bind_beep_sw = {
10825        .ops = &snd_hda_bind_sw,
10826        .values = {
10827                HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10828                HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10829                0
10830        },
10831};
10832
10833static struct snd_kcontrol_new alc268_beep_mixer[] = {
10834        HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10835        HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10836        { }
10837};
10838
10839static struct hda_verb alc268_eapd_verbs[] = {
10840        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10841        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10842        { }
10843};
10844
10845/* Toshiba specific */
10846#define alc268_toshiba_automute        alc262_hippo_automute
10847
10848static struct hda_verb alc268_toshiba_verbs[] = {
10849        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10850        { } /* end */
10851};
10852
10853static struct hda_input_mux alc268_acer_lc_capture_source = {
10854        .num_items = 2,
10855        .items = {
10856                { "i-Mic", 0x6 },
10857                { "E-Mic", 0x0 },
10858        },
10859};
10860
10861/* Acer specific */
10862/* bind volumes of both NID 0x02 and 0x03 */
10863static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10864        .ops = &snd_hda_bind_vol,
10865        .values = {
10866                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10867                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10868                0
10869        },
10870};
10871
10872/* mute/unmute internal speaker according to the hp jack and mute state */
10873static void alc268_acer_automute(struct hda_codec *codec, int force)
10874{
10875        struct alc_spec *spec = codec->spec;
10876        unsigned int mute;
10877
10878        if (force || !spec->sense_updated) {
10879                unsigned int present;
10880                present = snd_hda_codec_read(codec, 0x14, 0,
10881                                             AC_VERB_GET_PIN_SENSE, 0);
10882                spec->jack_present = (present & 0x80000000) != 0;
10883                spec->sense_updated = 1;
10884        }
10885        if (spec->jack_present)
10886                mute = HDA_AMP_MUTE; /* mute internal speaker */
10887        else /* unmute internal speaker if necessary */
10888                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10889        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10890                                 HDA_AMP_MUTE, mute);
10891}
10892
10893
10894/* bind hp and internal speaker mute (with plug check) */
10895static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10896                                     struct snd_ctl_elem_value *ucontrol)
10897{
10898        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10899        long *valp = ucontrol->value.integer.value;
10900        int change;
10901
10902        change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10903                                          HDA_AMP_MUTE,
10904                                          valp[0] ? 0 : HDA_AMP_MUTE);
10905        change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10906                                           HDA_AMP_MUTE,
10907                                           valp[1] ? 0 : HDA_AMP_MUTE);
10908        if (change)
10909                alc268_acer_automute(codec, 0);
10910        return change;
10911}
10912
10913static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10914        /* output mixer control */
10915        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10916        {
10917                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10918                .name = "Master Playback Switch",
10919                .info = snd_hda_mixer_amp_switch_info,
10920                .get = snd_hda_mixer_amp_switch_get,
10921                .put = alc268_acer_master_sw_put,
10922                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10923        },
10924        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10925        { }
10926};
10927
10928static struct snd_kcontrol_new alc268_acer_mixer[] = {
10929        /* output mixer control */
10930        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10931        {
10932                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10933                .name = "Master Playback Switch",
10934                .info = snd_hda_mixer_amp_switch_info,
10935                .get = snd_hda_mixer_amp_switch_get,
10936                .put = alc268_acer_master_sw_put,
10937                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10938        },
10939        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10940        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10941        HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10942        { }
10943};
10944
10945static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10946        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10947        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10948        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10949        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10950        {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10951        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10952        { }
10953};
10954
10955static struct hda_verb alc268_acer_verbs[] = {
10956        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10957        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10958        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10959        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10960        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10961        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10962        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10963        { }
10964};
10965
10966/* unsolicited event for HP jack sensing */
10967static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10968                                       unsigned int res)
10969{
10970        if ((res >> 26) != ALC880_HP_EVENT)
10971                return;
10972        alc268_toshiba_automute(codec);
10973}
10974
10975static void alc268_acer_unsol_event(struct hda_codec *codec,
10976                                       unsigned int res)
10977{
10978        if ((res >> 26) != ALC880_HP_EVENT)
10979                return;
10980        alc268_acer_automute(codec, 1);
10981}
10982
10983static void alc268_acer_init_hook(struct hda_codec *codec)
10984{
10985        alc268_acer_automute(codec, 1);
10986}
10987
10988/* toggle speaker-output according to the hp-jack state */
10989static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10990{
10991        unsigned int present;
10992        unsigned char bits;
10993
10994        present = snd_hda_codec_read(codec, 0x15, 0,
10995                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10996        bits = present ? AMP_IN_MUTE(0) : 0;
10997        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10998                                AMP_IN_MUTE(0), bits);
10999        snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11000                                AMP_IN_MUTE(0), bits);
11001}
11002
11003
11004static void alc268_acer_mic_automute(struct hda_codec *codec)
11005{
11006        unsigned int present;
11007
11008        present = snd_hda_codec_read(codec, 0x18, 0,
11009                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11010        snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11011                            present ? 0x0 : 0x6);
11012}
11013
11014static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11015                                    unsigned int res)
11016{
11017        if ((res >> 26) == ALC880_HP_EVENT)
11018                alc268_aspire_one_speaker_automute(codec);
11019        if ((res >> 26) == ALC880_MIC_EVENT)
11020                alc268_acer_mic_automute(codec);
11021}
11022
11023static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11024{
11025        alc268_aspire_one_speaker_automute(codec);
11026        alc268_acer_mic_automute(codec);
11027}
11028
11029static struct snd_kcontrol_new alc268_dell_mixer[] = {
11030        /* output mixer control */
11031        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11032        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11033        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11034        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11035        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11036        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11037        { }
11038};
11039
11040static struct hda_verb alc268_dell_verbs[] = {
11041        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11042        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11043        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11044        { }
11045};
11046
11047/* mute/unmute internal speaker according to the hp jack and mute state */
11048static void alc268_dell_automute(struct hda_codec *codec)
11049{
11050        unsigned int present;
11051        unsigned int mute;
11052
11053        present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11054        if (present & 0x80000000)
11055                mute = HDA_AMP_MUTE;
11056        else
11057                mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11058        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11059                                 HDA_AMP_MUTE, mute);
11060}
11061
11062static void alc268_dell_unsol_event(struct hda_codec *codec,
11063                                    unsigned int res)
11064{
11065        if ((res >> 26) != ALC880_HP_EVENT)
11066                return;
11067        alc268_dell_automute(codec);
11068}
11069
11070#define alc268_dell_init_hook        alc268_dell_automute
11071
11072static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11073        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11074        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11075        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11076        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11077        HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11078        HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11079        HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11080        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11081        { }
11082};
11083
11084static struct hda_verb alc267_quanta_il1_verbs[] = {
11085        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11086        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11087        { }
11088};
11089
11090static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11091{
11092        unsigned int present;
11093
11094        present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11095                & AC_PINSENSE_PRESENCE;
11096        snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11097                            present ? 0 : PIN_OUT);
11098}
11099
11100static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11101{
11102        unsigned int present;
11103
11104        present = snd_hda_codec_read(codec, 0x18, 0,
11105                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11106        snd_hda_codec_write(codec, 0x23, 0,
11107                            AC_VERB_SET_CONNECT_SEL,
11108                            present ? 0x00 : 0x01);
11109}
11110
11111static void alc267_quanta_il1_automute(struct hda_codec *codec)
11112{
11113        alc267_quanta_il1_hp_automute(codec);
11114        alc267_quanta_il1_mic_automute(codec);
11115}
11116
11117static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11118                                           unsigned int res)
11119{
11120        switch (res >> 26) {
11121        case ALC880_HP_EVENT:
11122                alc267_quanta_il1_hp_automute(codec);
11123                break;
11124        case ALC880_MIC_EVENT:
11125                alc267_quanta_il1_mic_automute(codec);
11126                break;
11127        }
11128}
11129
11130/*
11131 * generic initialization of ADC, input mixers and output mixers
11132 */
11133static struct hda_verb alc268_base_init_verbs[] = {
11134        /* Unmute DAC0-1 and set vol = 0 */
11135        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11136        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11137        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11138        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11139        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11140        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11141
11142        /*
11143         * Set up output mixers (0x0c - 0x0e)
11144         */
11145        /* set vol=0 to output mixers */
11146        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11147        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11148        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11149        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11150
11151        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11152        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11153
11154        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11155        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11156        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11157        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11158        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11159        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11160        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11161        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11162
11163        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11164        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11165        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11166        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11167        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11168        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11169        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11170
11171        /* set PCBEEP vol = 0, mute connections */
11172        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11173        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11174        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11175
11176        /* Unmute Selector 23h,24h and set the default input to mic-in */
11177
11178        {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11179        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11180        {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11181        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11182
11183        { }
11184};
11185
11186/*
11187 * generic initialization of ADC, input mixers and output mixers
11188 */
11189static struct hda_verb alc268_volume_init_verbs[] = {
11190        /* set output DAC */
11191        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11192        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11193        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11194        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11195
11196        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11197        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11198        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11199        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11200        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11201
11202        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11203        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11204        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11205        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11206        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11207
11208        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11209        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11210        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11211        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11212
11213        /* set PCBEEP vol = 0, mute connections */
11214        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11215        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11216        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11217
11218        { }
11219};
11220
11221#define alc268_mux_enum_info alc_mux_enum_info
11222#define alc268_mux_enum_get alc_mux_enum_get
11223#define alc268_mux_enum_put alc_mux_enum_put
11224
11225static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11226        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11227        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11228        {
11229                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11230                /* The multiple "Capture Source" controls confuse alsamixer
11231                 * So call somewhat different..
11232                 */
11233                /* .name = "Capture Source", */
11234                .name = "Input Source",
11235                .count = 1,
11236                .info = alc268_mux_enum_info,
11237                .get = alc268_mux_enum_get,
11238                .put = alc268_mux_enum_put,
11239        },
11240        { } /* end */
11241};
11242
11243static struct snd_kcontrol_new alc268_capture_mixer[] = {
11244        HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11245        HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11246        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11247        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11248        {
11249                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11250                /* The multiple "Capture Source" controls confuse alsamixer
11251                 * So call somewhat different..
11252                 */
11253                /* .name = "Capture Source", */
11254                .name = "Input Source",
11255                .count = 2,
11256                .info = alc268_mux_enum_info,
11257                .get = alc268_mux_enum_get,
11258                .put = alc268_mux_enum_put,
11259        },
11260        { } /* end */
11261};
11262
11263static struct hda_input_mux alc268_capture_source = {
11264        .num_items = 4,
11265        .items = {
11266                { "Mic", 0x0 },
11267                { "Front Mic", 0x1 },
11268                { "Line", 0x2 },
11269                { "CD", 0x3 },
11270        },
11271};
11272
11273static struct hda_input_mux alc268_acer_capture_source = {
11274        .num_items = 3,
11275        .items = {
11276                { "Mic", 0x0 },
11277                { "Internal Mic", 0x6 },
11278                { "Line", 0x2 },
11279        },
11280};
11281
11282#ifdef CONFIG_SND_DEBUG
11283static struct snd_kcontrol_new alc268_test_mixer[] = {
11284        /* Volume widgets */
11285        HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11286        HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11287        HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11288        HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11289        HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11290        HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11291        HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11292        HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11293        HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11294        HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11295        HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11296        HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11297        HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11298        /* The below appears problematic on some hardwares */
11299        /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11300        HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11301        HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11302        HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11303        HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11304
11305        /* Modes for retasking pin widgets */
11306        ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11307        ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11308        ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11309        ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11310
11311        /* Controls for GPIO pins, assuming they are configured as outputs */
11312        ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11313        ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11314        ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11315        ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11316
11317        /* Switches to allow the digital SPDIF output pin to be enabled.
11318         * The ALC268 does not have an SPDIF input.
11319         */
11320        ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11321
11322        /* A switch allowing EAPD to be enabled.  Some laptops seem to use
11323         * this output to turn on an external amplifier.
11324         */
11325        ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11326        ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11327
11328        { } /* end */
11329};
11330#endif
11331
11332/* create input playback/capture controls for the given pin */
11333static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11334                                    const char *ctlname, int idx)
11335{
11336        char name[32];
11337        int err;
11338
11339        sprintf(name, "%s Playback Volume", ctlname);
11340        if (nid == 0x14) {
11341                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11342                                  HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11343                                                      HDA_OUTPUT));
11344                if (err < 0)
11345                        return err;
11346        } else if (nid == 0x15) {
11347                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11348                                  HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11349                                                      HDA_OUTPUT));
11350                if (err < 0)
11351                        return err;
11352        } else
11353                return -1;
11354        sprintf(name, "%s Playback Switch", ctlname);
11355        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11356                          HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11357        if (err < 0)
11358                return err;
11359        return 0;
11360}
11361
11362/* add playback controls from the parsed DAC table */
11363static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11364                                             const struct auto_pin_cfg *cfg)
11365{
11366        hda_nid_t nid;
11367        int err;
11368
11369        spec->multiout.num_dacs = 2;        /* only use one dac */
11370        spec->multiout.dac_nids = spec->private_dac_nids;
11371        spec->multiout.dac_nids[0] = 2;
11372        spec->multiout.dac_nids[1] = 3;
11373
11374        nid = cfg->line_out_pins[0];
11375        if (nid)
11376                alc268_new_analog_output(spec, nid, "Front", 0);
11377
11378        nid = cfg->speaker_pins[0];
11379        if (nid == 0x1d) {
11380                err = add_control(spec, ALC_CTL_WIDGET_VOL,
11381                                  "Speaker Playback Volume",
11382                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11383                if (err < 0)
11384                        return err;
11385        }
11386        nid = cfg->hp_pins[0];
11387        if (nid)
11388                alc268_new_analog_output(spec, nid, "Headphone", 0);
11389
11390        nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11391        if (nid == 0x16) {
11392                err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11393                                  "Mono Playback Switch",
11394                                  HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11395                if (err < 0)
11396                        return err;
11397        }
11398        return 0;
11399}
11400
11401/* create playback/capture controls for input pins */
11402static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11403                                                const struct auto_pin_cfg *cfg)
11404{
11405        struct hda_input_mux *imux = &spec->private_imux;
11406        int i, idx1;
11407
11408        for (i = 0; i < AUTO_PIN_LAST; i++) {
11409                switch(cfg->input_pins[i]) {
11410                case 0x18:
11411                        idx1 = 0;        /* Mic 1 */
11412                        break;
11413                case 0x19:
11414                        idx1 = 1;        /* Mic 2 */
11415                        break;
11416                case 0x1a:
11417                        idx1 = 2;        /* Line In */
11418                        break;
11419                case 0x1c:
11420                        idx1 = 3;        /* CD */
11421                        break;
11422                case 0x12:
11423                case 0x13:
11424                        idx1 = 6;        /* digital mics */
11425                        break;
11426                default:
11427                        continue;
11428                }
11429                imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11430                imux->items[imux->num_items].index = idx1;
11431                imux->num_items++;
11432        }
11433        return 0;
11434}
11435
11436static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11437{
11438        struct alc_spec *spec = codec->spec;
11439        hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11440        hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11441        hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11442        unsigned int        dac_vol1, dac_vol2;
11443
11444        if (speaker_nid) {
11445                snd_hda_codec_write(codec, speaker_nid, 0,
11446                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11447                snd_hda_codec_write(codec, 0x0f, 0,
11448                                    AC_VERB_SET_AMP_GAIN_MUTE,
11449                                    AMP_IN_UNMUTE(1));
11450                snd_hda_codec_write(codec, 0x10, 0,
11451                                    AC_VERB_SET_AMP_GAIN_MUTE,
11452                                    AMP_IN_UNMUTE(1));
11453        } else {
11454                snd_hda_codec_write(codec, 0x0f, 0,
11455                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11456                snd_hda_codec_write(codec, 0x10, 0,
11457                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11458        }
11459
11460        dac_vol1 = dac_vol2 = 0xb000 | 0x40;        /* set max volume  */
11461        if (line_nid == 0x14)
11462                dac_vol2 = AMP_OUT_ZERO;
11463        else if (line_nid == 0x15)
11464                dac_vol1 = AMP_OUT_ZERO;
11465        if (hp_nid == 0x14)
11466                dac_vol2 = AMP_OUT_ZERO;
11467        else if (hp_nid == 0x15)
11468                dac_vol1 = AMP_OUT_ZERO;
11469        if (line_nid != 0x16 || hp_nid != 0x16 ||
11470            spec->autocfg.line_out_pins[1] != 0x16 ||
11471            spec->autocfg.line_out_pins[2] != 0x16)
11472                dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11473
11474        snd_hda_codec_write(codec, 0x02, 0,
11475                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11476        snd_hda_codec_write(codec, 0x03, 0,
11477                            AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11478}
11479
11480/* pcm configuration: identiacal with ALC880 */
11481#define alc268_pcm_analog_playback        alc880_pcm_analog_playback
11482#define alc268_pcm_analog_capture        alc880_pcm_analog_capture
11483#define alc268_pcm_analog_alt_capture        alc880_pcm_analog_alt_capture
11484#define alc268_pcm_digital_playback        alc880_pcm_digital_playback
11485
11486/*
11487 * BIOS auto configuration
11488 */
11489static int alc268_parse_auto_config(struct hda_codec *codec)
11490{
11491        struct alc_spec *spec = codec->spec;
11492        int err;
11493        static hda_nid_t alc268_ignore[] = { 0 };
11494
11495        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11496                                           alc268_ignore);
11497        if (err < 0)
11498                return err;
11499        if (!spec->autocfg.line_outs)
11500                return 0; /* can't find valid BIOS pin config */
11501
11502        err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11503        if (err < 0)
11504                return err;
11505        err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11506        if (err < 0)
11507                return err;
11508
11509        spec->multiout.max_channels = 2;
11510
11511        /* digital only support output */
11512        if (spec->autocfg.dig_out_pin)
11513                spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11514
11515        if (spec->kctl_alloc)
11516                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11517
11518        if (spec->autocfg.speaker_pins[0] != 0x1d)
11519                spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
11520
11521        spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
11522        spec->num_mux_defs = 1;
11523        spec->input_mux = &spec->private_imux;
11524
11525        err = alc_auto_add_mic_boost(codec);
11526        if (err < 0)
11527                return err;
11528
11529        store_pin_configs(codec);
11530        return 1;
11531}
11532
11533#define alc268_auto_init_multi_out        alc882_auto_init_multi_out
11534#define alc268_auto_init_hp_out                alc882_auto_init_hp_out
11535#define alc268_auto_init_analog_input        alc882_auto_init_analog_input
11536
11537/* init callback for auto-configuration model -- overriding the default init */
11538static void alc268_auto_init(struct hda_codec *codec)
11539{
11540        struct alc_spec *spec = codec->spec;
11541        alc268_auto_init_multi_out(codec);
11542        alc268_auto_init_hp_out(codec);
11543        alc268_auto_init_mono_speaker_out(codec);
11544        alc268_auto_init_analog_input(codec);
11545        if (spec->unsol_event)
11546                alc_inithook(codec);
11547}
11548
11549/*
11550 * configuration and preset
11551 */
11552static const char *alc268_models[ALC268_MODEL_LAST] = {
11553        [ALC267_QUANTA_IL1]        = "quanta-il1",
11554        [ALC268_3ST]                = "3stack",
11555        [ALC268_TOSHIBA]        = "toshiba",
11556        [ALC268_ACER]                = "acer",
11557        [ALC268_ACER_ASPIRE_ONE]        = "acer-aspire",
11558        [ALC268_DELL]                = "dell",
11559        [ALC268_ZEPTO]                = "zepto",
11560#ifdef CONFIG_SND_DEBUG
11561        [ALC268_TEST]                = "test",
11562#endif
11563        [ALC268_AUTO]                = "auto",
11564};
11565
11566static struct snd_pci_quirk alc268_cfg_tbl[] = {
11567        SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11568        SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11569        SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11570        SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11571        SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11572        SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11573                                                ALC268_ACER_ASPIRE_ONE),
11574        SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11575        SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11576        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11577        SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11578        SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11579        SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11580        SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11581        SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11582        SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11583        SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11584        {}
11585};
11586
11587static struct alc_config_preset alc268_presets[] = {
11588        [ALC267_QUANTA_IL1] = {
11589                .mixers = { alc267_quanta_il1_mixer },
11590                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11591                                alc267_quanta_il1_verbs },
11592                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11593                .dac_nids = alc268_dac_nids,
11594                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11595                .adc_nids = alc268_adc_nids_alt,
11596                .hp_nid = 0x03,
11597                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11598                .channel_mode = alc268_modes,
11599                .input_mux = &alc268_capture_source,
11600                .unsol_event = alc267_quanta_il1_unsol_event,
11601                .init_hook = alc267_quanta_il1_automute,
11602        },
11603        [ALC268_3ST] = {
11604                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11605                            alc268_beep_mixer },
11606                .init_verbs = { alc268_base_init_verbs },
11607                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11608                .dac_nids = alc268_dac_nids,
11609                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11610                .adc_nids = alc268_adc_nids_alt,
11611                .capsrc_nids = alc268_capsrc_nids,
11612                .hp_nid = 0x03,
11613                .dig_out_nid = ALC268_DIGOUT_NID,
11614                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11615                .channel_mode = alc268_modes,
11616                .input_mux = &alc268_capture_source,
11617        },
11618        [ALC268_TOSHIBA] = {
11619                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11620                            alc268_beep_mixer },
11621                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11622                                alc268_toshiba_verbs },
11623                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11624                .dac_nids = alc268_dac_nids,
11625                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11626                .adc_nids = alc268_adc_nids_alt,
11627                .capsrc_nids = alc268_capsrc_nids,
11628                .hp_nid = 0x03,
11629                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11630                .channel_mode = alc268_modes,
11631                .input_mux = &alc268_capture_source,
11632                .unsol_event = alc268_toshiba_unsol_event,
11633                .init_hook = alc268_toshiba_automute,
11634        },
11635        [ALC268_ACER] = {
11636                .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11637                            alc268_beep_mixer },
11638                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11639                                alc268_acer_verbs },
11640                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11641                .dac_nids = alc268_dac_nids,
11642                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11643                .adc_nids = alc268_adc_nids_alt,
11644                .capsrc_nids = alc268_capsrc_nids,
11645                .hp_nid = 0x02,
11646                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11647                .channel_mode = alc268_modes,
11648                .input_mux = &alc268_acer_capture_source,
11649                .unsol_event = alc268_acer_unsol_event,
11650                .init_hook = alc268_acer_init_hook,
11651        },
11652        [ALC268_ACER_ASPIRE_ONE] = {
11653                .mixers = { alc268_acer_aspire_one_mixer,
11654                                alc268_capture_alt_mixer },
11655                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11656                                alc268_acer_aspire_one_verbs },
11657                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11658                .dac_nids = alc268_dac_nids,
11659                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11660                .adc_nids = alc268_adc_nids_alt,
11661                .capsrc_nids = alc268_capsrc_nids,
11662                .hp_nid = 0x03,
11663                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11664                .channel_mode = alc268_modes,
11665                .input_mux = &alc268_acer_lc_capture_source,
11666                .unsol_event = alc268_acer_lc_unsol_event,
11667                .init_hook = alc268_acer_lc_init_hook,
11668        },
11669        [ALC268_DELL] = {
11670                .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11671                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11672                                alc268_dell_verbs },
11673                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11674                .dac_nids = alc268_dac_nids,
11675                .hp_nid = 0x02,
11676                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11677                .channel_mode = alc268_modes,
11678                .unsol_event = alc268_dell_unsol_event,
11679                .init_hook = alc268_dell_init_hook,
11680                .input_mux = &alc268_capture_source,
11681        },
11682        [ALC268_ZEPTO] = {
11683                .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11684                            alc268_beep_mixer },
11685                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11686                                alc268_toshiba_verbs },
11687                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11688                .dac_nids = alc268_dac_nids,
11689                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11690                .adc_nids = alc268_adc_nids_alt,
11691                .capsrc_nids = alc268_capsrc_nids,
11692                .hp_nid = 0x03,
11693                .dig_out_nid = ALC268_DIGOUT_NID,
11694                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11695                .channel_mode = alc268_modes,
11696                .input_mux = &alc268_capture_source,
11697                .unsol_event = alc268_toshiba_unsol_event,
11698                .init_hook = alc268_toshiba_automute
11699        },
11700#ifdef CONFIG_SND_DEBUG
11701        [ALC268_TEST] = {
11702                .mixers = { alc268_test_mixer, alc268_capture_mixer },
11703                .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11704                                alc268_volume_init_verbs },
11705                .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11706                .dac_nids = alc268_dac_nids,
11707                .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11708                .adc_nids = alc268_adc_nids_alt,
11709                .capsrc_nids = alc268_capsrc_nids,
11710                .hp_nid = 0x03,
11711                .dig_out_nid = ALC268_DIGOUT_NID,
11712                .num_channel_mode = ARRAY_SIZE(alc268_modes),
11713                .channel_mode = alc268_modes,
11714                .input_mux = &alc268_capture_source,
11715        },
11716#endif
11717};
11718
11719static int patch_alc268(struct hda_codec *codec)
11720{
11721        struct alc_spec *spec;
11722        int board_config;
11723        int err;
11724
11725        spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11726        if (spec == NULL)
11727                return -ENOMEM;
11728
11729        codec->spec = spec;
11730
11731        board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11732                                                  alc268_models,
11733                                                  alc268_cfg_tbl);
11734
11735        if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11736                printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11737                       "trying auto-probe from BIOS...\n");
11738                board_config = ALC268_AUTO;
11739        }
11740
11741        if (board_config == ALC268_AUTO) {
11742                /* automatic parse from the BIOS config */
11743                err = alc268_parse_auto_config(codec);
11744                if (err < 0) {
11745                        alc_free(codec);
11746                        return err;
11747                } else if (!err) {
11748                        printk(KERN_INFO
11749                               "hda_codec: Cannot set up configuration "
11750                               "from BIOS.  Using base mode...\n");
11751                        board_config = ALC268_3ST;
11752                }
11753        }
11754
11755        if (board_config != ALC268_AUTO)
11756                setup_preset(spec, &alc268_presets[board_config]);
11757
11758        if (codec->vendor_id == 0x10ec0267) {
11759                spec->stream_name_analog = "ALC267 Analog";
11760                spec->stream_name_digital = "ALC267 Digital";
11761        } else {
11762                spec->stream_name_analog = "ALC268 Analog";
11763                spec->stream_name_digital = "ALC268 Digital";
11764        }
11765
11766        spec->stream_analog_playback = &alc268_pcm_analog_playback;
11767        spec->stream_analog_capture = &alc268_pcm_analog_capture;
11768        spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11769
11770        spec->stream_digital_playback = &alc268_pcm_digital_playback;
11771
11772        if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11773                /* override the amp caps for beep generator */
11774                snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11775                                          (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11776                                          (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11777                                          (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11778                                          (0 << AC_AMPCAP_MUTE_SHIFT));
11779
11780        if (!spec->adc_nids && spec->input_mux) {
11781                /* check whether NID 0x07 is valid */
11782                unsigned int wcap = get_wcaps(codec, 0x07);
11783                int i;
11784
11785                /* get type */
11786                wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11787                if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11788                        spec->adc_nids = alc268_adc_nids_alt;
11789                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11790                        spec->mixers[spec->num_mixers] =
11791                                        alc268_capture_alt_mixer;
11792                        spec->num_mixers++;
11793                } else {
11794                        spec->adc_nids = alc268_adc_nids;
11795                        spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11796                        spec->mixers[spec->num_mixers] =
11797                                alc268_capture_mixer;
11798                        spec->num_mixers++;
11799                }
11800                spec->capsrc_nids = alc268_capsrc_nids;
11801                /* set default input source */
11802                for (i = 0; i < spec->num_adc_nids; i++)
11803                        snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11804                                0, AC_VERB_SET_CONNECT_SEL,
11805                                spec->input_mux->items[0].index);
11806        }
11807
11808        spec->vmaster_nid = 0x02;
11809
11810        codec->patch_ops = alc_patch_ops;
11811        if (board_config == ALC268_AUTO)
11812                spec->init_hook = alc268_auto_init;
11813
11814        return 0;
11815}
11816
11817/*
11818 *  ALC269 channel source setting (2 channel)
11819 */
11820#define ALC269_DIGOUT_NID        ALC880_DIGOUT_NID
11821
11822#define alc269_dac_nids                alc260_dac_nids
11823
11824static hda_nid_t alc269_adc_nids[1] = {
11825        /* ADC1 */
11826        0x08,
11827};
11828
11829static hda_nid_t alc269_capsrc_nids[1] = {
11830        0x23,
11831};
11832
11833/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11834 *       not a mux!
11835 */
11836
11837static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11838        .num_items = 2,
11839        .items = {
11840                { "i-Mic", 0x5 },
11841                { "e-Mic", 0x0 },
11842        },
11843};
11844
11845static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11846        .num_items = 2,
11847        .items = {
11848                { "i-Mic", 0x1 },
11849                { "e-Mic", 0x0 },
11850        },
11851};
11852
11853#define alc269_modes                alc260_modes
11854#define alc269_capture_source        alc880_lg_lw_capture_source
11855
11856static struct snd_kcontrol_new alc269_base_mixer[] = {
11857        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11858        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11859        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11860        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11861        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11862        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11863        HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11864        HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11865        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11866        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11867        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11868        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11869        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11870        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11871        { } /* end */
11872};
11873
11874static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11875        /* output mixer control */
11876        HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11877        {
11878                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11879                .name = "Master Playback Switch",
11880                .info = snd_hda_mixer_amp_switch_info,
11881                .get = snd_hda_mixer_amp_switch_get,
11882                .put = alc268_acer_master_sw_put,
11883                .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11884        },
11885        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11886        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11887        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11888        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11889        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11890        HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11891        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11892        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11893        { }
11894};
11895
11896/* bind volumes of both NID 0x0c and 0x0d */
11897static struct hda_bind_ctls alc269_epc_bind_vol = {
11898        .ops = &snd_hda_bind_vol,
11899        .values = {
11900                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11901                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11902                0
11903        },
11904};
11905
11906static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11907        HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11908        HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11909        HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11910        { } /* end */
11911};
11912
11913/* capture mixer elements */
11914static struct snd_kcontrol_new alc269_capture_mixer[] = {
11915        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11916        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11917        {
11918                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11919                /* The multiple "Capture Source" controls confuse alsamixer
11920                 * So call somewhat different..
11921                 */
11922                /* .name = "Capture Source", */
11923                .name = "Input Source",
11924                .count = 1,
11925                .info = alc_mux_enum_info,
11926                .get = alc_mux_enum_get,
11927                .put = alc_mux_enum_put,
11928        },
11929        { } /* end */
11930};
11931
11932/* capture mixer elements */
11933static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11934        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11935        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11936        { } /* end */
11937};
11938
11939/* beep control */
11940static struct snd_kcontrol_new alc269_beep_mixer[] = {
11941        HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11942        HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11943        { } /* end */
11944};
11945
11946static struct hda_verb alc269_quanta_fl1_verbs[] = {
11947        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11948        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11949        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11950        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11951        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11952        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11953        { }
11954};
11955
11956/* toggle speaker-output according to the hp-jack state */
11957static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11958{
11959        unsigned int present;
11960        unsigned char bits;
11961
11962        present = snd_hda_codec_read(codec, 0x15, 0,
11963                        AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11964        bits = present ? AMP_IN_MUTE(0) : 0;
11965        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11966                        AMP_IN_MUTE(0), bits);
11967        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11968                        AMP_IN_MUTE(0), bits);
11969
11970        snd_hda_codec_write(codec, 0x20, 0,
11971                        AC_VERB_SET_COEF_INDEX, 0x0c);
11972        snd_hda_codec_write(codec, 0x20, 0,
11973                        AC_VERB_SET_PROC_COEF, 0x680);
11974
11975        snd_hda_codec_write(codec, 0x20, 0,
11976                        AC_VERB_SET_COEF_INDEX, 0x0c);
11977        snd_hda_codec_write(codec, 0x20, 0,
11978                        AC_VERB_SET_PROC_COEF, 0x480);
11979}
11980
11981static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11982{
11983        unsigned int present;
11984
11985        present = snd_hda_codec_read(codec, 0x18, 0,
11986                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11987        snd_hda_codec_write(codec, 0x23, 0,
11988                            AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11989}
11990
11991static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11992                                    unsigned int res)
11993{
11994        if ((res >> 26) == ALC880_HP_EVENT)
11995                alc269_quanta_fl1_speaker_automute(codec);
11996        if ((res >> 26) == ALC880_MIC_EVENT)
11997                alc269_quanta_fl1_mic_automute(codec);
11998}
11999
12000static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12001{
12002        alc269_quanta_fl1_speaker_automute(codec);
12003        alc269_quanta_fl1_mic_automute(codec);
12004}
12005
12006static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12007        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12008        {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12009        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12010        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12011        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12012        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12013        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12014        {}
12015};
12016
12017static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12018        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12019        {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12020        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12021        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12022        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12023        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12024        {}
12025};
12026
12027/* toggle speaker-output according to the hp-jack state */
12028static void alc269_speaker_automute(struct hda_codec *codec)
12029{
12030        unsigned int present;
12031        unsigned char bits;
12032
12033        present = snd_hda_codec_read(codec, 0x15, 0,
12034                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12035        bits = present ? AMP_IN_MUTE(0) : 0;
12036        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12037                                AMP_IN_MUTE(0), bits);
12038        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12039                                AMP_IN_MUTE(0), bits);
12040}
12041
12042static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12043{
12044        unsigned int present;
12045
12046        present = snd_hda_codec_read(codec, 0x18, 0,
12047                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12048        snd_hda_codec_write(codec, 0x23, 0,
12049                                AC_VERB_SET_CONNECT_SEL,  (present ? 0 : 5));
12050}
12051
12052static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12053{
12054        unsigned int present;
12055
12056        present = snd_hda_codec_read(codec, 0x18, 0,
12057                                AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12058        snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12059                                0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12060        snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12061                                0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12062}
12063
12064/* unsolicited event for HP jack sensing */
12065static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12066                                     unsigned int res)
12067{
12068        if ((res >> 26) == ALC880_HP_EVENT)
12069                alc269_speaker_automute(codec);
12070
12071        if ((res >> 26) == ALC880_MIC_EVENT)
12072                alc269_eeepc_dmic_automute(codec);
12073}
12074
12075static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12076{
12077        alc269_speaker_automute(codec);
12078        alc269_eeepc_dmic_automute(codec);
12079}
12080
12081/* unsolicited event for HP jack sensing */
12082static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12083                                     unsigned int res)
12084{
12085        if ((res >> 26) == ALC880_HP_EVENT)
12086                alc269_speaker_automute(codec);
12087
12088        if ((res >> 26) == ALC880_MIC_EVENT)
12089                alc269_eeepc_amic_automute(codec);
12090}
12091
12092static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12093{
12094        alc269_speaker_automute(codec);
12095        alc269_eeepc_amic_automute(codec);
12096}
12097
12098/*
12099 * generic initialization of ADC, input mixers and output mixers
12100 */
12101static struct hda_verb alc269_init_verbs[] = {
12102        /*
12103         * Unmute ADC0 and set the default input to mic-in
12104         */
12105        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106
12107        /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12108         * analog-loopback mixer widget
12109         * Note: PASD motherboards uses the Line In 2 as the input for
12110         * front panel mic (mic 2)
12111         */
12112        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12113        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12114        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12115        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12116        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12117        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12118
12119        /*
12120         * Set up output mixers (0x0c - 0x0e)
12121         */
12122        /* set vol=0 to output mixers */
12123        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12124        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12125
12126        /* set up input amps for analog loopback */
12127        /* Amp Indices: DAC = 0, mixer = 1 */
12128        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12129        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12130        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12131        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12132        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12133        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12134
12135        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12136        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12137        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12138        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12139        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12140        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12141        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12142
12143        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12144        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12145        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12146        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12147        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12148        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12149        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12150
12151        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12152        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12153
12154        /* FIXME: use matrix-type input source selection */
12155        /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12156        /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12157        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12158        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12159        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12160        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12161
12162        /* set EAPD */
12163        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12164        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12165        { }
12166};
12167
12168/* add playback controls from the parsed DAC table */
12169static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12170                                             const struct auto_pin_cfg *cfg)
12171{
12172        hda_nid_t nid;
12173        int err;
12174
12175        spec->multiout.num_dacs = 1;        /* only use one dac */
12176        spec->multiout.dac_nids = spec->private_dac_nids;
12177        spec->multiout.dac_nids[0] = 2;
12178
12179        nid = cfg->line_out_pins[0];
12180        if (nid) {
12181                err = add_control(spec, ALC_CTL_WIDGET_VOL,
12182                                  "Front Playback Volume",
12183                                  HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12184                if (err < 0)
12185                        return err;
12186                err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12187                                  "Front Playback Switch",
12188                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12189                if (err < 0)
12190                        return err;
12191        }
12192
12193        nid = cfg->speaker_pins[0];
12194        if (nid) {
12195                if (!cfg->line_out_pins[0]) {
12196                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
12197                                          "Speaker Playback Volume",
12198                                          HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12199                                                              HDA_OUTPUT));
12200                        if (err < 0)
12201                                return err;
12202                }
12203                if (nid == 0x16) {
12204                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12205                                          "Speaker Playback Switch",
12206                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12207                                                              HDA_OUTPUT));
12208                        if (err < 0)
12209                                return err;
12210                } else {
12211                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12212                                          "Speaker Playback Switch",
12213                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12214                                                              HDA_OUTPUT));
12215                        if (err < 0)
12216                                return err;
12217                }
12218        }
12219        nid = cfg->hp_pins[0];
12220        if (nid) {
12221                /* spec->multiout.hp_nid = 2; */
12222                if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12223                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
12224                                          "Headphone Playback Volume",
12225                                          HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12226                                                              HDA_OUTPUT));
12227                        if (err < 0)
12228                                return err;
12229                }
12230                if (nid == 0x16) {
12231                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12232                                          "Headphone Playback Switch",
12233                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12234                                                              HDA_OUTPUT));
12235                        if (err < 0)
12236                                return err;
12237                } else {
12238                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12239                                          "Headphone Playback Switch",
12240                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12241                                                              HDA_OUTPUT));
12242                        if (err < 0)
12243                                return err;
12244                }
12245        }
12246        return 0;
12247}
12248
12249static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12250                                                const struct auto_pin_cfg *cfg)
12251{
12252        int err;
12253
12254        err = alc880_auto_create_analog_input_ctls(spec, cfg);
12255        if (err < 0)
12256                return err;
12257        /* digital-mic input pin is excluded in alc880_auto_create..()
12258         * because it's under 0x18
12259         */
12260        if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12261            cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12262                struct hda_input_mux *imux = &spec->private_imux;
12263                imux->items[imux->num_items].label = "Int Mic";
12264                imux->items[imux->num_items].index = 0x05;
12265                imux->num_items++;
12266        }
12267        return 0;
12268}
12269
12270#ifdef CONFIG_SND_HDA_POWER_SAVE
12271#define alc269_loopbacks        alc880_loopbacks
12272#endif
12273
12274/* pcm configuration: identiacal with ALC880 */
12275#define alc269_pcm_analog_playback        alc880_pcm_analog_playback
12276#define alc269_pcm_analog_capture        alc880_pcm_analog_capture
12277#define alc269_pcm_digital_playback        alc880_pcm_digital_playback
12278#define alc269_pcm_digital_capture        alc880_pcm_digital_capture
12279
12280/*
12281 * BIOS auto configuration
12282 */
12283static int alc269_parse_auto_config(struct hda_codec *codec)
12284{
12285        struct alc_spec *spec = codec->spec;
12286        int i, err;
12287        static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12288
12289        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12290                                           alc269_ignore);
12291        if (err < 0)
12292                return err;
12293
12294        err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12295        if (err < 0)
12296                return err;
12297        err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12298        if (err < 0)
12299                return err;
12300
12301        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12302
12303        if (spec->autocfg.dig_out_pin)
12304                spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12305
12306        if (spec->kctl_alloc)
12307                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12308
12309        /* create a beep mixer control if the pin 0x1d isn't assigned */
12310        for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12311                if (spec->autocfg.input_pins[i] == 0x1d)
12312                        break;
12313        if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12314                spec->mixers[spec->num_mixers++] = alc269_beep_mixer;
12315
12316        spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
12317        spec->num_mux_defs = 1;
12318        spec->input_mux = &spec->private_imux;
12319        /* set default input source */
12320        snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12321                                  0, AC_VERB_SET_CONNECT_SEL,
12322                                  spec->input_mux->items[0].index);
12323
12324        err = alc_auto_add_mic_boost(codec);
12325        if (err < 0)
12326                return err;
12327
12328        spec->mixers[spec->num_mixers] = alc269_capture_mixer;
12329        spec->num_mixers++;
12330
12331        store_pin_configs(codec);
12332        return 1;
12333}
12334
12335#define alc269_auto_init_multi_out        alc882_auto_init_multi_out
12336#define alc269_auto_init_hp_out                alc882_auto_init_hp_out
12337#define alc269_auto_init_analog_input        alc882_auto_init_analog_input
12338
12339
12340/* init callback for auto-configuration model -- overriding the default init */
12341static void alc269_auto_init(struct hda_codec *codec)
12342{
12343        struct alc_spec *spec = codec->spec;
12344        alc269_auto_init_multi_out(codec);
12345        alc269_auto_init_hp_out(codec);
12346        alc269_auto_init_analog_input(codec);
12347        if (spec->unsol_event)
12348                alc_inithook(codec);
12349}
12350
12351/*
12352 * configuration and preset
12353 */
12354static const char *alc269_models[ALC269_MODEL_LAST] = {
12355        [ALC269_BASIC]                        = "basic",
12356        [ALC269_QUANTA_FL1]                = "quanta",
12357        [ALC269_ASUS_EEEPC_P703]        = "eeepc-p703",
12358        [ALC269_ASUS_EEEPC_P901]        = "eeepc-p901"
12359};
12360
12361static struct snd_pci_quirk alc269_cfg_tbl[] = {
12362        SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12363        SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12364                      ALC269_ASUS_EEEPC_P703),
12365        SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12366                      ALC269_ASUS_EEEPC_P901),
12367        SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12368                      ALC269_ASUS_EEEPC_P901),
12369        {}
12370};
12371
12372static struct alc_config_preset alc269_presets[] = {
12373        [ALC269_BASIC] = {
12374                .mixers = { alc269_base_mixer, alc269_capture_mixer },
12375                .init_verbs = { alc269_init_verbs },
12376                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377                .dac_nids = alc269_dac_nids,
12378                .hp_nid = 0x03,
12379                .num_channel_mode = ARRAY_SIZE(alc269_modes),
12380                .channel_mode = alc269_modes,
12381                .input_mux = &alc269_capture_source,
12382        },
12383        [ALC269_QUANTA_FL1] = {
12384                .mixers = { alc269_quanta_fl1_mixer },
12385                .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12386                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12387                .dac_nids = alc269_dac_nids,
12388                .hp_nid = 0x03,
12389                .num_channel_mode = ARRAY_SIZE(alc269_modes),
12390                .channel_mode = alc269_modes,
12391                .input_mux = &alc269_capture_source,
12392                .unsol_event = alc269_quanta_fl1_unsol_event,
12393                .init_hook = alc269_quanta_fl1_init_hook,
12394        },
12395        [ALC269_ASUS_EEEPC_P703] = {
12396                .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12397                .init_verbs = { alc269_init_verbs,
12398                                alc269_eeepc_amic_init_verbs },
12399                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12400                .dac_nids = alc269_dac_nids,
12401                .hp_nid = 0x03,
12402                .num_channel_mode = ARRAY_SIZE(alc269_modes),
12403                .channel_mode = alc269_modes,
12404                .input_mux = &alc269_eeepc_amic_capture_source,
12405                .unsol_event = alc269_eeepc_amic_unsol_event,
12406                .init_hook = alc269_eeepc_amic_inithook,
12407        },
12408        [ALC269_ASUS_EEEPC_P901] = {
12409                .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12410                .init_verbs = { alc269_init_verbs,
12411                                alc269_eeepc_dmic_init_verbs },
12412                .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12413                .dac_nids = alc269_dac_nids,
12414                .hp_nid = 0x03,
12415                .num_channel_mode = ARRAY_SIZE(alc269_modes),
12416                .channel_mode = alc269_modes,
12417                .input_mux = &alc269_eeepc_dmic_capture_source,
12418                .unsol_event = alc269_eeepc_dmic_unsol_event,
12419                .init_hook = alc269_eeepc_dmic_inithook,
12420        },
12421};
12422
12423static int patch_alc269(struct hda_codec *codec)
12424{
12425        struct alc_spec *spec;
12426        int board_config;
12427        int err;
12428
12429        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12430        if (spec == NULL)
12431                return -ENOMEM;
12432
12433        codec->spec = spec;
12434
12435        alc_fix_pll_init(codec, 0x20, 0x04, 15);
12436
12437        board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12438                                                  alc269_models,
12439                                                  alc269_cfg_tbl);
12440
12441        if (board_config < 0) {
12442                printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12443                       "trying auto-probe from BIOS...\n");
12444                board_config = ALC269_AUTO;
12445        }
12446
12447        if (board_config == ALC269_AUTO) {
12448                /* automatic parse from the BIOS config */
12449                err = alc269_parse_auto_config(codec);
12450                if (err < 0) {
12451                        alc_free(codec);
12452                        return err;
12453                } else if (!err) {
12454                        printk(KERN_INFO
12455                               "hda_codec: Cannot set up configuration "
12456                               "from BIOS.  Using base mode...\n");
12457                        board_config = ALC269_BASIC;
12458                }
12459        }
12460
12461        if (board_config != ALC269_AUTO)
12462                setup_preset(spec, &alc269_presets[board_config]);
12463
12464        spec->stream_name_analog = "ALC269 Analog";
12465        spec->stream_analog_playback = &alc269_pcm_analog_playback;
12466        spec->stream_analog_capture = &alc269_pcm_analog_capture;
12467
12468        spec->stream_name_digital = "ALC269 Digital";
12469        spec->stream_digital_playback = &alc269_pcm_digital_playback;
12470        spec->stream_digital_capture = &alc269_pcm_digital_capture;
12471
12472        spec->adc_nids = alc269_adc_nids;
12473        spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12474        spec->capsrc_nids = alc269_capsrc_nids;
12475
12476        codec->patch_ops = alc_patch_ops;
12477        if (board_config == ALC269_AUTO)
12478                spec->init_hook = alc269_auto_init;
12479#ifdef CONFIG_SND_HDA_POWER_SAVE
12480        if (!spec->loopback.amplist)
12481                spec->loopback.amplist = alc269_loopbacks;
12482#endif
12483
12484        return 0;
12485}
12486
12487/*
12488 *  ALC861 channel source setting (2/6 channel selection for 3-stack)
12489 */
12490
12491/*
12492 * set the path ways for 2 channel output
12493 * need to set the codec line out and mic 1 pin widgets to inputs
12494 */
12495static struct hda_verb alc861_threestack_ch2_init[] = {
12496        /* set pin widget 1Ah (line in) for input */
12497        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12498        /* set pin widget 18h (mic1/2) for input, for mic also enable
12499         * the vref
12500         */
12501        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12502
12503        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12504#if 0
12505        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12506        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12507#endif
12508        { } /* end */
12509};
12510/*
12511 * 6ch mode
12512 * need to set the codec line out and mic 1 pin widgets to outputs
12513 */
12514static struct hda_verb alc861_threestack_ch6_init[] = {
12515        /* set pin widget 1Ah (line in) for output (Back Surround)*/
12516        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12517        /* set pin widget 18h (mic1) for output (CLFE)*/
12518        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12519
12520        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12521        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12522
12523        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12524#if 0
12525        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12526        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12527#endif
12528        { } /* end */
12529};
12530
12531static struct hda_channel_mode alc861_threestack_modes[2] = {
12532        { 2, alc861_threestack_ch2_init },
12533        { 6, alc861_threestack_ch6_init },
12534};
12535/* Set mic1 as input and unmute the mixer */
12536static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12537        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12538        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12539        { } /* end */
12540};
12541/* Set mic1 as output and mute mixer */
12542static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12543        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12544        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12545        { } /* end */
12546};
12547
12548static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12549        { 2, alc861_uniwill_m31_ch2_init },
12550        { 4, alc861_uniwill_m31_ch4_init },
12551};
12552
12553/* Set mic1 and line-in as input and unmute the mixer */
12554static struct hda_verb alc861_asus_ch2_init[] = {
12555        /* set pin widget 1Ah (line in) for input */
12556        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12557        /* set pin widget 18h (mic1/2) for input, for mic also enable
12558         * the vref
12559         */
12560        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12561
12562        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12563#if 0
12564        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12565        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12566#endif
12567        { } /* end */
12568};
12569/* Set mic1 nad line-in as output and mute mixer */
12570static struct hda_verb alc861_asus_ch6_init[] = {
12571        /* set pin widget 1Ah (line in) for output (Back Surround)*/
12572        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12573        /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12574        /* set pin widget 18h (mic1) for output (CLFE)*/
12575        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12576        /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12577        { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12578        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12579
12580        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12581#if 0
12582        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12583        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12584#endif
12585        { } /* end */
12586};
12587
12588static struct hda_channel_mode alc861_asus_modes[2] = {
12589        { 2, alc861_asus_ch2_init },
12590        { 6, alc861_asus_ch6_init },
12591};
12592
12593/* patch-ALC861 */
12594
12595static struct snd_kcontrol_new alc861_base_mixer[] = {
12596        /* output mixer control */
12597        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12598        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12599        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12600        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12601        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12602
12603        /*Input mixer control */
12604        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12605           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12606        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12607        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12608        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12609        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12610        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12611        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12612        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12613        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12614
12615        /* Capture mixer control */
12616        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12617        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12618        {
12619                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12620                .name = "Capture Source",
12621                .count = 1,
12622                .info = alc_mux_enum_info,
12623                .get = alc_mux_enum_get,
12624                .put = alc_mux_enum_put,
12625        },
12626        { } /* end */
12627};
12628
12629static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12630        /* output mixer control */
12631        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12632        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12633        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12634        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12635        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12636
12637        /* Input mixer control */
12638        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12639           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12640        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12641        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12642        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12643        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12644        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12645        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12646        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12647        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12648
12649        /* Capture mixer control */
12650        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12651        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12652        {
12653                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12654                .name = "Capture Source",
12655                .count = 1,
12656                .info = alc_mux_enum_info,
12657                .get = alc_mux_enum_get,
12658                .put = alc_mux_enum_put,
12659        },
12660        {
12661                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662                .name = "Channel Mode",
12663                .info = alc_ch_mode_info,
12664                .get = alc_ch_mode_get,
12665                .put = alc_ch_mode_put,
12666                .private_value = ARRAY_SIZE(alc861_threestack_modes),
12667        },
12668        { } /* end */
12669};
12670
12671static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12672        /* output mixer control */
12673        HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12674        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12675        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12676
12677        /*Capture mixer control */
12678        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12679        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12680        {
12681                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12682                .name = "Capture Source",
12683                .count = 1,
12684                .info = alc_mux_enum_info,
12685                .get = alc_mux_enum_get,
12686                .put = alc_mux_enum_put,
12687        },
12688
12689        { } /* end */
12690};
12691
12692static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12693        /* output mixer control */
12694        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12695        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12696        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12697        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12698        /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12699
12700        /* Input mixer control */
12701        /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12702           HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12703        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12704        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12705        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12706        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12707        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12708        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12709        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12710        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12711
12712        /* Capture mixer control */
12713        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12714        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12715        {
12716                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12717                .name = "Capture Source",
12718                .count = 1,
12719                .info = alc_mux_enum_info,
12720                .get = alc_mux_enum_get,
12721                .put = alc_mux_enum_put,
12722        },
12723        {
12724                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12725                .name = "Channel Mode",
12726                .info = alc_ch_mode_info,
12727                .get = alc_ch_mode_get,
12728                .put = alc_ch_mode_put,
12729                .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12730        },
12731        { } /* end */
12732};
12733
12734static struct snd_kcontrol_new alc861_asus_mixer[] = {
12735        /* output mixer control */
12736        HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12737        HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12738        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12739        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12740        HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12741
12742        /* Input mixer control */
12743        HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12744        HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12745        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12746        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12747        HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12748        HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12749        HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12750        HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12751        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12752        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12753
12754        /* Capture mixer control */
12755        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12756        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12757        {
12758                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12759                .name = "Capture Source",
12760                .count = 1,
12761                .info = alc_mux_enum_info,
12762                .get = alc_mux_enum_get,
12763                .put = alc_mux_enum_put,
12764        },
12765        {
12766                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12767                .name = "Channel Mode",
12768                .info = alc_ch_mode_info,
12769                .get = alc_ch_mode_get,
12770                .put = alc_ch_mode_put,
12771                .private_value = ARRAY_SIZE(alc861_asus_modes),
12772        },
12773        { }
12774};
12775
12776/* additional mixer */
12777static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12778        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12779        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12780        HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12781        HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12782        { }
12783};
12784
12785/*
12786 * generic initialization of ADC, input mixers and output mixers
12787 */
12788static struct hda_verb alc861_base_init_verbs[] = {
12789        /*
12790         * Unmute ADC0 and set the default input to mic-in
12791         */
12792        /* port-A for surround (rear panel) */
12793        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12794        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12795        /* port-B for mic-in (rear panel) with vref */
12796        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12797        /* port-C for line-in (rear panel) */
12798        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12799        /* port-D for Front */
12800        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12801        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12802        /* port-E for HP out (front panel) */
12803        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12804        /* route front PCM to HP */
12805        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12806        /* port-F for mic-in (front panel) with vref */
12807        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12808        /* port-G for CLFE (rear panel) */
12809        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12810        { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12811        /* port-H for side (rear panel) */
12812        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12813        { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12814        /* CD-in */
12815        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12816        /* route front mic to ADC1*/
12817        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12818        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819
12820        /* Unmute DAC0~3 & spdif out*/
12821        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12822        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12823        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12824        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12825        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12826
12827        /* Unmute Mixer 14 (mic) 1c (Line in)*/
12828        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12829        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12830        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12831        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12832
12833        /* Unmute Stereo Mixer 15 */
12834        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12835        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12836        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12837        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12838
12839        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12840        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12841        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12842        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12843        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12844        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12845        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12846        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12847        /* hp used DAC 3 (Front) */
12848        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12849        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12850
12851        { }
12852};
12853
12854static struct hda_verb alc861_threestack_init_verbs[] = {
12855        /*
12856         * Unmute ADC0 and set the default input to mic-in
12857         */
12858        /* port-A for surround (rear panel) */
12859        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12860        /* port-B for mic-in (rear panel) with vref */
12861        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12862        /* port-C for line-in (rear panel) */
12863        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12864        /* port-D for Front */
12865        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12866        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12867        /* port-E for HP out (front panel) */
12868        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12869        /* route front PCM to HP */
12870        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12871        /* port-F for mic-in (front panel) with vref */
12872        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12873        /* port-G for CLFE (rear panel) */
12874        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12875        /* port-H for side (rear panel) */
12876        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12877        /* CD-in */
12878        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12879        /* route front mic to ADC1*/
12880        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12881        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12882        /* Unmute DAC0~3 & spdif out*/
12883        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12884        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12885        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12886        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12887        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12888
12889        /* Unmute Mixer 14 (mic) 1c (Line in)*/
12890        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12891        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12892        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12893        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12894
12895        /* Unmute Stereo Mixer 15 */
12896        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12897        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12898        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12899        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12900
12901        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12902        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12903        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12904        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12905        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12906        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12907        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12908        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12909        /* hp used DAC 3 (Front) */
12910        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12911        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12912        { }
12913};
12914
12915static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12916        /*
12917         * Unmute ADC0 and set the default input to mic-in
12918         */
12919        /* port-A for surround (rear panel) */
12920        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12921        /* port-B for mic-in (rear panel) with vref */
12922        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12923        /* port-C for line-in (rear panel) */
12924        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12925        /* port-D for Front */
12926        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12927        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12928        /* port-E for HP out (front panel) */
12929        /* this has to be set to VREF80 */
12930        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12931        /* route front PCM to HP */
12932        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12933        /* port-F for mic-in (front panel) with vref */
12934        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12935        /* port-G for CLFE (rear panel) */
12936        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12937        /* port-H for side (rear panel) */
12938        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12939        /* CD-in */
12940        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12941        /* route front mic to ADC1*/
12942        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12943        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12944        /* Unmute DAC0~3 & spdif out*/
12945        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12946        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12947        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12948        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12949        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12950
12951        /* Unmute Mixer 14 (mic) 1c (Line in)*/
12952        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12953        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12954        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12955        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12956
12957        /* Unmute Stereo Mixer 15 */
12958        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12959        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12960        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12961        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12962
12963        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12964        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12965        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12966        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12967        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12968        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12969        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12970        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12971        /* hp used DAC 3 (Front) */
12972        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12973        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12974        { }
12975};
12976
12977static struct hda_verb alc861_asus_init_verbs[] = {
12978        /*
12979         * Unmute ADC0 and set the default input to mic-in
12980         */
12981        /* port-A for surround (rear panel)
12982         * according to codec#0 this is the HP jack
12983         */
12984        { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12985        /* route front PCM to HP */
12986        { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12987        /* port-B for mic-in (rear panel) with vref */
12988        { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12989        /* port-C for line-in (rear panel) */
12990        { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12991        /* port-D for Front */
12992        { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12993        { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12994        /* port-E for HP out (front panel) */
12995        /* this has to be set to VREF80 */
12996        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12997        /* route front PCM to HP */
12998        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12999        /* port-F for mic-in (front panel) with vref */
13000        { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13001        /* port-G for CLFE (rear panel) */
13002        { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13003        /* port-H for side (rear panel) */
13004        { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13005        /* CD-in */
13006        { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13007        /* route front mic to ADC1*/
13008        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13009        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010        /* Unmute DAC0~3 & spdif out*/
13011        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13012        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13013        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13014        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13015        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13016        /* Unmute Mixer 14 (mic) 1c (Line in)*/
13017        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13018        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13019        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13020        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13021
13022        /* Unmute Stereo Mixer 15 */
13023        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13024        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13025        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13026        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13027
13028        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13029        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13030        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13031        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13032        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13033        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13034        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13035        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13036        /* hp used DAC 3 (Front) */
13037        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13038        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13039        { }
13040};
13041
13042/* additional init verbs for ASUS laptops */
13043static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13044        { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13045        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13046        { }
13047};
13048
13049/*
13050 * generic initialization of ADC, input mixers and output mixers
13051 */
13052static struct hda_verb alc861_auto_init_verbs[] = {
13053        /*
13054         * Unmute ADC0 and set the default input to mic-in
13055         */
13056        /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13057        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13058
13059        /* Unmute DAC0~3 & spdif out*/
13060        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13061        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13062        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13063        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13064        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13065
13066        /* Unmute Mixer 14 (mic) 1c (Line in)*/
13067        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13068        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13069        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13070        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13071
13072        /* Unmute Stereo Mixer 15 */
13073        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13074        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13075        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13076        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13077
13078        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13079        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13080        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13081        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13082        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13083        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13084        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13085        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13086
13087        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13088        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13089        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13090        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13091        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13092        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13093        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13094        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13095
13096        {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},        /* set Mic 1 */
13097
13098        { }
13099};
13100
13101static struct hda_verb alc861_toshiba_init_verbs[] = {
13102        {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13103
13104        { }
13105};
13106
13107/* toggle speaker-output according to the hp-jack state */
13108static void alc861_toshiba_automute(struct hda_codec *codec)
13109{
13110        unsigned int present;
13111
13112        present = snd_hda_codec_read(codec, 0x0f, 0,
13113                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13114        snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13115                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13116        snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13117                                 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13118}
13119
13120static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13121                                       unsigned int res)
13122{
13123        if ((res >> 26) == ALC880_HP_EVENT)
13124                alc861_toshiba_automute(codec);
13125}
13126
13127/* pcm configuration: identiacal with ALC880 */
13128#define alc861_pcm_analog_playback        alc880_pcm_analog_playback
13129#define alc861_pcm_analog_capture        alc880_pcm_analog_capture
13130#define alc861_pcm_digital_playback        alc880_pcm_digital_playback
13131#define alc861_pcm_digital_capture        alc880_pcm_digital_capture
13132
13133
13134#define ALC861_DIGOUT_NID        0x07
13135
13136static struct hda_channel_mode alc861_8ch_modes[1] = {
13137        { 8, NULL }
13138};
13139
13140static hda_nid_t alc861_dac_nids[4] = {
13141        /* front, surround, clfe, side */
13142        0x03, 0x06, 0x05, 0x04
13143};
13144
13145static hda_nid_t alc660_dac_nids[3] = {
13146        /* front, clfe, surround */
13147        0x03, 0x05, 0x06
13148};
13149
13150static hda_nid_t alc861_adc_nids[1] = {
13151        /* ADC0-2 */
13152        0x08,
13153};
13154
13155static struct hda_input_mux alc861_capture_source = {
13156        .num_items = 5,
13157        .items = {
13158                { "Mic", 0x0 },
13159                { "Front Mic", 0x3 },
13160                { "Line", 0x1 },
13161                { "CD", 0x4 },
13162                { "Mixer", 0x5 },
13163        },
13164};
13165
13166/* fill in the dac_nids table from the parsed pin configuration */
13167static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13168                                     const struct auto_pin_cfg *cfg)
13169{
13170        int i;
13171        hda_nid_t nid;
13172
13173        spec->multiout.dac_nids = spec->private_dac_nids;
13174        for (i = 0; i < cfg->line_outs; i++) {
13175                nid = cfg->line_out_pins[i];
13176                if (nid) {
13177                        if (i >= ARRAY_SIZE(alc861_dac_nids))
13178                                continue;
13179                        spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13180                }
13181        }
13182        spec->multiout.num_dacs = cfg->line_outs;
13183        return 0;
13184}
13185
13186/* add playback controls from the parsed DAC table */
13187static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13188                                             const struct auto_pin_cfg *cfg)
13189{
13190        char name[32];
13191        static const char *chname[4] = {
13192                "Front", "Surround", NULL /*CLFE*/, "Side"
13193        };
13194        hda_nid_t nid;
13195        int i, idx, err;
13196
13197        for (i = 0; i < cfg->line_outs; i++) {
13198                nid = spec->multiout.dac_nids[i];
13199                if (!nid)
13200                        continue;
13201                if (nid == 0x05) {
13202                        /* Center/LFE */
13203                        err = add_control(spec, ALC_CTL_BIND_MUTE,
13204                                          "Center Playback Switch",
13205                                          HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13206                                                              HDA_OUTPUT));
13207                        if (err < 0)
13208                                return err;
13209                        err = add_control(spec, ALC_CTL_BIND_MUTE,
13210                                          "LFE Playback Switch",
13211                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13212                                                              HDA_OUTPUT));
13213                        if (err < 0)
13214                                return err;
13215                } else {
13216                        for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13217                             idx++)
13218                                if (nid == alc861_dac_nids[idx])
13219                                        break;
13220                        sprintf(name, "%s Playback Switch", chname[idx]);
13221                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13222                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13223                                                              HDA_OUTPUT));
13224                        if (err < 0)
13225                                return err;
13226                }
13227        }
13228        return 0;
13229}
13230
13231static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13232{
13233        int err;
13234        hda_nid_t nid;
13235
13236        if (!pin)
13237                return 0;
13238
13239        if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13240                nid = 0x03;
13241                err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13242                                  "Headphone Playback Switch",
13243                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13244                if (err < 0)
13245                        return err;
13246                spec->multiout.hp_nid = nid;
13247        }
13248        return 0;
13249}
13250
13251/* create playback/capture controls for input pins */
13252static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13253                                                const struct auto_pin_cfg *cfg)
13254{
13255        struct hda_input_mux *imux = &spec->private_imux;
13256        int i, err, idx, idx1;
13257
13258        for (i = 0; i < AUTO_PIN_LAST; i++) {
13259                switch (cfg->input_pins[i]) {
13260                case 0x0c:
13261                        idx1 = 1;
13262                        idx = 2;        /* Line In */
13263                        break;
13264                case 0x0f:
13265                        idx1 = 2;
13266                        idx = 2;        /* Line In */
13267                        break;
13268                case 0x0d:
13269                        idx1 = 0;
13270                        idx = 1;        /* Mic In */
13271                        break;
13272                case 0x10:
13273                        idx1 = 3;
13274                        idx = 1;        /* Mic In */
13275                        break;
13276                case 0x11:
13277                        idx1 = 4;
13278                        idx = 0;        /* CD */
13279                        break;
13280                default:
13281                        continue;
13282                }
13283
13284                err = new_analog_input(spec, cfg->input_pins[i],
13285                                       auto_pin_cfg_labels[i], idx, 0x15);
13286                if (err < 0)
13287                        return err;
13288
13289                imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13290                imux->items[imux->num_items].index = idx1;
13291                imux->num_items++;
13292        }
13293        return 0;
13294}
13295
13296static struct snd_kcontrol_new alc861_capture_mixer[] = {
13297        HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13298        HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13299
13300        {
13301                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13302                /* The multiple "Capture Source" controls confuse alsamixer
13303                 * So call somewhat different..
13304                 */
13305                /* .name = "Capture Source", */
13306                .name = "Input Source",
13307                .count = 1,
13308                .info = alc_mux_enum_info,
13309                .get = alc_mux_enum_get,
13310                .put = alc_mux_enum_put,
13311        },
13312        { } /* end */
13313};
13314
13315static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13316                                              hda_nid_t nid,
13317                                              int pin_type, int dac_idx)
13318{
13319        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13320                            pin_type);
13321        snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13322                            AMP_OUT_UNMUTE);
13323}
13324
13325static void alc861_auto_init_multi_out(struct hda_codec *codec)
13326{
13327        struct alc_spec *spec = codec->spec;
13328        int i;
13329
13330        alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13331        for (i = 0; i < spec->autocfg.line_outs; i++) {
13332                hda_nid_t nid = spec->autocfg.line_out_pins[i];
13333                int pin_type = get_pin_type(spec->autocfg.line_out_type);
13334                if (nid)
13335                        alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13336                                                          spec->multiout.dac_nids[i]);
13337        }
13338}
13339
13340static void alc861_auto_init_hp_out(struct hda_codec *codec)
13341{
13342        struct alc_spec *spec = codec->spec;
13343        hda_nid_t pin;
13344
13345        pin = spec->autocfg.hp_pins[0];
13346        if (pin) /* connect to front */
13347                alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13348                                                  spec->multiout.dac_nids[0]);
13349        pin = spec->autocfg.speaker_pins[0];
13350        if (pin)
13351                alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13352}
13353
13354static void alc861_auto_init_analog_input(struct hda_codec *codec)
13355{
13356        struct alc_spec *spec = codec->spec;
13357        int i;
13358
13359        for (i = 0; i < AUTO_PIN_LAST; i++) {
13360                hda_nid_t nid = spec->autocfg.input_pins[i];
13361                if (nid >= 0x0c && nid <= 0x11) {
13362                        snd_hda_codec_write(codec, nid, 0,
13363                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
13364                                            i <= AUTO_PIN_FRONT_MIC ?
13365                                            PIN_VREF80 : PIN_IN);
13366                }
13367        }
13368}
13369
13370/* parse the BIOS configuration and set up the alc_spec */
13371/* return 1 if successful, 0 if the proper config is not found,
13372 * or a negative error code
13373 */
13374static int alc861_parse_auto_config(struct hda_codec *codec)
13375{
13376        struct alc_spec *spec = codec->spec;
13377        int err;
13378        static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13379
13380        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13381                                           alc861_ignore);
13382        if (err < 0)
13383                return err;
13384        if (!spec->autocfg.line_outs)
13385                return 0; /* can't find valid BIOS pin config */
13386
13387        err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13388        if (err < 0)
13389                return err;
13390        err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13391        if (err < 0)
13392                return err;
13393        err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13394        if (err < 0)
13395                return err;
13396        err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13397        if (err < 0)
13398                return err;
13399
13400        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13401
13402        if (spec->autocfg.dig_out_pin)
13403                spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13404
13405        if (spec->kctl_alloc)
13406                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13407
13408        spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
13409
13410        spec->num_mux_defs = 1;
13411        spec->input_mux = &spec->private_imux;
13412
13413        spec->adc_nids = alc861_adc_nids;
13414        spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13415        spec->mixers[spec->num_mixers] = alc861_capture_mixer;
13416        spec->num_mixers++;
13417
13418        store_pin_configs(codec);
13419        return 1;
13420}
13421
13422/* additional initialization for auto-configuration model */
13423static void alc861_auto_init(struct hda_codec *codec)
13424{
13425        struct alc_spec *spec = codec->spec;
13426        alc861_auto_init_multi_out(codec);
13427        alc861_auto_init_hp_out(codec);
13428        alc861_auto_init_analog_input(codec);
13429        if (spec->unsol_event)
13430                alc_inithook(codec);
13431}
13432
13433#ifdef CONFIG_SND_HDA_POWER_SAVE
13434static struct hda_amp_list alc861_loopbacks[] = {
13435        { 0x15, HDA_INPUT, 0 },
13436        { 0x15, HDA_INPUT, 1 },
13437        { 0x15, HDA_INPUT, 2 },
13438        { 0x15, HDA_INPUT, 3 },
13439        { } /* end */
13440};
13441#endif
13442
13443
13444/*
13445 * configuration and preset
13446 */
13447static const char *alc861_models[ALC861_MODEL_LAST] = {
13448        [ALC861_3ST]                = "3stack",
13449        [ALC660_3ST]                = "3stack-660",
13450        [ALC861_3ST_DIG]        = "3stack-dig",
13451        [ALC861_6ST_DIG]        = "6stack-dig",
13452        [ALC861_UNIWILL_M31]        = "uniwill-m31",
13453        [ALC861_TOSHIBA]        = "toshiba",
13454        [ALC861_ASUS]                = "asus",
13455        [ALC861_ASUS_LAPTOP]        = "asus-laptop",
13456        [ALC861_AUTO]                = "auto",
13457};
13458
13459static struct snd_pci_quirk alc861_cfg_tbl[] = {
13460        SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13461        SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13462        SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13463        SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13464        SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13465        SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13466        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13467        /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13468         *        Any other models that need this preset?
13469         */
13470        /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13471        SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13472        SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13473        SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13474        SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13475        SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13476        /* FIXME: the below seems conflict */
13477        /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13478        SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13479        SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13480        {}
13481};
13482
13483static struct alc_config_preset alc861_presets[] = {
13484        [ALC861_3ST] = {
13485                .mixers = { alc861_3ST_mixer },
13486                .init_verbs = { alc861_threestack_init_verbs },
13487                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13488                .dac_nids = alc861_dac_nids,
13489                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13490                .channel_mode = alc861_threestack_modes,
13491                .need_dac_fix = 1,
13492                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13493                .adc_nids = alc861_adc_nids,
13494                .input_mux = &alc861_capture_source,
13495        },
13496        [ALC861_3ST_DIG] = {
13497                .mixers = { alc861_base_mixer },
13498                .init_verbs = { alc861_threestack_init_verbs },
13499                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13500                .dac_nids = alc861_dac_nids,
13501                .dig_out_nid = ALC861_DIGOUT_NID,
13502                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13503                .channel_mode = alc861_threestack_modes,
13504                .need_dac_fix = 1,
13505                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13506                .adc_nids = alc861_adc_nids,
13507                .input_mux = &alc861_capture_source,
13508        },
13509        [ALC861_6ST_DIG] = {
13510                .mixers = { alc861_base_mixer },
13511                .init_verbs = { alc861_base_init_verbs },
13512                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13513                .dac_nids = alc861_dac_nids,
13514                .dig_out_nid = ALC861_DIGOUT_NID,
13515                .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13516                .channel_mode = alc861_8ch_modes,
13517                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13518                .adc_nids = alc861_adc_nids,
13519                .input_mux = &alc861_capture_source,
13520        },
13521        [ALC660_3ST] = {
13522                .mixers = { alc861_3ST_mixer },
13523                .init_verbs = { alc861_threestack_init_verbs },
13524                .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13525                .dac_nids = alc660_dac_nids,
13526                .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13527                .channel_mode = alc861_threestack_modes,
13528                .need_dac_fix = 1,
13529                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13530                .adc_nids = alc861_adc_nids,
13531                .input_mux = &alc861_capture_source,
13532        },
13533        [ALC861_UNIWILL_M31] = {
13534                .mixers = { alc861_uniwill_m31_mixer },
13535                .init_verbs = { alc861_uniwill_m31_init_verbs },
13536                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13537                .dac_nids = alc861_dac_nids,
13538                .dig_out_nid = ALC861_DIGOUT_NID,
13539                .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13540                .channel_mode = alc861_uniwill_m31_modes,
13541                .need_dac_fix = 1,
13542                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13543                .adc_nids = alc861_adc_nids,
13544                .input_mux = &alc861_capture_source,
13545        },
13546        [ALC861_TOSHIBA] = {
13547                .mixers = { alc861_toshiba_mixer },
13548                .init_verbs = { alc861_base_init_verbs,
13549                                alc861_toshiba_init_verbs },
13550                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13551                .dac_nids = alc861_dac_nids,
13552                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13553                .channel_mode = alc883_3ST_2ch_modes,
13554                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13555                .adc_nids = alc861_adc_nids,
13556                .input_mux = &alc861_capture_source,
13557                .unsol_event = alc861_toshiba_unsol_event,
13558                .init_hook = alc861_toshiba_automute,
13559        },
13560        [ALC861_ASUS] = {
13561                .mixers = { alc861_asus_mixer },
13562                .init_verbs = { alc861_asus_init_verbs },
13563                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13564                .dac_nids = alc861_dac_nids,
13565                .dig_out_nid = ALC861_DIGOUT_NID,
13566                .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13567                .channel_mode = alc861_asus_modes,
13568                .need_dac_fix = 1,
13569                .hp_nid = 0x06,
13570                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13571                .adc_nids = alc861_adc_nids,
13572                .input_mux = &alc861_capture_source,
13573        },
13574        [ALC861_ASUS_LAPTOP] = {
13575                .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13576                .init_verbs = { alc861_asus_init_verbs,
13577                                alc861_asus_laptop_init_verbs },
13578                .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13579                .dac_nids = alc861_dac_nids,
13580                .dig_out_nid = ALC861_DIGOUT_NID,
13581                .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13582                .channel_mode = alc883_3ST_2ch_modes,
13583                .need_dac_fix = 1,
13584                .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13585                .adc_nids = alc861_adc_nids,
13586                .input_mux = &alc861_capture_source,
13587        },
13588};
13589
13590
13591static int patch_alc861(struct hda_codec *codec)
13592{
13593        struct alc_spec *spec;
13594        int board_config;
13595        int err;
13596
13597        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13598        if (spec == NULL)
13599                return -ENOMEM;
13600
13601        codec->spec = spec;
13602
13603        board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13604                                                  alc861_models,
13605                                                  alc861_cfg_tbl);
13606
13607        if (board_config < 0) {
13608                printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13609                       "trying auto-probe from BIOS...\n");
13610                board_config = ALC861_AUTO;
13611        }
13612
13613        if (board_config == ALC861_AUTO) {
13614                /* automatic parse from the BIOS config */
13615                err = alc861_parse_auto_config(codec);
13616                if (err < 0) {
13617                        alc_free(codec);
13618                        return err;
13619                } else if (!err) {
13620                        printk(KERN_INFO
13621                               "hda_codec: Cannot set up configuration "
13622                               "from BIOS.  Using base mode...\n");
13623                   board_config = ALC861_3ST_DIG;
13624                }
13625        }
13626
13627        if (board_config != ALC861_AUTO)
13628                setup_preset(spec, &alc861_presets[board_config]);
13629
13630        spec->stream_name_analog = "ALC861 Analog";
13631        spec->stream_analog_playback = &alc861_pcm_analog_playback;
13632        spec->stream_analog_capture = &alc861_pcm_analog_capture;
13633
13634        spec->stream_name_digital = "ALC861 Digital";
13635        spec->stream_digital_playback = &alc861_pcm_digital_playback;
13636        spec->stream_digital_capture = &alc861_pcm_digital_capture;
13637
13638        spec->vmaster_nid = 0x03;
13639
13640        codec->patch_ops = alc_patch_ops;
13641        if (board_config == ALC861_AUTO)
13642                spec->init_hook = alc861_auto_init;
13643#ifdef CONFIG_SND_HDA_POWER_SAVE
13644        if (!spec->loopback.amplist)
13645                spec->loopback.amplist = alc861_loopbacks;
13646#endif
13647
13648        return 0;
13649}
13650
13651/*
13652 * ALC861-VD support
13653 *
13654 * Based on ALC882
13655 *
13656 * In addition, an independent DAC
13657 */
13658#define ALC861VD_DIGOUT_NID        0x06
13659
13660static hda_nid_t alc861vd_dac_nids[4] = {
13661        /* front, surr, clfe, side surr */
13662        0x02, 0x03, 0x04, 0x05
13663};
13664
13665/* dac_nids for ALC660vd are in a different order - according to
13666 * Realtek's driver.
13667 * This should probably tesult in a different mixer for 6stack models
13668 * of ALC660vd codecs, but for now there is only 3stack mixer
13669 * - and it is the same as in 861vd.
13670 * adc_nids in ALC660vd are (is) the same as in 861vd
13671 */
13672static hda_nid_t alc660vd_dac_nids[3] = {
13673        /* front, rear, clfe, rear_surr */
13674        0x02, 0x04, 0x03
13675};
13676
13677static hda_nid_t alc861vd_adc_nids[1] = {
13678        /* ADC0 */
13679        0x09,
13680};
13681
13682static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13683
13684/* input MUX */
13685/* FIXME: should be a matrix-type input source selection */
13686static struct hda_input_mux alc861vd_capture_source = {
13687        .num_items = 4,
13688        .items = {
13689                { "Mic", 0x0 },
13690                { "Front Mic", 0x1 },
13691                { "Line", 0x2 },
13692                { "CD", 0x4 },
13693        },
13694};
13695
13696static struct hda_input_mux alc861vd_dallas_capture_source = {
13697        .num_items = 2,
13698        .items = {
13699                { "Ext Mic", 0x0 },
13700                { "Int Mic", 0x1 },
13701        },
13702};
13703
13704static struct hda_input_mux alc861vd_hp_capture_source = {
13705        .num_items = 2,
13706        .items = {
13707                { "Front Mic", 0x0 },
13708                { "ATAPI Mic", 0x1 },
13709        },
13710};
13711
13712#define alc861vd_mux_enum_info alc_mux_enum_info
13713#define alc861vd_mux_enum_get alc_mux_enum_get
13714/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13715#define alc861vd_mux_enum_put alc882_mux_enum_put
13716
13717/*
13718 * 2ch mode
13719 */
13720static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13721        { 2, NULL }
13722};
13723
13724/*
13725 * 6ch mode
13726 */
13727static struct hda_verb alc861vd_6stack_ch6_init[] = {
13728        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13729        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13730        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13731        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13732        { } /* end */
13733};
13734
13735/*
13736 * 8ch mode
13737 */
13738static struct hda_verb alc861vd_6stack_ch8_init[] = {
13739        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13740        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13741        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13742        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13743        { } /* end */
13744};
13745
13746static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13747        { 6, alc861vd_6stack_ch6_init },
13748        { 8, alc861vd_6stack_ch8_init },
13749};
13750
13751static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13752        {
13753                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13754                .name = "Channel Mode",
13755                .info = alc_ch_mode_info,
13756                .get = alc_ch_mode_get,
13757                .put = alc_ch_mode_put,
13758        },
13759        { } /* end */
13760};
13761
13762static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13763        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13764        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13765
13766        {
13767                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13768                /* The multiple "Capture Source" controls confuse alsamixer
13769                 * So call somewhat different..
13770                 */
13771                /* .name = "Capture Source", */
13772                .name = "Input Source",
13773                .count = 1,
13774                .info = alc861vd_mux_enum_info,
13775                .get = alc861vd_mux_enum_get,
13776                .put = alc861vd_mux_enum_put,
13777        },
13778        { } /* end */
13779};
13780
13781/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13782 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13783 */
13784static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13785        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13786        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13787
13788        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13789        HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13790
13791        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13792                                HDA_OUTPUT),
13793        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13794                                HDA_OUTPUT),
13795        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13796        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13797
13798        HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13799        HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13800
13801        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13802
13803        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13804        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13805        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13806
13807        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13808        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13809        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13810
13811        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13812        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13813
13814        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13815        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13816
13817        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13818        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13819
13820        { } /* end */
13821};
13822
13823static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13824        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13825        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13826
13827        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13828
13829        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13830        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13831        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13832
13833        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13834        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13835        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13836
13837        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13838        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13839
13840        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13841        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13842
13843        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13844        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13845
13846        { } /* end */
13847};
13848
13849static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13850        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13851        /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13852        HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13853
13854        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13855
13856        HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13857        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13858        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13859
13860        HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13861        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13862        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13863
13864        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13865        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13866
13867        { } /* end */
13868};
13869
13870/* Pin assignment: Speaker=0x14, HP = 0x15,
13871 *                 Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13872 */
13873static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13874        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13875        HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13876        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13877        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13878        HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13879        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13880        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13881        HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13882        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13883        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13884        HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13885        HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13886        { } /* end */
13887};
13888
13889/* Pin assignment: Speaker=0x14, Line-out = 0x15,
13890 *                 Front Mic=0x18, ATAPI Mic = 0x19,
13891 */
13892static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13893        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13894        HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13895        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13896        HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13897        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13898        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13899        HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13900        HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13901
13902        { } /* end */
13903};
13904
13905/*
13906 * generic initialization of ADC, input mixers and output mixers
13907 */
13908static struct hda_verb alc861vd_volume_init_verbs[] = {
13909        /*
13910         * Unmute ADC0 and set the default input to mic-in
13911         */
13912        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13913        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13914
13915        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13916         * the analog-loopback mixer widget
13917         */
13918        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13919        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13920        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13921        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13922        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13923        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13924
13925        /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13926        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13927        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13928        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13929        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13930
13931        /*
13932         * Set up output mixers (0x02 - 0x05)
13933         */
13934        /* set vol=0 to output mixers */
13935        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13936        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13937        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13938        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13939
13940        /* set up input amps for analog loopback */
13941        /* Amp Indices: DAC = 0, mixer = 1 */
13942        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13943        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13944        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13945        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13946        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13947        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13948        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13949        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13950
13951        { }
13952};
13953
13954/*
13955 * 3-stack pin configuration:
13956 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13957 */
13958static struct hda_verb alc861vd_3stack_init_verbs[] = {
13959        /*
13960         * Set pin mode and muting
13961         */
13962        /* set front pin widgets 0x14 for output */
13963        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13964        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13965        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13966
13967        /* Mic (rear) pin: input vref at 80% */
13968        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13969        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13970        /* Front Mic pin: input vref at 80% */
13971        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13972        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13973        /* Line In pin: input */
13974        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13975        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13976        /* Line-2 In: Headphone output (output 0 - 0x0c) */
13977        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13978        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13979        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13980        /* CD pin widget for input */
13981        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13982
13983        { }
13984};
13985
13986/*
13987 * 6-stack pin configuration:
13988 */
13989static struct hda_verb alc861vd_6stack_init_verbs[] = {
13990        /*
13991         * Set pin mode and muting
13992         */
13993        /* set front pin widgets 0x14 for output */
13994        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13995        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13996        {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13997
13998        /* Rear Pin: output 1 (0x0d) */
13999        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14000        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14001        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14002        /* CLFE Pin: output 2 (0x0e) */
14003        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14005        {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14006        /* Side Pin: output 3 (0x0f) */
14007        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14008        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14009        {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14010
14011        /* Mic (rear) pin: input vref at 80% */
14012        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14013        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14014        /* Front Mic pin: input vref at 80% */
14015        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14016        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14017        /* Line In pin: input */
14018        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14019        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14020        /* Line-2 In: Headphone output (output 0 - 0x0c) */
14021        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14022        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14023        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14024        /* CD pin widget for input */
14025        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14026
14027        { }
14028};
14029
14030static struct hda_verb alc861vd_eapd_verbs[] = {
14031        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14032        { }
14033};
14034
14035static struct hda_verb alc660vd_eapd_verbs[] = {
14036        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14037        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14038        { }
14039};
14040
14041static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14042        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14043        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14044        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14045        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14046        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14047        {}
14048};
14049
14050/* toggle speaker-output according to the hp-jack state */
14051static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14052{
14053        unsigned int present;
14054        unsigned char bits;
14055
14056        present = snd_hda_codec_read(codec, 0x1b, 0,
14057                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14058        bits = present ? HDA_AMP_MUTE : 0;
14059        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14060                                 HDA_AMP_MUTE, bits);
14061}
14062
14063static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14064{
14065        unsigned int present;
14066        unsigned char bits;
14067
14068        present = snd_hda_codec_read(codec, 0x18, 0,
14069                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14070        bits = present ? HDA_AMP_MUTE : 0;
14071        snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14072                                 HDA_AMP_MUTE, bits);
14073}
14074
14075static void alc861vd_lenovo_automute(struct hda_codec *codec)
14076{
14077        alc861vd_lenovo_hp_automute(codec);
14078        alc861vd_lenovo_mic_automute(codec);
14079}
14080
14081static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14082                                        unsigned int res)
14083{
14084        switch (res >> 26) {
14085        case ALC880_HP_EVENT:
14086                alc861vd_lenovo_hp_automute(codec);
14087                break;
14088        case ALC880_MIC_EVENT:
14089                alc861vd_lenovo_mic_automute(codec);
14090                break;
14091        }
14092}
14093
14094static struct hda_verb alc861vd_dallas_verbs[] = {
14095        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14096        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14097        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14098        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14099
14100        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14101        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14102        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14103        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14104        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14105        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14106        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14107        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14108
14109        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14110        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14111        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14112        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14113        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14114        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14115        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14116        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14117
14118        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14119        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14120        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14121        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14122        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14123        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14124        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14125        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14126
14127        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14128        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14129        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14130        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14131
14132        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14133        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14134        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14135
14136        { } /* end */
14137};
14138
14139/* toggle speaker-output according to the hp-jack state */
14140static void alc861vd_dallas_automute(struct hda_codec *codec)
14141{
14142        unsigned int present;
14143
14144        present = snd_hda_codec_read(codec, 0x15, 0,
14145                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14146        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14147                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14148}
14149
14150static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14151{
14152        if ((res >> 26) == ALC880_HP_EVENT)
14153                alc861vd_dallas_automute(codec);
14154}
14155
14156#ifdef CONFIG_SND_HDA_POWER_SAVE
14157#define alc861vd_loopbacks        alc880_loopbacks
14158#endif
14159
14160/* pcm configuration: identiacal with ALC880 */
14161#define alc861vd_pcm_analog_playback        alc880_pcm_analog_playback
14162#define alc861vd_pcm_analog_capture        alc880_pcm_analog_capture
14163#define alc861vd_pcm_digital_playback        alc880_pcm_digital_playback
14164#define alc861vd_pcm_digital_capture        alc880_pcm_digital_capture
14165
14166/*
14167 * configuration and preset
14168 */
14169static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14170        [ALC660VD_3ST]                = "3stack-660",
14171        [ALC660VD_3ST_DIG]        = "3stack-660-digout",
14172        [ALC861VD_3ST]                = "3stack",
14173        [ALC861VD_3ST_DIG]        = "3stack-digout",
14174        [ALC861VD_6ST_DIG]        = "6stack-digout",
14175        [ALC861VD_LENOVO]        = "lenovo",
14176        [ALC861VD_DALLAS]        = "dallas",
14177        [ALC861VD_HP]                = "hp",
14178        [ALC861VD_AUTO]                = "auto",
14179};
14180
14181static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14182        SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14183        SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14184        SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14185        SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14186        SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14187        SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14188        SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14189        SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14190        /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14191        SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14192        SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14193        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14194        SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14195        SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14196        SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14197        SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14198        SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14199        {}
14200};
14201
14202static struct alc_config_preset alc861vd_presets[] = {
14203        [ALC660VD_3ST] = {
14204                .mixers = { alc861vd_3st_mixer },
14205                .init_verbs = { alc861vd_volume_init_verbs,
14206                                 alc861vd_3stack_init_verbs },
14207                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14208                .dac_nids = alc660vd_dac_nids,
14209                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14210                .channel_mode = alc861vd_3stack_2ch_modes,
14211                .input_mux = &alc861vd_capture_source,
14212        },
14213        [ALC660VD_3ST_DIG] = {
14214                .mixers = { alc861vd_3st_mixer },
14215                .init_verbs = { alc861vd_volume_init_verbs,
14216                                 alc861vd_3stack_init_verbs },
14217                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14218                .dac_nids = alc660vd_dac_nids,
14219                .dig_out_nid = ALC861VD_DIGOUT_NID,
14220                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14221                .channel_mode = alc861vd_3stack_2ch_modes,
14222                .input_mux = &alc861vd_capture_source,
14223        },
14224        [ALC861VD_3ST] = {
14225                .mixers = { alc861vd_3st_mixer },
14226                .init_verbs = { alc861vd_volume_init_verbs,
14227                                 alc861vd_3stack_init_verbs },
14228                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14229                .dac_nids = alc861vd_dac_nids,
14230                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14231                .channel_mode = alc861vd_3stack_2ch_modes,
14232                .input_mux = &alc861vd_capture_source,
14233        },
14234        [ALC861VD_3ST_DIG] = {
14235                .mixers = { alc861vd_3st_mixer },
14236                .init_verbs = { alc861vd_volume_init_verbs,
14237                                  alc861vd_3stack_init_verbs },
14238                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14239                .dac_nids = alc861vd_dac_nids,
14240                .dig_out_nid = ALC861VD_DIGOUT_NID,
14241                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14242                .channel_mode = alc861vd_3stack_2ch_modes,
14243                .input_mux = &alc861vd_capture_source,
14244        },
14245        [ALC861VD_6ST_DIG] = {
14246                .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14247                .init_verbs = { alc861vd_volume_init_verbs,
14248                                alc861vd_6stack_init_verbs },
14249                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14250                .dac_nids = alc861vd_dac_nids,
14251                .dig_out_nid = ALC861VD_DIGOUT_NID,
14252                .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14253                .channel_mode = alc861vd_6stack_modes,
14254                .input_mux = &alc861vd_capture_source,
14255        },
14256        [ALC861VD_LENOVO] = {
14257                .mixers = { alc861vd_lenovo_mixer },
14258                .init_verbs = { alc861vd_volume_init_verbs,
14259                                alc861vd_3stack_init_verbs,
14260                                alc861vd_eapd_verbs,
14261                                alc861vd_lenovo_unsol_verbs },
14262                .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14263                .dac_nids = alc660vd_dac_nids,
14264                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14265                .channel_mode = alc861vd_3stack_2ch_modes,
14266                .input_mux = &alc861vd_capture_source,
14267                .unsol_event = alc861vd_lenovo_unsol_event,
14268                .init_hook = alc861vd_lenovo_automute,
14269        },
14270        [ALC861VD_DALLAS] = {
14271                .mixers = { alc861vd_dallas_mixer },
14272                .init_verbs = { alc861vd_dallas_verbs },
14273                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14274                .dac_nids = alc861vd_dac_nids,
14275                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14276                .channel_mode = alc861vd_3stack_2ch_modes,
14277                .input_mux = &alc861vd_dallas_capture_source,
14278                .unsol_event = alc861vd_dallas_unsol_event,
14279                .init_hook = alc861vd_dallas_automute,
14280        },
14281        [ALC861VD_HP] = {
14282                .mixers = { alc861vd_hp_mixer },
14283                .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14284                .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14285                .dac_nids = alc861vd_dac_nids,
14286                .dig_out_nid = ALC861VD_DIGOUT_NID,
14287                .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14288                .channel_mode = alc861vd_3stack_2ch_modes,
14289                .input_mux = &alc861vd_hp_capture_source,
14290                .unsol_event = alc861vd_dallas_unsol_event,
14291                .init_hook = alc861vd_dallas_automute,
14292        },
14293};
14294
14295/*
14296 * BIOS auto configuration
14297 */
14298static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14299                                hda_nid_t nid, int pin_type, int dac_idx)
14300{
14301        alc_set_pin_output(codec, nid, pin_type);
14302}
14303
14304static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14305{
14306        struct alc_spec *spec = codec->spec;
14307        int i;
14308
14309        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14310        for (i = 0; i <= HDA_SIDE; i++) {
14311                hda_nid_t nid = spec->autocfg.line_out_pins[i];
14312                int pin_type = get_pin_type(spec->autocfg.line_out_type);
14313                if (nid)
14314                        alc861vd_auto_set_output_and_unmute(codec, nid,
14315                                                            pin_type, i);
14316        }
14317}
14318
14319
14320static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14321{
14322        struct alc_spec *spec = codec->spec;
14323        hda_nid_t pin;
14324
14325        pin = spec->autocfg.hp_pins[0];
14326        if (pin) /* connect to front and  use dac 0 */
14327                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14328        pin = spec->autocfg.speaker_pins[0];
14329        if (pin)
14330                alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14331}
14332
14333#define alc861vd_is_input_pin(nid)        alc880_is_input_pin(nid)
14334#define ALC861VD_PIN_CD_NID                ALC880_PIN_CD_NID
14335
14336static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14337{
14338        struct alc_spec *spec = codec->spec;
14339        int i;
14340
14341        for (i = 0; i < AUTO_PIN_LAST; i++) {
14342                hda_nid_t nid = spec->autocfg.input_pins[i];
14343                if (alc861vd_is_input_pin(nid)) {
14344                        snd_hda_codec_write(codec, nid, 0,
14345                                        AC_VERB_SET_PIN_WIDGET_CONTROL,
14346                                        i <= AUTO_PIN_FRONT_MIC ?
14347                                                        PIN_VREF80 : PIN_IN);
14348                        if (nid != ALC861VD_PIN_CD_NID)
14349                                snd_hda_codec_write(codec, nid, 0,
14350                                                AC_VERB_SET_AMP_GAIN_MUTE,
14351                                                AMP_OUT_MUTE);
14352                }
14353        }
14354}
14355
14356#define alc861vd_auto_init_input_src        alc882_auto_init_input_src
14357
14358#define alc861vd_idx_to_mixer_vol(nid)                ((nid) + 0x02)
14359#define alc861vd_idx_to_mixer_switch(nid)        ((nid) + 0x0c)
14360
14361/* add playback controls from the parsed DAC table */
14362/* Based on ALC880 version. But ALC861VD has separate,
14363 * different NIDs for mute/unmute switch and volume control */
14364static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14365                                             const struct auto_pin_cfg *cfg)
14366{
14367        char name[32];
14368        static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14369        hda_nid_t nid_v, nid_s;
14370        int i, err;
14371
14372        for (i = 0; i < cfg->line_outs; i++) {
14373                if (!spec->multiout.dac_nids[i])
14374                        continue;
14375                nid_v = alc861vd_idx_to_mixer_vol(
14376                                alc880_dac_to_idx(
14377                                        spec->multiout.dac_nids[i]));
14378                nid_s = alc861vd_idx_to_mixer_switch(
14379                                alc880_dac_to_idx(
14380                                        spec->multiout.dac_nids[i]));
14381
14382                if (i == 2) {
14383                        /* Center/LFE */
14384                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
14385                                          "Center Playback Volume",
14386                                          HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14387                                                              HDA_OUTPUT));
14388                        if (err < 0)
14389                                return err;
14390                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
14391                                          "LFE Playback Volume",
14392                                          HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14393                                                              HDA_OUTPUT));
14394                        if (err < 0)
14395                                return err;
14396                        err = add_control(spec, ALC_CTL_BIND_MUTE,
14397                                          "Center Playback Switch",
14398                                          HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14399                                                              HDA_INPUT));
14400                        if (err < 0)
14401                                return err;
14402                        err = add_control(spec, ALC_CTL_BIND_MUTE,
14403                                          "LFE Playback Switch",
14404                                          HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14405                                                              HDA_INPUT));
14406                        if (err < 0)
14407                                return err;
14408                } else {
14409                        sprintf(name, "%s Playback Volume", chname[i]);
14410                        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14411                                          HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14412                                                              HDA_OUTPUT));
14413                        if (err < 0)
14414                                return err;
14415                        sprintf(name, "%s Playback Switch", chname[i]);
14416                        err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14417                                          HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14418                                                              HDA_INPUT));
14419                        if (err < 0)
14420                                return err;
14421                }
14422        }
14423        return 0;
14424}
14425
14426/* add playback controls for speaker and HP outputs */
14427/* Based on ALC880 version. But ALC861VD has separate,
14428 * different NIDs for mute/unmute switch and volume control */
14429static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14430                                        hda_nid_t pin, const char *pfx)
14431{
14432        hda_nid_t nid_v, nid_s;
14433        int err;
14434        char name[32];
14435
14436        if (!pin)
14437                return 0;
14438
14439        if (alc880_is_fixed_pin(pin)) {
14440                nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14441                /* specify the DAC as the extra output */
14442                if (!spec->multiout.hp_nid)
14443                        spec->multiout.hp_nid = nid_v;
14444                else
14445                        spec->multiout.extra_out_nid[0] = nid_v;
14446                /* control HP volume/switch on the output mixer amp */
14447                nid_v = alc861vd_idx_to_mixer_vol(
14448                                alc880_fixed_pin_idx(pin));
14449                nid_s = alc861vd_idx_to_mixer_switch(
14450                                alc880_fixed_pin_idx(pin));
14451
14452                sprintf(name, "%s Playback Volume", pfx);
14453                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14454                                  HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14455                if (err < 0)
14456                        return err;
14457                sprintf(name, "%s Playback Switch", pfx);
14458                err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14459                                  HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14460                if (err < 0)
14461                        return err;
14462        } else if (alc880_is_multi_pin(pin)) {
14463                /* set manual connection */
14464                /* we have only a switch on HP-out PIN */
14465                sprintf(name, "%s Playback Switch", pfx);
14466                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14467                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14468                if (err < 0)
14469                        return err;
14470        }
14471        return 0;
14472}
14473
14474/* parse the BIOS configuration and set up the alc_spec
14475 * return 1 if successful, 0 if the proper config is not found,
14476 * or a negative error code
14477 * Based on ALC880 version - had to change it to override
14478 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14479static int alc861vd_parse_auto_config(struct hda_codec *codec)
14480{
14481        struct alc_spec *spec = codec->spec;
14482        int err;
14483        static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14484
14485        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14486                                           alc861vd_ignore);
14487        if (err < 0)
14488                return err;
14489        if (!spec->autocfg.line_outs)
14490                return 0; /* can't find valid BIOS pin config */
14491
14492        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14493        if (err < 0)
14494                return err;
14495        err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14496        if (err < 0)
14497                return err;
14498        err = alc861vd_auto_create_extra_out(spec,
14499                                             spec->autocfg.speaker_pins[0],
14500                                             "Speaker");
14501        if (err < 0)
14502                return err;
14503        err = alc861vd_auto_create_extra_out(spec,
14504                                             spec->autocfg.hp_pins[0],
14505                                             "Headphone");
14506        if (err < 0)
14507                return err;
14508        err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14509        if (err < 0)
14510                return err;
14511
14512        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14513
14514        if (spec->autocfg.dig_out_pin)
14515                spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14516
14517        if (spec->kctl_alloc)
14518                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14519
14520        spec->init_verbs[spec->num_init_verbs++]
14521                = alc861vd_volume_init_verbs;
14522
14523        spec->num_mux_defs = 1;
14524        spec->input_mux = &spec->private_imux;
14525
14526        err = alc_auto_add_mic_boost(codec);
14527        if (err < 0)
14528                return err;
14529
14530        store_pin_configs(codec);
14531        return 1;
14532}
14533
14534/* additional initialization for auto-configuration model */
14535static void alc861vd_auto_init(struct hda_codec *codec)
14536{
14537        struct alc_spec *spec = codec->spec;
14538        alc861vd_auto_init_multi_out(codec);
14539        alc861vd_auto_init_hp_out(codec);
14540        alc861vd_auto_init_analog_input(codec);
14541        alc861vd_auto_init_input_src(codec);
14542        if (spec->unsol_event)
14543                alc_inithook(codec);
14544}
14545
14546static int patch_alc861vd(struct hda_codec *codec)
14547{
14548        struct alc_spec *spec;
14549        int err, board_config;
14550
14551        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14552        if (spec == NULL)
14553                return -ENOMEM;
14554
14555        codec->spec = spec;
14556
14557        board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14558                                                  alc861vd_models,
14559                                                  alc861vd_cfg_tbl);
14560
14561        if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14562                printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14563                        "ALC861VD, trying auto-probe from BIOS...\n");
14564                board_config = ALC861VD_AUTO;
14565        }
14566
14567        if (board_config == ALC861VD_AUTO) {
14568                /* automatic parse from the BIOS config */
14569                err = alc861vd_parse_auto_config(codec);
14570                if (err < 0) {
14571                        alc_free(codec);
14572                        return err;
14573                } else if (!err) {
14574                        printk(KERN_INFO
14575                               "hda_codec: Cannot set up configuration "
14576                               "from BIOS.  Using base mode...\n");
14577                        board_config = ALC861VD_3ST;
14578                }
14579        }
14580
14581        if (board_config != ALC861VD_AUTO)
14582                setup_preset(spec, &alc861vd_presets[board_config]);
14583
14584        if (codec->vendor_id == 0x10ec0660) {
14585                spec->stream_name_analog = "ALC660-VD Analog";
14586                spec->stream_name_digital = "ALC660-VD Digital";
14587                /* always turn on EAPD */
14588                spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs;
14589        } else {
14590                spec->stream_name_analog = "ALC861VD Analog";
14591                spec->stream_name_digital = "ALC861VD Digital";
14592        }
14593
14594        spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14595        spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14596
14597        spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14598        spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14599
14600        spec->adc_nids = alc861vd_adc_nids;
14601        spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14602        spec->capsrc_nids = alc861vd_capsrc_nids;
14603
14604        spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
14605        spec->num_mixers++;
14606
14607        spec->vmaster_nid = 0x02;
14608
14609        codec->patch_ops = alc_patch_ops;
14610
14611        if (board_config == ALC861VD_AUTO)
14612                spec->init_hook = alc861vd_auto_init;
14613#ifdef CONFIG_SND_HDA_POWER_SAVE
14614        if (!spec->loopback.amplist)
14615                spec->loopback.amplist = alc861vd_loopbacks;
14616#endif
14617
14618        return 0;
14619}
14620
14621/*
14622 * ALC662 support
14623 *
14624 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14625 * configuration.  Each pin widget can choose any input DACs and a mixer.
14626 * Each ADC is connected from a mixer of all inputs.  This makes possible
14627 * 6-channel independent captures.
14628 *
14629 * In addition, an independent DAC for the multi-playback (not used in this
14630 * driver yet).
14631 */
14632#define ALC662_DIGOUT_NID        0x06
14633#define ALC662_DIGIN_NID        0x0a
14634
14635static hda_nid_t alc662_dac_nids[4] = {
14636        /* front, rear, clfe, rear_surr */
14637        0x02, 0x03, 0x04
14638};
14639
14640static hda_nid_t alc662_adc_nids[1] = {
14641        /* ADC1-2 */
14642        0x09,
14643};
14644
14645static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14646
14647/* input MUX */
14648/* FIXME: should be a matrix-type input source selection */
14649static struct hda_input_mux alc662_capture_source = {
14650        .num_items = 4,
14651        .items = {
14652                { "Mic", 0x0 },
14653                { "Front Mic", 0x1 },
14654                { "Line", 0x2 },
14655                { "CD", 0x4 },
14656        },
14657};
14658
14659static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14660        .num_items = 2,
14661        .items = {
14662                { "Mic", 0x1 },
14663                { "Line", 0x2 },
14664        },
14665};
14666
14667static struct hda_input_mux alc662_eeepc_capture_source = {
14668        .num_items = 2,
14669        .items = {
14670                { "i-Mic", 0x1 },
14671                { "e-Mic", 0x0 },
14672        },
14673};
14674
14675static struct hda_input_mux alc663_capture_source = {
14676        .num_items = 3,
14677        .items = {
14678                { "Mic", 0x0 },
14679                { "Front Mic", 0x1 },
14680                { "Line", 0x2 },
14681        },
14682};
14683
14684static struct hda_input_mux alc663_m51va_capture_source = {
14685        .num_items = 2,
14686        .items = {
14687                { "Ext-Mic", 0x0 },
14688                { "D-Mic", 0x9 },
14689        },
14690};
14691
14692#define alc662_mux_enum_info alc_mux_enum_info
14693#define alc662_mux_enum_get alc_mux_enum_get
14694#define alc662_mux_enum_put alc882_mux_enum_put
14695
14696/*
14697 * 2ch mode
14698 */
14699static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14700        { 2, NULL }
14701};
14702
14703/*
14704 * 2ch mode
14705 */
14706static struct hda_verb alc662_3ST_ch2_init[] = {
14707        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14708        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14709        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14710        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14711        { } /* end */
14712};
14713
14714/*
14715 * 6ch mode
14716 */
14717static struct hda_verb alc662_3ST_ch6_init[] = {
14718        { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14719        { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14720        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14721        { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14722        { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14723        { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14724        { } /* end */
14725};
14726
14727static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14728        { 2, alc662_3ST_ch2_init },
14729        { 6, alc662_3ST_ch6_init },
14730};
14731
14732/*
14733 * 2ch mode
14734 */
14735static struct hda_verb alc662_sixstack_ch6_init[] = {
14736        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14737        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14738        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14739        { } /* end */
14740};
14741
14742/*
14743 * 6ch mode
14744 */
14745static struct hda_verb alc662_sixstack_ch8_init[] = {
14746        { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14747        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14748        { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14749        { } /* end */
14750};
14751
14752static struct hda_channel_mode alc662_5stack_modes[2] = {
14753        { 2, alc662_sixstack_ch6_init },
14754        { 6, alc662_sixstack_ch8_init },
14755};
14756
14757/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14758 *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14759 */
14760
14761static struct snd_kcontrol_new alc662_base_mixer[] = {
14762        /* output mixer control */
14763        HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14764        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14765        HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14766        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14767        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14768        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14769        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14770        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14771        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14772
14773        /*Input mixer control */
14774        HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14775        HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14776        HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14777        HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14778        HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14779        HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14780        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14781        HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14782        { } /* end */
14783};
14784
14785static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14786        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14787        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14788        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14789        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14790        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14791        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14792        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14793        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14794        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14795        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14796        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14797        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14798        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14799        { } /* end */
14800};
14801
14802static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14803        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14804        HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14805        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14806        HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14807        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14808        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14809        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14810        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14811        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14812        HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14813        HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14814        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14815        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14816        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14817        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14818        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14819        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14820        HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14821        HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14822        { } /* end */
14823};
14824
14825static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14826        HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14827        HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14828        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14829        HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14830        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14831        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14832        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14833        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14834        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14835        { } /* end */
14836};
14837
14838static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14839        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14840
14841        HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14842        HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14843
14844        HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14845        HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14846        HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14847
14848        HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14849        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14850        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14851        { } /* end */
14852};
14853
14854static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14855        HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14856        HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14857        HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14858        HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14859        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14860        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14861        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14862        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14863        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14864        HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14865        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14866        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14867        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14868        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14869        { } /* end */
14870};
14871
14872static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14873        .ops = &snd_hda_bind_vol,
14874        .values = {
14875                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14876                HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14877                0
14878        },
14879};
14880
14881static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14882        .ops = &snd_hda_bind_sw,
14883        .values = {
14884                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14885                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14886                0
14887        },
14888};
14889
14890static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14891        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14892        HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14893        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14894        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14895        { } /* end */
14896};
14897
14898static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14899        .ops = &snd_hda_bind_sw,
14900        .values = {
14901                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14902                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14903                HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14904                0
14905        },
14906};
14907
14908static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14909        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14910        HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14911        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14912        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14913        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14914        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14915
14916        { } /* end */
14917};
14918
14919static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14920        .ops = &snd_hda_bind_sw,
14921        .values = {
14922                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14923                HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14924                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14925                0
14926        },
14927};
14928
14929static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14930        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14931        HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14932        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14933        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14934        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14935        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14936        { } /* end */
14937};
14938
14939static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14940        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14941        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14942        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14943        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14944        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14945        HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14946        HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14947        { } /* end */
14948};
14949
14950static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14951        .ops = &snd_hda_bind_vol,
14952        .values = {
14953                HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14954                HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14955                0
14956        },
14957};
14958
14959static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14960        .ops = &snd_hda_bind_sw,
14961        .values = {
14962                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14963                HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14964                0
14965        },
14966};
14967
14968static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14969        HDA_BIND_VOL("Master Playback Volume",
14970                                &alc663_asus_two_bind_master_vol),
14971        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14972        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14973        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14974        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14975        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14976        { } /* end */
14977};
14978
14979static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14980        HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14981        HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14982        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14983        HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14984        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14985        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14986        { } /* end */
14987};
14988
14989static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14990        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14991        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14992        HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14993        HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14994        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14995
14996        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14997        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14998        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14999        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15000        { } /* end */
15001};
15002
15003static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15004        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15005        HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15006        HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15007
15008        HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15009        HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15010        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15011        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15012        HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15013        HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15014        { } /* end */
15015};
15016
15017static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15018        {
15019                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15020                .name = "Channel Mode",
15021                .info = alc_ch_mode_info,
15022                .get = alc_ch_mode_get,
15023                .put = alc_ch_mode_put,
15024        },
15025        { } /* end */
15026};
15027
15028static struct hda_verb alc662_init_verbs[] = {
15029        /* ADC: mute amp left and right */
15030        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15031        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15032        /* Front mixer: unmute input/output amp left and right (volume = 0) */
15033
15034        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15035        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15036        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15037        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15038        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15039
15040        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15041        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15042        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15043        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15044        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15045        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15046
15047        /* Front Pin: output 0 (0x0c) */
15048        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15049        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050
15051        /* Rear Pin: output 1 (0x0d) */
15052        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15053        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15054
15055        /* CLFE Pin: output 2 (0x0e) */
15056        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15057        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15058
15059        /* Mic (rear) pin: input vref at 80% */
15060        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15061        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15062        /* Front Mic pin: input vref at 80% */
15063        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15064        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15065        /* Line In pin: input */
15066        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15067        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15068        /* Line-2 In: Headphone output (output 0 - 0x0c) */
15069        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15070        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15071        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15072        /* CD pin widget for input */
15073        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15074
15075        /* FIXME: use matrix-type input source selection */
15076        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15077        /* Input mixer */
15078        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15079        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15080        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15081        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15082
15083        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15084        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15085        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15086        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15087
15088        /* always trun on EAPD */
15089        {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15090        {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15091
15092        { }
15093};
15094
15095static struct hda_verb alc662_sue_init_verbs[] = {
15096        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15097        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15098        {}
15099};
15100
15101static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15102        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15103        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15104        {}
15105};
15106
15107/* Set Unsolicited Event*/
15108static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15109        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15110        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15111        {}
15112};
15113
15114/*
15115 * generic initialization of ADC, input mixers and output mixers
15116 */
15117static struct hda_verb alc662_auto_init_verbs[] = {
15118        /*
15119         * Unmute ADC and set the default input to mic-in
15120         */
15121        {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15122        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15123
15124        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15125         * mixer widget
15126         * Note: PASD motherboards uses the Line In 2 as the input for front
15127         * panel mic (mic 2)
15128         */
15129        /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15130        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15131        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15132        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15133        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15134        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15135
15136        /*
15137         * Set up output mixers (0x0c - 0x0f)
15138         */
15139        /* set vol=0 to output mixers */
15140        {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15141        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15142        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15143
15144        /* set up input amps for analog loopback */
15145        /* Amp Indices: DAC = 0, mixer = 1 */
15146        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15147        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15148        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15149        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15150        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15151        {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15152
15153
15154        /* FIXME: use matrix-type input source selection */
15155        /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15156        /* Input mixer */
15157        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15158        {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159        { }
15160};
15161
15162/* additional verbs for ALC663 */
15163static struct hda_verb alc663_auto_init_verbs[] = {
15164        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15165        {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15166        { }
15167};
15168
15169static struct hda_verb alc663_m51va_init_verbs[] = {
15170        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15171        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15172        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15173        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15174        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Headphone */
15175        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15176        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15177        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15178        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15179        {}
15180};
15181
15182static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15183        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15184        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15185        {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Headphone */
15186        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15187        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15188        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15189        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15190        {}
15191};
15192
15193static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15194        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15195        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15196        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15197        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},        /* Headphone */
15198        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15199        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15200        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15201        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15202        {}
15203};
15204
15205static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15206        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15207        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15208        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Headphone */
15209        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15210        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15211        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15212        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15213        {}
15214};
15215
15216static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15217        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15218        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15219        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15220        {0x21, AC_VERB_SET_CONNECT_SEL, 0x0},        /* Headphone */
15221        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15222        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15223        {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},        /* Headphone */
15224        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15225        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15226        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15227        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15228        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15229        {}
15230};
15231
15232static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15233        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15234        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15235        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15236        {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Headphone */
15237        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15238        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15239        {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},        /* Headphone */
15240        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15241        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15242        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15243        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15244        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15245        {}
15246};
15247
15248static struct hda_verb alc663_g71v_init_verbs[] = {
15249        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15250        /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15251        /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15252
15253        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15254        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15255        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},        /* Headphone */
15256
15257        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15258        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15259        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15260        {}
15261};
15262
15263static struct hda_verb alc663_g50v_init_verbs[] = {
15264        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15265        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15266        {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},        /* Headphone */
15267
15268        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15269        {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15270        {}
15271};
15272
15273static struct hda_verb alc662_ecs_init_verbs[] = {
15274        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15275        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15276        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15277        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15278        {}
15279};
15280
15281/* capture mixer elements */
15282static struct snd_kcontrol_new alc662_capture_mixer[] = {
15283        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15284        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15285        {
15286                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15287                /* The multiple "Capture Source" controls confuse alsamixer
15288                 * So call somewhat different..
15289                 */
15290                /* .name = "Capture Source", */
15291                .name = "Input Source",
15292                .count = 1,
15293                .info = alc662_mux_enum_info,
15294                .get = alc662_mux_enum_get,
15295                .put = alc662_mux_enum_put,
15296        },
15297        { } /* end */
15298};
15299
15300static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15301        HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15302        HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15303        { } /* end */
15304};
15305
15306static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15307{
15308        unsigned int present;
15309        unsigned char bits;
15310
15311        present = snd_hda_codec_read(codec, 0x14, 0,
15312                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15313        bits = present ? HDA_AMP_MUTE : 0;
15314        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15315                                 HDA_AMP_MUTE, bits);
15316}
15317
15318static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15319{
15320        unsigned int present;
15321        unsigned char bits;
15322
15323         present = snd_hda_codec_read(codec, 0x1b, 0,
15324                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15325        bits = present ? HDA_AMP_MUTE : 0;
15326        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15327                                 HDA_AMP_MUTE, bits);
15328        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15329                                 HDA_AMP_MUTE, bits);
15330}
15331
15332static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15333                                           unsigned int res)
15334{
15335        if ((res >> 26) == ALC880_HP_EVENT)
15336                alc662_lenovo_101e_all_automute(codec);
15337        if ((res >> 26) == ALC880_FRONT_EVENT)
15338                alc662_lenovo_101e_ispeaker_automute(codec);
15339}
15340
15341static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15342{
15343        unsigned int present;
15344
15345        present = snd_hda_codec_read(codec, 0x18, 0,
15346                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15347        snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15348                            0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15349        snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15350                            0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15351        snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15352                            0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15353        snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15354                            0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15355}
15356
15357/* unsolicited event for HP jack sensing */
15358static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15359                                     unsigned int res)
15360{
15361        if ((res >> 26) == ALC880_HP_EVENT)
15362                alc262_hippo1_automute( codec );
15363
15364        if ((res >> 26) == ALC880_MIC_EVENT)
15365                alc662_eeepc_mic_automute(codec);
15366}
15367
15368static void alc662_eeepc_inithook(struct hda_codec *codec)
15369{
15370        alc262_hippo1_automute( codec );
15371        alc662_eeepc_mic_automute(codec);
15372}
15373
15374static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15375{
15376        unsigned int mute;
15377        unsigned int present;
15378
15379        snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15380        present = snd_hda_codec_read(codec, 0x14, 0,
15381                                     AC_VERB_GET_PIN_SENSE, 0);
15382        present = (present & 0x80000000) != 0;
15383        if (present) {
15384                /* mute internal speaker */
15385                snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15386                                        HDA_AMP_MUTE, HDA_AMP_MUTE);
15387        } else {
15388                /* unmute internal speaker if necessary */
15389                mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15390                snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15391                                        HDA_AMP_MUTE, mute);
15392        }
15393}
15394
15395/* unsolicited event for HP jack sensing */
15396static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15397                                          unsigned int res)
15398{
15399        if ((res >> 26) == ALC880_HP_EVENT)
15400                alc662_eeepc_ep20_automute(codec);
15401}
15402
15403static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15404{
15405        alc662_eeepc_ep20_automute(codec);
15406}
15407
15408static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15409{
15410        unsigned int present;
15411        unsigned char bits;
15412
15413        present = snd_hda_codec_read(codec, 0x21, 0,
15414                        AC_VERB_GET_PIN_SENSE, 0)
15415                        & AC_PINSENSE_PRESENCE;
15416        bits = present ? HDA_AMP_MUTE : 0;
15417        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15418                                AMP_IN_MUTE(0), bits);
15419        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15420                                AMP_IN_MUTE(0), bits);
15421}
15422
15423static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15424{
15425        unsigned int present;
15426        unsigned char bits;
15427
15428        present = snd_hda_codec_read(codec, 0x21, 0,
15429                        AC_VERB_GET_PIN_SENSE, 0)
15430                        & AC_PINSENSE_PRESENCE;
15431        bits = present ? HDA_AMP_MUTE : 0;
15432        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15433                                AMP_IN_MUTE(0), bits);
15434        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15435                                AMP_IN_MUTE(0), bits);
15436        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15437                                AMP_IN_MUTE(0), bits);
15438        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15439                                AMP_IN_MUTE(0), bits);
15440}
15441
15442static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15443{
15444        unsigned int present;
15445        unsigned char bits;
15446
15447        present = snd_hda_codec_read(codec, 0x15, 0,
15448                        AC_VERB_GET_PIN_SENSE, 0)
15449                        & AC_PINSENSE_PRESENCE;
15450        bits = present ? HDA_AMP_MUTE : 0;
15451        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15452                                AMP_IN_MUTE(0), bits);
15453        snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15454                                AMP_IN_MUTE(0), bits);
15455        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15456                                AMP_IN_MUTE(0), bits);
15457        snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15458                                AMP_IN_MUTE(0), bits);
15459}
15460
15461static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15462{
15463        unsigned int present;
15464        unsigned char bits;
15465
15466        present = snd_hda_codec_read(codec, 0x1b, 0,
15467                        AC_VERB_GET_PIN_SENSE, 0)
15468                        & AC_PINSENSE_PRESENCE;
15469        bits = present ? 0 : PIN_OUT;
15470        snd_hda_codec_write(codec, 0x14, 0,
15471                         AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15472}
15473
15474static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15475{
15476        unsigned int present1, present2;
15477
15478        present1 = snd_hda_codec_read(codec, 0x21, 0,
15479                        AC_VERB_GET_PIN_SENSE, 0)
15480                        & AC_PINSENSE_PRESENCE;
15481        present2 = snd_hda_codec_read(codec, 0x15, 0,
15482                        AC_VERB_GET_PIN_SENSE, 0)
15483                        & AC_PINSENSE_PRESENCE;
15484
15485        if (present1 || present2) {
15486                snd_hda_codec_write_cache(codec, 0x14, 0,
15487                        AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15488        } else {
15489                snd_hda_codec_write_cache(codec, 0x14, 0,
15490                        AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15491        }
15492}
15493
15494static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15495{
15496        unsigned int present1, present2;
15497
15498        present1 = snd_hda_codec_read(codec, 0x1b, 0,
15499                                AC_VERB_GET_PIN_SENSE, 0)
15500                                & AC_PINSENSE_PRESENCE;
15501        present2 = snd_hda_codec_read(codec, 0x15, 0,
15502                                AC_VERB_GET_PIN_SENSE, 0)
15503                                & AC_PINSENSE_PRESENCE;
15504
15505        if (present1 || present2) {
15506                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15507                                AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15508                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15509                                AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15510        } else {
15511                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15512                                AMP_IN_MUTE(0), 0);
15513                snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15514                                AMP_IN_MUTE(0), 0);
15515        }
15516}
15517
15518static void alc663_m51va_mic_automute(struct hda_codec *codec)
15519{
15520        unsigned int present;
15521
15522        present = snd_hda_codec_read(codec, 0x18, 0,
15523                        AC_VERB_GET_PIN_SENSE, 0)
15524                        & AC_PINSENSE_PRESENCE;
15525        snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15526                        0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15527        snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15528                        0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15529        snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15530                        0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15531        snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15532                        0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15533}
15534
15535static void alc663_m51va_unsol_event(struct hda_codec *codec,
15536                                           unsigned int res)
15537{
15538        switch (res >> 26) {
15539        case ALC880_HP_EVENT:
15540                alc663_m51va_speaker_automute(codec);
15541                break;
15542        case ALC880_MIC_EVENT:
15543                alc663_m51va_mic_automute(codec);
15544                break;
15545        }
15546}
15547
15548static void alc663_m51va_inithook(struct hda_codec *codec)
15549{
15550        alc663_m51va_speaker_automute(codec);
15551        alc663_m51va_mic_automute(codec);
15552}
15553
15554/* ***************** Mode1 ******************************/
15555static void alc663_mode1_unsol_event(struct hda_codec *codec,
15556                                           unsigned int res)
15557{
15558        switch (res >> 26) {
15559        case ALC880_HP_EVENT:
15560                alc663_m51va_speaker_automute(codec);
15561                break;
15562        case ALC880_MIC_EVENT:
15563                alc662_eeepc_mic_automute(codec);
15564                break;
15565        }
15566}
15567
15568static void alc663_mode1_inithook(struct hda_codec *codec)
15569{
15570        alc663_m51va_speaker_automute(codec);
15571        alc662_eeepc_mic_automute(codec);
15572}
15573/* ***************** Mode2 ******************************/
15574static void alc662_mode2_unsol_event(struct hda_codec *codec,
15575                                           unsigned int res)
15576{
15577        switch (res >> 26) {
15578        case ALC880_HP_EVENT:
15579                alc662_f5z_speaker_automute(codec);
15580                break;
15581        case ALC880_MIC_EVENT:
15582                alc662_eeepc_mic_automute(codec);
15583                break;
15584        }
15585}
15586
15587static void alc662_mode2_inithook(struct hda_codec *codec)
15588{
15589        alc662_f5z_speaker_automute(codec);
15590        alc662_eeepc_mic_automute(codec);
15591}
15592/* ***************** Mode3 ******************************/
15593static void alc663_mode3_unsol_event(struct hda_codec *codec,
15594                                           unsigned int res)
15595{
15596        switch (res >> 26) {
15597        case ALC880_HP_EVENT:
15598                alc663_two_hp_m1_speaker_automute(codec);
15599                break;
15600        case ALC880_MIC_EVENT:
15601                alc662_eeepc_mic_automute(codec);
15602                break;
15603        }
15604}
15605
15606static void alc663_mode3_inithook(struct hda_codec *codec)
15607{
15608        alc663_two_hp_m1_speaker_automute(codec);
15609        alc662_eeepc_mic_automute(codec);
15610}
15611/* ***************** Mode4 ******************************/
15612static void alc663_mode4_unsol_event(struct hda_codec *codec,
15613                                           unsigned int res)
15614{
15615        switch (res >> 26) {
15616        case ALC880_HP_EVENT:
15617                alc663_21jd_two_speaker_automute(codec);
15618                break;
15619        case ALC880_MIC_EVENT:
15620                alc662_eeepc_mic_automute(codec);
15621                break;
15622        }
15623}
15624
15625static void alc663_mode4_inithook(struct hda_codec *codec)
15626{
15627        alc663_21jd_two_speaker_automute(codec);
15628        alc662_eeepc_mic_automute(codec);
15629}
15630/* ***************** Mode5 ******************************/
15631static void alc663_mode5_unsol_event(struct hda_codec *codec,
15632                                           unsigned int res)
15633{
15634        switch (res >> 26) {
15635        case ALC880_HP_EVENT:
15636                alc663_15jd_two_speaker_automute(codec);
15637                break;
15638        case ALC880_MIC_EVENT:
15639                alc662_eeepc_mic_automute(codec);
15640                break;
15641        }
15642}
15643
15644static void alc663_mode5_inithook(struct hda_codec *codec)
15645{
15646        alc663_15jd_two_speaker_automute(codec);
15647        alc662_eeepc_mic_automute(codec);
15648}
15649/* ***************** Mode6 ******************************/
15650static void alc663_mode6_unsol_event(struct hda_codec *codec,
15651                                           unsigned int res)
15652{
15653        switch (res >> 26) {
15654        case ALC880_HP_EVENT:
15655                alc663_two_hp_m2_speaker_automute(codec);
15656                break;
15657        case ALC880_MIC_EVENT:
15658                alc662_eeepc_mic_automute(codec);
15659                break;
15660        }
15661}
15662
15663static void alc663_mode6_inithook(struct hda_codec *codec)
15664{
15665        alc663_two_hp_m2_speaker_automute(codec);
15666        alc662_eeepc_mic_automute(codec);
15667}
15668
15669static void alc663_g71v_hp_automute(struct hda_codec *codec)
15670{
15671        unsigned int present;
15672        unsigned char bits;
15673
15674        present = snd_hda_codec_read(codec, 0x21, 0,
15675                                     AC_VERB_GET_PIN_SENSE, 0)
15676                & AC_PINSENSE_PRESENCE;
15677        bits = present ? HDA_AMP_MUTE : 0;
15678        snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15679                                 HDA_AMP_MUTE, bits);
15680        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15681                                 HDA_AMP_MUTE, bits);
15682}
15683
15684static void alc663_g71v_front_automute(struct hda_codec *codec)
15685{
15686        unsigned int present;
15687        unsigned char bits;
15688
15689        present = snd_hda_codec_read(codec, 0x15, 0,
15690                                     AC_VERB_GET_PIN_SENSE, 0)
15691                & AC_PINSENSE_PRESENCE;
15692        bits = present ? HDA_AMP_MUTE : 0;
15693        snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15694                                 HDA_AMP_MUTE, bits);
15695}
15696
15697static void alc663_g71v_unsol_event(struct hda_codec *codec,
15698                                           unsigned int res)
15699{
15700        switch (res >> 26) {
15701        case ALC880_HP_EVENT:
15702                alc663_g71v_hp_automute(codec);
15703                break;
15704        case ALC880_FRONT_EVENT:
15705                alc663_g71v_front_automute(codec);
15706                break;
15707        case ALC880_MIC_EVENT:
15708                alc662_eeepc_mic_automute(codec);
15709                break;
15710        }
15711}
15712
15713static void alc663_g71v_inithook(struct hda_codec *codec)
15714{
15715        alc663_g71v_front_automute(codec);
15716        alc663_g71v_hp_automute(codec);
15717        alc662_eeepc_mic_automute(codec);
15718}
15719
15720static void alc663_g50v_unsol_event(struct hda_codec *codec,
15721                                           unsigned int res)
15722{
15723        switch (res >> 26) {
15724        case ALC880_HP_EVENT:
15725                alc663_m51va_speaker_automute(codec);
15726                break;
15727        case ALC880_MIC_EVENT:
15728                alc662_eeepc_mic_automute(codec);
15729                break;
15730        }
15731}
15732
15733static void alc663_g50v_inithook(struct hda_codec *codec)
15734{
15735        alc663_m51va_speaker_automute(codec);
15736        alc662_eeepc_mic_automute(codec);
15737}
15738
15739/* bind hp and internal speaker mute (with plug check) */
15740static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15741                                     struct snd_ctl_elem_value *ucontrol)
15742{
15743        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15744        long *valp = ucontrol->value.integer.value;
15745        int change;
15746
15747        change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15748                                          HDA_AMP_MUTE,
15749                                          valp[0] ? 0 : HDA_AMP_MUTE);
15750        change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15751                                           HDA_AMP_MUTE,
15752                                           valp[1] ? 0 : HDA_AMP_MUTE);
15753        if (change)
15754                alc262_hippo1_automute(codec);
15755        return change;
15756}
15757
15758static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15759        HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15760        {
15761                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15762                .name = "Master Playback Switch",
15763                .info = snd_hda_mixer_amp_switch_info,
15764                .get = snd_hda_mixer_amp_switch_get,
15765                .put = alc662_ecs_master_sw_put,
15766                .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15767        },
15768
15769        HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15770        HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15771        HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15772
15773        HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15774        HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15775        HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15776        { } /* end */
15777};
15778
15779#ifdef CONFIG_SND_HDA_POWER_SAVE
15780#define alc662_loopbacks        alc880_loopbacks
15781#endif
15782
15783
15784/* pcm configuration: identiacal with ALC880 */
15785#define alc662_pcm_analog_playback        alc880_pcm_analog_playback
15786#define alc662_pcm_analog_capture        alc880_pcm_analog_capture
15787#define alc662_pcm_digital_playback        alc880_pcm_digital_playback
15788#define alc662_pcm_digital_capture        alc880_pcm_digital_capture
15789
15790/*
15791 * configuration and preset
15792 */
15793static const char *alc662_models[ALC662_MODEL_LAST] = {
15794        [ALC662_3ST_2ch_DIG]        = "3stack-dig",
15795        [ALC662_3ST_6ch_DIG]        = "3stack-6ch-dig",
15796        [ALC662_3ST_6ch]        = "3stack-6ch",
15797        [ALC662_5ST_DIG]        = "6stack-dig",
15798        [ALC662_LENOVO_101E]        = "lenovo-101e",
15799        [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15800        [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15801        [ALC662_ECS] = "ecs",
15802        [ALC663_ASUS_M51VA] = "m51va",
15803        [ALC663_ASUS_G71V] = "g71v",
15804        [ALC663_ASUS_H13] = "h13",
15805        [ALC663_ASUS_G50V] = "g50v",
15806        [ALC663_ASUS_MODE1] = "asus-mode1",
15807        [ALC662_ASUS_MODE2] = "asus-mode2",
15808        [ALC663_ASUS_MODE3] = "asus-mode3",
15809        [ALC663_ASUS_MODE4] = "asus-mode4",
15810        [ALC663_ASUS_MODE5] = "asus-mode5",
15811        [ALC663_ASUS_MODE6] = "asus-mode6",
15812        [ALC662_AUTO]                = "auto",
15813};
15814
15815static struct snd_pci_quirk alc662_cfg_tbl[] = {
15816        SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15817        SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15818        SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15819        SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15820        SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15821        SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15822        SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15823        SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15824        SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15825        SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15826        SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15827        SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15828        SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15829        SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15830        SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15831        SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15832        SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15833        SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15834        SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15835        SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15836        SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15837        SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15838        SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15839        SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15840        SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15841        SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15842        SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15843        SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15844        SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15845        SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15846        SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15847        SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15848        SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15849        SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15850        SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15851        SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15852        SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15853        SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15854                      ALC662_3ST_6ch_DIG),
15855        SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15856        SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15857        SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15858        SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15859                      ALC662_3ST_6ch_DIG),
15860        SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15861        SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15862                                        ALC662_3ST_6ch_DIG),
15863        SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15864        SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15865        SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15866        {}
15867};
15868
15869static struct alc_config_preset alc662_presets[] = {
15870        [ALC662_3ST_2ch_DIG] = {
15871                .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15872                .init_verbs = { alc662_init_verbs },
15873                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15874                .dac_nids = alc662_dac_nids,
15875                .dig_out_nid = ALC662_DIGOUT_NID,
15876                .dig_in_nid = ALC662_DIGIN_NID,
15877                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15878                .channel_mode = alc662_3ST_2ch_modes,
15879                .input_mux = &alc662_capture_source,
15880        },
15881        [ALC662_3ST_6ch_DIG] = {
15882                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15883                            alc662_capture_mixer },
15884                .init_verbs = { alc662_init_verbs },
15885                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886                .dac_nids = alc662_dac_nids,
15887                .dig_out_nid = ALC662_DIGOUT_NID,
15888                .dig_in_nid = ALC662_DIGIN_NID,
15889                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15890                .channel_mode = alc662_3ST_6ch_modes,
15891                .need_dac_fix = 1,
15892                .input_mux = &alc662_capture_source,
15893        },
15894        [ALC662_3ST_6ch] = {
15895                .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15896                            alc662_capture_mixer },
15897                .init_verbs = { alc662_init_verbs },
15898                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15899                .dac_nids = alc662_dac_nids,
15900                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15901                .channel_mode = alc662_3ST_6ch_modes,
15902                .need_dac_fix = 1,
15903                .input_mux = &alc662_capture_source,
15904        },
15905        [ALC662_5ST_DIG] = {
15906                .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15907                            alc662_capture_mixer },
15908                .init_verbs = { alc662_init_verbs },
15909                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910                .dac_nids = alc662_dac_nids,
15911                .dig_out_nid = ALC662_DIGOUT_NID,
15912                .dig_in_nid = ALC662_DIGIN_NID,
15913                .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15914                .channel_mode = alc662_5stack_modes,
15915                .input_mux = &alc662_capture_source,
15916        },
15917        [ALC662_LENOVO_101E] = {
15918                .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15919                .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15920                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15921                .dac_nids = alc662_dac_nids,
15922                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15923                .channel_mode = alc662_3ST_2ch_modes,
15924                .input_mux = &alc662_lenovo_101e_capture_source,
15925                .unsol_event = alc662_lenovo_101e_unsol_event,
15926                .init_hook = alc662_lenovo_101e_all_automute,
15927        },
15928        [ALC662_ASUS_EEEPC_P701] = {
15929                .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15930                .init_verbs = { alc662_init_verbs,
15931                                alc662_eeepc_sue_init_verbs },
15932                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15933                .dac_nids = alc662_dac_nids,
15934                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15935                .channel_mode = alc662_3ST_2ch_modes,
15936                .input_mux = &alc662_eeepc_capture_source,
15937                .unsol_event = alc662_eeepc_unsol_event,
15938                .init_hook = alc662_eeepc_inithook,
15939        },
15940        [ALC662_ASUS_EEEPC_EP20] = {
15941                .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15942                            alc662_chmode_mixer },
15943                .init_verbs = { alc662_init_verbs,
15944                                alc662_eeepc_ep20_sue_init_verbs },
15945                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15946                .dac_nids = alc662_dac_nids,
15947                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15948                .channel_mode = alc662_3ST_6ch_modes,
15949                .input_mux = &alc662_lenovo_101e_capture_source,
15950                .unsol_event = alc662_eeepc_ep20_unsol_event,
15951                .init_hook = alc662_eeepc_ep20_inithook,
15952        },
15953        [ALC662_ECS] = {
15954                .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15955                .init_verbs = { alc662_init_verbs,
15956                                alc662_ecs_init_verbs },
15957                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15958                .dac_nids = alc662_dac_nids,
15959                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15960                .channel_mode = alc662_3ST_2ch_modes,
15961                .input_mux = &alc662_eeepc_capture_source,
15962                .unsol_event = alc662_eeepc_unsol_event,
15963                .init_hook = alc662_eeepc_inithook,
15964        },
15965        [ALC663_ASUS_M51VA] = {
15966                .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15967                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15968                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15969                .dac_nids = alc662_dac_nids,
15970                .dig_out_nid = ALC662_DIGOUT_NID,
15971                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15972                .channel_mode = alc662_3ST_2ch_modes,
15973                .input_mux = &alc663_m51va_capture_source,
15974                .unsol_event = alc663_m51va_unsol_event,
15975                .init_hook = alc663_m51va_inithook,
15976        },
15977        [ALC663_ASUS_G71V] = {
15978                .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15979                .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15980                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15981                .dac_nids = alc662_dac_nids,
15982                .dig_out_nid = ALC662_DIGOUT_NID,
15983                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15984                .channel_mode = alc662_3ST_2ch_modes,
15985                .input_mux = &alc662_eeepc_capture_source,
15986                .unsol_event = alc663_g71v_unsol_event,
15987                .init_hook = alc663_g71v_inithook,
15988        },
15989        [ALC663_ASUS_H13] = {
15990                .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15991                .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15992                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15993                .dac_nids = alc662_dac_nids,
15994                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15995                .channel_mode = alc662_3ST_2ch_modes,
15996                .input_mux = &alc663_m51va_capture_source,
15997                .unsol_event = alc663_m51va_unsol_event,
15998                .init_hook = alc663_m51va_inithook,
15999        },
16000        [ALC663_ASUS_G50V] = {
16001                .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
16002                .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16003                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16004                .dac_nids = alc662_dac_nids,
16005                .dig_out_nid = ALC662_DIGOUT_NID,
16006                .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16007                .channel_mode = alc662_3ST_6ch_modes,
16008                .input_mux = &alc663_capture_source,
16009                .unsol_event = alc663_g50v_unsol_event,
16010                .init_hook = alc663_g50v_inithook,
16011        },
16012        [ALC663_ASUS_MODE1] = {
16013                .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
16014                .init_verbs = { alc662_init_verbs,
16015                                alc663_21jd_amic_init_verbs },
16016                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16017                .hp_nid = 0x03,
16018                .dac_nids = alc662_dac_nids,
16019                .dig_out_nid = ALC662_DIGOUT_NID,
16020                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16021                .channel_mode = alc662_3ST_2ch_modes,
16022                .input_mux = &alc662_eeepc_capture_source,
16023                .unsol_event = alc663_mode1_unsol_event,
16024                .init_hook = alc663_mode1_inithook,
16025        },
16026        [ALC662_ASUS_MODE2] = {
16027                .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
16028                .init_verbs = { alc662_init_verbs,
16029                                alc662_1bjd_amic_init_verbs },
16030                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16031                .dac_nids = alc662_dac_nids,
16032                .dig_out_nid = ALC662_DIGOUT_NID,
16033                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16034                .channel_mode = alc662_3ST_2ch_modes,
16035                .input_mux = &alc662_eeepc_capture_source,
16036                .unsol_event = alc662_mode2_unsol_event,
16037                .init_hook = alc662_mode2_inithook,
16038        },
16039        [ALC663_ASUS_MODE3] = {
16040                .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
16041                .init_verbs = { alc662_init_verbs,
16042                                alc663_two_hp_amic_m1_init_verbs },
16043                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16044                .hp_nid = 0x03,
16045                .dac_nids = alc662_dac_nids,
16046                .dig_out_nid = ALC662_DIGOUT_NID,
16047                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16048                .channel_mode = alc662_3ST_2ch_modes,
16049                .input_mux = &alc662_eeepc_capture_source,
16050                .unsol_event = alc663_mode3_unsol_event,
16051                .init_hook = alc663_mode3_inithook,
16052        },
16053        [ALC663_ASUS_MODE4] = {
16054                .mixers = { alc663_asus_21jd_clfe_mixer,
16055                                alc662_auto_capture_mixer},
16056                .init_verbs = { alc662_init_verbs,
16057                                alc663_21jd_amic_init_verbs},
16058                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16059                .hp_nid = 0x03,
16060                .dac_nids = alc662_dac_nids,
16061                .dig_out_nid = ALC662_DIGOUT_NID,
16062                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16063                .channel_mode = alc662_3ST_2ch_modes,
16064                .input_mux = &alc662_eeepc_capture_source,
16065                .unsol_event = alc663_mode4_unsol_event,
16066                .init_hook = alc663_mode4_inithook,
16067        },
16068        [ALC663_ASUS_MODE5] = {
16069                .mixers = { alc663_asus_15jd_clfe_mixer,
16070                                alc662_auto_capture_mixer },
16071                .init_verbs = { alc662_init_verbs,
16072                                alc663_15jd_amic_init_verbs },
16073                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16074                .hp_nid = 0x03,
16075                .dac_nids = alc662_dac_nids,
16076                .dig_out_nid = ALC662_DIGOUT_NID,
16077                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16078                .channel_mode = alc662_3ST_2ch_modes,
16079                .input_mux = &alc662_eeepc_capture_source,
16080                .unsol_event = alc663_mode5_unsol_event,
16081                .init_hook = alc663_mode5_inithook,
16082        },
16083        [ALC663_ASUS_MODE6] = {
16084                .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
16085                .init_verbs = { alc662_init_verbs,
16086                                alc663_two_hp_amic_m2_init_verbs },
16087                .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16088                .hp_nid = 0x03,
16089                .dac_nids = alc662_dac_nids,
16090                .dig_out_nid = ALC662_DIGOUT_NID,
16091                .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16092                .channel_mode = alc662_3ST_2ch_modes,
16093                .input_mux = &alc662_eeepc_capture_source,
16094                .unsol_event = alc663_mode6_unsol_event,
16095                .init_hook = alc663_mode6_inithook,
16096        },
16097};
16098
16099
16100/*
16101 * BIOS auto configuration
16102 */
16103
16104/* add playback controls from the parsed DAC table */
16105static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16106                                             const struct auto_pin_cfg *cfg)
16107{
16108        char name[32];
16109        static const char *chname[4] = {
16110                "Front", "Surround", NULL /*CLFE*/, "Side"
16111        };
16112        hda_nid_t nid;
16113        int i, err;
16114
16115        for (i = 0; i < cfg->line_outs; i++) {
16116                if (!spec->multiout.dac_nids[i])
16117                        continue;
16118                nid = alc880_idx_to_dac(i);
16119                if (i == 2) {
16120                        /* Center/LFE */
16121                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
16122                                          "Center Playback Volume",
16123                                          HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16124                                                              HDA_OUTPUT));
16125                        if (err < 0)
16126                                return err;
16127                        err = add_control(spec, ALC_CTL_WIDGET_VOL,
16128                                          "LFE Playback Volume",
16129                                          HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16130                                                              HDA_OUTPUT));
16131                        if (err < 0)
16132                                return err;
16133                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16134                                          "Center Playback Switch",
16135                                          HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16136                                                              HDA_INPUT));
16137                        if (err < 0)
16138                                return err;
16139                        err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16140                                          "LFE Playback Switch",
16141                                          HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16142                                                              HDA_INPUT));
16143                        if (err < 0)
16144                                return err;
16145                } else {
16146                        sprintf(name, "%s Playback Volume", chname[i]);
16147                        err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16148                                          HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16149                                                              HDA_OUTPUT));
16150                        if (err < 0)
16151                                return err;
16152                        sprintf(name, "%s Playback Switch", chname[i]);
16153                        err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16154                                HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16155                                                    3, 0, HDA_INPUT));
16156                        if (err < 0)
16157                                return err;
16158                }
16159        }
16160        return 0;
16161}
16162
16163/* add playback controls for speaker and HP outputs */
16164static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16165                                        const char *pfx)
16166{
16167        hda_nid_t nid;
16168        int err;
16169        char name[32];
16170
16171        if (!pin)
16172                return 0;
16173
16174        if (pin == 0x17) {
16175                /* ALC663 has a mono output pin on 0x17 */
16176                sprintf(name, "%s Playback Switch", pfx);
16177                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16178                                  HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16179                return err;
16180        }
16181
16182        if (alc880_is_fixed_pin(pin)) {
16183                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16184                /* printk("DAC nid=%x\n",nid); */
16185                /* specify the DAC as the extra output */
16186                if (!spec->multiout.hp_nid)
16187                        spec->multiout.hp_nid = nid;
16188                else
16189                        spec->multiout.extra_out_nid[0] = nid;
16190                /* control HP volume/switch on the output mixer amp */
16191                nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16192                sprintf(name, "%s Playback Volume", pfx);
16193                err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16194                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16195                if (err < 0)
16196                        return err;
16197                sprintf(name, "%s Playback Switch", pfx);
16198                err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16199                                  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16200                if (err < 0)
16201                        return err;
16202        } else if (alc880_is_multi_pin(pin)) {
16203                /* set manual connection */
16204                /* we have only a switch on HP-out PIN */
16205                sprintf(name, "%s Playback Switch", pfx);
16206                err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16207                                  HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16208                if (err < 0)
16209                        return err;
16210        }
16211        return 0;
16212}
16213
16214/* create playback/capture controls for input pins */
16215static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16216                                                const struct auto_pin_cfg *cfg)
16217{
16218        struct hda_input_mux *imux = &spec->private_imux;
16219        int i, err, idx;
16220
16221        for (i = 0; i < AUTO_PIN_LAST; i++) {
16222                if (alc880_is_input_pin(cfg->input_pins[i])) {
16223                        idx = alc880_input_pin_idx(cfg->input_pins[i]);
16224                        err = new_analog_input(spec, cfg->input_pins[i],
16225                                               auto_pin_cfg_labels[i],
16226                                               idx, 0x0b);
16227                        if (err < 0)
16228                                return err;
16229                        imux->items[imux->num_items].label =
16230                                auto_pin_cfg_labels[i];
16231                        imux->items[imux->num_items].index =
16232                                alc880_input_pin_idx(cfg->input_pins[i]);
16233                        imux->num_items++;
16234                }
16235        }
16236        return 0;
16237}
16238
16239static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16240                                              hda_nid_t nid, int pin_type,
16241                                              int dac_idx)
16242{
16243        alc_set_pin_output(codec, nid, pin_type);
16244        /* need the manual connection? */
16245        if (alc880_is_multi_pin(nid)) {
16246                struct alc_spec *spec = codec->spec;
16247                int idx = alc880_multi_pin_idx(nid);
16248                snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16249                                    AC_VERB_SET_CONNECT_SEL,
16250                                    alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16251        }
16252}
16253
16254static void alc662_auto_init_multi_out(struct hda_codec *codec)
16255{
16256        struct alc_spec *spec = codec->spec;
16257        int i;
16258
16259        alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16260        for (i = 0; i <= HDA_SIDE; i++) {
16261                hda_nid_t nid = spec->autocfg.line_out_pins[i];
16262                int pin_type = get_pin_type(spec->autocfg.line_out_type);
16263                if (nid)
16264                        alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16265                                                          i);
16266        }
16267}
16268
16269static void alc662_auto_init_hp_out(struct hda_codec *codec)
16270{
16271        struct alc_spec *spec = codec->spec;
16272        hda_nid_t pin;
16273
16274        pin = spec->autocfg.hp_pins[0];
16275        if (pin) /* connect to front */
16276                /* use dac 0 */
16277                alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16278        pin = spec->autocfg.speaker_pins[0];
16279        if (pin)
16280                alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16281}
16282
16283#define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
16284#define ALC662_PIN_CD_NID                ALC880_PIN_CD_NID
16285
16286static void alc662_auto_init_analog_input(struct hda_codec *codec)
16287{
16288        struct alc_spec *spec = codec->spec;
16289        int i;
16290
16291        for (i = 0; i < AUTO_PIN_LAST; i++) {
16292                hda_nid_t nid = spec->autocfg.input_pins[i];
16293                if (alc662_is_input_pin(nid)) {
16294                        snd_hda_codec_write(codec, nid, 0,
16295                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
16296                                            (i <= AUTO_PIN_FRONT_MIC ?
16297                                             PIN_VREF80 : PIN_IN));
16298                        if (nid != ALC662_PIN_CD_NID)
16299                                snd_hda_codec_write(codec, nid, 0,
16300                                                    AC_VERB_SET_AMP_GAIN_MUTE,
16301                                                    AMP_OUT_MUTE);
16302                }
16303        }
16304}
16305
16306#define alc662_auto_init_input_src        alc882_auto_init_input_src
16307
16308static int alc662_parse_auto_config(struct hda_codec *codec)
16309{
16310        struct alc_spec *spec = codec->spec;
16311        int err;
16312        static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16313
16314        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16315                                           alc662_ignore);
16316        if (err < 0)
16317                return err;
16318        if (!spec->autocfg.line_outs)
16319                return 0; /* can't find valid BIOS pin config */
16320
16321        err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16322        if (err < 0)
16323                return err;
16324        err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16325        if (err < 0)
16326                return err;
16327        err = alc662_auto_create_extra_out(spec,
16328                                           spec->autocfg.speaker_pins[0],
16329                                           "Speaker");
16330        if (err < 0)
16331                return err;
16332        err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16333                                           "Headphone");
16334        if (err < 0)
16335                return err;
16336        err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16337        if (err < 0)
16338                return err;
16339
16340        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16341
16342        if (spec->autocfg.dig_out_pin)
16343                spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16344
16345        if (spec->kctl_alloc)
16346                spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
16347
16348        spec->num_mux_defs = 1;
16349        spec->input_mux = &spec->private_imux;
16350
16351        spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
16352        if (codec->vendor_id == 0x10ec0663)
16353                spec->init_verbs[spec->num_init_verbs++] =
16354                        alc663_auto_init_verbs;
16355
16356        err = alc_auto_add_mic_boost(codec);
16357        if (err < 0)
16358                return err;
16359
16360        spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16361        spec->num_mixers++;
16362
16363        store_pin_configs(codec);
16364        return 1;
16365}
16366
16367/* additional initialization for auto-configuration model */
16368static void alc662_auto_init(struct hda_codec *codec)
16369{
16370        struct alc_spec *spec = codec->spec;
16371        alc662_auto_init_multi_out(codec);
16372        alc662_auto_init_hp_out(codec);
16373        alc662_auto_init_analog_input(codec);
16374        alc662_auto_init_input_src(codec);
16375        if (spec->unsol_event)
16376                alc_inithook(codec);
16377}
16378
16379static int patch_alc662(struct hda_codec *codec)
16380{
16381        struct alc_spec *spec;
16382        int err, board_config;
16383
16384        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16385        if (!spec)
16386                return -ENOMEM;
16387
16388        codec->spec = spec;
16389
16390        alc_fix_pll_init(codec, 0x20, 0x04, 15);
16391
16392        board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16393                                                  alc662_models,
16394                                                    alc662_cfg_tbl);
16395        if (board_config < 0) {
16396                printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16397                       "trying auto-probe from BIOS...\n");
16398                board_config = ALC662_AUTO;
16399        }
16400
16401        if (board_config == ALC662_AUTO) {
16402                /* automatic parse from the BIOS config */
16403                err = alc662_parse_auto_config(codec);
16404                if (err < 0) {
16405                        alc_free(codec);
16406                        return err;
16407                } else if (!err) {
16408                        printk(KERN_INFO
16409                               "hda_codec: Cannot set up configuration "
16410                               "from BIOS.  Using base mode...\n");
16411                        board_config = ALC662_3ST_2ch_DIG;
16412                }
16413        }
16414
16415        if (board_config != ALC662_AUTO)
16416                setup_preset(spec, &alc662_presets[board_config]);
16417
16418        if (codec->vendor_id == 0x10ec0663) {
16419                spec->stream_name_analog = "ALC663 Analog";
16420                spec->stream_name_digital = "ALC663 Digital";
16421        } else if (codec->vendor_id == 0x10ec0272) {
16422                spec->stream_name_analog = "ALC272 Analog";
16423                spec->stream_name_digital = "ALC272 Digital";
16424        } else {
16425                spec->stream_name_analog = "ALC662 Analog";
16426                spec->stream_name_digital = "ALC662 Digital";
16427        }
16428
16429        spec->stream_analog_playback = &alc662_pcm_analog_playback;
16430        spec->stream_analog_capture = &alc662_pcm_analog_capture;
16431
16432        spec->stream_digital_playback = &alc662_pcm_digital_playback;
16433        spec->stream_digital_capture = &alc662_pcm_digital_capture;
16434
16435        spec->adc_nids = alc662_adc_nids;
16436        spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16437        spec->capsrc_nids = alc662_capsrc_nids;
16438
16439        spec->vmaster_nid = 0x02;
16440
16441        codec->patch_ops = alc_patch_ops;
16442        if (board_config == ALC662_AUTO)
16443                spec->init_hook = alc662_auto_init;
16444#ifdef CONFIG_SND_HDA_POWER_SAVE
16445        if (!spec->loopback.amplist)
16446                spec->loopback.amplist = alc662_loopbacks;
16447#endif
16448
16449        return 0;
16450}
16451
16452/*
16453 * patch entries
16454 */
16455struct hda_codec_preset snd_hda_preset_realtek[] = {
16456        { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16457        { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16458        { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16459        { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16460        { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16461        { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16462        { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16463          .patch = patch_alc861 },
16464        { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16465        { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16466        { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16467        { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16468          .patch = patch_alc883 },
16469        { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16470          .patch = patch_alc662 },
16471        { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16472        { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16473        { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16474        { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16475        { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16476          .patch = patch_alc882 }, /* should be patch_alc883() in future */
16477        { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16478          .patch = patch_alc882 }, /* should be patch_alc883() in future */
16479        { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16480        { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16481        { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16482        { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16483          .patch = patch_alc883 },
16484        { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16485        {} /* terminator */
16486};