linux/sound/pci/hda/patch_via.c
<<
>>
Prefs
   1/*
   2 * Universal Interface for Intel High Definition Audio Codec
   3 *
   4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
   5 *
   6 *  (C) 2006-2009 VIA Technology, Inc.
   7 *  (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
   8 *
   9 *  This driver is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  This driver is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to the Free Software
  21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  22 */
  23
  24/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
  25/*                                                                           */
  26/* 2006-03-03  Lydia Wang  Create the basic patch to support VT1708 codec    */
  27/* 2006-03-14  Lydia Wang  Modify hard code for some pin widget nid          */
  28/* 2006-08-02  Lydia Wang  Add support to VT1709 codec                       */
  29/* 2006-09-08  Lydia Wang  Fix internal loopback recording source select bug */
  30/* 2007-09-12  Lydia Wang  Add EAPD enable during driver initialization      */
  31/* 2007-09-17  Lydia Wang  Add VT1708B codec support                        */
  32/* 2007-11-14  Lydia Wang  Add VT1708A codec HP and CD pin connect config    */
  33/* 2008-02-03  Lydia Wang  Fix Rear channels and Back channels inverse issue */
  34/* 2008-03-06  Lydia Wang  Add VT1702 codec and VT1708S codec support        */
  35/* 2008-04-09  Lydia Wang  Add mute front speaker when HP plugin             */
  36/* 2008-04-09  Lydia Wang  Add Independent HP feature                        */
  37/* 2008-05-28  Lydia Wang  Add second S/PDIF Out support for VT1702          */
  38/* 2008-09-15  Logan Li    Add VT1708S Mic Boost workaround/backdoor         */
  39/* 2009-02-16  Logan Li    Add support for VT1718S                           */
  40/* 2009-03-13  Logan Li    Add support for VT1716S                           */
  41/* 2009-04-14  Lydai Wang  Add support for VT1828S and VT2020                */
  42/* 2009-07-08  Lydia Wang  Add support for VT2002P                           */
  43/* 2009-07-21  Lydia Wang  Add support for VT1812                            */
  44/* 2009-09-19  Lydia Wang  Add support for VT1818S                           */
  45/*                                                                           */
  46/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  47
  48
  49#include <linux/init.h>
  50#include <linux/delay.h>
  51#include <linux/slab.h>
  52#include <sound/core.h>
  53#include <sound/asoundef.h>
  54#include "hda_codec.h"
  55#include "hda_local.h"
  56
  57#define NID_MAPPING             (-1)
  58
  59/* amp values */
  60#define AMP_VAL_IDX_SHIFT       19
  61#define AMP_VAL_IDX_MASK        (0x0f<<19)
  62
  63/* Pin Widget NID */
  64#define VT1708_HP_NID           0x13
  65#define VT1708_DIGOUT_NID       0x14
  66#define VT1708_DIGIN_NID        0x16
  67#define VT1708_DIGIN_PIN        0x26
  68#define VT1708_HP_PIN_NID       0x20
  69#define VT1708_CD_PIN_NID       0x24
  70
  71#define VT1709_HP_DAC_NID       0x28
  72#define VT1709_DIGOUT_NID       0x13
  73#define VT1709_DIGIN_NID        0x17
  74#define VT1709_DIGIN_PIN        0x25
  75
  76#define VT1708B_HP_NID          0x25
  77#define VT1708B_DIGOUT_NID      0x12
  78#define VT1708B_DIGIN_NID       0x15
  79#define VT1708B_DIGIN_PIN       0x21
  80
  81#define VT1708S_HP_NID          0x25
  82#define VT1708S_DIGOUT_NID      0x12
  83
  84#define VT1702_HP_NID           0x17
  85#define VT1702_DIGOUT_NID       0x11
  86
  87enum VIA_HDA_CODEC {
  88        UNKNOWN = -1,
  89        VT1708,
  90        VT1709_10CH,
  91        VT1709_6CH,
  92        VT1708B_8CH,
  93        VT1708B_4CH,
  94        VT1708S,
  95        VT1708BCE,
  96        VT1702,
  97        VT1718S,
  98        VT1716S,
  99        VT2002P,
 100        VT1812,
 101        CODEC_TYPES,
 102};
 103
 104struct via_spec {
 105        /* codec parameterization */
 106        struct snd_kcontrol_new *mixers[6];
 107        unsigned int num_mixers;
 108
 109        struct hda_verb *init_verbs[5];
 110        unsigned int num_iverbs;
 111
 112        char *stream_name_analog;
 113        struct hda_pcm_stream *stream_analog_playback;
 114        struct hda_pcm_stream *stream_analog_capture;
 115
 116        char *stream_name_digital;
 117        struct hda_pcm_stream *stream_digital_playback;
 118        struct hda_pcm_stream *stream_digital_capture;
 119
 120        /* playback */
 121        struct hda_multi_out multiout;
 122        hda_nid_t slave_dig_outs[2];
 123
 124        /* capture */
 125        unsigned int num_adc_nids;
 126        hda_nid_t *adc_nids;
 127        hda_nid_t mux_nids[3];
 128        hda_nid_t dig_in_nid;
 129        hda_nid_t dig_in_pin;
 130
 131        /* capture source */
 132        const struct hda_input_mux *input_mux;
 133        unsigned int cur_mux[3];
 134
 135        /* PCM information */
 136        struct hda_pcm pcm_rec[3];
 137
 138        /* dynamic controls, init_verbs and input_mux */
 139        struct auto_pin_cfg autocfg;
 140        struct snd_array kctls;
 141        struct hda_input_mux private_imux[2];
 142        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 143
 144        /* HP mode source */
 145        const struct hda_input_mux *hp_mux;
 146        unsigned int hp_independent_mode;
 147        unsigned int hp_independent_mode_index;
 148        unsigned int smart51_enabled;
 149        unsigned int dmic_enabled;
 150        enum VIA_HDA_CODEC codec_type;
 151
 152        /* work to check hp jack state */
 153        struct hda_codec *codec;
 154        struct delayed_work vt1708_hp_work;
 155        int vt1708_jack_detectect;
 156        int vt1708_hp_present;
 157#ifdef CONFIG_SND_HDA_POWER_SAVE
 158        struct hda_loopback_check loopback;
 159#endif
 160};
 161
 162static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
 163static struct via_spec * via_new_spec(struct hda_codec *codec)
 164{
 165        struct via_spec *spec;
 166
 167        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 168        if (spec == NULL)
 169                return NULL;
 170
 171        codec->spec = spec;
 172        spec->codec = codec;
 173        spec->codec_type = get_codec_type(codec);
 174        /* VT1708BCE & VT1708S are almost same */
 175        if (spec->codec_type == VT1708BCE)
 176                spec->codec_type = VT1708S;
 177        return spec;
 178}
 179
 180static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
 181{
 182        u32 vendor_id = codec->vendor_id;
 183        u16 ven_id = vendor_id >> 16;
 184        u16 dev_id = vendor_id & 0xffff;
 185        enum VIA_HDA_CODEC codec_type;
 186
 187        /* get codec type */
 188        if (ven_id != 0x1106)
 189                codec_type = UNKNOWN;
 190        else if (dev_id >= 0x1708 && dev_id <= 0x170b)
 191                codec_type = VT1708;
 192        else if (dev_id >= 0xe710 && dev_id <= 0xe713)
 193                codec_type = VT1709_10CH;
 194        else if (dev_id >= 0xe714 && dev_id <= 0xe717)
 195                codec_type = VT1709_6CH;
 196        else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
 197                codec_type = VT1708B_8CH;
 198                if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
 199                        codec_type = VT1708BCE;
 200        } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
 201                codec_type = VT1708B_4CH;
 202        else if ((dev_id & 0xfff) == 0x397
 203                 && (dev_id >> 12) < 8)
 204                codec_type = VT1708S;
 205        else if ((dev_id & 0xfff) == 0x398
 206                 && (dev_id >> 12) < 8)
 207                codec_type = VT1702;
 208        else if ((dev_id & 0xfff) == 0x428
 209                 && (dev_id >> 12) < 8)
 210                codec_type = VT1718S;
 211        else if (dev_id == 0x0433 || dev_id == 0xa721)
 212                codec_type = VT1716S;
 213        else if (dev_id == 0x0441 || dev_id == 0x4441)
 214                codec_type = VT1718S;
 215        else if (dev_id == 0x0438 || dev_id == 0x4438)
 216                codec_type = VT2002P;
 217        else if (dev_id == 0x0448)
 218                codec_type = VT1812;
 219        else if (dev_id == 0x0440)
 220                codec_type = VT1708S;
 221        else
 222                codec_type = UNKNOWN;
 223        return codec_type;
 224};
 225
 226#define VIA_HP_EVENT            0x01
 227#define VIA_GPIO_EVENT          0x02
 228#define VIA_JACK_EVENT          0x04
 229#define VIA_MONO_EVENT          0x08
 230#define VIA_SPEAKER_EVENT       0x10
 231#define VIA_BIND_HP_EVENT       0x20
 232
 233enum {
 234        VIA_CTL_WIDGET_VOL,
 235        VIA_CTL_WIDGET_MUTE,
 236        VIA_CTL_WIDGET_ANALOG_MUTE,
 237        VIA_CTL_WIDGET_BIND_PIN_MUTE,
 238};
 239
 240enum {
 241        AUTO_SEQ_FRONT = 0,
 242        AUTO_SEQ_SURROUND,
 243        AUTO_SEQ_CENLFE,
 244        AUTO_SEQ_SIDE
 245};
 246
 247static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
 248static void set_jack_power_state(struct hda_codec *codec);
 249static int is_aa_path_mute(struct hda_codec *codec);
 250
 251static void vt1708_start_hp_work(struct via_spec *spec)
 252{
 253        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
 254                return;
 255        snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
 256                            !spec->vt1708_jack_detectect);
 257        if (!delayed_work_pending(&spec->vt1708_hp_work))
 258                schedule_delayed_work(&spec->vt1708_hp_work,
 259                                      msecs_to_jiffies(100));
 260}
 261
 262static void vt1708_stop_hp_work(struct via_spec *spec)
 263{
 264        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
 265                return;
 266        if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
 267            && !is_aa_path_mute(spec->codec))
 268                return;
 269        snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
 270                            !spec->vt1708_jack_detectect);
 271        cancel_delayed_work_sync(&spec->vt1708_hp_work);
 272}
 273
 274
 275static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
 276                                   struct snd_ctl_elem_value *ucontrol)
 277{
 278        int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
 279        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 280
 281        set_jack_power_state(codec);
 282        analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
 283        if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
 284                if (is_aa_path_mute(codec))
 285                        vt1708_start_hp_work(codec->spec);
 286                else
 287                        vt1708_stop_hp_work(codec->spec);
 288        }
 289        return change;
 290}
 291
 292/* modify .put = snd_hda_mixer_amp_switch_put */
 293#define ANALOG_INPUT_MUTE                                               \
 294        {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
 295                        .name = NULL,                                   \
 296                        .index = 0,                                     \
 297                        .info = snd_hda_mixer_amp_switch_info,          \
 298                        .get = snd_hda_mixer_amp_switch_get,            \
 299                        .put = analog_input_switch_put,                 \
 300                        .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
 301
 302static void via_hp_bind_automute(struct hda_codec *codec);
 303
 304static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
 305                               struct snd_ctl_elem_value *ucontrol)
 306{
 307        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 308        struct via_spec *spec = codec->spec;
 309        int i;
 310        int change = 0;
 311
 312        long *valp = ucontrol->value.integer.value;
 313        int lmute, rmute;
 314        if (strstr(kcontrol->id.name, "Switch") == NULL) {
 315                snd_printd("Invalid control!\n");
 316                return change;
 317        }
 318        change = snd_hda_mixer_amp_switch_put(kcontrol,
 319                                              ucontrol);
 320        /* Get mute value */
 321        lmute = *valp ? 0 : HDA_AMP_MUTE;
 322        valp++;
 323        rmute = *valp ? 0 : HDA_AMP_MUTE;
 324
 325        /* Set hp pins */
 326        if (!spec->hp_independent_mode) {
 327                for (i = 0; i < spec->autocfg.hp_outs; i++) {
 328                        snd_hda_codec_amp_update(
 329                                codec, spec->autocfg.hp_pins[i],
 330                                0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 331                                lmute);
 332                        snd_hda_codec_amp_update(
 333                                codec, spec->autocfg.hp_pins[i],
 334                                1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 335                                rmute);
 336                }
 337        }
 338
 339        if (!lmute && !rmute) {
 340                /* Line Outs */
 341                for (i = 0; i < spec->autocfg.line_outs; i++)
 342                        snd_hda_codec_amp_stereo(
 343                                codec, spec->autocfg.line_out_pins[i],
 344                                HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
 345                /* Speakers */
 346                for (i = 0; i < spec->autocfg.speaker_outs; i++)
 347                        snd_hda_codec_amp_stereo(
 348                                codec, spec->autocfg.speaker_pins[i],
 349                                HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
 350                /* unmute */
 351                via_hp_bind_automute(codec);
 352
 353        } else {
 354                if (lmute) {
 355                        /* Mute all left channels */
 356                        for (i = 1; i < spec->autocfg.line_outs; i++)
 357                                snd_hda_codec_amp_update(
 358                                        codec,
 359                                        spec->autocfg.line_out_pins[i],
 360                                        0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 361                                        lmute);
 362                        for (i = 0; i < spec->autocfg.speaker_outs; i++)
 363                                snd_hda_codec_amp_update(
 364                                        codec,
 365                                        spec->autocfg.speaker_pins[i],
 366                                        0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 367                                        lmute);
 368                }
 369                if (rmute) {
 370                        /* mute all right channels */
 371                        for (i = 1; i < spec->autocfg.line_outs; i++)
 372                                snd_hda_codec_amp_update(
 373                                        codec,
 374                                        spec->autocfg.line_out_pins[i],
 375                                        1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 376                                        rmute);
 377                        for (i = 0; i < spec->autocfg.speaker_outs; i++)
 378                                snd_hda_codec_amp_update(
 379                                        codec,
 380                                        spec->autocfg.speaker_pins[i],
 381                                        1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 382                                        rmute);
 383                }
 384        }
 385        return change;
 386}
 387
 388#define BIND_PIN_MUTE                                                   \
 389        {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
 390                        .name = NULL,                                   \
 391                        .index = 0,                                     \
 392                        .info = snd_hda_mixer_amp_switch_info,          \
 393                        .get = snd_hda_mixer_amp_switch_get,            \
 394                        .put = bind_pin_switch_put,                     \
 395                        .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
 396
 397static struct snd_kcontrol_new via_control_templates[] = {
 398        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 399        HDA_CODEC_MUTE(NULL, 0, 0, 0),
 400        ANALOG_INPUT_MUTE,
 401        BIND_PIN_MUTE,
 402};
 403
 404static hda_nid_t vt1708_adc_nids[2] = {
 405        /* ADC1-2 */
 406        0x15, 0x27
 407};
 408
 409static hda_nid_t vt1709_adc_nids[3] = {
 410        /* ADC1-2 */
 411        0x14, 0x15, 0x16
 412};
 413
 414static hda_nid_t vt1708B_adc_nids[2] = {
 415        /* ADC1-2 */
 416        0x13, 0x14
 417};
 418
 419static hda_nid_t vt1708S_adc_nids[2] = {
 420        /* ADC1-2 */
 421        0x13, 0x14
 422};
 423
 424static hda_nid_t vt1702_adc_nids[3] = {
 425        /* ADC1-2 */
 426        0x12, 0x20, 0x1F
 427};
 428
 429static hda_nid_t vt1718S_adc_nids[2] = {
 430        /* ADC1-2 */
 431        0x10, 0x11
 432};
 433
 434static hda_nid_t vt1716S_adc_nids[2] = {
 435        /* ADC1-2 */
 436        0x13, 0x14
 437};
 438
 439static hda_nid_t vt2002P_adc_nids[2] = {
 440        /* ADC1-2 */
 441        0x10, 0x11
 442};
 443
 444static hda_nid_t vt1812_adc_nids[2] = {
 445        /* ADC1-2 */
 446        0x10, 0x11
 447};
 448
 449
 450/* add dynamic controls */
 451static int __via_add_control(struct via_spec *spec, int type, const char *name,
 452                             int idx, unsigned long val)
 453{
 454        struct snd_kcontrol_new *knew;
 455
 456        snd_array_init(&spec->kctls, sizeof(*knew), 32);
 457        knew = snd_array_new(&spec->kctls);
 458        if (!knew)
 459                return -ENOMEM;
 460        *knew = via_control_templates[type];
 461        knew->name = kstrdup(name, GFP_KERNEL);
 462        if (!knew->name)
 463                return -ENOMEM;
 464        if (get_amp_nid_(val))
 465                knew->subdevice = HDA_SUBDEV_AMP_FLAG;
 466        knew->private_value = val;
 467        return 0;
 468}
 469
 470#define via_add_control(spec, type, name, val) \
 471        __via_add_control(spec, type, name, 0, val)
 472
 473static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
 474                                                struct snd_kcontrol_new *tmpl)
 475{
 476        struct snd_kcontrol_new *knew;
 477
 478        snd_array_init(&spec->kctls, sizeof(*knew), 32);
 479        knew = snd_array_new(&spec->kctls);
 480        if (!knew)
 481                return NULL;
 482        *knew = *tmpl;
 483        knew->name = kstrdup(tmpl->name, GFP_KERNEL);
 484        if (!knew->name)
 485                return NULL;
 486        return knew;
 487}
 488
 489static void via_free_kctls(struct hda_codec *codec)
 490{
 491        struct via_spec *spec = codec->spec;
 492
 493        if (spec->kctls.list) {
 494                struct snd_kcontrol_new *kctl = spec->kctls.list;
 495                int i;
 496                for (i = 0; i < spec->kctls.used; i++)
 497                        kfree(kctl[i].name);
 498        }
 499        snd_array_free(&spec->kctls);
 500}
 501
 502/* create input playback/capture controls for the given pin */
 503static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
 504                                int type_idx, int idx, int mix_nid)
 505{
 506        char name[32];
 507        int err;
 508
 509        sprintf(name, "%s Playback Volume", ctlname);
 510        err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
 511                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 512        if (err < 0)
 513                return err;
 514        sprintf(name, "%s Playback Switch", ctlname);
 515        err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
 516                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 517        if (err < 0)
 518                return err;
 519        return 0;
 520}
 521
 522static void via_auto_set_output_and_unmute(struct hda_codec *codec,
 523                                           hda_nid_t nid, int pin_type,
 524                                           int dac_idx)
 525{
 526        /* set as output */
 527        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 528                            pin_type);
 529        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 530                            AMP_OUT_UNMUTE);
 531        if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
 532                snd_hda_codec_write(codec, nid, 0,
 533                                    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
 534}
 535
 536
 537static void via_auto_init_multi_out(struct hda_codec *codec)
 538{
 539        struct via_spec *spec = codec->spec;
 540        int i;
 541
 542        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
 543                hda_nid_t nid = spec->autocfg.line_out_pins[i];
 544                if (nid)
 545                        via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
 546        }
 547}
 548
 549static void via_auto_init_hp_out(struct hda_codec *codec)
 550{
 551        struct via_spec *spec = codec->spec;
 552        hda_nid_t pin;
 553        int i;
 554
 555        for (i = 0; i < spec->autocfg.hp_outs; i++) {
 556                pin = spec->autocfg.hp_pins[i];
 557                if (pin) /* connect to front */
 558                        via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 559        }
 560}
 561
 562static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
 563
 564static void via_auto_init_analog_input(struct hda_codec *codec)
 565{
 566        struct via_spec *spec = codec->spec;
 567        const struct auto_pin_cfg *cfg = &spec->autocfg;
 568        unsigned int ctl;
 569        int i;
 570
 571        for (i = 0; i < cfg->num_inputs; i++) {
 572                hda_nid_t nid = cfg->inputs[i].pin;
 573                if (spec->smart51_enabled && is_smart51_pins(spec, nid))
 574                        ctl = PIN_OUT;
 575                else if (cfg->inputs[i].type == AUTO_PIN_MIC)
 576                        ctl = PIN_VREF50;
 577                else
 578                        ctl = PIN_IN;
 579                snd_hda_codec_write(codec, nid, 0,
 580                                    AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
 581        }
 582}
 583
 584static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
 585                                unsigned int *affected_parm)
 586{
 587        unsigned parm;
 588        unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
 589        unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
 590                >> AC_DEFCFG_MISC_SHIFT
 591                & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
 592        unsigned present = snd_hda_jack_detect(codec, nid);
 593        struct via_spec *spec = codec->spec;
 594        if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
 595            || ((no_presence || present)
 596                && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
 597                *affected_parm = AC_PWRST_D0; /* if it's connected */
 598                parm = AC_PWRST_D0;
 599        } else
 600                parm = AC_PWRST_D3;
 601
 602        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
 603}
 604
 605static void set_jack_power_state(struct hda_codec *codec)
 606{
 607        struct via_spec *spec = codec->spec;
 608        int imux_is_smixer;
 609        unsigned int parm;
 610
 611        if (spec->codec_type == VT1702) {
 612                imux_is_smixer = snd_hda_codec_read(
 613                        codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
 614                /* inputs */
 615                /* PW 1/2/5 (14h/15h/18h) */
 616                parm = AC_PWRST_D3;
 617                set_pin_power_state(codec, 0x14, &parm);
 618                set_pin_power_state(codec, 0x15, &parm);
 619                set_pin_power_state(codec, 0x18, &parm);
 620                if (imux_is_smixer)
 621                        parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
 622                /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
 623                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 624                                    parm);
 625                snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
 626                                    parm);
 627                snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
 628                                    parm);
 629                snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
 630                                    parm);
 631
 632                /* outputs */
 633                /* PW 3/4 (16h/17h) */
 634                parm = AC_PWRST_D3;
 635                set_pin_power_state(codec, 0x16, &parm);
 636                set_pin_power_state(codec, 0x17, &parm);
 637                /* MW0 (1ah), AOW 0/1 (10h/1dh) */
 638                snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
 639                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 640                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 641                                    parm);
 642                snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
 643                                    parm);
 644        } else if (spec->codec_type == VT1708B_8CH
 645                   || spec->codec_type == VT1708B_4CH
 646                   || spec->codec_type == VT1708S) {
 647                /* SW0 (17h) = stereo mixer */
 648                int is_8ch = spec->codec_type != VT1708B_4CH;
 649                imux_is_smixer = snd_hda_codec_read(
 650                        codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
 651                        == ((spec->codec_type == VT1708S)  ? 5 : 0);
 652                /* inputs */
 653                /* PW 1/2/5 (1ah/1bh/1eh) */
 654                parm = AC_PWRST_D3;
 655                set_pin_power_state(codec, 0x1a, &parm);
 656                set_pin_power_state(codec, 0x1b, &parm);
 657                set_pin_power_state(codec, 0x1e, &parm);
 658                if (imux_is_smixer)
 659                        parm = AC_PWRST_D0;
 660                /* SW0 (17h), AIW 0/1 (13h/14h) */
 661                snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
 662                                    parm);
 663                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 664                                    parm);
 665                snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
 666                                    parm);
 667
 668                /* outputs */
 669                /* PW0 (19h), SW1 (18h), AOW1 (11h) */
 670                parm = AC_PWRST_D3;
 671                set_pin_power_state(codec, 0x19, &parm);
 672                if (spec->smart51_enabled)
 673                        parm = AC_PWRST_D0;
 674                snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
 675                                    parm);
 676                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 677                                    parm);
 678
 679                /* PW6 (22h), SW2 (26h), AOW2 (24h) */
 680                if (is_8ch) {
 681                        parm = AC_PWRST_D3;
 682                        set_pin_power_state(codec, 0x22, &parm);
 683                        if (spec->smart51_enabled)
 684                                parm = AC_PWRST_D0;
 685                        snd_hda_codec_write(codec, 0x26, 0,
 686                                            AC_VERB_SET_POWER_STATE, parm);
 687                        snd_hda_codec_write(codec, 0x24, 0,
 688                                            AC_VERB_SET_POWER_STATE, parm);
 689                }
 690
 691                /* PW 3/4/7 (1ch/1dh/23h) */
 692                parm = AC_PWRST_D3;
 693                /* force to D0 for internal Speaker */
 694                set_pin_power_state(codec, 0x1c, &parm);
 695                set_pin_power_state(codec, 0x1d, &parm);
 696                if (is_8ch)
 697                        set_pin_power_state(codec, 0x23, &parm);
 698                /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
 699                snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
 700                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 701                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 702                                    parm);
 703                if (is_8ch) {
 704                        snd_hda_codec_write(codec, 0x25, 0,
 705                                            AC_VERB_SET_POWER_STATE, parm);
 706                        snd_hda_codec_write(codec, 0x27, 0,
 707                                            AC_VERB_SET_POWER_STATE, parm);
 708                }
 709        }  else if (spec->codec_type == VT1718S) {
 710                /* MUX6 (1eh) = stereo mixer */
 711                imux_is_smixer = snd_hda_codec_read(
 712                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
 713                /* inputs */
 714                /* PW 5/6/7 (29h/2ah/2bh) */
 715                parm = AC_PWRST_D3;
 716                set_pin_power_state(codec, 0x29, &parm);
 717                set_pin_power_state(codec, 0x2a, &parm);
 718                set_pin_power_state(codec, 0x2b, &parm);
 719                if (imux_is_smixer)
 720                        parm = AC_PWRST_D0;
 721                /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
 722                snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
 723                                    parm);
 724                snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
 725                                    parm);
 726                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 727                                    parm);
 728                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 729                                    parm);
 730
 731                /* outputs */
 732                /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
 733                parm = AC_PWRST_D3;
 734                set_pin_power_state(codec, 0x27, &parm);
 735                snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
 736                                    parm);
 737                snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
 738                                    parm);
 739
 740                /* PW2 (26h), AOW2 (ah) */
 741                parm = AC_PWRST_D3;
 742                set_pin_power_state(codec, 0x26, &parm);
 743                snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
 744                                    parm);
 745
 746                /* PW0/1 (24h/25h) */
 747                parm = AC_PWRST_D3;
 748                set_pin_power_state(codec, 0x24, &parm);
 749                set_pin_power_state(codec, 0x25, &parm);
 750                if (!spec->hp_independent_mode) /* check for redirected HP */
 751                        set_pin_power_state(codec, 0x28, &parm);
 752                snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
 753                                    parm);
 754                snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
 755                                    parm);
 756                /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
 757                snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
 758                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 759                if (spec->hp_independent_mode) {
 760                        /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
 761                        parm = AC_PWRST_D3;
 762                        set_pin_power_state(codec, 0x28, &parm);
 763                        snd_hda_codec_write(codec, 0x1b, 0,
 764                                            AC_VERB_SET_POWER_STATE, parm);
 765                        snd_hda_codec_write(codec, 0x34, 0,
 766                                            AC_VERB_SET_POWER_STATE, parm);
 767                        snd_hda_codec_write(codec, 0xc, 0,
 768                                            AC_VERB_SET_POWER_STATE, parm);
 769                }
 770        } else if (spec->codec_type == VT1716S) {
 771                unsigned int mono_out, present;
 772                /* SW0 (17h) = stereo mixer */
 773                imux_is_smixer = snd_hda_codec_read(
 774                        codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
 775                /* inputs */
 776                /* PW 1/2/5 (1ah/1bh/1eh) */
 777                parm = AC_PWRST_D3;
 778                set_pin_power_state(codec, 0x1a, &parm);
 779                set_pin_power_state(codec, 0x1b, &parm);
 780                set_pin_power_state(codec, 0x1e, &parm);
 781                if (imux_is_smixer)
 782                        parm = AC_PWRST_D0;
 783                /* SW0 (17h), AIW0(13h) */
 784                snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
 785                                    parm);
 786                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 787                                    parm);
 788
 789                parm = AC_PWRST_D3;
 790                set_pin_power_state(codec, 0x1e, &parm);
 791                /* PW11 (22h) */
 792                if (spec->dmic_enabled)
 793                        set_pin_power_state(codec, 0x22, &parm);
 794                else
 795                        snd_hda_codec_write(
 796                                codec, 0x22, 0,
 797                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 798
 799                /* SW2(26h), AIW1(14h) */
 800                snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
 801                                    parm);
 802                snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
 803                                    parm);
 804
 805                /* outputs */
 806                /* PW0 (19h), SW1 (18h), AOW1 (11h) */
 807                parm = AC_PWRST_D3;
 808                set_pin_power_state(codec, 0x19, &parm);
 809                /* Smart 5.1 PW2(1bh) */
 810                if (spec->smart51_enabled)
 811                        set_pin_power_state(codec, 0x1b, &parm);
 812                snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
 813                                    parm);
 814                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 815                                    parm);
 816
 817                /* PW7 (23h), SW3 (27h), AOW3 (25h) */
 818                parm = AC_PWRST_D3;
 819                set_pin_power_state(codec, 0x23, &parm);
 820                /* Smart 5.1 PW1(1ah) */
 821                if (spec->smart51_enabled)
 822                        set_pin_power_state(codec, 0x1a, &parm);
 823                snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
 824                                    parm);
 825
 826                /* Smart 5.1 PW5(1eh) */
 827                if (spec->smart51_enabled)
 828                        set_pin_power_state(codec, 0x1e, &parm);
 829                snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
 830                                    parm);
 831
 832                /* Mono out */
 833                /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
 834                present = snd_hda_jack_detect(codec, 0x1c);
 835                if (present)
 836                        mono_out = 0;
 837                else {
 838                        present = snd_hda_jack_detect(codec, 0x1d);
 839                        if (!spec->hp_independent_mode && present)
 840                                mono_out = 0;
 841                        else
 842                                mono_out = 1;
 843                }
 844                parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
 845                snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
 846                                    parm);
 847                snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
 848                                    parm);
 849                snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
 850                                    parm);
 851
 852                /* PW 3/4 (1ch/1dh) */
 853                parm = AC_PWRST_D3;
 854                set_pin_power_state(codec, 0x1c, &parm);
 855                set_pin_power_state(codec, 0x1d, &parm);
 856                /* HP Independent Mode, power on AOW3 */
 857                if (spec->hp_independent_mode)
 858                        snd_hda_codec_write(codec, 0x25, 0,
 859                                            AC_VERB_SET_POWER_STATE, parm);
 860
 861                /* force to D0 for internal Speaker */
 862                /* MW0 (16h), AOW0 (10h) */
 863                snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
 864                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 865                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 866                                    mono_out ? AC_PWRST_D0 : parm);
 867        } else if (spec->codec_type == VT2002P) {
 868                unsigned int present;
 869                /* MUX9 (1eh) = stereo mixer */
 870                imux_is_smixer = snd_hda_codec_read(
 871                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
 872                /* inputs */
 873                /* PW 5/6/7 (29h/2ah/2bh) */
 874                parm = AC_PWRST_D3;
 875                set_pin_power_state(codec, 0x29, &parm);
 876                set_pin_power_state(codec, 0x2a, &parm);
 877                set_pin_power_state(codec, 0x2b, &parm);
 878                if (imux_is_smixer)
 879                        parm = AC_PWRST_D0;
 880                /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
 881                snd_hda_codec_write(codec, 0x1e, 0,
 882                                    AC_VERB_SET_POWER_STATE, parm);
 883                snd_hda_codec_write(codec, 0x1f, 0,
 884                                    AC_VERB_SET_POWER_STATE, parm);
 885                snd_hda_codec_write(codec, 0x10, 0,
 886                                    AC_VERB_SET_POWER_STATE, parm);
 887                snd_hda_codec_write(codec, 0x11, 0,
 888                                    AC_VERB_SET_POWER_STATE, parm);
 889
 890                /* outputs */
 891                /* AOW0 (8h)*/
 892                snd_hda_codec_write(codec, 0x8, 0,
 893                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 894
 895                /* PW4 (26h), MW4 (1ch), MUX4(37h) */
 896                parm = AC_PWRST_D3;
 897                set_pin_power_state(codec, 0x26, &parm);
 898                snd_hda_codec_write(codec, 0x1c, 0,
 899                                    AC_VERB_SET_POWER_STATE, parm);
 900                snd_hda_codec_write(codec, 0x37,
 901                                    0, AC_VERB_SET_POWER_STATE, parm);
 902
 903                /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
 904                parm = AC_PWRST_D3;
 905                set_pin_power_state(codec, 0x25, &parm);
 906                snd_hda_codec_write(codec, 0x19, 0,
 907                                    AC_VERB_SET_POWER_STATE, parm);
 908                snd_hda_codec_write(codec, 0x35, 0,
 909                                    AC_VERB_SET_POWER_STATE, parm);
 910                if (spec->hp_independent_mode)  {
 911                        snd_hda_codec_write(codec, 0x9, 0,
 912                                            AC_VERB_SET_POWER_STATE, parm);
 913                }
 914
 915                /* Class-D */
 916                /* PW0 (24h), MW0(18h), MUX0(34h) */
 917                present = snd_hda_jack_detect(codec, 0x25);
 918                parm = AC_PWRST_D3;
 919                set_pin_power_state(codec, 0x24, &parm);
 920                if (present) {
 921                        snd_hda_codec_write(
 922                                codec, 0x18, 0,
 923                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 924                        snd_hda_codec_write(
 925                                codec, 0x34, 0,
 926                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 927                } else {
 928                        snd_hda_codec_write(
 929                                codec, 0x18, 0,
 930                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 931                        snd_hda_codec_write(
 932                                codec, 0x34, 0,
 933                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 934                }
 935
 936                /* Mono Out */
 937                /* PW15 (31h), MW8(17h), MUX8(3bh) */
 938                present = snd_hda_jack_detect(codec, 0x26);
 939                parm = AC_PWRST_D3;
 940                set_pin_power_state(codec, 0x31, &parm);
 941                if (present) {
 942                        snd_hda_codec_write(
 943                                codec, 0x17, 0,
 944                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 945                        snd_hda_codec_write(
 946                                codec, 0x3b, 0,
 947                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 948                } else {
 949                        snd_hda_codec_write(
 950                                codec, 0x17, 0,
 951                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 952                        snd_hda_codec_write(
 953                                codec, 0x3b, 0,
 954                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 955                }
 956
 957                /* MW9 (21h) */
 958                if (imux_is_smixer || !is_aa_path_mute(codec))
 959                        snd_hda_codec_write(
 960                                codec, 0x21, 0,
 961                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 962                else
 963                        snd_hda_codec_write(
 964                                codec, 0x21, 0,
 965                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 966        } else if (spec->codec_type == VT1812) {
 967                unsigned int present;
 968                /* MUX10 (1eh) = stereo mixer */
 969                imux_is_smixer = snd_hda_codec_read(
 970                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
 971                /* inputs */
 972                /* PW 5/6/7 (29h/2ah/2bh) */
 973                parm = AC_PWRST_D3;
 974                set_pin_power_state(codec, 0x29, &parm);
 975                set_pin_power_state(codec, 0x2a, &parm);
 976                set_pin_power_state(codec, 0x2b, &parm);
 977                if (imux_is_smixer)
 978                        parm = AC_PWRST_D0;
 979                /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
 980                snd_hda_codec_write(codec, 0x1e, 0,
 981                                    AC_VERB_SET_POWER_STATE, parm);
 982                snd_hda_codec_write(codec, 0x1f, 0,
 983                                    AC_VERB_SET_POWER_STATE, parm);
 984                snd_hda_codec_write(codec, 0x10, 0,
 985                                    AC_VERB_SET_POWER_STATE, parm);
 986                snd_hda_codec_write(codec, 0x11, 0,
 987                                    AC_VERB_SET_POWER_STATE, parm);
 988
 989                /* outputs */
 990                /* AOW0 (8h)*/
 991                snd_hda_codec_write(codec, 0x8, 0,
 992                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 993
 994                /* PW4 (28h), MW4 (18h), MUX4(38h) */
 995                parm = AC_PWRST_D3;
 996                set_pin_power_state(codec, 0x28, &parm);
 997                snd_hda_codec_write(codec, 0x18, 0,
 998                                    AC_VERB_SET_POWER_STATE, parm);
 999                snd_hda_codec_write(codec, 0x38, 0,
1000                                    AC_VERB_SET_POWER_STATE, parm);
1001
1002                /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1003                parm = AC_PWRST_D3;
1004                set_pin_power_state(codec, 0x25, &parm);
1005                snd_hda_codec_write(codec, 0x15, 0,
1006                                    AC_VERB_SET_POWER_STATE, parm);
1007                snd_hda_codec_write(codec, 0x35, 0,
1008                                    AC_VERB_SET_POWER_STATE, parm);
1009                if (spec->hp_independent_mode)  {
1010                        snd_hda_codec_write(codec, 0x9, 0,
1011                                            AC_VERB_SET_POWER_STATE, parm);
1012                }
1013
1014                /* Internal Speaker */
1015                /* PW0 (24h), MW0(14h), MUX0(34h) */
1016                present = snd_hda_jack_detect(codec, 0x25);
1017                parm = AC_PWRST_D3;
1018                set_pin_power_state(codec, 0x24, &parm);
1019                if (present) {
1020                        snd_hda_codec_write(codec, 0x14, 0,
1021                                            AC_VERB_SET_POWER_STATE,
1022                                            AC_PWRST_D3);
1023                        snd_hda_codec_write(codec, 0x34, 0,
1024                                            AC_VERB_SET_POWER_STATE,
1025                                            AC_PWRST_D3);
1026                } else {
1027                        snd_hda_codec_write(codec, 0x14, 0,
1028                                            AC_VERB_SET_POWER_STATE,
1029                                            AC_PWRST_D0);
1030                        snd_hda_codec_write(codec, 0x34, 0,
1031                                            AC_VERB_SET_POWER_STATE,
1032                                            AC_PWRST_D0);
1033                }
1034                /* Mono Out */
1035                /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1036                present = snd_hda_jack_detect(codec, 0x28);
1037                parm = AC_PWRST_D3;
1038                set_pin_power_state(codec, 0x31, &parm);
1039                if (present) {
1040                        snd_hda_codec_write(codec, 0x1c, 0,
1041                                            AC_VERB_SET_POWER_STATE,
1042                                            AC_PWRST_D3);
1043                        snd_hda_codec_write(codec, 0x3c, 0,
1044                                            AC_VERB_SET_POWER_STATE,
1045                                            AC_PWRST_D3);
1046                        snd_hda_codec_write(codec, 0x3e, 0,
1047                                            AC_VERB_SET_POWER_STATE,
1048                                            AC_PWRST_D3);
1049                } else {
1050                        snd_hda_codec_write(codec, 0x1c, 0,
1051                                            AC_VERB_SET_POWER_STATE,
1052                                            AC_PWRST_D0);
1053                        snd_hda_codec_write(codec, 0x3c, 0,
1054                                            AC_VERB_SET_POWER_STATE,
1055                                            AC_PWRST_D0);
1056                        snd_hda_codec_write(codec, 0x3e, 0,
1057                                            AC_VERB_SET_POWER_STATE,
1058                                            AC_PWRST_D0);
1059                }
1060
1061                /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1062                parm = AC_PWRST_D3;
1063                set_pin_power_state(codec, 0x33, &parm);
1064                snd_hda_codec_write(codec, 0x1d, 0,
1065                                    AC_VERB_SET_POWER_STATE, parm);
1066                snd_hda_codec_write(codec, 0x3d, 0,
1067                                    AC_VERB_SET_POWER_STATE, parm);
1068
1069                /* MW9 (21h) */
1070                if (imux_is_smixer || !is_aa_path_mute(codec))
1071                        snd_hda_codec_write(
1072                                codec, 0x21, 0,
1073                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1074                else
1075                        snd_hda_codec_write(
1076                                codec, 0x21, 0,
1077                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1078        }
1079}
1080
1081/*
1082 * input MUX handling
1083 */
1084static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1085                             struct snd_ctl_elem_info *uinfo)
1086{
1087        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1088        struct via_spec *spec = codec->spec;
1089        return snd_hda_input_mux_info(spec->input_mux, uinfo);
1090}
1091
1092static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1093                            struct snd_ctl_elem_value *ucontrol)
1094{
1095        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1096        struct via_spec *spec = codec->spec;
1097        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1098
1099        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1100        return 0;
1101}
1102
1103static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1104                            struct snd_ctl_elem_value *ucontrol)
1105{
1106        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1107        struct via_spec *spec = codec->spec;
1108        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1109        int ret;
1110
1111        if (!spec->mux_nids[adc_idx])
1112                return -EINVAL;
1113        /* switch to D0 beofre change index */
1114        if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1115                               AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1116                snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1117                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1118
1119        ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1120                                     spec->mux_nids[adc_idx],
1121                                     &spec->cur_mux[adc_idx]);
1122        /* update jack power state */
1123        set_jack_power_state(codec);
1124
1125        return ret;
1126}
1127
1128static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
1129                                   struct snd_ctl_elem_info *uinfo)
1130{
1131        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1132        struct via_spec *spec = codec->spec;
1133        return snd_hda_input_mux_info(spec->hp_mux, uinfo);
1134}
1135
1136static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1137                                  struct snd_ctl_elem_value *ucontrol)
1138{
1139        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1140        hda_nid_t nid = kcontrol->private_value;
1141        unsigned int pinsel;
1142
1143        /* use !! to translate conn sel 2 for VT1718S */
1144        pinsel = !!snd_hda_codec_read(codec, nid, 0,
1145                                      AC_VERB_GET_CONNECT_SEL,
1146                                      0x00);
1147        ucontrol->value.enumerated.item[0] = pinsel;
1148
1149        return 0;
1150}
1151
1152static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1153{
1154        struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1155        if (ctl) {
1156                ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1157                ctl->vd[0].access |= active
1158                        ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1159                snd_ctl_notify(codec->bus->card,
1160                               SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1161        }
1162}
1163
1164static hda_nid_t side_mute_channel(struct via_spec *spec)
1165{
1166        switch (spec->codec_type) {
1167        case VT1708:            return 0x1b;
1168        case VT1709_10CH:       return 0x29;
1169        case VT1708B_8CH:       /* fall thru */
1170        case VT1708S:           return 0x27;
1171        default:                return 0;
1172        }
1173}
1174
1175static int update_side_mute_status(struct hda_codec *codec)
1176{
1177        /* mute side channel */
1178        struct via_spec *spec = codec->spec;
1179        unsigned int parm = spec->hp_independent_mode
1180                ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1181        hda_nid_t sw3 = side_mute_channel(spec);
1182
1183        if (sw3)
1184                snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1185                                    parm);
1186        return 0;
1187}
1188
1189static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1190                                  struct snd_ctl_elem_value *ucontrol)
1191{
1192        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1193        struct via_spec *spec = codec->spec;
1194        hda_nid_t nid = kcontrol->private_value;
1195        unsigned int pinsel = ucontrol->value.enumerated.item[0];
1196        /* Get Independent Mode index of headphone pin widget */
1197        spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1198                ? 1 : 0;
1199        if (spec->codec_type == VT1718S)
1200                snd_hda_codec_write(codec, nid, 0,
1201                                    AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
1202        else
1203                snd_hda_codec_write(codec, nid, 0,
1204                                    AC_VERB_SET_CONNECT_SEL, pinsel);
1205
1206        if (spec->codec_type == VT1812)
1207                snd_hda_codec_write(codec, 0x35, 0,
1208                                    AC_VERB_SET_CONNECT_SEL, pinsel);
1209        if (spec->multiout.hp_nid && spec->multiout.hp_nid
1210            != spec->multiout.dac_nids[HDA_FRONT])
1211                snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1212                                           0, 0, 0);
1213
1214        update_side_mute_status(codec);
1215        /* update HP volume/swtich active state */
1216        if (spec->codec_type == VT1708S
1217            || spec->codec_type == VT1702
1218            || spec->codec_type == VT1718S
1219            || spec->codec_type == VT1716S
1220            || spec->codec_type == VT2002P
1221            || spec->codec_type == VT1812) {
1222                activate_ctl(codec, "Headphone Playback Volume",
1223                             spec->hp_independent_mode);
1224                activate_ctl(codec, "Headphone Playback Switch",
1225                             spec->hp_independent_mode);
1226        }
1227        /* update jack power state */
1228        set_jack_power_state(codec);
1229        return 0;
1230}
1231
1232static struct snd_kcontrol_new via_hp_mixer[2] = {
1233        {
1234                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1235                .name = "Independent HP",
1236                .info = via_independent_hp_info,
1237                .get = via_independent_hp_get,
1238                .put = via_independent_hp_put,
1239        },
1240        {
1241                .iface = NID_MAPPING,
1242                .name = "Independent HP",
1243        },
1244};
1245
1246static int via_hp_build(struct hda_codec *codec)
1247{
1248        struct via_spec *spec = codec->spec;
1249        struct snd_kcontrol_new *knew;
1250        hda_nid_t nid;
1251        int nums;
1252        hda_nid_t conn[HDA_MAX_CONNECTIONS];
1253
1254        switch (spec->codec_type) {
1255        case VT1718S:
1256                nid = 0x34;
1257                break;
1258        case VT2002P:
1259                nid = 0x35;
1260                break;
1261        case VT1812:
1262                nid = 0x3d;
1263                break;
1264        default:
1265                nid = spec->autocfg.hp_pins[0];
1266                break;
1267        }
1268
1269        if (spec->codec_type != VT1708) {
1270                nums = snd_hda_get_connections(codec, nid,
1271                                               conn, HDA_MAX_CONNECTIONS);
1272                if (nums <= 1)
1273                        return 0;
1274        }
1275
1276        knew = via_clone_control(spec, &via_hp_mixer[0]);
1277        if (knew == NULL)
1278                return -ENOMEM;
1279
1280        knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1281        knew->private_value = nid;
1282
1283        knew = via_clone_control(spec, &via_hp_mixer[1]);
1284        if (knew == NULL)
1285                return -ENOMEM;
1286        knew->subdevice = side_mute_channel(spec);
1287
1288        return 0;
1289}
1290
1291static void notify_aa_path_ctls(struct hda_codec *codec)
1292{
1293        int i;
1294        struct snd_ctl_elem_id id;
1295        const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"};
1296        struct snd_kcontrol *ctl;
1297
1298        memset(&id, 0, sizeof(id));
1299        id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1300        for (i = 0; i < ARRAY_SIZE(labels); i++) {
1301                sprintf(id.name, "%s Playback Volume", labels[i]);
1302                ctl = snd_hda_find_mixer_ctl(codec, id.name);
1303                if (ctl)
1304                        snd_ctl_notify(codec->bus->card,
1305                                        SNDRV_CTL_EVENT_MASK_VALUE,
1306                                        &ctl->id);
1307        }
1308}
1309
1310static void mute_aa_path(struct hda_codec *codec, int mute)
1311{
1312        struct via_spec *spec = codec->spec;
1313        hda_nid_t  nid_mixer;
1314        int start_idx;
1315        int end_idx;
1316        int i;
1317        /* get nid of MW0 and start & end index */
1318        switch (spec->codec_type) {
1319        case VT1708:
1320                nid_mixer = 0x17;
1321                start_idx = 2;
1322                end_idx = 4;
1323                break;
1324        case VT1709_10CH:
1325        case VT1709_6CH:
1326                nid_mixer = 0x18;
1327                start_idx = 2;
1328                end_idx = 4;
1329                break;
1330        case VT1708B_8CH:
1331        case VT1708B_4CH:
1332        case VT1708S:
1333        case VT1716S:
1334                nid_mixer = 0x16;
1335                start_idx = 2;
1336                end_idx = 4;
1337                break;
1338        case VT1718S:
1339                nid_mixer = 0x21;
1340                start_idx = 1;
1341                end_idx = 3;
1342                break;
1343        default:
1344                return;
1345        }
1346        /* check AA path's mute status */
1347        for (i = start_idx; i <= end_idx; i++) {
1348                int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1349                snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1350                                         HDA_AMP_MUTE, val);
1351        }
1352}
1353static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1354{
1355        const struct auto_pin_cfg *cfg = &spec->autocfg;
1356        int i;
1357
1358        for (i = 0; i < cfg->num_inputs; i++) {
1359                if (pin == cfg->inputs[i].pin)
1360                        return cfg->inputs[i].type <= AUTO_PIN_LINE_IN;
1361        }
1362        return 0;
1363}
1364
1365static int via_smart51_info(struct snd_kcontrol *kcontrol,
1366                            struct snd_ctl_elem_info *uinfo)
1367{
1368        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1369        uinfo->count = 1;
1370        uinfo->value.integer.min = 0;
1371        uinfo->value.integer.max = 1;
1372        return 0;
1373}
1374
1375static int via_smart51_get(struct snd_kcontrol *kcontrol,
1376                           struct snd_ctl_elem_value *ucontrol)
1377{
1378        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1379        struct via_spec *spec = codec->spec;
1380        const struct auto_pin_cfg *cfg = &spec->autocfg;
1381        int on = 1;
1382        int i;
1383
1384        for (i = 0; i < cfg->num_inputs; i++) {
1385                hda_nid_t nid = cfg->inputs[i].pin;
1386                int ctl = snd_hda_codec_read(codec, nid, 0,
1387                                             AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1388                if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1389                        continue;
1390                if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1391                    spec->hp_independent_mode && spec->codec_type != VT1718S)
1392                        continue; /* ignore FMic for independent HP */
1393                if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
1394                        on = 0;
1395        }
1396        *ucontrol->value.integer.value = on;
1397        return 0;
1398}
1399
1400static int via_smart51_put(struct snd_kcontrol *kcontrol,
1401                           struct snd_ctl_elem_value *ucontrol)
1402{
1403        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1404        struct via_spec *spec = codec->spec;
1405        const struct auto_pin_cfg *cfg = &spec->autocfg;
1406        int out_in = *ucontrol->value.integer.value
1407                ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1408        int i;
1409
1410        for (i = 0; i < cfg->num_inputs; i++) {
1411                hda_nid_t nid = cfg->inputs[i].pin;
1412                unsigned int parm;
1413
1414                if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1415                        continue;
1416                if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1417                    spec->hp_independent_mode && spec->codec_type != VT1718S)
1418                        continue; /* don't retask FMic for independent HP */
1419
1420                parm = snd_hda_codec_read(codec, nid, 0,
1421                                          AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1422                parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1423                parm |= out_in;
1424                snd_hda_codec_write(codec, nid, 0,
1425                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
1426                                    parm);
1427                if (out_in == AC_PINCTL_OUT_EN) {
1428                        mute_aa_path(codec, 1);
1429                        notify_aa_path_ctls(codec);
1430                }
1431                if (spec->codec_type == VT1718S) {
1432                        snd_hda_codec_amp_stereo(
1433                                        codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1434                                        HDA_AMP_UNMUTE);
1435                }
1436                if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1437                        if (spec->codec_type == VT1708S
1438                            || spec->codec_type == VT1716S) {
1439                                /* input = index 1 (AOW3) */
1440                                snd_hda_codec_write(
1441                                        codec, nid, 0,
1442                                        AC_VERB_SET_CONNECT_SEL, 1);
1443                                snd_hda_codec_amp_stereo(
1444                                        codec, nid, HDA_OUTPUT,
1445                                        0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1446                        }
1447                }
1448        }
1449        spec->smart51_enabled = *ucontrol->value.integer.value;
1450        set_jack_power_state(codec);
1451        return 1;
1452}
1453
1454static struct snd_kcontrol_new via_smart51_mixer[2] = {
1455        {
1456         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1457         .name = "Smart 5.1",
1458         .count = 1,
1459         .info = via_smart51_info,
1460         .get = via_smart51_get,
1461         .put = via_smart51_put,
1462         },
1463        {
1464         .iface = NID_MAPPING,
1465         .name = "Smart 5.1",
1466        }
1467};
1468
1469static int via_smart51_build(struct via_spec *spec)
1470{
1471        struct snd_kcontrol_new *knew;
1472        const struct auto_pin_cfg *cfg = &spec->autocfg;
1473        hda_nid_t nid;
1474        int i;
1475
1476        knew = via_clone_control(spec, &via_smart51_mixer[0]);
1477        if (knew == NULL)
1478                return -ENOMEM;
1479
1480        for (i = 0; i < cfg->num_inputs; i++) {
1481                nid = cfg->inputs[i].pin;
1482                if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1483                        knew = via_clone_control(spec, &via_smart51_mixer[1]);
1484                        if (knew == NULL)
1485                                return -ENOMEM;
1486                        knew->subdevice = nid;
1487                        break;
1488                }
1489        }
1490
1491        return 0;
1492}
1493
1494/* capture mixer elements */
1495static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1496        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1497        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1498        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1499        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1500        {
1501                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1502                /* The multiple "Capture Source" controls confuse alsamixer
1503                 * So call somewhat different..
1504                 */
1505                /* .name = "Capture Source", */
1506                .name = "Input Source",
1507                .count = 1,
1508                .info = via_mux_enum_info,
1509                .get = via_mux_enum_get,
1510                .put = via_mux_enum_put,
1511        },
1512        { } /* end */
1513};
1514
1515/* check AA path's mute statue */
1516static int is_aa_path_mute(struct hda_codec *codec)
1517{
1518        int mute = 1;
1519        hda_nid_t  nid_mixer;
1520        int start_idx;
1521        int end_idx;
1522        int i;
1523        struct via_spec *spec = codec->spec;
1524        /* get nid of MW0 and start & end index */
1525        switch (spec->codec_type) {
1526        case VT1708B_8CH:
1527        case VT1708B_4CH:
1528        case VT1708S:
1529        case VT1716S:
1530                nid_mixer = 0x16;
1531                start_idx = 2;
1532                end_idx = 4;
1533                break;
1534        case VT1702:
1535                nid_mixer = 0x1a;
1536                start_idx = 1;
1537                end_idx = 3;
1538                break;
1539        case VT1718S:
1540                nid_mixer = 0x21;
1541                start_idx = 1;
1542                end_idx = 3;
1543                break;
1544        case VT2002P:
1545        case VT1812:
1546                nid_mixer = 0x21;
1547                start_idx = 0;
1548                end_idx = 2;
1549                break;
1550        default:
1551                return 0;
1552        }
1553        /* check AA path's mute status */
1554        for (i = start_idx; i <= end_idx; i++) {
1555                unsigned int con_list = snd_hda_codec_read(
1556                        codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1557                int shift = 8 * (i % 4);
1558                hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1559                unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1560                if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1561                        /* check mute status while the pin is connected */
1562                        int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1563                                                            HDA_INPUT, i) >> 7;
1564                        int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1565                                                            HDA_INPUT, i) >> 7;
1566                        if (!mute_l || !mute_r) {
1567                                mute = 0;
1568                                break;
1569                        }
1570                }
1571        }
1572        return mute;
1573}
1574
1575/* enter/exit analog low-current mode */
1576static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1577{
1578        struct via_spec *spec = codec->spec;
1579        static int saved_stream_idle = 1; /* saved stream idle status */
1580        int enable = is_aa_path_mute(codec);
1581        unsigned int verb = 0;
1582        unsigned int parm = 0;
1583
1584        if (stream_idle == -1)  /* stream status did not change */
1585                enable = enable && saved_stream_idle;
1586        else {
1587                enable = enable && stream_idle;
1588                saved_stream_idle = stream_idle;
1589        }
1590
1591        /* decide low current mode's verb & parameter */
1592        switch (spec->codec_type) {
1593        case VT1708B_8CH:
1594        case VT1708B_4CH:
1595                verb = 0xf70;
1596                parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1597                break;
1598        case VT1708S:
1599        case VT1718S:
1600        case VT1716S:
1601                verb = 0xf73;
1602                parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1603                break;
1604        case VT1702:
1605                verb = 0xf73;
1606                parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1607                break;
1608        case VT2002P:
1609        case VT1812:
1610                verb = 0xf93;
1611                parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1612                break;
1613        default:
1614                return;         /* other codecs are not supported */
1615        }
1616        /* send verb */
1617        snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1618}
1619
1620/*
1621 * generic initialization of ADC, input mixers and output mixers
1622 */
1623static struct hda_verb vt1708_volume_init_verbs[] = {
1624        /*
1625         * Unmute ADC0-1 and set the default input to mic-in
1626         */
1627        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1628        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1629
1630
1631        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1632         * mixer widget
1633         */
1634        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1635        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1636        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1637        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1638        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1639        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1640
1641        /*
1642         * Set up output mixers (0x19 - 0x1b)
1643         */
1644        /* set vol=0 to output mixers */
1645        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1646        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1647        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1648
1649        /* Setup default input MW0 to PW4 */
1650        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1651        /* PW9 Output enable */
1652        {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1653        { }
1654};
1655
1656static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1657                                 struct hda_codec *codec,
1658                                 struct snd_pcm_substream *substream)
1659{
1660        struct via_spec *spec = codec->spec;
1661        int idle = substream->pstr->substream_opened == 1
1662                && substream->ref_count == 0;
1663        analog_low_current_mode(codec, idle);
1664        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1665                                             hinfo);
1666}
1667
1668static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1669                                      unsigned int stream_tag,
1670                                      unsigned int format,
1671                                      struct snd_pcm_substream *substream)
1672{
1673        struct via_spec *spec = codec->spec;
1674        struct hda_multi_out *mout = &spec->multiout;
1675        hda_nid_t *nids = mout->dac_nids;
1676        int chs = substream->runtime->channels;
1677        int i;
1678
1679        mutex_lock(&codec->spdif_mutex);
1680        if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1681                if (chs == 2 &&
1682                    snd_hda_is_supported_format(codec, mout->dig_out_nid,
1683                                                format) &&
1684                    !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1685                        mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1686                        /* turn off SPDIF once; otherwise the IEC958 bits won't
1687                         * be updated */
1688                        if (codec->spdif_ctls & AC_DIG1_ENABLE)
1689                                snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1690                                                    AC_VERB_SET_DIGI_CONVERT_1,
1691                                                    codec->spdif_ctls &
1692                                                        ~AC_DIG1_ENABLE & 0xff);
1693                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1694                                                   stream_tag, 0, format);
1695                        /* turn on again (if needed) */
1696                        if (codec->spdif_ctls & AC_DIG1_ENABLE)
1697                                snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1698                                                    AC_VERB_SET_DIGI_CONVERT_1,
1699                                                    codec->spdif_ctls & 0xff);
1700                } else {
1701                        mout->dig_out_used = 0;
1702                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1703                                                   0, 0, 0);
1704                }
1705        }
1706        mutex_unlock(&codec->spdif_mutex);
1707
1708        /* front */
1709        snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1710                                   0, format);
1711
1712        if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1713            && !spec->hp_independent_mode)
1714                /* headphone out will just decode front left/right (stereo) */
1715                snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1716                                           0, format);
1717
1718        /* extra outputs copied from front */
1719        for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1720                if (mout->extra_out_nid[i])
1721                        snd_hda_codec_setup_stream(codec,
1722                                                   mout->extra_out_nid[i],
1723                                                   stream_tag, 0, format);
1724
1725        /* surrounds */
1726        for (i = 1; i < mout->num_dacs; i++) {
1727                if (chs >= (i + 1) * 2) /* independent out */
1728                        snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1729                                                   i * 2, format);
1730                else /* copy front */
1731                        snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1732                                                   0, format);
1733        }
1734}
1735
1736static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1737                                          struct hda_codec *codec,
1738                                          unsigned int stream_tag,
1739                                          unsigned int format,
1740                                          struct snd_pcm_substream *substream)
1741{
1742        struct via_spec *spec = codec->spec;
1743        struct hda_multi_out *mout = &spec->multiout;
1744        hda_nid_t *nids = mout->dac_nids;
1745
1746        if (substream->number == 0)
1747                playback_multi_pcm_prep_0(codec, stream_tag, format,
1748                                          substream);
1749        else {
1750                if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1751                    spec->hp_independent_mode)
1752                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1753                                                   stream_tag, 0, format);
1754        }
1755        vt1708_start_hp_work(spec);
1756        return 0;
1757}
1758
1759static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1760                                    struct hda_codec *codec,
1761                                    struct snd_pcm_substream *substream)
1762{
1763        struct via_spec *spec = codec->spec;
1764        struct hda_multi_out *mout = &spec->multiout;
1765        hda_nid_t *nids = mout->dac_nids;
1766        int i;
1767
1768        if (substream->number == 0) {
1769                for (i = 0; i < mout->num_dacs; i++)
1770                        snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1771
1772                if (mout->hp_nid && !spec->hp_independent_mode)
1773                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1774                                                   0, 0, 0);
1775
1776                for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1777                        if (mout->extra_out_nid[i])
1778                                snd_hda_codec_setup_stream(codec,
1779                                                        mout->extra_out_nid[i],
1780                                                        0, 0, 0);
1781                mutex_lock(&codec->spdif_mutex);
1782                if (mout->dig_out_nid &&
1783                    mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1784                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1785                                                   0, 0, 0);
1786                        mout->dig_out_used = 0;
1787                }
1788                mutex_unlock(&codec->spdif_mutex);
1789        } else {
1790                if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1791                    spec->hp_independent_mode)
1792                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1793                                                   0, 0, 0);
1794        }
1795        vt1708_stop_hp_work(spec);
1796        return 0;
1797}
1798
1799/*
1800 * Digital out
1801 */
1802static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1803                                     struct hda_codec *codec,
1804                                     struct snd_pcm_substream *substream)
1805{
1806        struct via_spec *spec = codec->spec;
1807        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1808}
1809
1810static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1811                                      struct hda_codec *codec,
1812                                      struct snd_pcm_substream *substream)
1813{
1814        struct via_spec *spec = codec->spec;
1815        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1816}
1817
1818static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1819                                        struct hda_codec *codec,
1820                                        unsigned int stream_tag,
1821                                        unsigned int format,
1822                                        struct snd_pcm_substream *substream)
1823{
1824        struct via_spec *spec = codec->spec;
1825        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1826                                             stream_tag, format, substream);
1827}
1828
1829static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1830                                        struct hda_codec *codec,
1831                                        struct snd_pcm_substream *substream)
1832{
1833        struct via_spec *spec = codec->spec;
1834        snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1835        return 0;
1836}
1837
1838/*
1839 * Analog capture
1840 */
1841static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1842                                   struct hda_codec *codec,
1843                                   unsigned int stream_tag,
1844                                   unsigned int format,
1845                                   struct snd_pcm_substream *substream)
1846{
1847        struct via_spec *spec = codec->spec;
1848
1849        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1850                                   stream_tag, 0, format);
1851        return 0;
1852}
1853
1854static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1855                                   struct hda_codec *codec,
1856                                   struct snd_pcm_substream *substream)
1857{
1858        struct via_spec *spec = codec->spec;
1859        snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1860        return 0;
1861}
1862
1863static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1864        .substreams = 2,
1865        .channels_min = 2,
1866        .channels_max = 8,
1867        .nid = 0x10, /* NID to query formats and rates */
1868        .ops = {
1869                .open = via_playback_pcm_open,
1870                .prepare = via_playback_multi_pcm_prepare,
1871                .cleanup = via_playback_multi_pcm_cleanup
1872        },
1873};
1874
1875static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1876        .substreams = 2,
1877        .channels_min = 2,
1878        .channels_max = 8,
1879        .nid = 0x10, /* NID to query formats and rates */
1880        /* We got noisy outputs on the right channel on VT1708 when
1881         * 24bit samples are used.  Until any workaround is found,
1882         * disable the 24bit format, so far.
1883         */
1884        .formats = SNDRV_PCM_FMTBIT_S16_LE,
1885        .ops = {
1886                .open = via_playback_pcm_open,
1887                .prepare = via_playback_multi_pcm_prepare,
1888                .cleanup = via_playback_multi_pcm_cleanup
1889        },
1890};
1891
1892static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1893        .substreams = 2,
1894        .channels_min = 2,
1895        .channels_max = 2,
1896        .nid = 0x15, /* NID to query formats and rates */
1897        .ops = {
1898                .prepare = via_capture_pcm_prepare,
1899                .cleanup = via_capture_pcm_cleanup
1900        },
1901};
1902
1903static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1904        .substreams = 1,
1905        .channels_min = 2,
1906        .channels_max = 2,
1907        /* NID is set in via_build_pcms */
1908        .ops = {
1909                .open = via_dig_playback_pcm_open,
1910                .close = via_dig_playback_pcm_close,
1911                .prepare = via_dig_playback_pcm_prepare,
1912                .cleanup = via_dig_playback_pcm_cleanup
1913        },
1914};
1915
1916static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1917        .substreams = 1,
1918        .channels_min = 2,
1919        .channels_max = 2,
1920};
1921
1922static int via_build_controls(struct hda_codec *codec)
1923{
1924        struct via_spec *spec = codec->spec;
1925        struct snd_kcontrol *kctl;
1926        struct snd_kcontrol_new *knew;
1927        int err, i;
1928
1929        for (i = 0; i < spec->num_mixers; i++) {
1930                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1931                if (err < 0)
1932                        return err;
1933        }
1934
1935        if (spec->multiout.dig_out_nid) {
1936                err = snd_hda_create_spdif_out_ctls(codec,
1937                                                    spec->multiout.dig_out_nid);
1938                if (err < 0)
1939                        return err;
1940                err = snd_hda_create_spdif_share_sw(codec,
1941                                                    &spec->multiout);
1942                if (err < 0)
1943                        return err;
1944                spec->multiout.share_spdif = 1;
1945        }
1946        if (spec->dig_in_nid) {
1947                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1948                if (err < 0)
1949                        return err;
1950        }
1951
1952        /* assign Capture Source enums to NID */
1953        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1954        for (i = 0; kctl && i < kctl->count; i++) {
1955                err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1956                if (err < 0)
1957                        return err;
1958        }
1959
1960        /* other nid->control mapping */
1961        for (i = 0; i < spec->num_mixers; i++) {
1962                for (knew = spec->mixers[i]; knew->name; knew++) {
1963                        if (knew->iface != NID_MAPPING)
1964                                continue;
1965                        kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1966                        if (kctl == NULL)
1967                                continue;
1968                        err = snd_hda_add_nid(codec, kctl, 0,
1969                                              knew->subdevice);
1970                }
1971        }
1972
1973        /* init power states */
1974        set_jack_power_state(codec);
1975        analog_low_current_mode(codec, 1);
1976
1977        via_free_kctls(codec); /* no longer needed */
1978        return 0;
1979}
1980
1981static int via_build_pcms(struct hda_codec *codec)
1982{
1983        struct via_spec *spec = codec->spec;
1984        struct hda_pcm *info = spec->pcm_rec;
1985
1986        codec->num_pcms = 1;
1987        codec->pcm_info = info;
1988
1989        info->name = spec->stream_name_analog;
1990        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1991                *(spec->stream_analog_playback);
1992        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1993                spec->multiout.dac_nids[0];
1994        info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1995        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1996
1997        info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1998                spec->multiout.max_channels;
1999
2000        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2001                codec->num_pcms++;
2002                info++;
2003                info->name = spec->stream_name_digital;
2004                info->pcm_type = HDA_PCM_TYPE_SPDIF;
2005                if (spec->multiout.dig_out_nid) {
2006                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2007                                *(spec->stream_digital_playback);
2008                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2009                                spec->multiout.dig_out_nid;
2010                }
2011                if (spec->dig_in_nid) {
2012                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2013                                *(spec->stream_digital_capture);
2014                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2015                                spec->dig_in_nid;
2016                }
2017        }
2018
2019        return 0;
2020}
2021
2022static void via_free(struct hda_codec *codec)
2023{
2024        struct via_spec *spec = codec->spec;
2025
2026        if (!spec)
2027                return;
2028
2029        via_free_kctls(codec);
2030        vt1708_stop_hp_work(spec);
2031        kfree(codec->spec);
2032}
2033
2034/* mute internal speaker if HP is plugged */
2035static void via_hp_automute(struct hda_codec *codec)
2036{
2037        unsigned int present = 0;
2038        struct via_spec *spec = codec->spec;
2039
2040        present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2041
2042        if (!spec->hp_independent_mode) {
2043                struct snd_ctl_elem_id id;
2044                /* auto mute */
2045                snd_hda_codec_amp_stereo(
2046                        codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2047                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2048                /* notify change */
2049                memset(&id, 0, sizeof(id));
2050                id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2051                strcpy(id.name, "Front Playback Switch");
2052                snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2053                               &id);
2054        }
2055}
2056
2057/* mute mono out if HP or Line out is plugged */
2058static void via_mono_automute(struct hda_codec *codec)
2059{
2060        unsigned int hp_present, lineout_present;
2061        struct via_spec *spec = codec->spec;
2062
2063        if (spec->codec_type != VT1716S)
2064                return;
2065
2066        lineout_present = snd_hda_jack_detect(codec,
2067                                              spec->autocfg.line_out_pins[0]);
2068
2069        /* Mute Mono Out if Line Out is plugged */
2070        if (lineout_present) {
2071                snd_hda_codec_amp_stereo(
2072                        codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2073                return;
2074        }
2075
2076        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2077
2078        if (!spec->hp_independent_mode)
2079                snd_hda_codec_amp_stereo(
2080                        codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2081                        hp_present ? HDA_AMP_MUTE : 0);
2082}
2083
2084static void via_gpio_control(struct hda_codec *codec)
2085{
2086        unsigned int gpio_data;
2087        unsigned int vol_counter;
2088        unsigned int vol;
2089        unsigned int master_vol;
2090
2091        struct via_spec *spec = codec->spec;
2092
2093        gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
2094                                       AC_VERB_GET_GPIO_DATA, 0) & 0x03;
2095
2096        vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
2097                                          0xF84, 0) & 0x3F0000) >> 16;
2098
2099        vol = vol_counter & 0x1F;
2100        master_vol = snd_hda_codec_read(codec, 0x1A, 0,
2101                                        AC_VERB_GET_AMP_GAIN_MUTE,
2102                                        AC_AMP_GET_INPUT);
2103
2104        if (gpio_data == 0x02) {
2105                /* unmute line out */
2106                snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
2107                                         HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
2108
2109                if (vol_counter & 0x20) {
2110                        /* decrease volume */
2111                        if (vol > master_vol)
2112                                vol = master_vol;
2113                        snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
2114                                                 0, HDA_AMP_VOLMASK,
2115                                                 master_vol-vol);
2116                } else {
2117                        /* increase volume */
2118                        snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
2119                                         HDA_AMP_VOLMASK,
2120                                         ((master_vol+vol) > 0x2A) ? 0x2A :
2121                                          (master_vol+vol));
2122                }
2123        } else if (!(gpio_data & 0x02)) {
2124                /* mute line out */
2125                snd_hda_codec_amp_stereo(codec,
2126                                         spec->autocfg.line_out_pins[0],
2127                                         HDA_OUTPUT, 0, HDA_AMP_MUTE,
2128                                         HDA_AMP_MUTE);
2129        }
2130}
2131
2132/* mute Internal-Speaker if HP is plugged */
2133static void via_speaker_automute(struct hda_codec *codec)
2134{
2135        unsigned int hp_present;
2136        struct via_spec *spec = codec->spec;
2137
2138        if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2139                return;
2140
2141        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2142
2143        if (!spec->hp_independent_mode) {
2144                struct snd_ctl_elem_id id;
2145                snd_hda_codec_amp_stereo(
2146                        codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2147                        HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2148                /* notify change */
2149                memset(&id, 0, sizeof(id));
2150                id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2151                strcpy(id.name, "Speaker Playback Switch");
2152                snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2153                               &id);
2154        }
2155}
2156
2157/* mute line-out and internal speaker if HP is plugged */
2158static void via_hp_bind_automute(struct hda_codec *codec)
2159{
2160        /* use long instead of int below just to avoid an internal compiler
2161         * error with gcc 4.0.x
2162         */
2163        unsigned long hp_present, present = 0;
2164        struct via_spec *spec = codec->spec;
2165        int i;
2166
2167        if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2168                return;
2169
2170        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2171
2172        present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2173
2174        if (!spec->hp_independent_mode) {
2175                /* Mute Line-Outs */
2176                for (i = 0; i < spec->autocfg.line_outs; i++)
2177                        snd_hda_codec_amp_stereo(
2178                                codec, spec->autocfg.line_out_pins[i],
2179                                HDA_OUTPUT, 0,
2180                                HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2181                if (hp_present)
2182                        present = hp_present;
2183        }
2184        /* Speakers */
2185        for (i = 0; i < spec->autocfg.speaker_outs; i++)
2186                snd_hda_codec_amp_stereo(
2187                        codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2188                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2189}
2190
2191
2192/* unsolicited event for jack sensing */
2193static void via_unsol_event(struct hda_codec *codec,
2194                                  unsigned int res)
2195{
2196        res >>= 26;
2197        if (res & VIA_HP_EVENT)
2198                via_hp_automute(codec);
2199        if (res & VIA_GPIO_EVENT)
2200                via_gpio_control(codec);
2201        if (res & VIA_JACK_EVENT)
2202                set_jack_power_state(codec);
2203        if (res & VIA_MONO_EVENT)
2204                via_mono_automute(codec);
2205        if (res & VIA_SPEAKER_EVENT)
2206                via_speaker_automute(codec);
2207        if (res & VIA_BIND_HP_EVENT)
2208                via_hp_bind_automute(codec);
2209}
2210
2211static int via_init(struct hda_codec *codec)
2212{
2213        struct via_spec *spec = codec->spec;
2214        int i;
2215        for (i = 0; i < spec->num_iverbs; i++)
2216                snd_hda_sequence_write(codec, spec->init_verbs[i]);
2217
2218        /* Lydia Add for EAPD enable */
2219        if (!spec->dig_in_nid) { /* No Digital In connection */
2220                if (spec->dig_in_pin) {
2221                        snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2222                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
2223                                            PIN_OUT);
2224                        snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2225                                            AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2226                }
2227        } else /* enable SPDIF-input pin */
2228                snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2229                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2230
2231        /* assign slave outs */
2232        if (spec->slave_dig_outs[0])
2233                codec->slave_dig_outs = spec->slave_dig_outs;
2234
2235        return 0;
2236}
2237
2238#ifdef SND_HDA_NEEDS_RESUME
2239static int via_suspend(struct hda_codec *codec, pm_message_t state)
2240{
2241        struct via_spec *spec = codec->spec;
2242        vt1708_stop_hp_work(spec);
2243        return 0;
2244}
2245#endif
2246
2247#ifdef CONFIG_SND_HDA_POWER_SAVE
2248static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2249{
2250        struct via_spec *spec = codec->spec;
2251        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2252}
2253#endif
2254
2255/*
2256 */
2257static struct hda_codec_ops via_patch_ops = {
2258        .build_controls = via_build_controls,
2259        .build_pcms = via_build_pcms,
2260        .init = via_init,
2261        .free = via_free,
2262#ifdef SND_HDA_NEEDS_RESUME
2263        .suspend = via_suspend,
2264#endif
2265#ifdef CONFIG_SND_HDA_POWER_SAVE
2266        .check_power_status = via_check_power_status,
2267#endif
2268};
2269
2270/* fill in the dac_nids table from the parsed pin configuration */
2271static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2272                                     const struct auto_pin_cfg *cfg)
2273{
2274        int i;
2275        hda_nid_t nid;
2276
2277        spec->multiout.num_dacs = cfg->line_outs;
2278
2279        spec->multiout.dac_nids = spec->private_dac_nids;
2280
2281        for (i = 0; i < 4; i++) {
2282                nid = cfg->line_out_pins[i];
2283                if (nid) {
2284                        /* config dac list */
2285                        switch (i) {
2286                        case AUTO_SEQ_FRONT:
2287                                spec->multiout.dac_nids[i] = 0x10;
2288                                break;
2289                        case AUTO_SEQ_CENLFE:
2290                                spec->multiout.dac_nids[i] = 0x12;
2291                                break;
2292                        case AUTO_SEQ_SURROUND:
2293                                spec->multiout.dac_nids[i] = 0x11;
2294                                break;
2295                        case AUTO_SEQ_SIDE:
2296                                spec->multiout.dac_nids[i] = 0x13;
2297                                break;
2298                        }
2299                }
2300        }
2301
2302        return 0;
2303}
2304
2305/* add playback controls from the parsed DAC table */
2306static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2307                                             const struct auto_pin_cfg *cfg)
2308{
2309        char name[32];
2310        static const char * const chname[4] = {
2311                "Front", "Surround", "C/LFE", "Side"
2312        };
2313        hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2314        int i, err;
2315
2316        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2317                nid = cfg->line_out_pins[i];
2318
2319                if (!nid)
2320                        continue;
2321
2322                nid_vol = nid_vols[i];
2323
2324                if (i == AUTO_SEQ_CENLFE) {
2325                        /* Center/LFE */
2326                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2327                                        "Center Playback Volume",
2328                                        HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2329                                                            HDA_OUTPUT));
2330                        if (err < 0)
2331                                return err;
2332                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2333                                              "LFE Playback Volume",
2334                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2335                                                                  HDA_OUTPUT));
2336                        if (err < 0)
2337                                return err;
2338                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2339                                              "Center Playback Switch",
2340                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2341                                                                  HDA_OUTPUT));
2342                        if (err < 0)
2343                                return err;
2344                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2345                                              "LFE Playback Switch",
2346                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2347                                                                  HDA_OUTPUT));
2348                        if (err < 0)
2349                                return err;
2350                } else if (i == AUTO_SEQ_FRONT) {
2351                        /* add control to mixer index 0 */
2352                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2353                                              "Master Front Playback Volume",
2354                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2355                                                                  HDA_INPUT));
2356                        if (err < 0)
2357                                return err;
2358                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2359                                              "Master Front Playback Switch",
2360                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2361                                                                  HDA_INPUT));
2362                        if (err < 0)
2363                                return err;
2364
2365                        /* add control to PW3 */
2366                        sprintf(name, "%s Playback Volume", chname[i]);
2367                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2368                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2369                                                                  HDA_OUTPUT));
2370                        if (err < 0)
2371                                return err;
2372                        sprintf(name, "%s Playback Switch", chname[i]);
2373                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2374                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2375                                                                  HDA_OUTPUT));
2376                        if (err < 0)
2377                                return err;
2378                } else {
2379                        sprintf(name, "%s Playback Volume", chname[i]);
2380                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2381                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2382                                                                  HDA_OUTPUT));
2383                        if (err < 0)
2384                                return err;
2385                        sprintf(name, "%s Playback Switch", chname[i]);
2386                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2387                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2388                                                                  HDA_OUTPUT));
2389                        if (err < 0)
2390                                return err;
2391                }
2392        }
2393
2394        return 0;
2395}
2396
2397static void create_hp_imux(struct via_spec *spec)
2398{
2399        int i;
2400        struct hda_input_mux *imux = &spec->private_imux[1];
2401        static const char * const texts[] = { "OFF", "ON", NULL};
2402
2403        /* for hp mode select */
2404        for (i = 0; texts[i]; i++)
2405                snd_hda_add_imux_item(imux, texts[i], i, NULL);
2406
2407        spec->hp_mux = &spec->private_imux[1];
2408}
2409
2410static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2411{
2412        int err;
2413
2414        if (!pin)
2415                return 0;
2416
2417        spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2418        spec->hp_independent_mode_index = 1;
2419
2420        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2421                              "Headphone Playback Volume",
2422                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2423        if (err < 0)
2424                return err;
2425        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2426                              "Headphone Playback Switch",
2427                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2428        if (err < 0)
2429                return err;
2430
2431        create_hp_imux(spec);
2432
2433        return 0;
2434}
2435
2436/* create playback/capture controls for input pins */
2437static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2438                                            const struct auto_pin_cfg *cfg,
2439                                            hda_nid_t cap_nid,
2440                                            hda_nid_t pin_idxs[], int num_idxs)
2441{
2442        struct via_spec *spec = codec->spec;
2443        struct hda_input_mux *imux = &spec->private_imux[0];
2444        int i, err, idx, type, type_idx = 0;
2445
2446        /* for internal loopback recording select */
2447        for (idx = 0; idx < num_idxs; idx++) {
2448                if (pin_idxs[idx] == 0xff) {
2449                        snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
2450                        break;
2451                }
2452        }
2453
2454        for (i = 0; i < cfg->num_inputs; i++) {
2455                const char *label;
2456                type = cfg->inputs[i].type;
2457                for (idx = 0; idx < num_idxs; idx++)
2458                        if (pin_idxs[idx] == cfg->inputs[i].pin)
2459                                break;
2460                if (idx >= num_idxs)
2461                        continue;
2462                if (i > 0 && type == cfg->inputs[i - 1].type)
2463                        type_idx++;
2464                else
2465                        type_idx = 0;
2466                label = hda_get_autocfg_input_label(codec, cfg, i);
2467                if (spec->codec_type == VT1708S ||
2468                    spec->codec_type == VT1702 ||
2469                    spec->codec_type == VT1716S)
2470                        err = via_new_analog_input(spec, label, type_idx,
2471                                                   idx+1, cap_nid);
2472                else
2473                        err = via_new_analog_input(spec, label, type_idx,
2474                                                   idx, cap_nid);
2475                if (err < 0)
2476                        return err;
2477                snd_hda_add_imux_item(imux, label, idx, NULL);
2478        }
2479        return 0;
2480}
2481
2482/* create playback/capture controls for input pins */
2483static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2484                                                const struct auto_pin_cfg *cfg)
2485{
2486        static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2487        return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2488                                                ARRAY_SIZE(pin_idxs));
2489}
2490
2491#ifdef CONFIG_SND_HDA_POWER_SAVE
2492static struct hda_amp_list vt1708_loopbacks[] = {
2493        { 0x17, HDA_INPUT, 1 },
2494        { 0x17, HDA_INPUT, 2 },
2495        { 0x17, HDA_INPUT, 3 },
2496        { 0x17, HDA_INPUT, 4 },
2497        { } /* end */
2498};
2499#endif
2500
2501static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2502{
2503        unsigned int def_conf;
2504        unsigned char seqassoc;
2505
2506        def_conf = snd_hda_codec_get_pincfg(codec, nid);
2507        seqassoc = (unsigned char) get_defcfg_association(def_conf);
2508        seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2509        if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2510            && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2511                def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2512                snd_hda_codec_set_pincfg(codec, nid, def_conf);
2513        }
2514
2515        return;
2516}
2517
2518static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2519                                     struct snd_ctl_elem_value *ucontrol)
2520{
2521        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2522        struct via_spec *spec = codec->spec;
2523
2524        if (spec->codec_type != VT1708)
2525                return 0;
2526        spec->vt1708_jack_detectect =
2527                !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2528        ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2529        return 0;
2530}
2531
2532static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2533                                     struct snd_ctl_elem_value *ucontrol)
2534{
2535        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2536        struct via_spec *spec = codec->spec;
2537        int change;
2538
2539        if (spec->codec_type != VT1708)
2540                return 0;
2541        spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2542        change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2543                == !spec->vt1708_jack_detectect;
2544        if (spec->vt1708_jack_detectect) {
2545                mute_aa_path(codec, 1);
2546                notify_aa_path_ctls(codec);
2547        }
2548        return change;
2549}
2550
2551static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2552        {
2553                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2554                .name = "Jack Detect",
2555                .count = 1,
2556                .info = snd_ctl_boolean_mono_info,
2557                .get = vt1708_jack_detectect_get,
2558                .put = vt1708_jack_detectect_put,
2559        },
2560        {} /* end */
2561};
2562
2563static int vt1708_parse_auto_config(struct hda_codec *codec)
2564{
2565        struct via_spec *spec = codec->spec;
2566        int err;
2567
2568        /* Add HP and CD pin config connect bit re-config action */
2569        vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2570        vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2571
2572        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2573        if (err < 0)
2574                return err;
2575        err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2576        if (err < 0)
2577                return err;
2578        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2579                return 0; /* can't find valid BIOS pin config */
2580
2581        err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2582        if (err < 0)
2583                return err;
2584        err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2585        if (err < 0)
2586                return err;
2587        err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg);
2588        if (err < 0)
2589                return err;
2590        /* add jack detect on/off control */
2591        err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2592        if (err < 0)
2593                return err;
2594
2595        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2596
2597        if (spec->autocfg.dig_outs)
2598                spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2599        spec->dig_in_pin = VT1708_DIGIN_PIN;
2600        if (spec->autocfg.dig_in_pin)
2601                spec->dig_in_nid = VT1708_DIGIN_NID;
2602
2603        if (spec->kctls.list)
2604                spec->mixers[spec->num_mixers++] = spec->kctls.list;
2605
2606        spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2607
2608        spec->input_mux = &spec->private_imux[0];
2609
2610        if (spec->hp_mux)
2611                via_hp_build(codec);
2612
2613        via_smart51_build(spec);
2614        return 1;
2615}
2616
2617/* init callback for auto-configuration model -- overriding the default init */
2618static int via_auto_init(struct hda_codec *codec)
2619{
2620        struct via_spec *spec = codec->spec;
2621
2622        via_init(codec);
2623        via_auto_init_multi_out(codec);
2624        via_auto_init_hp_out(codec);
2625        via_auto_init_analog_input(codec);
2626        if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2627                via_hp_bind_automute(codec);
2628        } else {
2629                via_hp_automute(codec);
2630                via_speaker_automute(codec);
2631        }
2632
2633        return 0;
2634}
2635
2636static void vt1708_update_hp_jack_state(struct work_struct *work)
2637{
2638        struct via_spec *spec = container_of(work, struct via_spec,
2639                                             vt1708_hp_work.work);
2640        if (spec->codec_type != VT1708)
2641                return;
2642        /* if jack state toggled */
2643        if (spec->vt1708_hp_present
2644            != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2645                spec->vt1708_hp_present ^= 1;
2646                via_hp_automute(spec->codec);
2647        }
2648        vt1708_start_hp_work(spec);
2649}
2650
2651static int get_mux_nids(struct hda_codec *codec)
2652{
2653        struct via_spec *spec = codec->spec;
2654        hda_nid_t nid, conn[8];
2655        unsigned int type;
2656        int i, n;
2657
2658        for (i = 0; i < spec->num_adc_nids; i++) {
2659                nid = spec->adc_nids[i];
2660                while (nid) {
2661                        type = get_wcaps_type(get_wcaps(codec, nid));
2662                        if (type == AC_WID_PIN)
2663                                break;
2664                        n = snd_hda_get_connections(codec, nid, conn,
2665                                                    ARRAY_SIZE(conn));
2666                        if (n <= 0)
2667                                break;
2668                        if (n > 1) {
2669                                spec->mux_nids[i] = nid;
2670                                break;
2671                        }
2672                        nid = conn[0];
2673                }
2674        }
2675        return 0;
2676}
2677
2678static int patch_vt1708(struct hda_codec *codec)
2679{
2680        struct via_spec *spec;
2681        int err;
2682
2683        /* create a codec specific record */
2684        spec = via_new_spec(codec);
2685        if (spec == NULL)
2686                return -ENOMEM;
2687
2688        /* automatic parse from the BIOS config */
2689        err = vt1708_parse_auto_config(codec);
2690        if (err < 0) {
2691                via_free(codec);
2692                return err;
2693        } else if (!err) {
2694                printk(KERN_INFO "hda_codec: Cannot set up configuration "
2695                       "from BIOS.  Using genenic mode...\n");
2696        }
2697
2698
2699        spec->stream_name_analog = "VT1708 Analog";
2700        spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2701        /* disable 32bit format on VT1708 */
2702        if (codec->vendor_id == 0x11061708)
2703                spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2704        spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2705
2706        spec->stream_name_digital = "VT1708 Digital";
2707        spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2708        spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2709
2710
2711        if (!spec->adc_nids && spec->input_mux) {
2712                spec->adc_nids = vt1708_adc_nids;
2713                spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2714                get_mux_nids(codec);
2715                spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2716                spec->num_mixers++;
2717        }
2718
2719        codec->patch_ops = via_patch_ops;
2720
2721        codec->patch_ops.init = via_auto_init;
2722#ifdef CONFIG_SND_HDA_POWER_SAVE
2723        spec->loopback.amplist = vt1708_loopbacks;
2724#endif
2725        INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2726        return 0;
2727}
2728
2729/* capture mixer elements */
2730static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2731        HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2732        HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2733        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2734        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2735        HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2736        HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2737        {
2738                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2739                /* The multiple "Capture Source" controls confuse alsamixer
2740                 * So call somewhat different..
2741                 */
2742                /* .name = "Capture Source", */
2743                .name = "Input Source",
2744                .count = 1,
2745                .info = via_mux_enum_info,
2746                .get = via_mux_enum_get,
2747                .put = via_mux_enum_put,
2748        },
2749        { } /* end */
2750};
2751
2752static struct hda_verb vt1709_uniwill_init_verbs[] = {
2753        {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2754         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2755        { }
2756};
2757
2758/*
2759 * generic initialization of ADC, input mixers and output mixers
2760 */
2761static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2762        /*
2763         * Unmute ADC0-2 and set the default input to mic-in
2764         */
2765        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2766        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2767        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2768
2769
2770        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2771         * mixer widget
2772         */
2773        /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2774        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2775        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2776        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2777        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2778        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2779
2780        /*
2781         * Set up output selector (0x1a, 0x1b, 0x29)
2782         */
2783        /* set vol=0 to output mixers */
2784        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2785        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2786        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2787
2788        /*
2789         *  Unmute PW3 and PW4
2790         */
2791        {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2792        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2793
2794        /* Set input of PW4 as MW0 */
2795        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2796        /* PW9 Output enable */
2797        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2798        { }
2799};
2800
2801static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2802        .substreams = 1,
2803        .channels_min = 2,
2804        .channels_max = 10,
2805        .nid = 0x10, /* NID to query formats and rates */
2806        .ops = {
2807                .open = via_playback_pcm_open,
2808                .prepare = via_playback_multi_pcm_prepare,
2809                .cleanup = via_playback_multi_pcm_cleanup,
2810        },
2811};
2812
2813static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2814        .substreams = 1,
2815        .channels_min = 2,
2816        .channels_max = 6,
2817        .nid = 0x10, /* NID to query formats and rates */
2818        .ops = {
2819                .open = via_playback_pcm_open,
2820                .prepare = via_playback_multi_pcm_prepare,
2821                .cleanup = via_playback_multi_pcm_cleanup,
2822        },
2823};
2824
2825static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2826        .substreams = 2,
2827        .channels_min = 2,
2828        .channels_max = 2,
2829        .nid = 0x14, /* NID to query formats and rates */
2830        .ops = {
2831                .prepare = via_capture_pcm_prepare,
2832                .cleanup = via_capture_pcm_cleanup
2833        },
2834};
2835
2836static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2837        .substreams = 1,
2838        .channels_min = 2,
2839        .channels_max = 2,
2840        /* NID is set in via_build_pcms */
2841        .ops = {
2842                .open = via_dig_playback_pcm_open,
2843                .close = via_dig_playback_pcm_close
2844        },
2845};
2846
2847static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2848        .substreams = 1,
2849        .channels_min = 2,
2850        .channels_max = 2,
2851};
2852
2853static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2854                                     const struct auto_pin_cfg *cfg)
2855{
2856        int i;
2857        hda_nid_t nid;
2858
2859        if (cfg->line_outs == 4)  /* 10 channels */
2860                spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2861        else if (cfg->line_outs == 3) /* 6 channels */
2862                spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2863
2864        spec->multiout.dac_nids = spec->private_dac_nids;
2865
2866        if (cfg->line_outs == 4) { /* 10 channels */
2867                for (i = 0; i < cfg->line_outs; i++) {
2868                        nid = cfg->line_out_pins[i];
2869                        if (nid) {
2870                                /* config dac list */
2871                                switch (i) {
2872                                case AUTO_SEQ_FRONT:
2873                                        /* AOW0 */
2874                                        spec->multiout.dac_nids[i] = 0x10;
2875                                        break;
2876                                case AUTO_SEQ_CENLFE:
2877                                        /* AOW2 */
2878                                        spec->multiout.dac_nids[i] = 0x12;
2879                                        break;
2880                                case AUTO_SEQ_SURROUND:
2881                                        /* AOW3 */
2882                                        spec->multiout.dac_nids[i] = 0x11;
2883                                        break;
2884                                case AUTO_SEQ_SIDE:
2885                                        /* AOW1 */
2886                                        spec->multiout.dac_nids[i] = 0x27;
2887                                        break;
2888                                default:
2889                                        break;
2890                                }
2891                        }
2892                }
2893                spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2894
2895        } else if (cfg->line_outs == 3) { /* 6 channels */
2896                for (i = 0; i < cfg->line_outs; i++) {
2897                        nid = cfg->line_out_pins[i];
2898                        if (nid) {
2899                                /* config dac list */
2900                                switch (i) {
2901                                case AUTO_SEQ_FRONT:
2902                                        /* AOW0 */
2903                                        spec->multiout.dac_nids[i] = 0x10;
2904                                        break;
2905                                case AUTO_SEQ_CENLFE:
2906                                        /* AOW2 */
2907                                        spec->multiout.dac_nids[i] = 0x12;
2908                                        break;
2909                                case AUTO_SEQ_SURROUND:
2910                                        /* AOW1 */
2911                                        spec->multiout.dac_nids[i] = 0x11;
2912                                        break;
2913                                default:
2914                                        break;
2915                                }
2916                        }
2917                }
2918        }
2919
2920        return 0;
2921}
2922
2923/* add playback controls from the parsed DAC table */
2924static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2925                                             const struct auto_pin_cfg *cfg)
2926{
2927        char name[32];
2928        static const char * const chname[4] = {
2929                "Front", "Surround", "C/LFE", "Side"
2930        };
2931        hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2932        int i, err;
2933
2934        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2935                nid = cfg->line_out_pins[i];
2936
2937                if (!nid)
2938                        continue;
2939
2940                nid_vol = nid_vols[i];
2941
2942                if (i == AUTO_SEQ_CENLFE) {
2943                        /* Center/LFE */
2944                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2945                                              "Center Playback Volume",
2946                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2947                                                                  HDA_OUTPUT));
2948                        if (err < 0)
2949                                return err;
2950                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2951                                              "LFE Playback Volume",
2952                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2953                                                                  HDA_OUTPUT));
2954                        if (err < 0)
2955                                return err;
2956                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2957                                              "Center Playback Switch",
2958                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2959                                                                  HDA_OUTPUT));
2960                        if (err < 0)
2961                                return err;
2962                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2963                                              "LFE Playback Switch",
2964                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2965                                                                  HDA_OUTPUT));
2966                        if (err < 0)
2967                                return err;
2968                } else if (i == AUTO_SEQ_FRONT) {
2969                        /* ADD control to mixer index 0 */
2970                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2971                                              "Master Front Playback Volume",
2972                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2973                                                                  HDA_INPUT));
2974                        if (err < 0)
2975                                return err;
2976                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2977                                              "Master Front Playback Switch",
2978                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2979                                                                  HDA_INPUT));
2980                        if (err < 0)
2981                                return err;
2982
2983                        /* add control to PW3 */
2984                        sprintf(name, "%s Playback Volume", chname[i]);
2985                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2986                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2987                                                                  HDA_OUTPUT));
2988                        if (err < 0)
2989                                return err;
2990                        sprintf(name, "%s Playback Switch", chname[i]);
2991                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2992                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2993                                                                  HDA_OUTPUT));
2994                        if (err < 0)
2995                                return err;
2996                } else if (i == AUTO_SEQ_SURROUND) {
2997                        sprintf(name, "%s Playback Volume", chname[i]);
2998                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2999                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3000                                                                  HDA_OUTPUT));
3001                        if (err < 0)
3002                                return err;
3003                        sprintf(name, "%s Playback Switch", chname[i]);
3004                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3005                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3006                                                                  HDA_OUTPUT));
3007                        if (err < 0)
3008                                return err;
3009                } else if (i == AUTO_SEQ_SIDE) {
3010                        sprintf(name, "%s Playback Volume", chname[i]);
3011                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3012                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3013                                                                  HDA_OUTPUT));
3014                        if (err < 0)
3015                                return err;
3016                        sprintf(name, "%s Playback Switch", chname[i]);
3017                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3018                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3019                                                                  HDA_OUTPUT));
3020                        if (err < 0)
3021                                return err;
3022                }
3023        }
3024
3025        return 0;
3026}
3027
3028static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3029{
3030        int err;
3031
3032        if (!pin)
3033                return 0;
3034
3035        if (spec->multiout.num_dacs == 5) /* 10 channels */
3036                spec->multiout.hp_nid = VT1709_HP_DAC_NID;
3037        else if (spec->multiout.num_dacs == 3) /* 6 channels */
3038                spec->multiout.hp_nid = 0;
3039        spec->hp_independent_mode_index = 1;
3040
3041        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3042                              "Headphone Playback Volume",
3043                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3044        if (err < 0)
3045                return err;
3046        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3047                              "Headphone Playback Switch",
3048                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3049        if (err < 0)
3050                return err;
3051
3052        return 0;
3053}
3054
3055/* create playback/capture controls for input pins */
3056static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3057                                                const struct auto_pin_cfg *cfg)
3058{
3059        static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3060        return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3061                                                ARRAY_SIZE(pin_idxs));
3062}
3063
3064static int vt1709_parse_auto_config(struct hda_codec *codec)
3065{
3066        struct via_spec *spec = codec->spec;
3067        int err;
3068
3069        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3070        if (err < 0)
3071                return err;
3072        err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
3073        if (err < 0)
3074                return err;
3075        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3076                return 0; /* can't find valid BIOS pin config */
3077
3078        err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
3079        if (err < 0)
3080                return err;
3081        err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3082        if (err < 0)
3083                return err;
3084        err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
3085        if (err < 0)
3086                return err;
3087
3088        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3089
3090        if (spec->autocfg.dig_outs)
3091                spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3092        spec->dig_in_pin = VT1709_DIGIN_PIN;
3093        if (spec->autocfg.dig_in_pin)
3094                spec->dig_in_nid = VT1709_DIGIN_NID;
3095
3096        if (spec->kctls.list)
3097                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3098
3099        spec->input_mux = &spec->private_imux[0];
3100
3101        if (spec->hp_mux)
3102                via_hp_build(codec);
3103
3104        via_smart51_build(spec);
3105        return 1;
3106}
3107
3108#ifdef CONFIG_SND_HDA_POWER_SAVE
3109static struct hda_amp_list vt1709_loopbacks[] = {
3110        { 0x18, HDA_INPUT, 1 },
3111        { 0x18, HDA_INPUT, 2 },
3112        { 0x18, HDA_INPUT, 3 },
3113        { 0x18, HDA_INPUT, 4 },
3114        { } /* end */
3115};
3116#endif
3117
3118static int patch_vt1709_10ch(struct hda_codec *codec)
3119{
3120        struct via_spec *spec;
3121        int err;
3122
3123        /* create a codec specific record */
3124        spec = via_new_spec(codec);
3125        if (spec == NULL)
3126                return -ENOMEM;
3127
3128        err = vt1709_parse_auto_config(codec);
3129        if (err < 0) {
3130                via_free(codec);
3131                return err;
3132        } else if (!err) {
3133                printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3134                       "Using genenic mode...\n");
3135        }
3136
3137        spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3138        spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3139
3140        spec->stream_name_analog = "VT1709 Analog";
3141        spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3142        spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3143
3144        spec->stream_name_digital = "VT1709 Digital";
3145        spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3146        spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3147
3148
3149        if (!spec->adc_nids && spec->input_mux) {
3150                spec->adc_nids = vt1709_adc_nids;
3151                spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3152                get_mux_nids(codec);
3153                spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3154                spec->num_mixers++;
3155        }
3156
3157        codec->patch_ops = via_patch_ops;
3158
3159        codec->patch_ops.init = via_auto_init;
3160        codec->patch_ops.unsol_event = via_unsol_event;
3161#ifdef CONFIG_SND_HDA_POWER_SAVE
3162        spec->loopback.amplist = vt1709_loopbacks;
3163#endif
3164
3165        return 0;
3166}
3167/*
3168 * generic initialization of ADC, input mixers and output mixers
3169 */
3170static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3171        /*
3172         * Unmute ADC0-2 and set the default input to mic-in
3173         */
3174        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3175        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3176        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3177
3178
3179        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3180         * mixer widget
3181         */
3182        /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3183        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3184        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3185        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3186        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3187        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3188
3189        /*
3190         * Set up output selector (0x1a, 0x1b, 0x29)
3191         */
3192        /* set vol=0 to output mixers */
3193        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3194        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3195        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3196
3197        /*
3198         *  Unmute PW3 and PW4
3199         */
3200        {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3201        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3202
3203        /* Set input of PW4 as MW0 */
3204        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
3205        /* PW9 Output enable */
3206        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3207        { }
3208};
3209
3210static int patch_vt1709_6ch(struct hda_codec *codec)
3211{
3212        struct via_spec *spec;
3213        int err;
3214
3215        /* create a codec specific record */
3216        spec = via_new_spec(codec);
3217        if (spec == NULL)
3218                return -ENOMEM;
3219
3220        err = vt1709_parse_auto_config(codec);
3221        if (err < 0) {
3222                via_free(codec);
3223                return err;
3224        } else if (!err) {
3225                printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3226                       "Using genenic mode...\n");
3227        }
3228
3229        spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3230        spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3231
3232        spec->stream_name_analog = "VT1709 Analog";
3233        spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3234        spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3235
3236        spec->stream_name_digital = "VT1709 Digital";
3237        spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3238        spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3239
3240
3241        if (!spec->adc_nids && spec->input_mux) {
3242                spec->adc_nids = vt1709_adc_nids;
3243                spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3244                get_mux_nids(codec);
3245                spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3246                spec->num_mixers++;
3247        }
3248
3249        codec->patch_ops = via_patch_ops;
3250
3251        codec->patch_ops.init = via_auto_init;
3252        codec->patch_ops.unsol_event = via_unsol_event;
3253#ifdef CONFIG_SND_HDA_POWER_SAVE
3254        spec->loopback.amplist = vt1709_loopbacks;
3255#endif
3256        return 0;
3257}
3258
3259/* capture mixer elements */
3260static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3261        HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3262        HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3263        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3264        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3265        {
3266                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3267                /* The multiple "Capture Source" controls confuse alsamixer
3268                 * So call somewhat different..
3269                 */
3270                /* .name = "Capture Source", */
3271                .name = "Input Source",
3272                .count = 1,
3273                .info = via_mux_enum_info,
3274                .get = via_mux_enum_get,
3275                .put = via_mux_enum_put,
3276        },
3277        { } /* end */
3278};
3279/*
3280 * generic initialization of ADC, input mixers and output mixers
3281 */
3282static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3283        /*
3284         * Unmute ADC0-1 and set the default input to mic-in
3285         */
3286        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3287        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3288
3289
3290        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3291         * mixer widget
3292         */
3293        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3294        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3295        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3296        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3297        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3298        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3299
3300        /*
3301         * Set up output mixers
3302         */
3303        /* set vol=0 to output mixers */
3304        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3305        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3306        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3307
3308        /* Setup default input to PW4 */
3309        {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3310        /* PW9 Output enable */
3311        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3312        /* PW10 Input enable */
3313        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3314        { }
3315};
3316
3317static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3318        /*
3319         * Unmute ADC0-1 and set the default input to mic-in
3320         */
3321        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3322        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3323
3324
3325        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3326         * mixer widget
3327         */
3328        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3329        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3330        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3331        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3332        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3333        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3334
3335        /*
3336         * Set up output mixers
3337         */
3338        /* set vol=0 to output mixers */
3339        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3340        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3341        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3342
3343        /* Setup default input of PW4 to MW0 */
3344        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3345        /* PW9 Output enable */
3346        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3347        /* PW10 Input enable */
3348        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3349        { }
3350};
3351
3352static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3353        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3354         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3355        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3356        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3357        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3358        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3359        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3360        {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3361        {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3362        { }
3363};
3364
3365static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3366                              struct hda_codec *codec,
3367                              struct snd_pcm_substream *substream)
3368{
3369        int idle = substream->pstr->substream_opened == 1
3370                && substream->ref_count == 0;
3371
3372        analog_low_current_mode(codec, idle);
3373        return 0;
3374}
3375
3376static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3377        .substreams = 2,
3378        .channels_min = 2,
3379        .channels_max = 8,
3380        .nid = 0x10, /* NID to query formats and rates */
3381        .ops = {
3382                .open = via_playback_pcm_open,
3383                .prepare = via_playback_multi_pcm_prepare,
3384                .cleanup = via_playback_multi_pcm_cleanup,
3385                .close = via_pcm_open_close
3386        },
3387};
3388
3389static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3390        .substreams = 2,
3391        .channels_min = 2,
3392        .channels_max = 4,
3393        .nid = 0x10, /* NID to query formats and rates */
3394        .ops = {
3395                .open = via_playback_pcm_open,
3396                .prepare = via_playback_multi_pcm_prepare,
3397                .cleanup = via_playback_multi_pcm_cleanup
3398        },
3399};
3400
3401static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3402        .substreams = 2,
3403        .channels_min = 2,
3404        .channels_max = 2,
3405        .nid = 0x13, /* NID to query formats and rates */
3406        .ops = {
3407                .open = via_pcm_open_close,
3408                .prepare = via_capture_pcm_prepare,
3409                .cleanup = via_capture_pcm_cleanup,
3410                .close = via_pcm_open_close
3411        },
3412};
3413
3414static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3415        .substreams = 1,
3416        .channels_min = 2,
3417        .channels_max = 2,
3418        /* NID is set in via_build_pcms */
3419        .ops = {
3420                .open = via_dig_playback_pcm_open,
3421                .close = via_dig_playback_pcm_close,
3422                .prepare = via_dig_playback_pcm_prepare,
3423                .cleanup = via_dig_playback_pcm_cleanup
3424        },
3425};
3426
3427static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3428        .substreams = 1,
3429        .channels_min = 2,
3430        .channels_max = 2,
3431};
3432
3433/* fill in the dac_nids table from the parsed pin configuration */
3434static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3435                                     const struct auto_pin_cfg *cfg)
3436{
3437        int i;
3438        hda_nid_t nid;
3439
3440        spec->multiout.num_dacs = cfg->line_outs;
3441
3442        spec->multiout.dac_nids = spec->private_dac_nids;
3443
3444        for (i = 0; i < 4; i++) {
3445                nid = cfg->line_out_pins[i];
3446                if (nid) {
3447                        /* config dac list */
3448                        switch (i) {
3449                        case AUTO_SEQ_FRONT:
3450                                spec->multiout.dac_nids[i] = 0x10;
3451                                break;
3452                        case AUTO_SEQ_CENLFE:
3453                                spec->multiout.dac_nids[i] = 0x24;
3454                                break;
3455                        case AUTO_SEQ_SURROUND:
3456                                spec->multiout.dac_nids[i] = 0x11;
3457                                break;
3458                        case AUTO_SEQ_SIDE:
3459                                spec->multiout.dac_nids[i] = 0x25;
3460                                break;
3461                        }
3462                }
3463        }
3464
3465        return 0;
3466}
3467
3468/* add playback controls from the parsed DAC table */
3469static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3470                                             const struct auto_pin_cfg *cfg)
3471{
3472        char name[32];
3473        static const char * const chname[4] = {
3474                "Front", "Surround", "C/LFE", "Side"
3475        };
3476        hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3477        hda_nid_t nid, nid_vol = 0;
3478        int i, err;
3479
3480        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3481                nid = cfg->line_out_pins[i];
3482
3483                if (!nid)
3484                        continue;
3485
3486                nid_vol = nid_vols[i];
3487
3488                if (i == AUTO_SEQ_CENLFE) {
3489                        /* Center/LFE */
3490                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3491                                              "Center Playback Volume",
3492                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3493                                                                  HDA_OUTPUT));
3494                        if (err < 0)
3495                                return err;
3496                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3497                                              "LFE Playback Volume",
3498                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3499                                                                  HDA_OUTPUT));
3500                        if (err < 0)
3501                                return err;
3502                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3503                                              "Center Playback Switch",
3504                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3505                                                                  HDA_OUTPUT));
3506                        if (err < 0)
3507                                return err;
3508                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3509                                              "LFE Playback Switch",
3510                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3511                                                                  HDA_OUTPUT));
3512                        if (err < 0)
3513                                return err;
3514                } else if (i == AUTO_SEQ_FRONT) {
3515                        /* add control to mixer index 0 */
3516                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3517                                              "Master Front Playback Volume",
3518                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3519                                                                  HDA_INPUT));
3520                        if (err < 0)
3521                                return err;
3522                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3523                                              "Master Front Playback Switch",
3524                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3525                                                                  HDA_INPUT));
3526                        if (err < 0)
3527                                return err;
3528
3529                        /* add control to PW3 */
3530                        sprintf(name, "%s Playback Volume", chname[i]);
3531                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3532                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3533                                                                  HDA_OUTPUT));
3534                        if (err < 0)
3535                                return err;
3536                        sprintf(name, "%s Playback Switch", chname[i]);
3537                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3538                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3539                                                                  HDA_OUTPUT));
3540                        if (err < 0)
3541                                return err;
3542                } else {
3543                        sprintf(name, "%s Playback Volume", chname[i]);
3544                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3545                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3546                                                                  HDA_OUTPUT));
3547                        if (err < 0)
3548                                return err;
3549                        sprintf(name, "%s Playback Switch", chname[i]);
3550                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3551                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3552                                                                  HDA_OUTPUT));
3553                        if (err < 0)
3554                                return err;
3555                }
3556        }
3557
3558        return 0;
3559}
3560
3561static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3562{
3563        int err;
3564
3565        if (!pin)
3566                return 0;
3567
3568        spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3569        spec->hp_independent_mode_index = 1;
3570
3571        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3572                              "Headphone Playback Volume",
3573                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3574        if (err < 0)
3575                return err;
3576        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3577                              "Headphone Playback Switch",
3578                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3579        if (err < 0)
3580                return err;
3581
3582        create_hp_imux(spec);
3583
3584        return 0;
3585}
3586
3587/* create playback/capture controls for input pins */
3588static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3589                                                const struct auto_pin_cfg *cfg)
3590{
3591        static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3592        return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3593                                                ARRAY_SIZE(pin_idxs));
3594}
3595
3596static int vt1708B_parse_auto_config(struct hda_codec *codec)
3597{
3598        struct via_spec *spec = codec->spec;
3599        int err;
3600
3601        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3602        if (err < 0)
3603                return err;
3604        err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3605        if (err < 0)
3606                return err;
3607        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3608                return 0; /* can't find valid BIOS pin config */
3609
3610        err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3611        if (err < 0)
3612                return err;
3613        err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3614        if (err < 0)
3615                return err;
3616        err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3617        if (err < 0)
3618                return err;
3619
3620        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3621
3622        if (spec->autocfg.dig_outs)
3623                spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3624        spec->dig_in_pin = VT1708B_DIGIN_PIN;
3625        if (spec->autocfg.dig_in_pin)
3626                spec->dig_in_nid = VT1708B_DIGIN_NID;
3627
3628        if (spec->kctls.list)
3629                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3630
3631        spec->input_mux = &spec->private_imux[0];
3632
3633        if (spec->hp_mux)
3634                via_hp_build(codec);
3635
3636        via_smart51_build(spec);
3637        return 1;
3638}
3639
3640#ifdef CONFIG_SND_HDA_POWER_SAVE
3641static struct hda_amp_list vt1708B_loopbacks[] = {
3642        { 0x16, HDA_INPUT, 1 },
3643        { 0x16, HDA_INPUT, 2 },
3644        { 0x16, HDA_INPUT, 3 },
3645        { 0x16, HDA_INPUT, 4 },
3646        { } /* end */
3647};
3648#endif
3649static int patch_vt1708S(struct hda_codec *codec);
3650static int patch_vt1708B_8ch(struct hda_codec *codec)
3651{
3652        struct via_spec *spec;
3653        int err;
3654
3655        if (get_codec_type(codec) == VT1708BCE)
3656                return patch_vt1708S(codec);
3657        /* create a codec specific record */
3658        spec = via_new_spec(codec);
3659        if (spec == NULL)
3660                return -ENOMEM;
3661
3662        /* automatic parse from the BIOS config */
3663        err = vt1708B_parse_auto_config(codec);
3664        if (err < 0) {
3665                via_free(codec);
3666                return err;
3667        } else if (!err) {
3668                printk(KERN_INFO "hda_codec: Cannot set up configuration "
3669                       "from BIOS.  Using genenic mode...\n");
3670        }
3671
3672        spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3673        spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3674
3675        spec->stream_name_analog = "VT1708B Analog";
3676        spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3677        spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3678
3679        spec->stream_name_digital = "VT1708B Digital";
3680        spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3681        spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3682
3683        if (!spec->adc_nids && spec->input_mux) {
3684                spec->adc_nids = vt1708B_adc_nids;
3685                spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3686                get_mux_nids(codec);
3687                spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3688                spec->num_mixers++;
3689        }
3690
3691        codec->patch_ops = via_patch_ops;
3692
3693        codec->patch_ops.init = via_auto_init;
3694        codec->patch_ops.unsol_event = via_unsol_event;
3695#ifdef CONFIG_SND_HDA_POWER_SAVE
3696        spec->loopback.amplist = vt1708B_loopbacks;
3697#endif
3698
3699        return 0;
3700}
3701
3702static int patch_vt1708B_4ch(struct hda_codec *codec)
3703{
3704        struct via_spec *spec;
3705        int err;
3706
3707        /* create a codec specific record */
3708        spec = via_new_spec(codec);
3709        if (spec == NULL)
3710                return -ENOMEM;
3711
3712        /* automatic parse from the BIOS config */
3713        err = vt1708B_parse_auto_config(codec);
3714        if (err < 0) {
3715                via_free(codec);
3716                return err;
3717        } else if (!err) {
3718                printk(KERN_INFO "hda_codec: Cannot set up configuration "
3719                       "from BIOS.  Using genenic mode...\n");
3720        }
3721
3722        spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3723        spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3724
3725        spec->stream_name_analog = "VT1708B Analog";
3726        spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3727        spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3728
3729        spec->stream_name_digital = "VT1708B Digital";
3730        spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3731        spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3732
3733        if (!spec->adc_nids && spec->input_mux) {
3734                spec->adc_nids = vt1708B_adc_nids;
3735                spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3736                get_mux_nids(codec);
3737                spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3738                spec->num_mixers++;
3739        }
3740
3741        codec->patch_ops = via_patch_ops;
3742
3743        codec->patch_ops.init = via_auto_init;
3744        codec->patch_ops.unsol_event = via_unsol_event;
3745#ifdef CONFIG_SND_HDA_POWER_SAVE
3746        spec->loopback.amplist = vt1708B_loopbacks;
3747#endif
3748
3749        return 0;
3750}
3751
3752/* Patch for VT1708S */
3753
3754/* capture mixer elements */
3755static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3756        HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3757        HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3758        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3759        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3760        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3761        HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3762                         HDA_INPUT),
3763        {
3764                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3765                /* The multiple "Capture Source" controls confuse alsamixer
3766                 * So call somewhat different..
3767                 */
3768                /* .name = "Capture Source", */
3769                .name = "Input Source",
3770                .count = 1,
3771                .info = via_mux_enum_info,
3772                .get = via_mux_enum_get,
3773                .put = via_mux_enum_put,
3774        },
3775        { } /* end */
3776};
3777
3778static struct hda_verb vt1708S_volume_init_verbs[] = {
3779        /* Unmute ADC0-1 and set the default input to mic-in */
3780        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3781        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3782
3783        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3784         * analog-loopback mixer widget */
3785        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3786        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3787        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3788        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3789        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3790        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3791
3792        /* Setup default input of PW4 to MW0 */
3793        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3794        /* PW9, PW10  Output enable */
3795        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3796        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3797        /* Enable Mic Boost Volume backdoor */
3798        {0x1, 0xf98, 0x1},
3799        /* don't bybass mixer */
3800        {0x1, 0xf88, 0xc0},
3801        { }
3802};
3803
3804static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3805        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3806         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3807        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3808        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3809        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3810        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3811        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3812        {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3813        {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3814        { }
3815};
3816
3817static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3818        .substreams = 2,
3819        .channels_min = 2,
3820        .channels_max = 8,
3821        .nid = 0x10, /* NID to query formats and rates */
3822        .ops = {
3823                .open = via_playback_pcm_open,
3824                .prepare = via_playback_multi_pcm_prepare,
3825                .cleanup = via_playback_multi_pcm_cleanup,
3826                .close = via_pcm_open_close
3827        },
3828};
3829
3830static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3831        .substreams = 2,
3832        .channels_min = 2,
3833        .channels_max = 2,
3834        .nid = 0x13, /* NID to query formats and rates */
3835        .ops = {
3836                .open = via_pcm_open_close,
3837                .prepare = via_capture_pcm_prepare,
3838                .cleanup = via_capture_pcm_cleanup,
3839                .close = via_pcm_open_close
3840        },
3841};
3842
3843static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3844        .substreams = 1,
3845        .channels_min = 2,
3846        .channels_max = 2,
3847        /* NID is set in via_build_pcms */
3848        .ops = {
3849                .open = via_dig_playback_pcm_open,
3850                .close = via_dig_playback_pcm_close,
3851                .prepare = via_dig_playback_pcm_prepare,
3852                .cleanup = via_dig_playback_pcm_cleanup
3853        },
3854};
3855
3856/* fill in the dac_nids table from the parsed pin configuration */
3857static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3858                                     const struct auto_pin_cfg *cfg)
3859{
3860        int i;
3861        hda_nid_t nid;
3862
3863        spec->multiout.num_dacs = cfg->line_outs;
3864
3865        spec->multiout.dac_nids = spec->private_dac_nids;
3866
3867        for (i = 0; i < 4; i++) {
3868                nid = cfg->line_out_pins[i];
3869                if (nid) {
3870                        /* config dac list */
3871                        switch (i) {
3872                        case AUTO_SEQ_FRONT:
3873                                spec->multiout.dac_nids[i] = 0x10;
3874                                break;
3875                        case AUTO_SEQ_CENLFE:
3876                                spec->multiout.dac_nids[i] = 0x24;
3877                                break;
3878                        case AUTO_SEQ_SURROUND:
3879                                spec->multiout.dac_nids[i] = 0x11;
3880                                break;
3881                        case AUTO_SEQ_SIDE:
3882                                spec->multiout.dac_nids[i] = 0x25;
3883                                break;
3884                        }
3885                }
3886        }
3887
3888        /* for Smart 5.1, line/mic inputs double as output pins */
3889        if (cfg->line_outs == 1) {
3890                spec->multiout.num_dacs = 3;
3891                spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3892                spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3893        }
3894
3895        return 0;
3896}
3897
3898/* add playback controls from the parsed DAC table */
3899static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3900                                             const struct auto_pin_cfg *cfg)
3901{
3902        char name[32];
3903        static const char * const chname[4] = {
3904                "Front", "Surround", "C/LFE", "Side"
3905        };
3906        hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3907        hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3908        hda_nid_t nid, nid_vol, nid_mute;
3909        int i, err;
3910
3911        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3912                nid = cfg->line_out_pins[i];
3913
3914                /* for Smart 5.1, there are always at least six channels */
3915                if (!nid && i > AUTO_SEQ_CENLFE)
3916                        continue;
3917
3918                nid_vol = nid_vols[i];
3919                nid_mute = nid_mutes[i];
3920
3921                if (i == AUTO_SEQ_CENLFE) {
3922                        /* Center/LFE */
3923                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3924                                              "Center Playback Volume",
3925                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3926                                                                  HDA_OUTPUT));
3927                        if (err < 0)
3928                                return err;
3929                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3930                                              "LFE Playback Volume",
3931                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3932                                                                  HDA_OUTPUT));
3933                        if (err < 0)
3934                                return err;
3935                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3936                                              "Center Playback Switch",
3937                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3938                                                                  1, 0,
3939                                                                  HDA_OUTPUT));
3940                        if (err < 0)
3941                                return err;
3942                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3943                                              "LFE Playback Switch",
3944                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3945                                                                  2, 0,
3946                                                                  HDA_OUTPUT));
3947                        if (err < 0)
3948                                return err;
3949                } else if (i == AUTO_SEQ_FRONT) {
3950                        /* add control to mixer index 0 */
3951                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3952                                              "Master Front Playback Volume",
3953                                              HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3954                                                                  HDA_INPUT));
3955                        if (err < 0)
3956                                return err;
3957                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3958                                              "Master Front Playback Switch",
3959                                              HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3960                                                                  HDA_INPUT));
3961                        if (err < 0)
3962                                return err;
3963
3964                        /* Front */
3965                        sprintf(name, "%s Playback Volume", chname[i]);
3966                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3967                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3968                                                                  HDA_OUTPUT));
3969                        if (err < 0)
3970                                return err;
3971                        sprintf(name, "%s Playback Switch", chname[i]);
3972                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3973                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3974                                                                  3, 0,
3975                                                                  HDA_OUTPUT));
3976                        if (err < 0)
3977                                return err;
3978                } else {
3979                        sprintf(name, "%s Playback Volume", chname[i]);
3980                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3981                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3982                                                                  HDA_OUTPUT));
3983                        if (err < 0)
3984                                return err;
3985                        sprintf(name, "%s Playback Switch", chname[i]);
3986                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3987                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3988                                                                  3, 0,
3989                                                                  HDA_OUTPUT));
3990                        if (err < 0)
3991                                return err;
3992                }
3993        }
3994
3995        return 0;
3996}
3997
3998static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3999{
4000        int err;
4001
4002        if (!pin)
4003                return 0;
4004
4005        spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
4006        spec->hp_independent_mode_index = 1;
4007
4008        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4009                              "Headphone Playback Volume",
4010                              HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
4011        if (err < 0)
4012                return err;
4013
4014        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4015                              "Headphone Playback Switch",
4016                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4017        if (err < 0)
4018                return err;
4019
4020        create_hp_imux(spec);
4021
4022        return 0;
4023}
4024
4025/* create playback/capture controls for input pins */
4026static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
4027                                                const struct auto_pin_cfg *cfg)
4028{
4029        static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
4030        return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
4031                                                ARRAY_SIZE(pin_idxs));
4032}
4033
4034/* fill out digital output widgets; one for master and one for slave outputs */
4035static void fill_dig_outs(struct hda_codec *codec)
4036{
4037        struct via_spec *spec = codec->spec;
4038        int i;
4039
4040        for (i = 0; i < spec->autocfg.dig_outs; i++) {
4041                hda_nid_t nid;
4042                int conn;
4043
4044                nid = spec->autocfg.dig_out_pins[i];
4045                if (!nid)
4046                        continue;
4047                conn = snd_hda_get_connections(codec, nid, &nid, 1);
4048                if (conn < 1)
4049                        continue;
4050                if (!spec->multiout.dig_out_nid)
4051                        spec->multiout.dig_out_nid = nid;
4052                else {
4053                        spec->slave_dig_outs[0] = nid;
4054                        break; /* at most two dig outs */
4055                }
4056        }
4057}
4058
4059static int vt1708S_parse_auto_config(struct hda_codec *codec)
4060{
4061        struct via_spec *spec = codec->spec;
4062        int err;
4063
4064        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4065        if (err < 0)
4066                return err;
4067        err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
4068        if (err < 0)
4069                return err;
4070        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4071                return 0; /* can't find valid BIOS pin config */
4072
4073        err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4074        if (err < 0)
4075                return err;
4076        err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4077        if (err < 0)
4078                return err;
4079        err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4080        if (err < 0)
4081                return err;
4082
4083        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4084
4085        fill_dig_outs(codec);
4086
4087        if (spec->kctls.list)
4088                spec->mixers[spec->num_mixers++] = spec->kctls.list;
4089
4090        spec->input_mux = &spec->private_imux[0];
4091
4092        if (spec->hp_mux)
4093                via_hp_build(codec);
4094
4095        via_smart51_build(spec);
4096        return 1;
4097}
4098
4099#ifdef CONFIG_SND_HDA_POWER_SAVE
4100static struct hda_amp_list vt1708S_loopbacks[] = {
4101        { 0x16, HDA_INPUT, 1 },
4102        { 0x16, HDA_INPUT, 2 },
4103        { 0x16, HDA_INPUT, 3 },
4104        { 0x16, HDA_INPUT, 4 },
4105        { } /* end */
4106};
4107#endif
4108
4109static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4110                               int offset, int num_steps, int step_size)
4111{
4112        snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4113                                  (offset << AC_AMPCAP_OFFSET_SHIFT) |
4114                                  (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4115                                  (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4116                                  (0 << AC_AMPCAP_MUTE_SHIFT));
4117}
4118
4119static int patch_vt1708S(struct hda_codec *codec)
4120{
4121        struct via_spec *spec;
4122        int err;
4123
4124        /* create a codec specific record */
4125        spec = via_new_spec(codec);
4126        if (spec == NULL)
4127                return -ENOMEM;
4128
4129        /* automatic parse from the BIOS config */
4130        err = vt1708S_parse_auto_config(codec);
4131        if (err < 0) {
4132                via_free(codec);
4133                return err;
4134        } else if (!err) {
4135                printk(KERN_INFO "hda_codec: Cannot set up configuration "
4136                       "from BIOS.  Using genenic mode...\n");
4137        }
4138
4139        spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4140        spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
4141
4142        if (codec->vendor_id == 0x11060440)
4143                spec->stream_name_analog = "VT1818S Analog";
4144        else
4145                spec->stream_name_analog = "VT1708S Analog";
4146        spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4147        spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4148
4149        if (codec->vendor_id == 0x11060440)
4150                spec->stream_name_digital = "VT1818S Digital";
4151        else
4152                spec->stream_name_digital = "VT1708S Digital";
4153        spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
4154
4155        if (!spec->adc_nids && spec->input_mux) {
4156                spec->adc_nids = vt1708S_adc_nids;
4157                spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
4158                get_mux_nids(codec);
4159                override_mic_boost(codec, 0x1a, 0, 3, 40);
4160                override_mic_boost(codec, 0x1e, 0, 3, 40);
4161                spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
4162                spec->num_mixers++;
4163        }
4164
4165        codec->patch_ops = via_patch_ops;
4166
4167        codec->patch_ops.init = via_auto_init;
4168        codec->patch_ops.unsol_event = via_unsol_event;
4169#ifdef CONFIG_SND_HDA_POWER_SAVE
4170        spec->loopback.amplist = vt1708S_loopbacks;
4171#endif
4172
4173        /* correct names for VT1708BCE */
4174        if (get_codec_type(codec) == VT1708BCE) {
4175                kfree(codec->chip_name);
4176                codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4177                snprintf(codec->bus->card->mixername,
4178                         sizeof(codec->bus->card->mixername),
4179                         "%s %s", codec->vendor_name, codec->chip_name);
4180                spec->stream_name_analog = "VT1708BCE Analog";
4181                spec->stream_name_digital = "VT1708BCE Digital";
4182        }
4183        /* correct names for VT1818S */
4184        if (codec->vendor_id == 0x11060440) {
4185                spec->stream_name_analog = "VT1818S Analog";
4186                spec->stream_name_digital = "VT1818S Digital";
4187        }
4188        return 0;
4189}
4190
4191/* Patch for VT1702 */
4192
4193/* capture mixer elements */
4194static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4195        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4196        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4197        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
4198        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
4199        HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
4200        HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
4201        HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
4202                         HDA_INPUT),
4203        {
4204                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4205                /* The multiple "Capture Source" controls confuse alsamixer
4206                 * So call somewhat different..
4207                 */
4208                /* .name = "Capture Source", */
4209                .name = "Input Source",
4210                .count = 1,
4211                .info = via_mux_enum_info,
4212                .get = via_mux_enum_get,
4213                .put = via_mux_enum_put,
4214        },
4215        { } /* end */
4216};
4217
4218static struct hda_verb vt1702_volume_init_verbs[] = {
4219        /*
4220         * Unmute ADC0-1 and set the default input to mic-in
4221         */
4222        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4223        {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4224        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4225
4226
4227        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4228         * mixer widget
4229         */
4230        /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
4231        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4232        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4233        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4234        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4235        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4236
4237        /* Setup default input of PW4 to MW0 */
4238        {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
4239        /* PW6 PW7 Output enable */
4240        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4241        {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4242        /* mixer enable */
4243        {0x1, 0xF88, 0x3},
4244        /* GPIO 0~2 */
4245        {0x1, 0xF82, 0x3F},
4246        { }
4247};
4248
4249static struct hda_verb vt1702_uniwill_init_verbs[] = {
4250        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4251         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4252        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4253        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4254        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4255        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4256        { }
4257};
4258
4259static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4260        .substreams = 2,
4261        .channels_min = 2,
4262        .channels_max = 2,
4263        .nid = 0x10, /* NID to query formats and rates */