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 struct via_spec * via_new_spec(struct hda_codec *codec)
 163{
 164        struct via_spec *spec;
 165
 166        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 167        if (spec == NULL)
 168                return NULL;
 169
 170        codec->spec = spec;
 171        spec->codec = codec;
 172        return spec;
 173}
 174
 175static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
 176{
 177        u32 vendor_id = codec->vendor_id;
 178        u16 ven_id = vendor_id >> 16;
 179        u16 dev_id = vendor_id & 0xffff;
 180        enum VIA_HDA_CODEC codec_type;
 181
 182        /* get codec type */
 183        if (ven_id != 0x1106)
 184                codec_type = UNKNOWN;
 185        else if (dev_id >= 0x1708 && dev_id <= 0x170b)
 186                codec_type = VT1708;
 187        else if (dev_id >= 0xe710 && dev_id <= 0xe713)
 188                codec_type = VT1709_10CH;
 189        else if (dev_id >= 0xe714 && dev_id <= 0xe717)
 190                codec_type = VT1709_6CH;
 191        else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
 192                codec_type = VT1708B_8CH;
 193                if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
 194                        codec_type = VT1708BCE;
 195        } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
 196                codec_type = VT1708B_4CH;
 197        else if ((dev_id & 0xfff) == 0x397
 198                 && (dev_id >> 12) < 8)
 199                codec_type = VT1708S;
 200        else if ((dev_id & 0xfff) == 0x398
 201                 && (dev_id >> 12) < 8)
 202                codec_type = VT1702;
 203        else if ((dev_id & 0xfff) == 0x428
 204                 && (dev_id >> 12) < 8)
 205                codec_type = VT1718S;
 206        else if (dev_id == 0x0433 || dev_id == 0xa721)
 207                codec_type = VT1716S;
 208        else if (dev_id == 0x0441 || dev_id == 0x4441)
 209                codec_type = VT1718S;
 210        else if (dev_id == 0x0438 || dev_id == 0x4438)
 211                codec_type = VT2002P;
 212        else if (dev_id == 0x0448)
 213                codec_type = VT1812;
 214        else if (dev_id == 0x0440)
 215                codec_type = VT1708S;
 216        else
 217                codec_type = UNKNOWN;
 218        return codec_type;
 219};
 220
 221#define VIA_HP_EVENT            0x01
 222#define VIA_GPIO_EVENT          0x02
 223#define VIA_JACK_EVENT          0x04
 224#define VIA_MONO_EVENT          0x08
 225#define VIA_SPEAKER_EVENT       0x10
 226#define VIA_BIND_HP_EVENT       0x20
 227
 228enum {
 229        VIA_CTL_WIDGET_VOL,
 230        VIA_CTL_WIDGET_MUTE,
 231        VIA_CTL_WIDGET_ANALOG_MUTE,
 232        VIA_CTL_WIDGET_BIND_PIN_MUTE,
 233};
 234
 235enum {
 236        AUTO_SEQ_FRONT = 0,
 237        AUTO_SEQ_SURROUND,
 238        AUTO_SEQ_CENLFE,
 239        AUTO_SEQ_SIDE
 240};
 241
 242static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
 243static void set_jack_power_state(struct hda_codec *codec);
 244static int is_aa_path_mute(struct hda_codec *codec);
 245
 246static void vt1708_start_hp_work(struct via_spec *spec)
 247{
 248        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
 249                return;
 250        snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
 251                            !spec->vt1708_jack_detectect);
 252        if (!delayed_work_pending(&spec->vt1708_hp_work))
 253                schedule_delayed_work(&spec->vt1708_hp_work,
 254                                      msecs_to_jiffies(100));
 255}
 256
 257static void vt1708_stop_hp_work(struct via_spec *spec)
 258{
 259        if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
 260                return;
 261        if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
 262            && !is_aa_path_mute(spec->codec))
 263                return;
 264        snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
 265                            !spec->vt1708_jack_detectect);
 266        cancel_delayed_work_sync(&spec->vt1708_hp_work);
 267}
 268
 269
 270static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
 271                                   struct snd_ctl_elem_value *ucontrol)
 272{
 273        int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
 274        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 275
 276        set_jack_power_state(codec);
 277        analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
 278        if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
 279                if (is_aa_path_mute(codec))
 280                        vt1708_start_hp_work(codec->spec);
 281                else
 282                        vt1708_stop_hp_work(codec->spec);
 283        }
 284        return change;
 285}
 286
 287/* modify .put = snd_hda_mixer_amp_switch_put */
 288#define ANALOG_INPUT_MUTE                                               \
 289        {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
 290                        .name = NULL,                                   \
 291                        .index = 0,                                     \
 292                        .info = snd_hda_mixer_amp_switch_info,          \
 293                        .get = snd_hda_mixer_amp_switch_get,            \
 294                        .put = analog_input_switch_put,                 \
 295                        .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
 296
 297static void via_hp_bind_automute(struct hda_codec *codec);
 298
 299static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
 300                               struct snd_ctl_elem_value *ucontrol)
 301{
 302        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 303        struct via_spec *spec = codec->spec;
 304        int i;
 305        int change = 0;
 306
 307        long *valp = ucontrol->value.integer.value;
 308        int lmute, rmute;
 309        if (strstr(kcontrol->id.name, "Switch") == NULL) {
 310                snd_printd("Invalid control!\n");
 311                return change;
 312        }
 313        change = snd_hda_mixer_amp_switch_put(kcontrol,
 314                                              ucontrol);
 315        /* Get mute value */
 316        lmute = *valp ? 0 : HDA_AMP_MUTE;
 317        valp++;
 318        rmute = *valp ? 0 : HDA_AMP_MUTE;
 319
 320        /* Set hp pins */
 321        if (!spec->hp_independent_mode) {
 322                for (i = 0; i < spec->autocfg.hp_outs; i++) {
 323                        snd_hda_codec_amp_update(
 324                                codec, spec->autocfg.hp_pins[i],
 325                                0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 326                                lmute);
 327                        snd_hda_codec_amp_update(
 328                                codec, spec->autocfg.hp_pins[i],
 329                                1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 330                                rmute);
 331                }
 332        }
 333
 334        if (!lmute && !rmute) {
 335                /* Line Outs */
 336                for (i = 0; i < spec->autocfg.line_outs; i++)
 337                        snd_hda_codec_amp_stereo(
 338                                codec, spec->autocfg.line_out_pins[i],
 339                                HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
 340                /* Speakers */
 341                for (i = 0; i < spec->autocfg.speaker_outs; i++)
 342                        snd_hda_codec_amp_stereo(
 343                                codec, spec->autocfg.speaker_pins[i],
 344                                HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
 345                /* unmute */
 346                via_hp_bind_automute(codec);
 347
 348        } else {
 349                if (lmute) {
 350                        /* Mute all left channels */
 351                        for (i = 1; i < spec->autocfg.line_outs; i++)
 352                                snd_hda_codec_amp_update(
 353                                        codec,
 354                                        spec->autocfg.line_out_pins[i],
 355                                        0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 356                                        lmute);
 357                        for (i = 0; i < spec->autocfg.speaker_outs; i++)
 358                                snd_hda_codec_amp_update(
 359                                        codec,
 360                                        spec->autocfg.speaker_pins[i],
 361                                        0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 362                                        lmute);
 363                }
 364                if (rmute) {
 365                        /* mute all right channels */
 366                        for (i = 1; i < spec->autocfg.line_outs; i++)
 367                                snd_hda_codec_amp_update(
 368                                        codec,
 369                                        spec->autocfg.line_out_pins[i],
 370                                        1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 371                                        rmute);
 372                        for (i = 0; i < spec->autocfg.speaker_outs; i++)
 373                                snd_hda_codec_amp_update(
 374                                        codec,
 375                                        spec->autocfg.speaker_pins[i],
 376                                        1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
 377                                        rmute);
 378                }
 379        }
 380        return change;
 381}
 382
 383#define BIND_PIN_MUTE                                                   \
 384        {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
 385                        .name = NULL,                                   \
 386                        .index = 0,                                     \
 387                        .info = snd_hda_mixer_amp_switch_info,          \
 388                        .get = snd_hda_mixer_amp_switch_get,            \
 389                        .put = bind_pin_switch_put,                     \
 390                        .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
 391
 392static struct snd_kcontrol_new via_control_templates[] = {
 393        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 394        HDA_CODEC_MUTE(NULL, 0, 0, 0),
 395        ANALOG_INPUT_MUTE,
 396        BIND_PIN_MUTE,
 397};
 398
 399static hda_nid_t vt1708_adc_nids[2] = {
 400        /* ADC1-2 */
 401        0x15, 0x27
 402};
 403
 404static hda_nid_t vt1709_adc_nids[3] = {
 405        /* ADC1-2 */
 406        0x14, 0x15, 0x16
 407};
 408
 409static hda_nid_t vt1708B_adc_nids[2] = {
 410        /* ADC1-2 */
 411        0x13, 0x14
 412};
 413
 414static hda_nid_t vt1708S_adc_nids[2] = {
 415        /* ADC1-2 */
 416        0x13, 0x14
 417};
 418
 419static hda_nid_t vt1702_adc_nids[3] = {
 420        /* ADC1-2 */
 421        0x12, 0x20, 0x1F
 422};
 423
 424static hda_nid_t vt1718S_adc_nids[2] = {
 425        /* ADC1-2 */
 426        0x10, 0x11
 427};
 428
 429static hda_nid_t vt1716S_adc_nids[2] = {
 430        /* ADC1-2 */
 431        0x13, 0x14
 432};
 433
 434static hda_nid_t vt2002P_adc_nids[2] = {
 435        /* ADC1-2 */
 436        0x10, 0x11
 437};
 438
 439static hda_nid_t vt1812_adc_nids[2] = {
 440        /* ADC1-2 */
 441        0x10, 0x11
 442};
 443
 444
 445/* add dynamic controls */
 446static int __via_add_control(struct via_spec *spec, int type, const char *name,
 447                             int idx, unsigned long val)
 448{
 449        struct snd_kcontrol_new *knew;
 450
 451        snd_array_init(&spec->kctls, sizeof(*knew), 32);
 452        knew = snd_array_new(&spec->kctls);
 453        if (!knew)
 454                return -ENOMEM;
 455        *knew = via_control_templates[type];
 456        knew->name = kstrdup(name, GFP_KERNEL);
 457        if (!knew->name)
 458                return -ENOMEM;
 459        if (get_amp_nid_(val))
 460                knew->subdevice = HDA_SUBDEV_AMP_FLAG;
 461        knew->private_value = val;
 462        return 0;
 463}
 464
 465#define via_add_control(spec, type, name, val) \
 466        __via_add_control(spec, type, name, 0, val)
 467
 468static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
 469                                                struct snd_kcontrol_new *tmpl)
 470{
 471        struct snd_kcontrol_new *knew;
 472
 473        snd_array_init(&spec->kctls, sizeof(*knew), 32);
 474        knew = snd_array_new(&spec->kctls);
 475        if (!knew)
 476                return NULL;
 477        *knew = *tmpl;
 478        knew->name = kstrdup(tmpl->name, GFP_KERNEL);
 479        if (!knew->name)
 480                return NULL;
 481        return knew;
 482}
 483
 484static void via_free_kctls(struct hda_codec *codec)
 485{
 486        struct via_spec *spec = codec->spec;
 487
 488        if (spec->kctls.list) {
 489                struct snd_kcontrol_new *kctl = spec->kctls.list;
 490                int i;
 491                for (i = 0; i < spec->kctls.used; i++)
 492                        kfree(kctl[i].name);
 493        }
 494        snd_array_free(&spec->kctls);
 495}
 496
 497/* create input playback/capture controls for the given pin */
 498static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
 499                                int type_idx, int idx, int mix_nid)
 500{
 501        char name[32];
 502        int err;
 503
 504        sprintf(name, "%s Playback Volume", ctlname);
 505        err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
 506                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 507        if (err < 0)
 508                return err;
 509        sprintf(name, "%s Playback Switch", ctlname);
 510        err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
 511                              HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
 512        if (err < 0)
 513                return err;
 514        return 0;
 515}
 516
 517static void via_auto_set_output_and_unmute(struct hda_codec *codec,
 518                                           hda_nid_t nid, int pin_type,
 519                                           int dac_idx)
 520{
 521        /* set as output */
 522        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
 523                            pin_type);
 524        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 525                            AMP_OUT_UNMUTE);
 526        if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
 527                snd_hda_codec_write(codec, nid, 0,
 528                                    AC_VERB_SET_EAPD_BTLENABLE, 0x02);
 529}
 530
 531
 532static void via_auto_init_multi_out(struct hda_codec *codec)
 533{
 534        struct via_spec *spec = codec->spec;
 535        int i;
 536
 537        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
 538                hda_nid_t nid = spec->autocfg.line_out_pins[i];
 539                if (nid)
 540                        via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
 541        }
 542}
 543
 544static void via_auto_init_hp_out(struct hda_codec *codec)
 545{
 546        struct via_spec *spec = codec->spec;
 547        hda_nid_t pin;
 548        int i;
 549
 550        for (i = 0; i < spec->autocfg.hp_outs; i++) {
 551                pin = spec->autocfg.hp_pins[i];
 552                if (pin) /* connect to front */
 553                        via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
 554        }
 555}
 556
 557static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
 558
 559static void via_auto_init_analog_input(struct hda_codec *codec)
 560{
 561        struct via_spec *spec = codec->spec;
 562        const struct auto_pin_cfg *cfg = &spec->autocfg;
 563        unsigned int ctl;
 564        int i;
 565
 566        for (i = 0; i < cfg->num_inputs; i++) {
 567                hda_nid_t nid = cfg->inputs[i].pin;
 568                if (spec->smart51_enabled && is_smart51_pins(spec, nid))
 569                        ctl = PIN_OUT;
 570                else if (cfg->inputs[i].type == AUTO_PIN_MIC)
 571                        ctl = PIN_VREF50;
 572                else
 573                        ctl = PIN_IN;
 574                snd_hda_codec_write(codec, nid, 0,
 575                                    AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
 576        }
 577}
 578
 579static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
 580                                unsigned int *affected_parm)
 581{
 582        unsigned parm;
 583        unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
 584        unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
 585                >> AC_DEFCFG_MISC_SHIFT
 586                & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
 587        unsigned present = snd_hda_jack_detect(codec, nid);
 588        struct via_spec *spec = codec->spec;
 589        if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
 590            || ((no_presence || present)
 591                && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
 592                *affected_parm = AC_PWRST_D0; /* if it's connected */
 593                parm = AC_PWRST_D0;
 594        } else
 595                parm = AC_PWRST_D3;
 596
 597        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
 598}
 599
 600static void set_jack_power_state(struct hda_codec *codec)
 601{
 602        struct via_spec *spec = codec->spec;
 603        int imux_is_smixer;
 604        unsigned int parm;
 605
 606        if (spec->codec_type == VT1702) {
 607                imux_is_smixer = snd_hda_codec_read(
 608                        codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
 609                /* inputs */
 610                /* PW 1/2/5 (14h/15h/18h) */
 611                parm = AC_PWRST_D3;
 612                set_pin_power_state(codec, 0x14, &parm);
 613                set_pin_power_state(codec, 0x15, &parm);
 614                set_pin_power_state(codec, 0x18, &parm);
 615                if (imux_is_smixer)
 616                        parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
 617                /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
 618                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 619                                    parm);
 620                snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
 621                                    parm);
 622                snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
 623                                    parm);
 624                snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
 625                                    parm);
 626
 627                /* outputs */
 628                /* PW 3/4 (16h/17h) */
 629                parm = AC_PWRST_D3;
 630                set_pin_power_state(codec, 0x16, &parm);
 631                set_pin_power_state(codec, 0x17, &parm);
 632                /* MW0 (1ah), AOW 0/1 (10h/1dh) */
 633                snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
 634                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 635                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 636                                    parm);
 637                snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
 638                                    parm);
 639        } else if (spec->codec_type == VT1708B_8CH
 640                   || spec->codec_type == VT1708B_4CH
 641                   || spec->codec_type == VT1708S) {
 642                /* SW0 (17h) = stereo mixer */
 643                int is_8ch = spec->codec_type != VT1708B_4CH;
 644                imux_is_smixer = snd_hda_codec_read(
 645                        codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
 646                        == ((spec->codec_type == VT1708S)  ? 5 : 0);
 647                /* inputs */
 648                /* PW 1/2/5 (1ah/1bh/1eh) */
 649                parm = AC_PWRST_D3;
 650                set_pin_power_state(codec, 0x1a, &parm);
 651                set_pin_power_state(codec, 0x1b, &parm);
 652                set_pin_power_state(codec, 0x1e, &parm);
 653                if (imux_is_smixer)
 654                        parm = AC_PWRST_D0;
 655                /* SW0 (17h), AIW 0/1 (13h/14h) */
 656                snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
 657                                    parm);
 658                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 659                                    parm);
 660                snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
 661                                    parm);
 662
 663                /* outputs */
 664                /* PW0 (19h), SW1 (18h), AOW1 (11h) */
 665                parm = AC_PWRST_D3;
 666                set_pin_power_state(codec, 0x19, &parm);
 667                if (spec->smart51_enabled)
 668                        parm = AC_PWRST_D0;
 669                snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
 670                                    parm);
 671                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 672                                    parm);
 673
 674                /* PW6 (22h), SW2 (26h), AOW2 (24h) */
 675                if (is_8ch) {
 676                        parm = AC_PWRST_D3;
 677                        set_pin_power_state(codec, 0x22, &parm);
 678                        if (spec->smart51_enabled)
 679                                parm = AC_PWRST_D0;
 680                        snd_hda_codec_write(codec, 0x26, 0,
 681                                            AC_VERB_SET_POWER_STATE, parm);
 682                        snd_hda_codec_write(codec, 0x24, 0,
 683                                            AC_VERB_SET_POWER_STATE, parm);
 684                }
 685
 686                /* PW 3/4/7 (1ch/1dh/23h) */
 687                parm = AC_PWRST_D3;
 688                /* force to D0 for internal Speaker */
 689                set_pin_power_state(codec, 0x1c, &parm);
 690                set_pin_power_state(codec, 0x1d, &parm);
 691                if (is_8ch)
 692                        set_pin_power_state(codec, 0x23, &parm);
 693                /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
 694                snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
 695                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 696                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 697                                    parm);
 698                if (is_8ch) {
 699                        snd_hda_codec_write(codec, 0x25, 0,
 700                                            AC_VERB_SET_POWER_STATE, parm);
 701                        snd_hda_codec_write(codec, 0x27, 0,
 702                                            AC_VERB_SET_POWER_STATE, parm);
 703                }
 704        }  else if (spec->codec_type == VT1718S) {
 705                /* MUX6 (1eh) = stereo mixer */
 706                imux_is_smixer = snd_hda_codec_read(
 707                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
 708                /* inputs */
 709                /* PW 5/6/7 (29h/2ah/2bh) */
 710                parm = AC_PWRST_D3;
 711                set_pin_power_state(codec, 0x29, &parm);
 712                set_pin_power_state(codec, 0x2a, &parm);
 713                set_pin_power_state(codec, 0x2b, &parm);
 714                if (imux_is_smixer)
 715                        parm = AC_PWRST_D0;
 716                /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
 717                snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
 718                                    parm);
 719                snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
 720                                    parm);
 721                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 722                                    parm);
 723                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 724                                    parm);
 725
 726                /* outputs */
 727                /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
 728                parm = AC_PWRST_D3;
 729                set_pin_power_state(codec, 0x27, &parm);
 730                snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
 731                                    parm);
 732                snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
 733                                    parm);
 734
 735                /* PW2 (26h), AOW2 (ah) */
 736                parm = AC_PWRST_D3;
 737                set_pin_power_state(codec, 0x26, &parm);
 738                snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
 739                                    parm);
 740
 741                /* PW0/1 (24h/25h) */
 742                parm = AC_PWRST_D3;
 743                set_pin_power_state(codec, 0x24, &parm);
 744                set_pin_power_state(codec, 0x25, &parm);
 745                if (!spec->hp_independent_mode) /* check for redirected HP */
 746                        set_pin_power_state(codec, 0x28, &parm);
 747                snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
 748                                    parm);
 749                snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
 750                                    parm);
 751                /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
 752                snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
 753                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 754                if (spec->hp_independent_mode) {
 755                        /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
 756                        parm = AC_PWRST_D3;
 757                        set_pin_power_state(codec, 0x28, &parm);
 758                        snd_hda_codec_write(codec, 0x1b, 0,
 759                                            AC_VERB_SET_POWER_STATE, parm);
 760                        snd_hda_codec_write(codec, 0x34, 0,
 761                                            AC_VERB_SET_POWER_STATE, parm);
 762                        snd_hda_codec_write(codec, 0xc, 0,
 763                                            AC_VERB_SET_POWER_STATE, parm);
 764                }
 765        } else if (spec->codec_type == VT1716S) {
 766                unsigned int mono_out, present;
 767                /* SW0 (17h) = stereo mixer */
 768                imux_is_smixer = snd_hda_codec_read(
 769                        codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
 770                /* inputs */
 771                /* PW 1/2/5 (1ah/1bh/1eh) */
 772                parm = AC_PWRST_D3;
 773                set_pin_power_state(codec, 0x1a, &parm);
 774                set_pin_power_state(codec, 0x1b, &parm);
 775                set_pin_power_state(codec, 0x1e, &parm);
 776                if (imux_is_smixer)
 777                        parm = AC_PWRST_D0;
 778                /* SW0 (17h), AIW0(13h) */
 779                snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
 780                                    parm);
 781                snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
 782                                    parm);
 783
 784                parm = AC_PWRST_D3;
 785                set_pin_power_state(codec, 0x1e, &parm);
 786                /* PW11 (22h) */
 787                if (spec->dmic_enabled)
 788                        set_pin_power_state(codec, 0x22, &parm);
 789                else
 790                        snd_hda_codec_write(
 791                                codec, 0x22, 0,
 792                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 793
 794                /* SW2(26h), AIW1(14h) */
 795                snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
 796                                    parm);
 797                snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
 798                                    parm);
 799
 800                /* outputs */
 801                /* PW0 (19h), SW1 (18h), AOW1 (11h) */
 802                parm = AC_PWRST_D3;
 803                set_pin_power_state(codec, 0x19, &parm);
 804                /* Smart 5.1 PW2(1bh) */
 805                if (spec->smart51_enabled)
 806                        set_pin_power_state(codec, 0x1b, &parm);
 807                snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
 808                                    parm);
 809                snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
 810                                    parm);
 811
 812                /* PW7 (23h), SW3 (27h), AOW3 (25h) */
 813                parm = AC_PWRST_D3;
 814                set_pin_power_state(codec, 0x23, &parm);
 815                /* Smart 5.1 PW1(1ah) */
 816                if (spec->smart51_enabled)
 817                        set_pin_power_state(codec, 0x1a, &parm);
 818                snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
 819                                    parm);
 820
 821                /* Smart 5.1 PW5(1eh) */
 822                if (spec->smart51_enabled)
 823                        set_pin_power_state(codec, 0x1e, &parm);
 824                snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
 825                                    parm);
 826
 827                /* Mono out */
 828                /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
 829                present = snd_hda_jack_detect(codec, 0x1c);
 830                if (present)
 831                        mono_out = 0;
 832                else {
 833                        present = snd_hda_jack_detect(codec, 0x1d);
 834                        if (!spec->hp_independent_mode && present)
 835                                mono_out = 0;
 836                        else
 837                                mono_out = 1;
 838                }
 839                parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
 840                snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
 841                                    parm);
 842                snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
 843                                    parm);
 844                snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
 845                                    parm);
 846
 847                /* PW 3/4 (1ch/1dh) */
 848                parm = AC_PWRST_D3;
 849                set_pin_power_state(codec, 0x1c, &parm);
 850                set_pin_power_state(codec, 0x1d, &parm);
 851                /* HP Independent Mode, power on AOW3 */
 852                if (spec->hp_independent_mode)
 853                        snd_hda_codec_write(codec, 0x25, 0,
 854                                            AC_VERB_SET_POWER_STATE, parm);
 855
 856                /* force to D0 for internal Speaker */
 857                /* MW0 (16h), AOW0 (10h) */
 858                snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
 859                                    imux_is_smixer ? AC_PWRST_D0 : parm);
 860                snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
 861                                    mono_out ? AC_PWRST_D0 : parm);
 862        } else if (spec->codec_type == VT2002P) {
 863                unsigned int present;
 864                /* MUX9 (1eh) = stereo mixer */
 865                imux_is_smixer = snd_hda_codec_read(
 866                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
 867                /* inputs */
 868                /* PW 5/6/7 (29h/2ah/2bh) */
 869                parm = AC_PWRST_D3;
 870                set_pin_power_state(codec, 0x29, &parm);
 871                set_pin_power_state(codec, 0x2a, &parm);
 872                set_pin_power_state(codec, 0x2b, &parm);
 873                if (imux_is_smixer)
 874                        parm = AC_PWRST_D0;
 875                /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
 876                snd_hda_codec_write(codec, 0x1e, 0,
 877                                    AC_VERB_SET_POWER_STATE, parm);
 878                snd_hda_codec_write(codec, 0x1f, 0,
 879                                    AC_VERB_SET_POWER_STATE, parm);
 880                snd_hda_codec_write(codec, 0x10, 0,
 881                                    AC_VERB_SET_POWER_STATE, parm);
 882                snd_hda_codec_write(codec, 0x11, 0,
 883                                    AC_VERB_SET_POWER_STATE, parm);
 884
 885                /* outputs */
 886                /* AOW0 (8h)*/
 887                snd_hda_codec_write(codec, 0x8, 0,
 888                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 889
 890                /* PW4 (26h), MW4 (1ch), MUX4(37h) */
 891                parm = AC_PWRST_D3;
 892                set_pin_power_state(codec, 0x26, &parm);
 893                snd_hda_codec_write(codec, 0x1c, 0,
 894                                    AC_VERB_SET_POWER_STATE, parm);
 895                snd_hda_codec_write(codec, 0x37,
 896                                    0, AC_VERB_SET_POWER_STATE, parm);
 897
 898                /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
 899                parm = AC_PWRST_D3;
 900                set_pin_power_state(codec, 0x25, &parm);
 901                snd_hda_codec_write(codec, 0x19, 0,
 902                                    AC_VERB_SET_POWER_STATE, parm);
 903                snd_hda_codec_write(codec, 0x35, 0,
 904                                    AC_VERB_SET_POWER_STATE, parm);
 905                if (spec->hp_independent_mode)  {
 906                        snd_hda_codec_write(codec, 0x9, 0,
 907                                            AC_VERB_SET_POWER_STATE, parm);
 908                }
 909
 910                /* Class-D */
 911                /* PW0 (24h), MW0(18h), MUX0(34h) */
 912                present = snd_hda_jack_detect(codec, 0x25);
 913                parm = AC_PWRST_D3;
 914                set_pin_power_state(codec, 0x24, &parm);
 915                if (present) {
 916                        snd_hda_codec_write(
 917                                codec, 0x18, 0,
 918                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 919                        snd_hda_codec_write(
 920                                codec, 0x34, 0,
 921                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 922                } else {
 923                        snd_hda_codec_write(
 924                                codec, 0x18, 0,
 925                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 926                        snd_hda_codec_write(
 927                                codec, 0x34, 0,
 928                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 929                }
 930
 931                /* Mono Out */
 932                /* PW15 (31h), MW8(17h), MUX8(3bh) */
 933                present = snd_hda_jack_detect(codec, 0x26);
 934                parm = AC_PWRST_D3;
 935                set_pin_power_state(codec, 0x31, &parm);
 936                if (present) {
 937                        snd_hda_codec_write(
 938                                codec, 0x17, 0,
 939                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 940                        snd_hda_codec_write(
 941                                codec, 0x3b, 0,
 942                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 943                } else {
 944                        snd_hda_codec_write(
 945                                codec, 0x17, 0,
 946                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 947                        snd_hda_codec_write(
 948                                codec, 0x3b, 0,
 949                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 950                }
 951
 952                /* MW9 (21h) */
 953                if (imux_is_smixer || !is_aa_path_mute(codec))
 954                        snd_hda_codec_write(
 955                                codec, 0x21, 0,
 956                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 957                else
 958                        snd_hda_codec_write(
 959                                codec, 0x21, 0,
 960                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 961        } else if (spec->codec_type == VT1812) {
 962                unsigned int present;
 963                /* MUX10 (1eh) = stereo mixer */
 964                imux_is_smixer = snd_hda_codec_read(
 965                        codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
 966                /* inputs */
 967                /* PW 5/6/7 (29h/2ah/2bh) */
 968                parm = AC_PWRST_D3;
 969                set_pin_power_state(codec, 0x29, &parm);
 970                set_pin_power_state(codec, 0x2a, &parm);
 971                set_pin_power_state(codec, 0x2b, &parm);
 972                if (imux_is_smixer)
 973                        parm = AC_PWRST_D0;
 974                /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
 975                snd_hda_codec_write(codec, 0x1e, 0,
 976                                    AC_VERB_SET_POWER_STATE, parm);
 977                snd_hda_codec_write(codec, 0x1f, 0,
 978                                    AC_VERB_SET_POWER_STATE, parm);
 979                snd_hda_codec_write(codec, 0x10, 0,
 980                                    AC_VERB_SET_POWER_STATE, parm);
 981                snd_hda_codec_write(codec, 0x11, 0,
 982                                    AC_VERB_SET_POWER_STATE, parm);
 983
 984                /* outputs */
 985                /* AOW0 (8h)*/
 986                snd_hda_codec_write(codec, 0x8, 0,
 987                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
 988
 989                /* PW4 (28h), MW4 (18h), MUX4(38h) */
 990                parm = AC_PWRST_D3;
 991                set_pin_power_state(codec, 0x28, &parm);
 992                snd_hda_codec_write(codec, 0x18, 0,
 993                                    AC_VERB_SET_POWER_STATE, parm);
 994                snd_hda_codec_write(codec, 0x38, 0,
 995                                    AC_VERB_SET_POWER_STATE, parm);
 996
 997                /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
 998                parm = AC_PWRST_D3;
 999                set_pin_power_state(codec, 0x25, &parm);
1000                snd_hda_codec_write(codec, 0x15, 0,
1001                                    AC_VERB_SET_POWER_STATE, parm);
1002                snd_hda_codec_write(codec, 0x35, 0,
1003                                    AC_VERB_SET_POWER_STATE, parm);
1004                if (spec->hp_independent_mode)  {
1005                        snd_hda_codec_write(codec, 0x9, 0,
1006                                            AC_VERB_SET_POWER_STATE, parm);
1007                }
1008
1009                /* Internal Speaker */
1010                /* PW0 (24h), MW0(14h), MUX0(34h) */
1011                present = snd_hda_jack_detect(codec, 0x25);
1012                parm = AC_PWRST_D3;
1013                set_pin_power_state(codec, 0x24, &parm);
1014                if (present) {
1015                        snd_hda_codec_write(codec, 0x14, 0,
1016                                            AC_VERB_SET_POWER_STATE,
1017                                            AC_PWRST_D3);
1018                        snd_hda_codec_write(codec, 0x34, 0,
1019                                            AC_VERB_SET_POWER_STATE,
1020                                            AC_PWRST_D3);
1021                } else {
1022                        snd_hda_codec_write(codec, 0x14, 0,
1023                                            AC_VERB_SET_POWER_STATE,
1024                                            AC_PWRST_D0);
1025                        snd_hda_codec_write(codec, 0x34, 0,
1026                                            AC_VERB_SET_POWER_STATE,
1027                                            AC_PWRST_D0);
1028                }
1029                /* Mono Out */
1030                /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1031                present = snd_hda_jack_detect(codec, 0x28);
1032                parm = AC_PWRST_D3;
1033                set_pin_power_state(codec, 0x31, &parm);
1034                if (present) {
1035                        snd_hda_codec_write(codec, 0x1c, 0,
1036                                            AC_VERB_SET_POWER_STATE,
1037                                            AC_PWRST_D3);
1038                        snd_hda_codec_write(codec, 0x3c, 0,
1039                                            AC_VERB_SET_POWER_STATE,
1040                                            AC_PWRST_D3);
1041                        snd_hda_codec_write(codec, 0x3e, 0,
1042                                            AC_VERB_SET_POWER_STATE,
1043                                            AC_PWRST_D3);
1044                } else {
1045                        snd_hda_codec_write(codec, 0x1c, 0,
1046                                            AC_VERB_SET_POWER_STATE,
1047                                            AC_PWRST_D0);
1048                        snd_hda_codec_write(codec, 0x3c, 0,
1049                                            AC_VERB_SET_POWER_STATE,
1050                                            AC_PWRST_D0);
1051                        snd_hda_codec_write(codec, 0x3e, 0,
1052                                            AC_VERB_SET_POWER_STATE,
1053                                            AC_PWRST_D0);
1054                }
1055
1056                /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1057                parm = AC_PWRST_D3;
1058                set_pin_power_state(codec, 0x33, &parm);
1059                snd_hda_codec_write(codec, 0x1d, 0,
1060                                    AC_VERB_SET_POWER_STATE, parm);
1061                snd_hda_codec_write(codec, 0x3d, 0,
1062                                    AC_VERB_SET_POWER_STATE, parm);
1063
1064                /* MW9 (21h) */
1065                if (imux_is_smixer || !is_aa_path_mute(codec))
1066                        snd_hda_codec_write(
1067                                codec, 0x21, 0,
1068                                AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1069                else
1070                        snd_hda_codec_write(
1071                                codec, 0x21, 0,
1072                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1073        }
1074}
1075
1076/*
1077 * input MUX handling
1078 */
1079static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1080                             struct snd_ctl_elem_info *uinfo)
1081{
1082        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1083        struct via_spec *spec = codec->spec;
1084        return snd_hda_input_mux_info(spec->input_mux, uinfo);
1085}
1086
1087static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1088                            struct snd_ctl_elem_value *ucontrol)
1089{
1090        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091        struct via_spec *spec = codec->spec;
1092        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1093
1094        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1095        return 0;
1096}
1097
1098static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1099                            struct snd_ctl_elem_value *ucontrol)
1100{
1101        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1102        struct via_spec *spec = codec->spec;
1103        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1104
1105        if (!spec->mux_nids[adc_idx])
1106                return -EINVAL;
1107        /* switch to D0 beofre change index */
1108        if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1109                               AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1110                snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1111                                    AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1112        /* update jack power state */
1113        set_jack_power_state(codec);
1114
1115        return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1116                                     spec->mux_nids[adc_idx],
1117                                     &spec->cur_mux[adc_idx]);
1118}
1119
1120static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
1121                                   struct snd_ctl_elem_info *uinfo)
1122{
1123        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1124        struct via_spec *spec = codec->spec;
1125        return snd_hda_input_mux_info(spec->hp_mux, uinfo);
1126}
1127
1128static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1129                                  struct snd_ctl_elem_value *ucontrol)
1130{
1131        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1132        hda_nid_t nid = kcontrol->private_value;
1133        unsigned int pinsel;
1134
1135        /* use !! to translate conn sel 2 for VT1718S */
1136        pinsel = !!snd_hda_codec_read(codec, nid, 0,
1137                                      AC_VERB_GET_CONNECT_SEL,
1138                                      0x00);
1139        ucontrol->value.enumerated.item[0] = pinsel;
1140
1141        return 0;
1142}
1143
1144static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1145{
1146        struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1147        if (ctl) {
1148                ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1149                ctl->vd[0].access |= active
1150                        ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1151                snd_ctl_notify(codec->bus->card,
1152                               SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1153        }
1154}
1155
1156static hda_nid_t side_mute_channel(struct via_spec *spec)
1157{
1158        switch (spec->codec_type) {
1159        case VT1708:            return 0x1b;
1160        case VT1709_10CH:       return 0x29;
1161        case VT1708B_8CH:       /* fall thru */
1162        case VT1708S:           return 0x27;
1163        default:                return 0;
1164        }
1165}
1166
1167static int update_side_mute_status(struct hda_codec *codec)
1168{
1169        /* mute side channel */
1170        struct via_spec *spec = codec->spec;
1171        unsigned int parm = spec->hp_independent_mode
1172                ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1173        hda_nid_t sw3 = side_mute_channel(spec);
1174
1175        if (sw3)
1176                snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1177                                    parm);
1178        return 0;
1179}
1180
1181static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1182                                  struct snd_ctl_elem_value *ucontrol)
1183{
1184        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1185        struct via_spec *spec = codec->spec;
1186        hda_nid_t nid = kcontrol->private_value;
1187        unsigned int pinsel = ucontrol->value.enumerated.item[0];
1188        /* Get Independent Mode index of headphone pin widget */
1189        spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1190                ? 1 : 0;
1191        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1192
1193        if (spec->multiout.hp_nid && spec->multiout.hp_nid
1194            != spec->multiout.dac_nids[HDA_FRONT])
1195                snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1196                                           0, 0, 0);
1197
1198        update_side_mute_status(codec);
1199        /* update HP volume/swtich active state */
1200        if (spec->codec_type == VT1708S
1201            || spec->codec_type == VT1702
1202            || spec->codec_type == VT1718S
1203            || spec->codec_type == VT1716S
1204            || spec->codec_type == VT2002P
1205            || spec->codec_type == VT1812) {
1206                activate_ctl(codec, "Headphone Playback Volume",
1207                             spec->hp_independent_mode);
1208                activate_ctl(codec, "Headphone Playback Switch",
1209                             spec->hp_independent_mode);
1210        }
1211        return 0;
1212}
1213
1214static struct snd_kcontrol_new via_hp_mixer[2] = {
1215        {
1216                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217                .name = "Independent HP",
1218                .info = via_independent_hp_info,
1219                .get = via_independent_hp_get,
1220                .put = via_independent_hp_put,
1221        },
1222        {
1223                .iface = NID_MAPPING,
1224                .name = "Independent HP",
1225        },
1226};
1227
1228static int via_hp_build(struct hda_codec *codec)
1229{
1230        struct via_spec *spec = codec->spec;
1231        struct snd_kcontrol_new *knew;
1232        hda_nid_t nid;
1233        int nums;
1234        hda_nid_t conn[HDA_MAX_CONNECTIONS];
1235
1236        switch (spec->codec_type) {
1237        case VT1718S:
1238                nid = 0x34;
1239                break;
1240        case VT2002P:
1241                nid = 0x35;
1242                break;
1243        case VT1812:
1244                nid = 0x3d;
1245                break;
1246        default:
1247                nid = spec->autocfg.hp_pins[0];
1248                break;
1249        }
1250
1251        nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
1252        if (nums <= 1)
1253                return 0;
1254
1255        knew = via_clone_control(spec, &via_hp_mixer[0]);
1256        if (knew == NULL)
1257                return -ENOMEM;
1258
1259        knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1260        knew->private_value = nid;
1261
1262        knew = via_clone_control(spec, &via_hp_mixer[1]);
1263        if (knew == NULL)
1264                return -ENOMEM;
1265        knew->subdevice = side_mute_channel(spec);
1266
1267        return 0;
1268}
1269
1270static void notify_aa_path_ctls(struct hda_codec *codec)
1271{
1272        int i;
1273        struct snd_ctl_elem_id id;
1274        const char *labels[] = {"Mic", "Front Mic", "Line"};
1275
1276        memset(&id, 0, sizeof(id));
1277        id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1278        for (i = 0; i < ARRAY_SIZE(labels); i++) {
1279                sprintf(id.name, "%s Playback Volume", labels[i]);
1280                snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1281                               &id);
1282        }
1283}
1284
1285static void mute_aa_path(struct hda_codec *codec, int mute)
1286{
1287        struct via_spec *spec = codec->spec;
1288        hda_nid_t  nid_mixer;
1289        int start_idx;
1290        int end_idx;
1291        int i;
1292        /* get nid of MW0 and start & end index */
1293        switch (spec->codec_type) {
1294        case VT1708:
1295                nid_mixer = 0x17;
1296                start_idx = 2;
1297                end_idx = 4;
1298                break;
1299        case VT1709_10CH:
1300        case VT1709_6CH:
1301                nid_mixer = 0x18;
1302                start_idx = 2;
1303                end_idx = 4;
1304                break;
1305        case VT1708B_8CH:
1306        case VT1708B_4CH:
1307        case VT1708S:
1308        case VT1716S:
1309                nid_mixer = 0x16;
1310                start_idx = 2;
1311                end_idx = 4;
1312                break;
1313        default:
1314                return;
1315        }
1316        /* check AA path's mute status */
1317        for (i = start_idx; i <= end_idx; i++) {
1318                int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1319                snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1320                                         HDA_AMP_MUTE, val);
1321        }
1322}
1323static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1324{
1325        const struct auto_pin_cfg *cfg = &spec->autocfg;
1326        int i;
1327
1328        for (i = 0; i < cfg->num_inputs; i++) {
1329                if (pin == cfg->inputs[i].pin)
1330                        return cfg->inputs[i].type <= AUTO_PIN_LINE_IN;
1331        }
1332        return 0;
1333}
1334
1335static int via_smart51_info(struct snd_kcontrol *kcontrol,
1336                            struct snd_ctl_elem_info *uinfo)
1337{
1338        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1339        uinfo->count = 1;
1340        uinfo->value.integer.min = 0;
1341        uinfo->value.integer.max = 1;
1342        return 0;
1343}
1344
1345static int via_smart51_get(struct snd_kcontrol *kcontrol,
1346                           struct snd_ctl_elem_value *ucontrol)
1347{
1348        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1349        struct via_spec *spec = codec->spec;
1350        const struct auto_pin_cfg *cfg = &spec->autocfg;
1351        int on = 1;
1352        int i;
1353
1354        for (i = 0; i < cfg->num_inputs; i++) {
1355                hda_nid_t nid = cfg->inputs[i].pin;
1356                int ctl = snd_hda_codec_read(codec, nid, 0,
1357                                             AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1358                if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1359                        continue;
1360                if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1361                    spec->hp_independent_mode && spec->codec_type != VT1718S)
1362                        continue; /* ignore FMic for independent HP */
1363                if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
1364                        on = 0;
1365        }
1366        *ucontrol->value.integer.value = on;
1367        return 0;
1368}
1369
1370static int via_smart51_put(struct snd_kcontrol *kcontrol,
1371                           struct snd_ctl_elem_value *ucontrol)
1372{
1373        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1374        struct via_spec *spec = codec->spec;
1375        const struct auto_pin_cfg *cfg = &spec->autocfg;
1376        int out_in = *ucontrol->value.integer.value
1377                ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1378        int i;
1379
1380        for (i = 0; i < cfg->num_inputs; i++) {
1381                hda_nid_t nid = cfg->inputs[i].pin;
1382                unsigned int parm;
1383
1384                if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1385                        continue;
1386                if (cfg->inputs[i].type == AUTO_PIN_MIC &&
1387                    spec->hp_independent_mode && spec->codec_type != VT1718S)
1388                        continue; /* don't retask FMic for independent HP */
1389
1390                parm = snd_hda_codec_read(codec, nid, 0,
1391                                          AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1392                parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1393                parm |= out_in;
1394                snd_hda_codec_write(codec, nid, 0,
1395                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
1396                                    parm);
1397                if (out_in == AC_PINCTL_OUT_EN) {
1398                        mute_aa_path(codec, 1);
1399                        notify_aa_path_ctls(codec);
1400                }
1401                if (spec->codec_type == VT1718S) {
1402                        snd_hda_codec_amp_stereo(
1403                                        codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1404                                        HDA_AMP_UNMUTE);
1405                }
1406                if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1407                        if (spec->codec_type == VT1708S
1408                            || spec->codec_type == VT1716S) {
1409                                /* input = index 1 (AOW3) */
1410                                snd_hda_codec_write(
1411                                        codec, nid, 0,
1412                                        AC_VERB_SET_CONNECT_SEL, 1);
1413                                snd_hda_codec_amp_stereo(
1414                                        codec, nid, HDA_OUTPUT,
1415                                        0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1416                        }
1417                }
1418        }
1419        spec->smart51_enabled = *ucontrol->value.integer.value;
1420        set_jack_power_state(codec);
1421        return 1;
1422}
1423
1424static struct snd_kcontrol_new via_smart51_mixer[2] = {
1425        {
1426         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427         .name = "Smart 5.1",
1428         .count = 1,
1429         .info = via_smart51_info,
1430         .get = via_smart51_get,
1431         .put = via_smart51_put,
1432         },
1433        {
1434         .iface = NID_MAPPING,
1435         .name = "Smart 5.1",
1436        }
1437};
1438
1439static int via_smart51_build(struct via_spec *spec)
1440{
1441        struct snd_kcontrol_new *knew;
1442        const struct auto_pin_cfg *cfg = &spec->autocfg;
1443        hda_nid_t nid;
1444        int i;
1445
1446        knew = via_clone_control(spec, &via_smart51_mixer[0]);
1447        if (knew == NULL)
1448                return -ENOMEM;
1449
1450        for (i = 0; i < cfg->num_inputs; i++) {
1451                nid = cfg->inputs[i].pin;
1452                if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1453                        knew = via_clone_control(spec, &via_smart51_mixer[1]);
1454                        if (knew == NULL)
1455                                return -ENOMEM;
1456                        knew->subdevice = nid;
1457                        break;
1458                }
1459        }
1460
1461        return 0;
1462}
1463
1464/* capture mixer elements */
1465static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1466        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1467        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1468        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1469        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1470        {
1471                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1472                /* The multiple "Capture Source" controls confuse alsamixer
1473                 * So call somewhat different..
1474                 */
1475                /* .name = "Capture Source", */
1476                .name = "Input Source",
1477                .count = 1,
1478                .info = via_mux_enum_info,
1479                .get = via_mux_enum_get,
1480                .put = via_mux_enum_put,
1481        },
1482        { } /* end */
1483};
1484
1485/* check AA path's mute statue */
1486static int is_aa_path_mute(struct hda_codec *codec)
1487{
1488        int mute = 1;
1489        hda_nid_t  nid_mixer;
1490        int start_idx;
1491        int end_idx;
1492        int i;
1493        struct via_spec *spec = codec->spec;
1494        /* get nid of MW0 and start & end index */
1495        switch (spec->codec_type) {
1496        case VT1708B_8CH:
1497        case VT1708B_4CH:
1498        case VT1708S:
1499        case VT1716S:
1500                nid_mixer = 0x16;
1501                start_idx = 2;
1502                end_idx = 4;
1503                break;
1504        case VT1702:
1505                nid_mixer = 0x1a;
1506                start_idx = 1;
1507                end_idx = 3;
1508                break;
1509        case VT1718S:
1510                nid_mixer = 0x21;
1511                start_idx = 1;
1512                end_idx = 3;
1513                break;
1514        case VT2002P:
1515        case VT1812:
1516                nid_mixer = 0x21;
1517                start_idx = 0;
1518                end_idx = 2;
1519                break;
1520        default:
1521                return 0;
1522        }
1523        /* check AA path's mute status */
1524        for (i = start_idx; i <= end_idx; i++) {
1525                unsigned int con_list = snd_hda_codec_read(
1526                        codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1527                int shift = 8 * (i % 4);
1528                hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1529                unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1530                if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1531                        /* check mute status while the pin is connected */
1532                        int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1533                                                            HDA_INPUT, i) >> 7;
1534                        int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1535                                                            HDA_INPUT, i) >> 7;
1536                        if (!mute_l || !mute_r) {
1537                                mute = 0;
1538                                break;
1539                        }
1540                }
1541        }
1542        return mute;
1543}
1544
1545/* enter/exit analog low-current mode */
1546static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1547{
1548        struct via_spec *spec = codec->spec;
1549        static int saved_stream_idle = 1; /* saved stream idle status */
1550        int enable = is_aa_path_mute(codec);
1551        unsigned int verb = 0;
1552        unsigned int parm = 0;
1553
1554        if (stream_idle == -1)  /* stream status did not change */
1555                enable = enable && saved_stream_idle;
1556        else {
1557                enable = enable && stream_idle;
1558                saved_stream_idle = stream_idle;
1559        }
1560
1561        /* decide low current mode's verb & parameter */
1562        switch (spec->codec_type) {
1563        case VT1708B_8CH:
1564        case VT1708B_4CH:
1565                verb = 0xf70;
1566                parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1567                break;
1568        case VT1708S:
1569        case VT1718S:
1570        case VT1716S:
1571                verb = 0xf73;
1572                parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1573                break;
1574        case VT1702:
1575                verb = 0xf73;
1576                parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1577                break;
1578        case VT2002P:
1579        case VT1812:
1580                verb = 0xf93;
1581                parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1582                break;
1583        default:
1584                return;         /* other codecs are not supported */
1585        }
1586        /* send verb */
1587        snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1588}
1589
1590/*
1591 * generic initialization of ADC, input mixers and output mixers
1592 */
1593static struct hda_verb vt1708_volume_init_verbs[] = {
1594        /*
1595         * Unmute ADC0-1 and set the default input to mic-in
1596         */
1597        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1598        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1599
1600
1601        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1602         * mixer widget
1603         */
1604        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1605        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1606        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1607        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1608        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1609        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1610
1611        /*
1612         * Set up output mixers (0x19 - 0x1b)
1613         */
1614        /* set vol=0 to output mixers */
1615        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1616        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1617        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1618
1619        /* Setup default input MW0 to PW4 */
1620        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1621        /* PW9 Output enable */
1622        {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1623        { }
1624};
1625
1626static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1627                                 struct hda_codec *codec,
1628                                 struct snd_pcm_substream *substream)
1629{
1630        struct via_spec *spec = codec->spec;
1631        int idle = substream->pstr->substream_opened == 1
1632                && substream->ref_count == 0;
1633        analog_low_current_mode(codec, idle);
1634        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1635                                             hinfo);
1636}
1637
1638static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1639                                      unsigned int stream_tag,
1640                                      unsigned int format,
1641                                      struct snd_pcm_substream *substream)
1642{
1643        struct via_spec *spec = codec->spec;
1644        struct hda_multi_out *mout = &spec->multiout;
1645        hda_nid_t *nids = mout->dac_nids;
1646        int chs = substream->runtime->channels;
1647        int i;
1648
1649        mutex_lock(&codec->spdif_mutex);
1650        if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1651                if (chs == 2 &&
1652                    snd_hda_is_supported_format(codec, mout->dig_out_nid,
1653                                                format) &&
1654                    !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1655                        mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1656                        /* turn off SPDIF once; otherwise the IEC958 bits won't
1657                         * be updated */
1658                        if (codec->spdif_ctls & AC_DIG1_ENABLE)
1659                                snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1660                                                    AC_VERB_SET_DIGI_CONVERT_1,
1661                                                    codec->spdif_ctls &
1662                                                        ~AC_DIG1_ENABLE & 0xff);
1663                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1664                                                   stream_tag, 0, format);
1665                        /* turn on again (if needed) */
1666                        if (codec->spdif_ctls & AC_DIG1_ENABLE)
1667                                snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1668                                                    AC_VERB_SET_DIGI_CONVERT_1,
1669                                                    codec->spdif_ctls & 0xff);
1670                } else {
1671                        mout->dig_out_used = 0;
1672                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1673                                                   0, 0, 0);
1674                }
1675        }
1676        mutex_unlock(&codec->spdif_mutex);
1677
1678        /* front */
1679        snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1680                                   0, format);
1681
1682        if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1683            && !spec->hp_independent_mode)
1684                /* headphone out will just decode front left/right (stereo) */
1685                snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1686                                           0, format);
1687
1688        /* extra outputs copied from front */
1689        for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1690                if (mout->extra_out_nid[i])
1691                        snd_hda_codec_setup_stream(codec,
1692                                                   mout->extra_out_nid[i],
1693                                                   stream_tag, 0, format);
1694
1695        /* surrounds */
1696        for (i = 1; i < mout->num_dacs; i++) {
1697                if (chs >= (i + 1) * 2) /* independent out */
1698                        snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1699                                                   i * 2, format);
1700                else /* copy front */
1701                        snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1702                                                   0, format);
1703        }
1704}
1705
1706static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1707                                          struct hda_codec *codec,
1708                                          unsigned int stream_tag,
1709                                          unsigned int format,
1710                                          struct snd_pcm_substream *substream)
1711{
1712        struct via_spec *spec = codec->spec;
1713        struct hda_multi_out *mout = &spec->multiout;
1714        hda_nid_t *nids = mout->dac_nids;
1715
1716        if (substream->number == 0)
1717                playback_multi_pcm_prep_0(codec, stream_tag, format,
1718                                          substream);
1719        else {
1720                if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1721                    spec->hp_independent_mode)
1722                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1723                                                   stream_tag, 0, format);
1724        }
1725        vt1708_start_hp_work(spec);
1726        return 0;
1727}
1728
1729static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1730                                    struct hda_codec *codec,
1731                                    struct snd_pcm_substream *substream)
1732{
1733        struct via_spec *spec = codec->spec;
1734        struct hda_multi_out *mout = &spec->multiout;
1735        hda_nid_t *nids = mout->dac_nids;
1736        int i;
1737
1738        if (substream->number == 0) {
1739                for (i = 0; i < mout->num_dacs; i++)
1740                        snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1741
1742                if (mout->hp_nid && !spec->hp_independent_mode)
1743                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1744                                                   0, 0, 0);
1745
1746                for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1747                        if (mout->extra_out_nid[i])
1748                                snd_hda_codec_setup_stream(codec,
1749                                                        mout->extra_out_nid[i],
1750                                                        0, 0, 0);
1751                mutex_lock(&codec->spdif_mutex);
1752                if (mout->dig_out_nid &&
1753                    mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1754                        snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1755                                                   0, 0, 0);
1756                        mout->dig_out_used = 0;
1757                }
1758                mutex_unlock(&codec->spdif_mutex);
1759        } else {
1760                if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1761                    spec->hp_independent_mode)
1762                        snd_hda_codec_setup_stream(codec, mout->hp_nid,
1763                                                   0, 0, 0);
1764        }
1765        vt1708_stop_hp_work(spec);
1766        return 0;
1767}
1768
1769/*
1770 * Digital out
1771 */
1772static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1773                                     struct hda_codec *codec,
1774                                     struct snd_pcm_substream *substream)
1775{
1776        struct via_spec *spec = codec->spec;
1777        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1778}
1779
1780static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1781                                      struct hda_codec *codec,
1782                                      struct snd_pcm_substream *substream)
1783{
1784        struct via_spec *spec = codec->spec;
1785        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1786}
1787
1788static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1789                                        struct hda_codec *codec,
1790                                        unsigned int stream_tag,
1791                                        unsigned int format,
1792                                        struct snd_pcm_substream *substream)
1793{
1794        struct via_spec *spec = codec->spec;
1795        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1796                                             stream_tag, format, substream);
1797}
1798
1799static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1800                                        struct hda_codec *codec,
1801                                        struct snd_pcm_substream *substream)
1802{
1803        struct via_spec *spec = codec->spec;
1804        snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1805        return 0;
1806}
1807
1808/*
1809 * Analog capture
1810 */
1811static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1812                                   struct hda_codec *codec,
1813                                   unsigned int stream_tag,
1814                                   unsigned int format,
1815                                   struct snd_pcm_substream *substream)
1816{
1817        struct via_spec *spec = codec->spec;
1818
1819        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1820                                   stream_tag, 0, format);
1821        return 0;
1822}
1823
1824static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1825                                   struct hda_codec *codec,
1826                                   struct snd_pcm_substream *substream)
1827{
1828        struct via_spec *spec = codec->spec;
1829        snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1830        return 0;
1831}
1832
1833static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1834        .substreams = 2,
1835        .channels_min = 2,
1836        .channels_max = 8,
1837        .nid = 0x10, /* NID to query formats and rates */
1838        .ops = {
1839                .open = via_playback_pcm_open,
1840                .prepare = via_playback_multi_pcm_prepare,
1841                .cleanup = via_playback_multi_pcm_cleanup
1842        },
1843};
1844
1845static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1846        .substreams = 2,
1847        .channels_min = 2,
1848        .channels_max = 8,
1849        .nid = 0x10, /* NID to query formats and rates */
1850        /* We got noisy outputs on the right channel on VT1708 when
1851         * 24bit samples are used.  Until any workaround is found,
1852         * disable the 24bit format, so far.
1853         */
1854        .formats = SNDRV_PCM_FMTBIT_S16_LE,
1855        .ops = {
1856                .open = via_playback_pcm_open,
1857                .prepare = via_playback_multi_pcm_prepare,
1858                .cleanup = via_playback_multi_pcm_cleanup
1859        },
1860};
1861
1862static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1863        .substreams = 2,
1864        .channels_min = 2,
1865        .channels_max = 2,
1866        .nid = 0x15, /* NID to query formats and rates */
1867        .ops = {
1868                .prepare = via_capture_pcm_prepare,
1869                .cleanup = via_capture_pcm_cleanup
1870        },
1871};
1872
1873static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1874        .substreams = 1,
1875        .channels_min = 2,
1876        .channels_max = 2,
1877        /* NID is set in via_build_pcms */
1878        .ops = {
1879                .open = via_dig_playback_pcm_open,
1880                .close = via_dig_playback_pcm_close,
1881                .prepare = via_dig_playback_pcm_prepare,
1882                .cleanup = via_dig_playback_pcm_cleanup
1883        },
1884};
1885
1886static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1887        .substreams = 1,
1888        .channels_min = 2,
1889        .channels_max = 2,
1890};
1891
1892static int via_build_controls(struct hda_codec *codec)
1893{
1894        struct via_spec *spec = codec->spec;
1895        struct snd_kcontrol *kctl;
1896        struct snd_kcontrol_new *knew;
1897        int err, i;
1898
1899        for (i = 0; i < spec->num_mixers; i++) {
1900                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1901                if (err < 0)
1902                        return err;
1903        }
1904
1905        if (spec->multiout.dig_out_nid) {
1906                err = snd_hda_create_spdif_out_ctls(codec,
1907                                                    spec->multiout.dig_out_nid);
1908                if (err < 0)
1909                        return err;
1910                err = snd_hda_create_spdif_share_sw(codec,
1911                                                    &spec->multiout);
1912                if (err < 0)
1913                        return err;
1914                spec->multiout.share_spdif = 1;
1915        }
1916        if (spec->dig_in_nid) {
1917                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1918                if (err < 0)
1919                        return err;
1920        }
1921
1922        /* assign Capture Source enums to NID */
1923        kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1924        for (i = 0; kctl && i < kctl->count; i++) {
1925                err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1926                if (err < 0)
1927                        return err;
1928        }
1929
1930        /* other nid->control mapping */
1931        for (i = 0; i < spec->num_mixers; i++) {
1932                for (knew = spec->mixers[i]; knew->name; knew++) {
1933                        if (knew->iface != NID_MAPPING)
1934                                continue;
1935                        kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1936                        if (kctl == NULL)
1937                                continue;
1938                        err = snd_hda_add_nid(codec, kctl, 0,
1939                                              knew->subdevice);
1940                }
1941        }
1942
1943        /* init power states */
1944        set_jack_power_state(codec);
1945        analog_low_current_mode(codec, 1);
1946
1947        via_free_kctls(codec); /* no longer needed */
1948        return 0;
1949}
1950
1951static int via_build_pcms(struct hda_codec *codec)
1952{
1953        struct via_spec *spec = codec->spec;
1954        struct hda_pcm *info = spec->pcm_rec;
1955
1956        codec->num_pcms = 1;
1957        codec->pcm_info = info;
1958
1959        info->name = spec->stream_name_analog;
1960        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1961                *(spec->stream_analog_playback);
1962        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1963                spec->multiout.dac_nids[0];
1964        info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1965        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1966
1967        info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1968                spec->multiout.max_channels;
1969
1970        if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1971                codec->num_pcms++;
1972                info++;
1973                info->name = spec->stream_name_digital;
1974                info->pcm_type = HDA_PCM_TYPE_SPDIF;
1975                if (spec->multiout.dig_out_nid) {
1976                        info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1977                                *(spec->stream_digital_playback);
1978                        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1979                                spec->multiout.dig_out_nid;
1980                }
1981                if (spec->dig_in_nid) {
1982                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1983                                *(spec->stream_digital_capture);
1984                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1985                                spec->dig_in_nid;
1986                }
1987        }
1988
1989        return 0;
1990}
1991
1992static void via_free(struct hda_codec *codec)
1993{
1994        struct via_spec *spec = codec->spec;
1995
1996        if (!spec)
1997                return;
1998
1999        via_free_kctls(codec);
2000        vt1708_stop_hp_work(spec);
2001        kfree(codec->spec);
2002}
2003
2004/* mute internal speaker if HP is plugged */
2005static void via_hp_automute(struct hda_codec *codec)
2006{
2007        unsigned int present = 0;
2008        struct via_spec *spec = codec->spec;
2009
2010        present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2011
2012        if (!spec->hp_independent_mode) {
2013                struct snd_ctl_elem_id id;
2014                /* auto mute */
2015                snd_hda_codec_amp_stereo(
2016                        codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2017                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2018                /* notify change */
2019                memset(&id, 0, sizeof(id));
2020                id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2021                strcpy(id.name, "Front Playback Switch");
2022                snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2023                               &id);
2024        }
2025}
2026
2027/* mute mono out if HP or Line out is plugged */
2028static void via_mono_automute(struct hda_codec *codec)
2029{
2030        unsigned int hp_present, lineout_present;
2031        struct via_spec *spec = codec->spec;
2032
2033        if (spec->codec_type != VT1716S)
2034                return;
2035
2036        lineout_present = snd_hda_jack_detect(codec,
2037                                              spec->autocfg.line_out_pins[0]);
2038
2039        /* Mute Mono Out if Line Out is plugged */
2040        if (lineout_present) {
2041                snd_hda_codec_amp_stereo(
2042                        codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2043                return;
2044        }
2045
2046        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2047
2048        if (!spec->hp_independent_mode)
2049                snd_hda_codec_amp_stereo(
2050                        codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2051                        hp_present ? HDA_AMP_MUTE : 0);
2052}
2053
2054static void via_gpio_control(struct hda_codec *codec)
2055{
2056        unsigned int gpio_data;
2057        unsigned int vol_counter;
2058        unsigned int vol;
2059        unsigned int master_vol;
2060
2061        struct via_spec *spec = codec->spec;
2062
2063        gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
2064                                       AC_VERB_GET_GPIO_DATA, 0) & 0x03;
2065
2066        vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
2067                                          0xF84, 0) & 0x3F0000) >> 16;
2068
2069        vol = vol_counter & 0x1F;
2070        master_vol = snd_hda_codec_read(codec, 0x1A, 0,
2071                                        AC_VERB_GET_AMP_GAIN_MUTE,
2072                                        AC_AMP_GET_INPUT);
2073
2074        if (gpio_data == 0x02) {
2075                /* unmute line out */
2076                snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
2077                                         HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
2078
2079                if (vol_counter & 0x20) {
2080                        /* decrease volume */
2081                        if (vol > master_vol)
2082                                vol = master_vol;
2083                        snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
2084                                                 0, HDA_AMP_VOLMASK,
2085                                                 master_vol-vol);
2086                } else {
2087                        /* increase volume */
2088                        snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
2089                                         HDA_AMP_VOLMASK,
2090                                         ((master_vol+vol) > 0x2A) ? 0x2A :
2091                                          (master_vol+vol));
2092                }
2093        } else if (!(gpio_data & 0x02)) {
2094                /* mute line out */
2095                snd_hda_codec_amp_stereo(codec,
2096                                         spec->autocfg.line_out_pins[0],
2097                                         HDA_OUTPUT, 0, HDA_AMP_MUTE,
2098                                         HDA_AMP_MUTE);
2099        }
2100}
2101
2102/* mute Internal-Speaker if HP is plugged */
2103static void via_speaker_automute(struct hda_codec *codec)
2104{
2105        unsigned int hp_present;
2106        struct via_spec *spec = codec->spec;
2107
2108        if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2109                return;
2110
2111        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2112
2113        if (!spec->hp_independent_mode) {
2114                struct snd_ctl_elem_id id;
2115                snd_hda_codec_amp_stereo(
2116                        codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2117                        HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2118                /* notify change */
2119                memset(&id, 0, sizeof(id));
2120                id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2121                strcpy(id.name, "Speaker Playback Switch");
2122                snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2123                               &id);
2124        }
2125}
2126
2127/* mute line-out and internal speaker if HP is plugged */
2128static void via_hp_bind_automute(struct hda_codec *codec)
2129{
2130        /* use long instead of int below just to avoid an internal compiler
2131         * error with gcc 4.0.x
2132         */
2133        unsigned long hp_present, present = 0;
2134        struct via_spec *spec = codec->spec;
2135        int i;
2136
2137        if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2138                return;
2139
2140        hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2141
2142        present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2143
2144        if (!spec->hp_independent_mode) {
2145                /* Mute Line-Outs */
2146                for (i = 0; i < spec->autocfg.line_outs; i++)
2147                        snd_hda_codec_amp_stereo(
2148                                codec, spec->autocfg.line_out_pins[i],
2149                                HDA_OUTPUT, 0,
2150                                HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2151                if (hp_present)
2152                        present = hp_present;
2153        }
2154        /* Speakers */
2155        for (i = 0; i < spec->autocfg.speaker_outs; i++)
2156                snd_hda_codec_amp_stereo(
2157                        codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2158                        HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2159}
2160
2161
2162/* unsolicited event for jack sensing */
2163static void via_unsol_event(struct hda_codec *codec,
2164                                  unsigned int res)
2165{
2166        res >>= 26;
2167        if (res & VIA_HP_EVENT)
2168                via_hp_automute(codec);
2169        if (res & VIA_GPIO_EVENT)
2170                via_gpio_control(codec);
2171        if (res & VIA_JACK_EVENT)
2172                set_jack_power_state(codec);
2173        if (res & VIA_MONO_EVENT)
2174                via_mono_automute(codec);
2175        if (res & VIA_SPEAKER_EVENT)
2176                via_speaker_automute(codec);
2177        if (res & VIA_BIND_HP_EVENT)
2178                via_hp_bind_automute(codec);
2179}
2180
2181static int via_init(struct hda_codec *codec)
2182{
2183        struct via_spec *spec = codec->spec;
2184        int i;
2185        for (i = 0; i < spec->num_iverbs; i++)
2186                snd_hda_sequence_write(codec, spec->init_verbs[i]);
2187
2188        spec->codec_type = get_codec_type(codec);
2189        if (spec->codec_type == VT1708BCE)
2190                spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2191                                               same */
2192        /* Lydia Add for EAPD enable */
2193        if (!spec->dig_in_nid) { /* No Digital In connection */
2194                if (spec->dig_in_pin) {
2195                        snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2196                                            AC_VERB_SET_PIN_WIDGET_CONTROL,
2197                                            PIN_OUT);
2198                        snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2199                                            AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2200                }
2201        } else /* enable SPDIF-input pin */
2202                snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2203                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2204
2205        /* assign slave outs */
2206        if (spec->slave_dig_outs[0])
2207                codec->slave_dig_outs = spec->slave_dig_outs;
2208
2209        return 0;
2210}
2211
2212#ifdef SND_HDA_NEEDS_RESUME
2213static int via_suspend(struct hda_codec *codec, pm_message_t state)
2214{
2215        struct via_spec *spec = codec->spec;
2216        vt1708_stop_hp_work(spec);
2217        return 0;
2218}
2219#endif
2220
2221#ifdef CONFIG_SND_HDA_POWER_SAVE
2222static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2223{
2224        struct via_spec *spec = codec->spec;
2225        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2226}
2227#endif
2228
2229/*
2230 */
2231static struct hda_codec_ops via_patch_ops = {
2232        .build_controls = via_build_controls,
2233        .build_pcms = via_build_pcms,
2234        .init = via_init,
2235        .free = via_free,
2236#ifdef SND_HDA_NEEDS_RESUME
2237        .suspend = via_suspend,
2238#endif
2239#ifdef CONFIG_SND_HDA_POWER_SAVE
2240        .check_power_status = via_check_power_status,
2241#endif
2242};
2243
2244/* fill in the dac_nids table from the parsed pin configuration */
2245static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2246                                     const struct auto_pin_cfg *cfg)
2247{
2248        int i;
2249        hda_nid_t nid;
2250
2251        spec->multiout.num_dacs = cfg->line_outs;
2252
2253        spec->multiout.dac_nids = spec->private_dac_nids;
2254
2255        for (i = 0; i < 4; i++) {
2256                nid = cfg->line_out_pins[i];
2257                if (nid) {
2258                        /* config dac list */
2259                        switch (i) {
2260                        case AUTO_SEQ_FRONT:
2261                                spec->multiout.dac_nids[i] = 0x10;
2262                                break;
2263                        case AUTO_SEQ_CENLFE:
2264                                spec->multiout.dac_nids[i] = 0x12;
2265                                break;
2266                        case AUTO_SEQ_SURROUND:
2267                                spec->multiout.dac_nids[i] = 0x11;
2268                                break;
2269                        case AUTO_SEQ_SIDE:
2270                                spec->multiout.dac_nids[i] = 0x13;
2271                                break;
2272                        }
2273                }
2274        }
2275
2276        return 0;
2277}
2278
2279/* add playback controls from the parsed DAC table */
2280static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2281                                             const struct auto_pin_cfg *cfg)
2282{
2283        char name[32];
2284        static const char * const chname[4] = {
2285                "Front", "Surround", "C/LFE", "Side"
2286        };
2287        hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2288        int i, err;
2289
2290        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2291                nid = cfg->line_out_pins[i];
2292
2293                if (!nid)
2294                        continue;
2295
2296                nid_vol = nid_vols[i];
2297
2298                if (i == AUTO_SEQ_CENLFE) {
2299                        /* Center/LFE */
2300                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2301                                        "Center Playback Volume",
2302                                        HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2303                                                            HDA_OUTPUT));
2304                        if (err < 0)
2305                                return err;
2306                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2307                                              "LFE Playback Volume",
2308                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2309                                                                  HDA_OUTPUT));
2310                        if (err < 0)
2311                                return err;
2312                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2313                                              "Center Playback Switch",
2314                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2315                                                                  HDA_OUTPUT));
2316                        if (err < 0)
2317                                return err;
2318                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2319                                              "LFE Playback Switch",
2320                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2321                                                                  HDA_OUTPUT));
2322                        if (err < 0)
2323                                return err;
2324                } else if (i == AUTO_SEQ_FRONT) {
2325                        /* add control to mixer index 0 */
2326                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2327                                              "Master Front Playback Volume",
2328                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2329                                                                  HDA_INPUT));
2330                        if (err < 0)
2331                                return err;
2332                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2333                                              "Master Front Playback Switch",
2334                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2335                                                                  HDA_INPUT));
2336                        if (err < 0)
2337                                return err;
2338
2339                        /* add control to PW3 */
2340                        sprintf(name, "%s Playback Volume", chname[i]);
2341                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2342                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2343                                                                  HDA_OUTPUT));
2344                        if (err < 0)
2345                                return err;
2346                        sprintf(name, "%s Playback Switch", chname[i]);
2347                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2348                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2349                                                                  HDA_OUTPUT));
2350                        if (err < 0)
2351                                return err;
2352                } else {
2353                        sprintf(name, "%s Playback Volume", chname[i]);
2354                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2355                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2356                                                                  HDA_OUTPUT));
2357                        if (err < 0)
2358                                return err;
2359                        sprintf(name, "%s Playback Switch", chname[i]);
2360                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2361                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2362                                                                  HDA_OUTPUT));
2363                        if (err < 0)
2364                                return err;
2365                }
2366        }
2367
2368        return 0;
2369}
2370
2371static void create_hp_imux(struct via_spec *spec)
2372{
2373        int i;
2374        struct hda_input_mux *imux = &spec->private_imux[1];
2375        static const char * const texts[] = { "OFF", "ON", NULL};
2376
2377        /* for hp mode select */
2378        for (i = 0; texts[i]; i++)
2379                snd_hda_add_imux_item(imux, texts[i], i, NULL);
2380
2381        spec->hp_mux = &spec->private_imux[1];
2382}
2383
2384static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2385{
2386        int err;
2387
2388        if (!pin)
2389                return 0;
2390
2391        spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2392        spec->hp_independent_mode_index = 1;
2393
2394        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2395                              "Headphone Playback Volume",
2396                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2397        if (err < 0)
2398                return err;
2399        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2400                              "Headphone Playback Switch",
2401                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2402        if (err < 0)
2403                return err;
2404
2405        create_hp_imux(spec);
2406
2407        return 0;
2408}
2409
2410/* create playback/capture controls for input pins */
2411static int vt_auto_create_analog_input_ctls(struct hda_codec *codec,
2412                                            const struct auto_pin_cfg *cfg,
2413                                            hda_nid_t cap_nid,
2414                                            hda_nid_t pin_idxs[], int num_idxs)
2415{
2416        struct via_spec *spec = codec->spec;
2417        struct hda_input_mux *imux = &spec->private_imux[0];
2418        int i, err, idx, type, type_idx = 0;
2419
2420        /* for internal loopback recording select */
2421        for (idx = 0; idx < num_idxs; idx++) {
2422                if (pin_idxs[idx] == 0xff) {
2423                        snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
2424                        break;
2425                }
2426        }
2427
2428        for (i = 0; i < cfg->num_inputs; i++) {
2429                const char *label;
2430                type = cfg->inputs[i].type;
2431                for (idx = 0; idx < num_idxs; idx++)
2432                        if (pin_idxs[idx] == cfg->inputs[i].pin)
2433                                break;
2434                if (idx >= num_idxs)
2435                        continue;
2436                if (i > 0 && type == cfg->inputs[i - 1].type)
2437                        type_idx++;
2438                else
2439                        type_idx = 0;
2440                label = hda_get_autocfg_input_label(codec, cfg, i);
2441                err = via_new_analog_input(spec, label, type_idx, idx, cap_nid);
2442                if (err < 0)
2443                        return err;
2444                snd_hda_add_imux_item(imux, label, idx, NULL);
2445        }
2446        return 0;
2447}
2448
2449/* create playback/capture controls for input pins */
2450static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec,
2451                                                const struct auto_pin_cfg *cfg)
2452{
2453        static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2454        return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs,
2455                                                ARRAY_SIZE(pin_idxs));
2456}
2457
2458#ifdef CONFIG_SND_HDA_POWER_SAVE
2459static struct hda_amp_list vt1708_loopbacks[] = {
2460        { 0x17, HDA_INPUT, 1 },
2461        { 0x17, HDA_INPUT, 2 },
2462        { 0x17, HDA_INPUT, 3 },
2463        { 0x17, HDA_INPUT, 4 },
2464        { } /* end */
2465};
2466#endif
2467
2468static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2469{
2470        unsigned int def_conf;
2471        unsigned char seqassoc;
2472
2473        def_conf = snd_hda_codec_get_pincfg(codec, nid);
2474        seqassoc = (unsigned char) get_defcfg_association(def_conf);
2475        seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2476        if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2477            && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2478                def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2479                snd_hda_codec_set_pincfg(codec, nid, def_conf);
2480        }
2481
2482        return;
2483}
2484
2485static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2486                                     struct snd_ctl_elem_value *ucontrol)
2487{
2488        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2489        struct via_spec *spec = codec->spec;
2490
2491        if (spec->codec_type != VT1708)
2492                return 0;
2493        spec->vt1708_jack_detectect =
2494                !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2495        ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2496        return 0;
2497}
2498
2499static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2500                                     struct snd_ctl_elem_value *ucontrol)
2501{
2502        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2503        struct via_spec *spec = codec->spec;
2504        int change;
2505
2506        if (spec->codec_type != VT1708)
2507                return 0;
2508        spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2509        change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2510                == !spec->vt1708_jack_detectect;
2511        if (spec->vt1708_jack_detectect) {
2512                mute_aa_path(codec, 1);
2513                notify_aa_path_ctls(codec);
2514        }
2515        return change;
2516}
2517
2518static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2519        {
2520                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2521                .name = "Jack Detect",
2522                .count = 1,
2523                .info = snd_ctl_boolean_mono_info,
2524                .get = vt1708_jack_detectect_get,
2525                .put = vt1708_jack_detectect_put,
2526        },
2527        {} /* end */
2528};
2529
2530static int vt1708_parse_auto_config(struct hda_codec *codec)
2531{
2532        struct via_spec *spec = codec->spec;
2533        int err;
2534
2535        /* Add HP and CD pin config connect bit re-config action */
2536        vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2537        vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2538
2539        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2540        if (err < 0)
2541                return err;
2542        err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2543        if (err < 0)
2544                return err;
2545        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2546                return 0; /* can't find valid BIOS pin config */
2547
2548        err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2549        if (err < 0)
2550                return err;
2551        err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2552        if (err < 0)
2553                return err;
2554        err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg);
2555        if (err < 0)
2556                return err;
2557        /* add jack detect on/off control */
2558        err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2559        if (err < 0)
2560                return err;
2561
2562        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2563
2564        if (spec->autocfg.dig_outs)
2565                spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2566        spec->dig_in_pin = VT1708_DIGIN_PIN;
2567        if (spec->autocfg.dig_in_pin)
2568                spec->dig_in_nid = VT1708_DIGIN_NID;
2569
2570        if (spec->kctls.list)
2571                spec->mixers[spec->num_mixers++] = spec->kctls.list;
2572
2573        spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2574
2575        spec->input_mux = &spec->private_imux[0];
2576
2577        if (spec->hp_mux)
2578                via_hp_build(codec);
2579
2580        via_smart51_build(spec);
2581        return 1;
2582}
2583
2584/* init callback for auto-configuration model -- overriding the default init */
2585static int via_auto_init(struct hda_codec *codec)
2586{
2587        struct via_spec *spec = codec->spec;
2588
2589        via_init(codec);
2590        via_auto_init_multi_out(codec);
2591        via_auto_init_hp_out(codec);
2592        via_auto_init_analog_input(codec);
2593        if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2594                via_hp_bind_automute(codec);
2595        } else {
2596                via_hp_automute(codec);
2597                via_speaker_automute(codec);
2598        }
2599
2600        return 0;
2601}
2602
2603static void vt1708_update_hp_jack_state(struct work_struct *work)
2604{
2605        struct via_spec *spec = container_of(work, struct via_spec,
2606                                             vt1708_hp_work.work);
2607        if (spec->codec_type != VT1708)
2608                return;
2609        /* if jack state toggled */
2610        if (spec->vt1708_hp_present
2611            != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2612                spec->vt1708_hp_present ^= 1;
2613                via_hp_automute(spec->codec);
2614        }
2615        vt1708_start_hp_work(spec);
2616}
2617
2618static int get_mux_nids(struct hda_codec *codec)
2619{
2620        struct via_spec *spec = codec->spec;
2621        hda_nid_t nid, conn[8];
2622        unsigned int type;
2623        int i, n;
2624
2625        for (i = 0; i < spec->num_adc_nids; i++) {
2626                nid = spec->adc_nids[i];
2627                while (nid) {
2628                        type = get_wcaps_type(get_wcaps(codec, nid));
2629                        if (type == AC_WID_PIN)
2630                                break;
2631                        n = snd_hda_get_connections(codec, nid, conn,
2632                                                    ARRAY_SIZE(conn));
2633                        if (n <= 0)
2634                                break;
2635                        if (n > 1) {
2636                                spec->mux_nids[i] = nid;
2637                                break;
2638                        }
2639                        nid = conn[0];
2640                }
2641        }
2642        return 0;
2643}
2644
2645static int patch_vt1708(struct hda_codec *codec)
2646{
2647        struct via_spec *spec;
2648        int err;
2649
2650        /* create a codec specific record */
2651        spec = via_new_spec(codec);
2652        if (spec == NULL)
2653                return -ENOMEM;
2654
2655        /* automatic parse from the BIOS config */
2656        err = vt1708_parse_auto_config(codec);
2657        if (err < 0) {
2658                via_free(codec);
2659                return err;
2660        } else if (!err) {
2661                printk(KERN_INFO "hda_codec: Cannot set up configuration "
2662                       "from BIOS.  Using genenic mode...\n");
2663        }
2664
2665
2666        spec->stream_name_analog = "VT1708 Analog";
2667        spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2668        /* disable 32bit format on VT1708 */
2669        if (codec->vendor_id == 0x11061708)
2670                spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2671        spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2672
2673        spec->stream_name_digital = "VT1708 Digital";
2674        spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2675        spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2676
2677
2678        if (!spec->adc_nids && spec->input_mux) {
2679                spec->adc_nids = vt1708_adc_nids;
2680                spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2681                get_mux_nids(codec);
2682                spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2683                spec->num_mixers++;
2684        }
2685
2686        codec->patch_ops = via_patch_ops;
2687
2688        codec->patch_ops.init = via_auto_init;
2689#ifdef CONFIG_SND_HDA_POWER_SAVE
2690        spec->loopback.amplist = vt1708_loopbacks;
2691#endif
2692        INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2693        return 0;
2694}
2695
2696/* capture mixer elements */
2697static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2698        HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2699        HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2700        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2701        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2702        HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2703        HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2704        {
2705                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2706                /* The multiple "Capture Source" controls confuse alsamixer
2707                 * So call somewhat different..
2708                 */
2709                /* .name = "Capture Source", */
2710                .name = "Input Source",
2711                .count = 1,
2712                .info = via_mux_enum_info,
2713                .get = via_mux_enum_get,
2714                .put = via_mux_enum_put,
2715        },
2716        { } /* end */
2717};
2718
2719static struct hda_verb vt1709_uniwill_init_verbs[] = {
2720        {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2721         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2722        { }
2723};
2724
2725/*
2726 * generic initialization of ADC, input mixers and output mixers
2727 */
2728static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2729        /*
2730         * Unmute ADC0-2 and set the default input to mic-in
2731         */
2732        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2733        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2734        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2735
2736
2737        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2738         * mixer widget
2739         */
2740        /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2741        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2742        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2743        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2744        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2745        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2746
2747        /*
2748         * Set up output selector (0x1a, 0x1b, 0x29)
2749         */
2750        /* set vol=0 to output mixers */
2751        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2752        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2753        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2754
2755        /*
2756         *  Unmute PW3 and PW4
2757         */
2758        {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2759        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2760
2761        /* Set input of PW4 as MW0 */
2762        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2763        /* PW9 Output enable */
2764        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2765        { }
2766};
2767
2768static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2769        .substreams = 1,
2770        .channels_min = 2,
2771        .channels_max = 10,
2772        .nid = 0x10, /* NID to query formats and rates */
2773        .ops = {
2774                .open = via_playback_pcm_open,
2775                .prepare = via_playback_multi_pcm_prepare,
2776                .cleanup = via_playback_multi_pcm_cleanup,
2777        },
2778};
2779
2780static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2781        .substreams = 1,
2782        .channels_min = 2,
2783        .channels_max = 6,
2784        .nid = 0x10, /* NID to query formats and rates */
2785        .ops = {
2786                .open = via_playback_pcm_open,
2787                .prepare = via_playback_multi_pcm_prepare,
2788                .cleanup = via_playback_multi_pcm_cleanup,
2789        },
2790};
2791
2792static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2793        .substreams = 2,
2794        .channels_min = 2,
2795        .channels_max = 2,
2796        .nid = 0x14, /* NID to query formats and rates */
2797        .ops = {
2798                .prepare = via_capture_pcm_prepare,
2799                .cleanup = via_capture_pcm_cleanup
2800        },
2801};
2802
2803static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2804        .substreams = 1,
2805        .channels_min = 2,
2806        .channels_max = 2,
2807        /* NID is set in via_build_pcms */
2808        .ops = {
2809                .open = via_dig_playback_pcm_open,
2810                .close = via_dig_playback_pcm_close
2811        },
2812};
2813
2814static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2815        .substreams = 1,
2816        .channels_min = 2,
2817        .channels_max = 2,
2818};
2819
2820static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2821                                     const struct auto_pin_cfg *cfg)
2822{
2823        int i;
2824        hda_nid_t nid;
2825
2826        if (cfg->line_outs == 4)  /* 10 channels */
2827                spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2828        else if (cfg->line_outs == 3) /* 6 channels */
2829                spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2830
2831        spec->multiout.dac_nids = spec->private_dac_nids;
2832
2833        if (cfg->line_outs == 4) { /* 10 channels */
2834                for (i = 0; i < cfg->line_outs; i++) {
2835                        nid = cfg->line_out_pins[i];
2836                        if (nid) {
2837                                /* config dac list */
2838                                switch (i) {
2839                                case AUTO_SEQ_FRONT:
2840                                        /* AOW0 */
2841                                        spec->multiout.dac_nids[i] = 0x10;
2842                                        break;
2843                                case AUTO_SEQ_CENLFE:
2844                                        /* AOW2 */
2845                                        spec->multiout.dac_nids[i] = 0x12;
2846                                        break;
2847                                case AUTO_SEQ_SURROUND:
2848                                        /* AOW3 */
2849                                        spec->multiout.dac_nids[i] = 0x11;
2850                                        break;
2851                                case AUTO_SEQ_SIDE:
2852                                        /* AOW1 */
2853                                        spec->multiout.dac_nids[i] = 0x27;
2854                                        break;
2855                                default:
2856                                        break;
2857                                }
2858                        }
2859                }
2860                spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2861
2862        } else if (cfg->line_outs == 3) { /* 6 channels */
2863                for (i = 0; i < cfg->line_outs; i++) {
2864                        nid = cfg->line_out_pins[i];
2865                        if (nid) {
2866                                /* config dac list */
2867                                switch (i) {
2868                                case AUTO_SEQ_FRONT:
2869                                        /* AOW0 */
2870                                        spec->multiout.dac_nids[i] = 0x10;
2871                                        break;
2872                                case AUTO_SEQ_CENLFE:
2873                                        /* AOW2 */
2874                                        spec->multiout.dac_nids[i] = 0x12;
2875                                        break;
2876                                case AUTO_SEQ_SURROUND:
2877                                        /* AOW1 */
2878                                        spec->multiout.dac_nids[i] = 0x11;
2879                                        break;
2880                                default:
2881                                        break;
2882                                }
2883                        }
2884                }
2885        }
2886
2887        return 0;
2888}
2889
2890/* add playback controls from the parsed DAC table */
2891static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2892                                             const struct auto_pin_cfg *cfg)
2893{
2894        char name[32];
2895        static const char * const chname[4] = {
2896                "Front", "Surround", "C/LFE", "Side"
2897        };
2898        hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2899        int i, err;
2900
2901        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2902                nid = cfg->line_out_pins[i];
2903
2904                if (!nid)
2905                        continue;
2906
2907                nid_vol = nid_vols[i];
2908
2909                if (i == AUTO_SEQ_CENLFE) {
2910                        /* Center/LFE */
2911                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2912                                              "Center Playback Volume",
2913                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2914                                                                  HDA_OUTPUT));
2915                        if (err < 0)
2916                                return err;
2917                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2918                                              "LFE Playback Volume",
2919                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2920                                                                  HDA_OUTPUT));
2921                        if (err < 0)
2922                                return err;
2923                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2924                                              "Center Playback Switch",
2925                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2926                                                                  HDA_OUTPUT));
2927                        if (err < 0)
2928                                return err;
2929                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2930                                              "LFE Playback Switch",
2931                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2932                                                                  HDA_OUTPUT));
2933                        if (err < 0)
2934                                return err;
2935                } else if (i == AUTO_SEQ_FRONT) {
2936                        /* ADD control to mixer index 0 */
2937                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2938                                              "Master Front Playback Volume",
2939                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2940                                                                  HDA_INPUT));
2941                        if (err < 0)
2942                                return err;
2943                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2944                                              "Master Front Playback Switch",
2945                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2946                                                                  HDA_INPUT));
2947                        if (err < 0)
2948                                return err;
2949
2950                        /* add control to PW3 */
2951                        sprintf(name, "%s Playback Volume", chname[i]);
2952                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2953                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2954                                                                  HDA_OUTPUT));
2955                        if (err < 0)
2956                                return err;
2957                        sprintf(name, "%s Playback Switch", chname[i]);
2958                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2959                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2960                                                                  HDA_OUTPUT));
2961                        if (err < 0)
2962                                return err;
2963                } else if (i == AUTO_SEQ_SURROUND) {
2964                        sprintf(name, "%s Playback Volume", chname[i]);
2965                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2966                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2967                                                                  HDA_OUTPUT));
2968                        if (err < 0)
2969                                return err;
2970                        sprintf(name, "%s Playback Switch", chname[i]);
2971                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2972                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2973                                                                  HDA_OUTPUT));
2974                        if (err < 0)
2975                                return err;
2976                } else if (i == AUTO_SEQ_SIDE) {
2977                        sprintf(name, "%s Playback Volume", chname[i]);
2978                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2979                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2980                                                                  HDA_OUTPUT));
2981                        if (err < 0)
2982                                return err;
2983                        sprintf(name, "%s Playback Switch", chname[i]);
2984                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2985                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2986                                                                  HDA_OUTPUT));
2987                        if (err < 0)
2988                                return err;
2989                }
2990        }
2991
2992        return 0;
2993}
2994
2995static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2996{
2997        int err;
2998
2999        if (!pin)
3000                return 0;
3001
3002        if (spec->multiout.num_dacs == 5) /* 10 channels */
3003                spec->multiout.hp_nid = VT1709_HP_DAC_NID;
3004        else if (spec->multiout.num_dacs == 3) /* 6 channels */
3005                spec->multiout.hp_nid = 0;
3006        spec->hp_independent_mode_index = 1;
3007
3008        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3009                              "Headphone Playback Volume",
3010                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3011        if (err < 0)
3012                return err;
3013        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3014                              "Headphone Playback Switch",
3015                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3016        if (err < 0)
3017                return err;
3018
3019        return 0;
3020}
3021
3022/* create playback/capture controls for input pins */
3023static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
3024                                                const struct auto_pin_cfg *cfg)
3025{
3026        static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3027        return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
3028                                                ARRAY_SIZE(pin_idxs));
3029}
3030
3031static int vt1709_parse_auto_config(struct hda_codec *codec)
3032{
3033        struct via_spec *spec = codec->spec;
3034        int err;
3035
3036        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3037        if (err < 0)
3038                return err;
3039        err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
3040        if (err < 0)
3041                return err;
3042        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3043                return 0; /* can't find valid BIOS pin config */
3044
3045        err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
3046        if (err < 0)
3047                return err;
3048        err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3049        if (err < 0)
3050                return err;
3051        err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
3052        if (err < 0)
3053                return err;
3054
3055        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3056
3057        if (spec->autocfg.dig_outs)
3058                spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3059        spec->dig_in_pin = VT1709_DIGIN_PIN;
3060        if (spec->autocfg.dig_in_pin)
3061                spec->dig_in_nid = VT1709_DIGIN_NID;
3062
3063        if (spec->kctls.list)
3064                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3065
3066        spec->input_mux = &spec->private_imux[0];
3067
3068        if (spec->hp_mux)
3069                via_hp_build(codec);
3070
3071        via_smart51_build(spec);
3072        return 1;
3073}
3074
3075#ifdef CONFIG_SND_HDA_POWER_SAVE
3076static struct hda_amp_list vt1709_loopbacks[] = {
3077        { 0x18, HDA_INPUT, 1 },
3078        { 0x18, HDA_INPUT, 2 },
3079        { 0x18, HDA_INPUT, 3 },
3080        { 0x18, HDA_INPUT, 4 },
3081        { } /* end */
3082};
3083#endif
3084
3085static int patch_vt1709_10ch(struct hda_codec *codec)
3086{
3087        struct via_spec *spec;
3088        int err;
3089
3090        /* create a codec specific record */
3091        spec = via_new_spec(codec);
3092        if (spec == NULL)
3093                return -ENOMEM;
3094
3095        err = vt1709_parse_auto_config(codec);
3096        if (err < 0) {
3097                via_free(codec);
3098                return err;
3099        } else if (!err) {
3100                printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3101                       "Using genenic mode...\n");
3102        }
3103
3104        spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3105        spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3106
3107        spec->stream_name_analog = "VT1709 Analog";
3108        spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3109        spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3110
3111        spec->stream_name_digital = "VT1709 Digital";
3112        spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3113        spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3114
3115
3116        if (!spec->adc_nids && spec->input_mux) {
3117                spec->adc_nids = vt1709_adc_nids;
3118                spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3119                get_mux_nids(codec);
3120                spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3121                spec->num_mixers++;
3122        }
3123
3124        codec->patch_ops = via_patch_ops;
3125
3126        codec->patch_ops.init = via_auto_init;
3127        codec->patch_ops.unsol_event = via_unsol_event;
3128#ifdef CONFIG_SND_HDA_POWER_SAVE
3129        spec->loopback.amplist = vt1709_loopbacks;
3130#endif
3131
3132        return 0;
3133}
3134/*
3135 * generic initialization of ADC, input mixers and output mixers
3136 */
3137static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3138        /*
3139         * Unmute ADC0-2 and set the default input to mic-in
3140         */
3141        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3142        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3143        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3144
3145
3146        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3147         * mixer widget
3148         */
3149        /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3150        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3151        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3152        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3153        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3154        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3155
3156        /*
3157         * Set up output selector (0x1a, 0x1b, 0x29)
3158         */
3159        /* set vol=0 to output mixers */
3160        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3161        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3162        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3163
3164        /*
3165         *  Unmute PW3 and PW4
3166         */
3167        {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3168        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3169
3170        /* Set input of PW4 as MW0 */
3171        {0x20, AC_VERB_SET_CONNECT_SEL, 0},
3172        /* PW9 Output enable */
3173        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3174        { }
3175};
3176
3177static int patch_vt1709_6ch(struct hda_codec *codec)
3178{
3179        struct via_spec *spec;
3180        int err;
3181
3182        /* create a codec specific record */
3183        spec = via_new_spec(codec);
3184        if (spec == NULL)
3185                return -ENOMEM;
3186
3187        err = vt1709_parse_auto_config(codec);
3188        if (err < 0) {
3189                via_free(codec);
3190                return err;
3191        } else if (!err) {
3192                printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3193                       "Using genenic mode...\n");
3194        }
3195
3196        spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3197        spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3198
3199        spec->stream_name_analog = "VT1709 Analog";
3200        spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3201        spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3202
3203        spec->stream_name_digital = "VT1709 Digital";
3204        spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3205        spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3206
3207
3208        if (!spec->adc_nids && spec->input_mux) {
3209                spec->adc_nids = vt1709_adc_nids;
3210                spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3211                get_mux_nids(codec);
3212                spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3213                spec->num_mixers++;
3214        }
3215
3216        codec->patch_ops = via_patch_ops;
3217
3218        codec->patch_ops.init = via_auto_init;
3219        codec->patch_ops.unsol_event = via_unsol_event;
3220#ifdef CONFIG_SND_HDA_POWER_SAVE
3221        spec->loopback.amplist = vt1709_loopbacks;
3222#endif
3223        return 0;
3224}
3225
3226/* capture mixer elements */
3227static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3228        HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3229        HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3230        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3231        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3232        {
3233                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3234                /* The multiple "Capture Source" controls confuse alsamixer
3235                 * So call somewhat different..
3236                 */
3237                /* .name = "Capture Source", */
3238                .name = "Input Source",
3239                .count = 1,
3240                .info = via_mux_enum_info,
3241                .get = via_mux_enum_get,
3242                .put = via_mux_enum_put,
3243        },
3244        { } /* end */
3245};
3246/*
3247 * generic initialization of ADC, input mixers and output mixers
3248 */
3249static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3250        /*
3251         * Unmute ADC0-1 and set the default input to mic-in
3252         */
3253        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3254        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3255
3256
3257        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3258         * mixer widget
3259         */
3260        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3261        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3262        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3263        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3264        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3265        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3266
3267        /*
3268         * Set up output mixers
3269         */
3270        /* set vol=0 to output mixers */
3271        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3272        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3273        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3274
3275        /* Setup default input to PW4 */
3276        {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3277        /* PW9 Output enable */
3278        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3279        /* PW10 Input enable */
3280        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3281        { }
3282};
3283
3284static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3285        /*
3286         * Unmute ADC0-1 and set the default input to mic-in
3287         */
3288        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3289        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3290
3291
3292        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3293         * mixer widget
3294         */
3295        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3296        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3297        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3298        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3299        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3300        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3301
3302        /*
3303         * Set up output mixers
3304         */
3305        /* set vol=0 to output mixers */
3306        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3307        {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3308        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3309
3310        /* Setup default input of PW4 to MW0 */
3311        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3312        /* PW9 Output enable */
3313        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3314        /* PW10 Input enable */
3315        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3316        { }
3317};
3318
3319static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3320        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3321         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3322        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3323        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3324        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3325        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3326        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3327        {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3328        {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3329        { }
3330};
3331
3332static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3333                              struct hda_codec *codec,
3334                              struct snd_pcm_substream *substream)
3335{
3336        int idle = substream->pstr->substream_opened == 1
3337                && substream->ref_count == 0;
3338
3339        analog_low_current_mode(codec, idle);
3340        return 0;
3341}
3342
3343static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3344        .substreams = 2,
3345        .channels_min = 2,
3346        .channels_max = 8,
3347        .nid = 0x10, /* NID to query formats and rates */
3348        .ops = {
3349                .open = via_playback_pcm_open,
3350                .prepare = via_playback_multi_pcm_prepare,
3351                .cleanup = via_playback_multi_pcm_cleanup,
3352                .close = via_pcm_open_close
3353        },
3354};
3355
3356static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3357        .substreams = 2,
3358        .channels_min = 2,
3359        .channels_max = 4,
3360        .nid = 0x10, /* NID to query formats and rates */
3361        .ops = {
3362                .open = via_playback_pcm_open,
3363                .prepare = via_playback_multi_pcm_prepare,
3364                .cleanup = via_playback_multi_pcm_cleanup
3365        },
3366};
3367
3368static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3369        .substreams = 2,
3370        .channels_min = 2,
3371        .channels_max = 2,
3372        .nid = 0x13, /* NID to query formats and rates */
3373        .ops = {
3374                .open = via_pcm_open_close,
3375                .prepare = via_capture_pcm_prepare,
3376                .cleanup = via_capture_pcm_cleanup,
3377                .close = via_pcm_open_close
3378        },
3379};
3380
3381static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3382        .substreams = 1,
3383        .channels_min = 2,
3384        .channels_max = 2,
3385        /* NID is set in via_build_pcms */
3386        .ops = {
3387                .open = via_dig_playback_pcm_open,
3388                .close = via_dig_playback_pcm_close,
3389                .prepare = via_dig_playback_pcm_prepare,
3390                .cleanup = via_dig_playback_pcm_cleanup
3391        },
3392};
3393
3394static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3395        .substreams = 1,
3396        .channels_min = 2,
3397        .channels_max = 2,
3398};
3399
3400/* fill in the dac_nids table from the parsed pin configuration */
3401static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3402                                     const struct auto_pin_cfg *cfg)
3403{
3404        int i;
3405        hda_nid_t nid;
3406
3407        spec->multiout.num_dacs = cfg->line_outs;
3408
3409        spec->multiout.dac_nids = spec->private_dac_nids;
3410
3411        for (i = 0; i < 4; i++) {
3412                nid = cfg->line_out_pins[i];
3413                if (nid) {
3414                        /* config dac list */
3415                        switch (i) {
3416                        case AUTO_SEQ_FRONT:
3417                                spec->multiout.dac_nids[i] = 0x10;
3418                                break;
3419                        case AUTO_SEQ_CENLFE:
3420                                spec->multiout.dac_nids[i] = 0x24;
3421                                break;
3422                        case AUTO_SEQ_SURROUND:
3423                                spec->multiout.dac_nids[i] = 0x11;
3424                                break;
3425                        case AUTO_SEQ_SIDE:
3426                                spec->multiout.dac_nids[i] = 0x25;
3427                                break;
3428                        }
3429                }
3430        }
3431
3432        return 0;
3433}
3434
3435/* add playback controls from the parsed DAC table */
3436static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3437                                             const struct auto_pin_cfg *cfg)
3438{
3439        char name[32];
3440        static const char * const chname[4] = {
3441                "Front", "Surround", "C/LFE", "Side"
3442        };
3443        hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3444        hda_nid_t nid, nid_vol = 0;
3445        int i, err;
3446
3447        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3448                nid = cfg->line_out_pins[i];
3449
3450                if (!nid)
3451                        continue;
3452
3453                nid_vol = nid_vols[i];
3454
3455                if (i == AUTO_SEQ_CENLFE) {
3456                        /* Center/LFE */
3457                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3458                                              "Center Playback Volume",
3459                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3460                                                                  HDA_OUTPUT));
3461                        if (err < 0)
3462                                return err;
3463                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3464                                              "LFE Playback Volume",
3465                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3466                                                                  HDA_OUTPUT));
3467                        if (err < 0)
3468                                return err;
3469                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3470                                              "Center Playback Switch",
3471                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3472                                                                  HDA_OUTPUT));
3473                        if (err < 0)
3474                                return err;
3475                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3476                                              "LFE Playback Switch",
3477                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3478                                                                  HDA_OUTPUT));
3479                        if (err < 0)
3480                                return err;
3481                } else if (i == AUTO_SEQ_FRONT) {
3482                        /* add control to mixer index 0 */
3483                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3484                                              "Master Front Playback Volume",
3485                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3486                                                                  HDA_INPUT));
3487                        if (err < 0)
3488                                return err;
3489                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3490                                              "Master Front Playback Switch",
3491                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3492                                                                  HDA_INPUT));
3493                        if (err < 0)
3494                                return err;
3495
3496                        /* add control to PW3 */
3497                        sprintf(name, "%s Playback Volume", chname[i]);
3498                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3499                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3500                                                                  HDA_OUTPUT));
3501                        if (err < 0)
3502                                return err;
3503                        sprintf(name, "%s Playback Switch", chname[i]);
3504                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3505                                              HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3506                                                                  HDA_OUTPUT));
3507                        if (err < 0)
3508                                return err;
3509                } else {
3510                        sprintf(name, "%s Playback Volume", chname[i]);
3511                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3512                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3513                                                                  HDA_OUTPUT));
3514                        if (err < 0)
3515                                return err;
3516                        sprintf(name, "%s Playback Switch", chname[i]);
3517                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3518                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3519                                                                  HDA_OUTPUT));
3520                        if (err < 0)
3521                                return err;
3522                }
3523        }
3524
3525        return 0;
3526}
3527
3528static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3529{
3530        int err;
3531
3532        if (!pin)
3533                return 0;
3534
3535        spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3536        spec->hp_independent_mode_index = 1;
3537
3538        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3539                              "Headphone Playback Volume",
3540                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3541        if (err < 0)
3542                return err;
3543        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3544                              "Headphone Playback Switch",
3545                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3546        if (err < 0)
3547                return err;
3548
3549        create_hp_imux(spec);
3550
3551        return 0;
3552}
3553
3554/* create playback/capture controls for input pins */
3555static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3556                                                const struct auto_pin_cfg *cfg)
3557{
3558        static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3559        return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3560                                                ARRAY_SIZE(pin_idxs));
3561}
3562
3563static int vt1708B_parse_auto_config(struct hda_codec *codec)
3564{
3565        struct via_spec *spec = codec->spec;
3566        int err;
3567
3568        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3569        if (err < 0)
3570                return err;
3571        err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3572        if (err < 0)
3573                return err;
3574        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3575                return 0; /* can't find valid BIOS pin config */
3576
3577        err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3578        if (err < 0)
3579                return err;
3580        err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3581        if (err < 0)
3582                return err;
3583        err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3584        if (err < 0)
3585                return err;
3586
3587        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3588
3589        if (spec->autocfg.dig_outs)
3590                spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3591        spec->dig_in_pin = VT1708B_DIGIN_PIN;
3592        if (spec->autocfg.dig_in_pin)
3593                spec->dig_in_nid = VT1708B_DIGIN_NID;
3594
3595        if (spec->kctls.list)
3596                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3597
3598        spec->input_mux = &spec->private_imux[0];
3599
3600        if (spec->hp_mux)
3601                via_hp_build(codec);
3602
3603        via_smart51_build(spec);
3604        return 1;
3605}
3606
3607#ifdef CONFIG_SND_HDA_POWER_SAVE
3608static struct hda_amp_list vt1708B_loopbacks[] = {
3609        { 0x16, HDA_INPUT, 1 },
3610        { 0x16, HDA_INPUT, 2 },
3611        { 0x16, HDA_INPUT, 3 },
3612        { 0x16, HDA_INPUT, 4 },
3613        { } /* end */
3614};
3615#endif
3616static int patch_vt1708S(struct hda_codec *codec);
3617static int patch_vt1708B_8ch(struct hda_codec *codec)
3618{
3619        struct via_spec *spec;
3620        int err;
3621
3622        if (get_codec_type(codec) == VT1708BCE)
3623                return patch_vt1708S(codec);
3624        /* create a codec specific record */
3625        spec = via_new_spec(codec);
3626        if (spec == NULL)
3627                return -ENOMEM;
3628
3629        /* automatic parse from the BIOS config */
3630        err = vt1708B_parse_auto_config(codec);
3631        if (err < 0) {
3632                via_free(codec);
3633                return err;
3634        } else if (!err) {
3635                printk(KERN_INFO "hda_codec: Cannot set up configuration "
3636                       "from BIOS.  Using genenic mode...\n");
3637        }
3638
3639        spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3640        spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3641
3642        spec->stream_name_analog = "VT1708B Analog";
3643        spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3644        spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3645
3646        spec->stream_name_digital = "VT1708B Digital";
3647        spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3648        spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3649
3650        if (!spec->adc_nids && spec->input_mux) {
3651                spec->adc_nids = vt1708B_adc_nids;
3652                spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3653                get_mux_nids(codec);
3654                spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3655                spec->num_mixers++;
3656        }
3657
3658        codec->patch_ops = via_patch_ops;
3659
3660        codec->patch_ops.init = via_auto_init;
3661        codec->patch_ops.unsol_event = via_unsol_event;
3662#ifdef CONFIG_SND_HDA_POWER_SAVE
3663        spec->loopback.amplist = vt1708B_loopbacks;
3664#endif
3665
3666        return 0;
3667}
3668
3669static int patch_vt1708B_4ch(struct hda_codec *codec)
3670{
3671        struct via_spec *spec;
3672        int err;
3673
3674        /* create a codec specific record */
3675        spec = via_new_spec(codec);
3676        if (spec == NULL)
3677                return -ENOMEM;
3678
3679        /* automatic parse from the BIOS config */
3680        err = vt1708B_parse_auto_config(codec);
3681        if (err < 0) {
3682                via_free(codec);
3683                return err;
3684        } else if (!err) {
3685                printk(KERN_INFO "hda_codec: Cannot set up configuration "
3686                       "from BIOS.  Using genenic mode...\n");
3687        }
3688
3689        spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3690        spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3691
3692        spec->stream_name_analog = "VT1708B Analog";
3693        spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3694        spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3695
3696        spec->stream_name_digital = "VT1708B Digital";
3697        spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3698        spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3699
3700        if (!spec->adc_nids && spec->input_mux) {
3701                spec->adc_nids = vt1708B_adc_nids;
3702                spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3703                get_mux_nids(codec);
3704                spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3705                spec->num_mixers++;
3706        }
3707
3708        codec->patch_ops = via_patch_ops;
3709
3710        codec->patch_ops.init = via_auto_init;
3711        codec->patch_ops.unsol_event = via_unsol_event;
3712#ifdef CONFIG_SND_HDA_POWER_SAVE
3713        spec->loopback.amplist = vt1708B_loopbacks;
3714#endif
3715
3716        return 0;
3717}
3718
3719/* Patch for VT1708S */
3720
3721/* capture mixer elements */
3722static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3723        HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3724        HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3725        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3726        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3727        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3728        HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3729                         HDA_INPUT),
3730        {
3731                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3732                /* The multiple "Capture Source" controls confuse alsamixer
3733                 * So call somewhat different..
3734                 */
3735                /* .name = "Capture Source", */
3736                .name = "Input Source",
3737                .count = 1,
3738                .info = via_mux_enum_info,
3739                .get = via_mux_enum_get,
3740                .put = via_mux_enum_put,
3741        },
3742        { } /* end */
3743};
3744
3745static struct hda_verb vt1708S_volume_init_verbs[] = {
3746        /* Unmute ADC0-1 and set the default input to mic-in */
3747        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3748        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3749
3750        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3751         * analog-loopback mixer widget */
3752        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3753        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3754        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3755        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3756        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3757        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3758
3759        /* Setup default input of PW4 to MW0 */
3760        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3761        /* PW9, PW10  Output enable */
3762        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3763        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3764        /* Enable Mic Boost Volume backdoor */
3765        {0x1, 0xf98, 0x1},
3766        /* don't bybass mixer */
3767        {0x1, 0xf88, 0xc0},
3768        { }
3769};
3770
3771static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3772        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3773         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3774        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3775        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3776        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3777        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3778        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3779        {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3780        {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3781        { }
3782};
3783
3784static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3785        .substreams = 2,
3786        .channels_min = 2,
3787        .channels_max = 8,
3788        .nid = 0x10, /* NID to query formats and rates */
3789        .ops = {
3790                .open = via_playback_pcm_open,
3791                .prepare = via_playback_multi_pcm_prepare,
3792                .cleanup = via_playback_multi_pcm_cleanup,
3793                .close = via_pcm_open_close
3794        },
3795};
3796
3797static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3798        .substreams = 2,
3799        .channels_min = 2,
3800        .channels_max = 2,
3801        .nid = 0x13, /* NID to query formats and rates */
3802        .ops = {
3803                .open = via_pcm_open_close,
3804                .prepare = via_capture_pcm_prepare,
3805                .cleanup = via_capture_pcm_cleanup,
3806                .close = via_pcm_open_close
3807        },
3808};
3809
3810static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3811        .substreams = 1,
3812        .channels_min = 2,
3813        .channels_max = 2,
3814        /* NID is set in via_build_pcms */
3815        .ops = {
3816                .open = via_dig_playback_pcm_open,
3817                .close = via_dig_playback_pcm_close,
3818                .prepare = via_dig_playback_pcm_prepare,
3819                .cleanup = via_dig_playback_pcm_cleanup
3820        },
3821};
3822
3823/* fill in the dac_nids table from the parsed pin configuration */
3824static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3825                                     const struct auto_pin_cfg *cfg)
3826{
3827        int i;
3828        hda_nid_t nid;
3829
3830        spec->multiout.num_dacs = cfg->line_outs;
3831
3832        spec->multiout.dac_nids = spec->private_dac_nids;
3833
3834        for (i = 0; i < 4; i++) {
3835                nid = cfg->line_out_pins[i];
3836                if (nid) {
3837                        /* config dac list */
3838                        switch (i) {
3839                        case AUTO_SEQ_FRONT:
3840                                spec->multiout.dac_nids[i] = 0x10;
3841                                break;
3842                        case AUTO_SEQ_CENLFE:
3843                                spec->multiout.dac_nids[i] = 0x24;
3844                                break;
3845                        case AUTO_SEQ_SURROUND:
3846                                spec->multiout.dac_nids[i] = 0x11;
3847                                break;
3848                        case AUTO_SEQ_SIDE:
3849                                spec->multiout.dac_nids[i] = 0x25;
3850                                break;
3851                        }
3852                }
3853        }
3854
3855        /* for Smart 5.1, line/mic inputs double as output pins */
3856        if (cfg->line_outs == 1) {
3857                spec->multiout.num_dacs = 3;
3858                spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3859                spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3860        }
3861
3862        return 0;
3863}
3864
3865/* add playback controls from the parsed DAC table */
3866static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3867                                             const struct auto_pin_cfg *cfg)
3868{
3869        char name[32];
3870        static const char * const chname[4] = {
3871                "Front", "Surround", "C/LFE", "Side"
3872        };
3873        hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3874        hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3875        hda_nid_t nid, nid_vol, nid_mute;
3876        int i, err;
3877
3878        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3879                nid = cfg->line_out_pins[i];
3880
3881                /* for Smart 5.1, there are always at least six channels */
3882                if (!nid && i > AUTO_SEQ_CENLFE)
3883                        continue;
3884
3885                nid_vol = nid_vols[i];
3886                nid_mute = nid_mutes[i];
3887
3888                if (i == AUTO_SEQ_CENLFE) {
3889                        /* Center/LFE */
3890                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3891                                              "Center Playback Volume",
3892                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3893                                                                  HDA_OUTPUT));
3894                        if (err < 0)
3895                                return err;
3896                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3897                                              "LFE Playback Volume",
3898                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3899                                                                  HDA_OUTPUT));
3900                        if (err < 0)
3901                                return err;
3902                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3903                                              "Center Playback Switch",
3904                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3905                                                                  1, 0,
3906                                                                  HDA_OUTPUT));
3907                        if (err < 0)
3908                                return err;
3909                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3910                                              "LFE Playback Switch",
3911                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3912                                                                  2, 0,
3913                                                                  HDA_OUTPUT));
3914                        if (err < 0)
3915                                return err;
3916                } else if (i == AUTO_SEQ_FRONT) {
3917                        /* add control to mixer index 0 */
3918                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3919                                              "Master Front Playback Volume",
3920                                              HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3921                                                                  HDA_INPUT));
3922                        if (err < 0)
3923                                return err;
3924                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3925                                              "Master Front Playback Switch",
3926                                              HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3927                                                                  HDA_INPUT));
3928                        if (err < 0)
3929                                return err;
3930
3931                        /* Front */
3932                        sprintf(name, "%s Playback Volume", chname[i]);
3933                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3934                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3935                                                                  HDA_OUTPUT));
3936                        if (err < 0)
3937                                return err;
3938                        sprintf(name, "%s Playback Switch", chname[i]);
3939                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3940                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3941                                                                  3, 0,
3942                                                                  HDA_OUTPUT));
3943                        if (err < 0)
3944                                return err;
3945                } else {
3946                        sprintf(name, "%s Playback Volume", chname[i]);
3947                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3948                                              HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3949                                                                  HDA_OUTPUT));
3950                        if (err < 0)
3951                                return err;
3952                        sprintf(name, "%s Playback Switch", chname[i]);
3953                        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3954                                              HDA_COMPOSE_AMP_VAL(nid_mute,
3955                                                                  3, 0,
3956                                                                  HDA_OUTPUT));
3957                        if (err < 0)
3958                                return err;
3959                }
3960        }
3961
3962        return 0;
3963}
3964
3965static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3966{
3967        int err;
3968
3969        if (!pin)
3970                return 0;
3971
3972        spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3973        spec->hp_independent_mode_index = 1;
3974
3975        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3976                              "Headphone Playback Volume",
3977                              HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
3978        if (err < 0)
3979                return err;
3980
3981        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3982                              "Headphone Playback Switch",
3983                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3984        if (err < 0)
3985                return err;
3986
3987        create_hp_imux(spec);
3988
3989        return 0;
3990}
3991
3992/* create playback/capture controls for input pins */
3993static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
3994                                                const struct auto_pin_cfg *cfg)
3995{
3996        static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
3997        return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3998                                                ARRAY_SIZE(pin_idxs));
3999}
4000
4001/* fill out digital output widgets; one for master and one for slave outputs */
4002static void fill_dig_outs(struct hda_codec *codec)
4003{
4004        struct via_spec *spec = codec->spec;
4005        int i;
4006
4007        for (i = 0; i < spec->autocfg.dig_outs; i++) {
4008                hda_nid_t nid;
4009                int conn;
4010
4011                nid = spec->autocfg.dig_out_pins[i];
4012                if (!nid)
4013                        continue;
4014                conn = snd_hda_get_connections(codec, nid, &nid, 1);
4015                if (conn < 1)
4016                        continue;
4017                if (!spec->multiout.dig_out_nid)
4018                        spec->multiout.dig_out_nid = nid;
4019                else {
4020                        spec->slave_dig_outs[0] = nid;
4021                        break; /* at most two dig outs */
4022                }
4023        }
4024}
4025
4026static int vt1708S_parse_auto_config(struct hda_codec *codec)
4027{
4028        struct via_spec *spec = codec->spec;
4029        int err;
4030
4031        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4032        if (err < 0)
4033                return err;
4034        err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
4035        if (err < 0)
4036                return err;
4037        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4038                return 0; /* can't find valid BIOS pin config */
4039
4040        err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4041        if (err < 0)
4042                return err;
4043        err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4044        if (err < 0)
4045                return err;
4046        err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4047        if (err < 0)
4048                return err;
4049
4050        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4051
4052        fill_dig_outs(codec);
4053
4054        if (spec->kctls.list)
4055                spec->mixers[spec->num_mixers++] = spec->kctls.list;
4056
4057        spec->input_mux = &spec->private_imux[0];
4058
4059        if (spec->hp_mux)
4060                via_hp_build(codec);
4061
4062        via_smart51_build(spec);
4063        return 1;
4064}
4065
4066#ifdef CONFIG_SND_HDA_POWER_SAVE
4067static struct hda_amp_list vt1708S_loopbacks[] = {
4068        { 0x16, HDA_INPUT, 1 },
4069        { 0x16, HDA_INPUT, 2 },
4070        { 0x16, HDA_INPUT, 3 },
4071        { 0x16, HDA_INPUT, 4 },
4072        { } /* end */
4073};
4074#endif
4075
4076static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4077                               int offset, int num_steps, int step_size)
4078{
4079        snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4080                                  (offset << AC_AMPCAP_OFFSET_SHIFT) |
4081                                  (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4082                                  (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4083                                  (0 << AC_AMPCAP_MUTE_SHIFT));
4084}
4085
4086static int patch_vt1708S(struct hda_codec *codec)
4087{
4088        struct via_spec *spec;
4089        int err;
4090
4091        /* create a codec specific record */
4092        spec = via_new_spec(codec);
4093        if (spec == NULL)
4094                return -ENOMEM;
4095
4096        /* automatic parse from the BIOS config */
4097        err = vt1708S_parse_auto_config(codec);
4098        if (err < 0) {
4099                via_free(codec);
4100                return err;
4101        } else if (!err) {
4102                printk(KERN_INFO "hda_codec: Cannot set up configuration "
4103                       "from BIOS.  Using genenic mode...\n");
4104        }
4105
4106        spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4107        spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
4108
4109        if (codec->vendor_id == 0x11060440)
4110                spec->stream_name_analog = "VT1818S Analog";
4111        else
4112                spec->stream_name_analog = "VT1708S Analog";
4113        spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4114        spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4115
4116        if (codec->vendor_id == 0x11060440)
4117                spec->stream_name_digital = "VT1818S Digital";
4118        else
4119                spec->stream_name_digital = "VT1708S Digital";
4120        spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
4121
4122        if (!spec->adc_nids && spec->input_mux) {
4123                spec->adc_nids = vt1708S_adc_nids;
4124                spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
4125                get_mux_nids(codec);
4126                override_mic_boost(codec, 0x1a, 0, 3, 40);
4127                override_mic_boost(codec, 0x1e, 0, 3, 40);
4128                spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
4129                spec->num_mixers++;
4130        }
4131
4132        codec->patch_ops = via_patch_ops;
4133
4134        codec->patch_ops.init = via_auto_init;
4135        codec->patch_ops.unsol_event = via_unsol_event;
4136#ifdef CONFIG_SND_HDA_POWER_SAVE
4137        spec->loopback.amplist = vt1708S_loopbacks;
4138#endif
4139
4140        /* correct names for VT1708BCE */
4141        if (get_codec_type(codec) == VT1708BCE) {
4142                kfree(codec->chip_name);
4143                codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4144                snprintf(codec->bus->card->mixername,
4145                         sizeof(codec->bus->card->mixername),
4146                         "%s %s", codec->vendor_name, codec->chip_name);
4147                spec->stream_name_analog = "VT1708BCE Analog";
4148                spec->stream_name_digital = "VT1708BCE Digital";
4149        }
4150        return 0;
4151}
4152
4153/* Patch for VT1702 */
4154
4155/* capture mixer elements */
4156static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4157        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4158        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4159        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
4160        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
4161        HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
4162        HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
4163        HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
4164                         HDA_INPUT),
4165        {
4166                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4167                /* The multiple "Capture Source" controls confuse alsamixer
4168                 * So call somewhat different..
4169                 */
4170                /* .name = "Capture Source", */
4171                .name = "Input Source",
4172                .count = 1,
4173                .info = via_mux_enum_info,
4174                .get = via_mux_enum_get,
4175                .put = via_mux_enum_put,
4176        },
4177        { } /* end */
4178};
4179
4180static struct hda_verb vt1702_volume_init_verbs[] = {
4181        /*
4182         * Unmute ADC0-1 and set the default input to mic-in
4183         */
4184        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4185        {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4186        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4187
4188
4189        /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4190         * mixer widget
4191         */
4192        /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
4193        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4194        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4195        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4196        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4197        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4198
4199        /* Setup default input of PW4 to MW0 */
4200        {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
4201        /* PW6 PW7 Output enable */
4202        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4203        {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4204        /* mixer enable */
4205        {0x1, 0xF88, 0x3},
4206        /* GPIO 0~2 */
4207        {0x1, 0xF82, 0x3F},
4208        { }
4209};
4210
4211static struct hda_verb vt1702_uniwill_init_verbs[] = {
4212        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4213         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4214        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4215        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4216        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4217        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4218        { }
4219};
4220
4221static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4222        .substreams = 2,
4223        .channels_min = 2,
4224        .channels_max = 2,
4225        .nid = 0x10, /* NID to query formats and rates */
4226        .ops = {
4227                .open = via_playback_pcm_open,
4228                .prepare = via_playback_multi_pcm_prepare,
4229                .cleanup = via_playback_multi_pcm_cleanup,
4230                .close = via_pcm_open_close
4231        },
4232};
4233
4234static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4235        .substreams = 3,
4236        .channels_min = 2,
4237        .channels_max = 2,
4238        .nid = 0x12, /* NID to query formats and rates */
4239        .ops = {
4240                .open = via_pcm_open_close,
4241                .prepare = via_capture_pcm_prepare,
4242                .cleanup = via_capture_pcm_cleanup,
4243                .close = via_pcm_open_close
4244        },
4245};
4246
4247static struct hda_pcm_stream vt1702_pcm_digital_playback = {
4248        .substreams = 2,
4249        .channels_min = 2,
4250        .channels_max = 2,
4251        /* NID is set in via_build_pcms */
4252        .ops = {
4253                .open = via_dig_playback_pcm_open,
4254                .close = via_dig_playback_pcm_close,
4255                .prepare = via_dig_playback_pcm_prepare,
4256                .cleanup = via_dig_playback_pcm_cleanup
4257        },
4258};
4259
4260/* fill in the dac_nids table from the parsed pin configuration */
4261static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4262                                     const struct auto_pin_cfg *cfg)
4263{
4264        spec->multiout.num_dacs = 1;
4265        spec->multiout.dac_nids = spec->private_dac_nids;
4266
4267        if (cfg->line_out_pins[0]) {
4268                /* config dac list */
4269                spec->multiout.dac_nids[0] = 0x10;
4270        }
4271
4272        return 0;
4273}
4274
4275/* add playback controls from the parsed DAC table */
4276static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4277                                             const struct auto_pin_cfg *cfg)
4278{
4279        int err;
4280
4281        if (!cfg->line_out_pins[0])
4282                return -1;
4283
4284        /* add control to mixer index 0 */
4285        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4286                              "Master Front Playback Volume",
4287                              HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4288        if (err < 0)
4289                return err;
4290        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4291                              "Master Front Playback Switch",
4292                              HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4293        if (err < 0)
4294                return err;
4295
4296        /* Front */
4297        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4298                              "Front Playback Volume",
4299                              HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4300        if (err < 0)
4301                return err;
4302        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4303                              "Front Playback Switch",
4304                              HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4305        if (err < 0)
4306                return err;
4307
4308        return 0;
4309}
4310
4311static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4312{
4313        int err, i;
4314        struct hda_input_mux *imux;
4315        static const char * const texts[] = { "ON", "OFF", NULL};
4316        if (!pin)
4317                return 0;
4318        spec->multiout.hp_nid = 0x1D;
4319        spec->hp_independent_mode_index = 0;
4320
4321        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4322                              "Headphone Playback Volume",
4323                              HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4324        if (err < 0)
4325                return err;
4326
4327        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4328                              "Headphone Playback Switch",
4329                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4330        if (err < 0)
4331                return err;
4332
4333        imux = &spec->private_imux[1];
4334
4335        /* for hp mode select */
4336        for (i = 0; texts[i]; i++)
4337                snd_hda_add_imux_item(imux, texts[i], i, NULL);
4338
4339        spec->hp_mux = &spec->private_imux[1];
4340        return 0;
4341}
4342
4343/* create playback/capture controls for input pins */
4344static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4345                                                const struct auto_pin_cfg *cfg)
4346{
4347        static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4348        return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4349                                                ARRAY_SIZE(pin_idxs));
4350}
4351
4352static int vt1702_parse_auto_config(struct hda_codec *codec)
4353{
4354        struct via_spec *spec = codec->spec;
4355        int err;
4356
4357        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4358        if (err < 0)
4359                return err;
4360        err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4361        if (err < 0)
4362                return err;
4363        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4364                return 0; /* can't find valid BIOS pin config */
4365
4366        err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4367        if (err < 0)
4368                return err;
4369        err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4370        if (err < 0)
4371                return err;
4372        /* limit AA path volume to 0 dB */
4373        snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4374                                  (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4375                                  (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4376                                  (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4377                                  (1 << AC_AMPCAP_MUTE_SHIFT));
4378        err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4379        if (err < 0)
4380                return err;
4381
4382        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4383
4384        fill_dig_outs(codec);
4385
4386        if (spec->kctls.list)
4387                spec->mixers[spec->num_mixers++] = spec->kctls.list;
4388
4389        spec->input_mux = &spec->private_imux[0];
4390
4391        if (spec->hp_mux)
4392                via_hp_build(codec);
4393
4394        return 1;
4395}
4396
4397#ifdef CONFIG_SND_HDA_POWER_SAVE
4398static struct hda_amp_list vt1702_loopbacks[] = {
4399        { 0x1A, HDA_INPUT, 1 },
4400        { 0x1A, HDA_INPUT, 2 },
4401        { 0x1A, HDA_INPUT, 3 },
4402        { 0x1A, HDA_INPUT, 4 },
4403        { } /* end */
4404};
4405#endif
4406
4407static int patch_vt1702(struct hda_codec *codec)
4408{
4409        struct via_spec *spec;
4410        int err;
4411
4412        /* create a codec specific record */
4413        spec = via_new_spec(codec);
4414        if (spec == NULL)
4415                return -ENOMEM;
4416
4417        /* automatic parse from the BIOS config */
4418        err = vt1702_parse_auto_config(codec);
4419        if (err < 0) {
4420                via_free(codec);
4421                return err;
4422        } else if (!err) {
4423                printk(KERN_INFO "hda_codec: Cannot set up configuration "
4424                       "from BIOS.  Using genenic mode...\n");
4425        }
4426
4427        spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
4428        spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4429
4430        spec->stream_name_analog = "VT1702 Analog";
4431        spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4432        spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4433
4434        spec->stream_name_digital = "VT1702 Digital";
4435        spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4436
4437        if (!spec->adc_nids && spec->input_mux) {
4438                spec->adc_nids = vt1702_adc_nids;
4439                spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4440                get_mux_nids(codec);
4441                spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4442                spec->num_mixers++;
4443        }
4444
4445        codec->patch_ops = via_patch_ops;
4446
4447        codec->patch_ops.init = via_auto_init;
4448        codec->patch_ops.unsol_event = via_unsol_event;
4449#ifdef CONFIG_SND_HDA_POWER_SAVE
4450        spec->loopback.amplist = vt1702_loopbacks;
4451#endif
4452
4453        return 0;
4454}
4455
4456/* Patch for VT1718S */
4457
4458/* capture mixer elements */
4459static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4460        HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4461        HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4462        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4463        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4464        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4465        HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4466                         HDA_INPUT),
4467        {
4468                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4469                /* The multiple "Capture Source" controls confuse alsamixer
4470                 * So call somewhat different..
4471                 */
4472                .name = "Input Source",
4473                .count = 2,
4474                .info = via_mux_enum_info,
4475                .get = via_mux_enum_get,
4476                .put = via_mux_enum_put,
4477        },
4478        { } /* end */
4479};
4480
4481static struct hda_verb vt1718S_volume_init_verbs[] = {
4482        /*
4483         * Unmute ADC0-1 and set the default input to mic-in
4484         */
4485        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4486        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4487
4488
4489        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4490         * mixer widget
4491         */
4492        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4493        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4494        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4495        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4496        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4497        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4498
4499        /* Setup default input of Front HP to MW9 */
4500        {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4501        /* PW9 PW10 Output enable */
4502        {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4503        {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4504        /* PW11 Input enable */
4505        {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4506        /* Enable Boost Volume backdoor */
4507        {0x1, 0xf88, 0x8},
4508        /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4509        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4510        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4511        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4512        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4513        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4515        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4516        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4517        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4518        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4519        /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4520        {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4521        {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4522        /* Unmute MW4's index 0 */
4523        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4524        { }
4525};
4526
4527
4528static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4529        {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4530         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4531        {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4532        {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4533        {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4534        {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4535        {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4536        {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4537        {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4538        { }
4539};
4540
4541static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4542        .substreams = 2,
4543        .channels_min = 2,
4544        .channels_max = 10,
4545        .nid = 0x8, /* NID to query formats and rates */
4546        .ops = {
4547                .open = via_playback_pcm_open,
4548                .prepare = via_playback_multi_pcm_prepare,
4549                .cleanup = via_playback_multi_pcm_cleanup,
4550                .close = via_pcm_open_close,
4551        },
4552};
4553
4554static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4555        .substreams = 2,
4556        .channels_min = 2,
4557        .channels_max = 2,
4558        .nid = 0x10, /* NID to query formats and rates */
4559        .ops = {
4560                .open = via_pcm_open_close,
4561                .prepare = via_capture_pcm_prepare,
4562                .cleanup = via_capture_pcm_cleanup,
4563                .close = via_pcm_open_close,
4564        },
4565};
4566
4567static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4568        .substreams = 2,
4569        .channels_min = 2,
4570        .channels_max = 2,
4571        /* NID is set in via_build_pcms */
4572        .ops = {
4573                .open = via_dig_playback_pcm_open,
4574                .close = via_dig_playback_pcm_close,
4575                .prepare = via_dig_playback_pcm_prepare,
4576                .cleanup = via_dig_playback_pcm_cleanup
4577        },
4578};
4579
4580static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4581        .substreams = 1,
4582        .channels_min = 2,
4583        .channels_max = 2,
4584};
4585
4586/* fill in the dac_nids table from the parsed pin configuration */
4587static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4588                                     const struct auto_pin_cfg *cfg)
4589{
4590        int i;
4591        hda_nid_t nid;
4592
4593        spec->multiout.num_dacs = cfg->line_outs;
4594
4595        spec->multiout.dac_nids = spec->private_dac_nids;
4596
4597        for (i = 0; i < 4; i++) {
4598                nid = cfg->line_out_pins[i];
4599                if (nid) {
4600                        /* config dac list */
4601                        switch (i) {
4602                        case AUTO_SEQ_FRONT:
4603                                spec->multiout.dac_nids[i] = 0x8;
4604                                break;
4605                        case AUTO_SEQ_CENLFE:
4606                                spec->multiout.dac_nids[i] = 0xa;
4607                                break;
4608                        case AUTO_SEQ_SURROUND:
4609                                spec->multiout.dac_nids[i] = 0x9;
4610                                break;
4611                        case AUTO_SEQ_SIDE:
4612                                spec->multiout.dac_nids[i] = 0xb;
4613                                break;
4614                        }
4615                }
4616        }
4617
4618        return 0;
4619}
4620
4621/* add playback controls from the parsed DAC table */
4622static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4623                                             const struct auto_pin_cfg *cfg)
4624{
4625        char name[32];
4626        static const char * const chname[4] = {
4627                "Front", "Surround", "C/LFE", "Side"
4628        };
4629        hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4630        hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4631        hda_nid_t nid, nid_vol, nid_mute = 0;
4632        int i, err;
4633
4634        for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4635                nid = cfg->line_out_pins[i];
4636
4637                if (!nid)
4638                        continue;
4639                nid_vol = nid_vols[i];
4640                nid_mute = nid_mutes[i];
4641
4642                if (i == AUTO_SEQ_CENLFE) {
4643                        /* Center/LFE */
4644                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4645                                              "Center Playback Volume",
4646                                              HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4647                                                                  HDA_OUTPUT));
4648                        if (err < 0)
4649                                return err;
4650                        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4651                                              "LFE Playback Volume",
4652                                              HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4653                                                                  HDA_OUTPUT));
4654                        if (err < 0)
4655                                return err;
4656                        err = via_add_control(
4657                                spec, VIA_CTL_WIDGET_MUTE,
4658                                "Center Playback Switch",
4659                                HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4660                                                    HDA_OUTPUT));
4661                        if (err < 0)
4662                                return err;
4663                        err = via_add_control(
4664                                spec, VIA_CTL_WIDGET_MUTE,
4665                                "LFE Playback Switch",
4666                                HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4667                                                    HDA_OUTPUT));
4668                        if (err < 0)
4669                                return err;
4670                } else if (i == AUTO_SEQ_FRONT) {
4671                        /* Front */
4672                        sprintf(name, "%s Playback Volume", chname[i]);
4673                        err = via_add_control(
4674                                spec, VIA_CTL_WIDGET_VOL, name,
4675                                HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4676                        if (err < 0)
4677                                return err;
4678                        sprintf(name, "%s Playback Switch", chname[i]);
4679                        err = via_add_control(
4680                                spec, VIA_CTL_WIDGET_MUTE, name,
4681                                HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4682                                                    HDA_OUTPUT));
4683                        if (err < 0)
4684                                return err;
4685                } else {
4686                        sprintf(name, "%s Playback Volume", chname[i]);
4687                        err = via_add_control(
4688                                spec, VIA_CTL_WIDGET_VOL, name,
4689                                HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4690                        if (err < 0)
4691                                return err;
4692                        sprintf(name, "%s Playback Switch", chname[i]);
4693                        err = via_add_control(
4694                                spec, VIA_CTL_WIDGET_MUTE, name,
4695                                HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4696                                                    HDA_OUTPUT));
4697                        if (err < 0)
4698                                return err;
4699                }
4700        }
4701        return 0;
4702}
4703
4704static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4705{
4706        int err;
4707
4708        if (!pin)
4709                return 0;
4710
4711        spec->multiout.hp_nid = 0xc; /* AOW4 */
4712        spec->hp_independent_mode_index = 1;
4713
4714        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4715                              "Headphone Playback Volume",
4716                              HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4717        if (err < 0)
4718                return err;
4719
4720        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4721                              "Headphone Playback Switch",
4722                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4723        if (err < 0)
4724                return err;
4725
4726        create_hp_imux(spec);
4727        return 0;
4728}
4729
4730/* create playback/capture controls for input pins */
4731static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4732                                                const struct auto_pin_cfg *cfg)
4733{
4734        static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4735        return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4736                                                ARRAY_SIZE(pin_idxs));
4737}
4738
4739static int vt1718S_parse_auto_config(struct hda_codec *codec)
4740{
4741        struct via_spec *spec = codec->spec;
4742        int err;
4743
4744        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4745
4746        if (err < 0)
4747                return err;
4748        err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4749        if (err < 0)
4750                return err;
4751        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4752                return 0; /* can't find valid BIOS pin config */
4753
4754        err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4755        if (err < 0)
4756                return err;
4757        err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4758        if (err < 0)
4759                return err;
4760        err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4761        if (err < 0)
4762                return err;
4763
4764        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4765
4766        fill_dig_outs(codec);
4767
4768        if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4769                spec->dig_in_nid = 0x13;
4770
4771        if (spec->kctls.list)
4772                spec->mixers[spec->num_mixers++] = spec->kctls.list;
4773
4774        spec->input_mux = &spec->private_imux[0];
4775
4776        if (spec->hp_mux)
4777                via_hp_build(codec);
4778
4779        via_smart51_build(spec);
4780
4781        return 1;
4782}
4783
4784#ifdef CONFIG_SND_HDA_POWER_SAVE
4785static struct hda_amp_list vt1718S_loopbacks[] = {
4786        { 0x21, HDA_INPUT, 1 },
4787        { 0x21, HDA_INPUT, 2 },
4788        { 0x21, HDA_INPUT, 3 },
4789        { 0x21, HDA_INPUT, 4 },
4790        { } /* end */
4791};
4792#endif
4793
4794static int patch_vt1718S(struct hda_codec *codec)
4795{
4796        struct via_spec *spec;
4797        int err;
4798
4799        /* create a codec specific record */
4800        spec = via_new_spec(codec);
4801        if (spec == NULL)
4802                return -ENOMEM;
4803
4804        /* automatic parse from the BIOS config */
4805        err = vt1718S_parse_auto_config(codec);
4806        if (err < 0) {
4807                via_free(codec);
4808                return err;
4809        } else if (!err) {
4810                printk(KERN_INFO "hda_codec: Cannot set up configuration "
4811                       "from BIOS.  Using genenic mode...\n");
4812        }
4813
4814        spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4815        spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4816
4817        if (codec->vendor_id == 0x11060441)
4818                spec->stream_name_analog = "VT2020 Analog";
4819        else if (codec->vendor_id == 0x11064441)
4820                spec->stream_name_analog = "VT1828S Analog";
4821        else
4822                spec->stream_name_analog = "VT1718S Analog";
4823        spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4824        spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4825
4826        if (codec->vendor_id == 0x11060441)
4827                spec->stream_name_digital = "VT2020 Digital";
4828        else if (codec->vendor_id == 0x11064441)
4829                spec->stream_name_digital = "VT1828S Digital";
4830        else
4831                spec->stream_name_digital = "VT1718S Digital";
4832        spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4833        if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4834                spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4835
4836        if (!spec->adc_nids && spec->input_mux) {
4837                spec->adc_nids = vt1718S_adc_nids;
4838                spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4839                get_mux_nids(codec);
4840                override_mic_boost(codec, 0x2b, 0, 3, 40);
4841                override_mic_boost(codec, 0x29, 0, 3, 40);
4842                spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4843                spec->num_mixers++;
4844        }
4845
4846        codec->patch_ops = via_patch_ops;
4847
4848        codec->patch_ops.init = via_auto_init;
4849        codec->patch_ops.unsol_event = via_unsol_event;
4850
4851#ifdef CONFIG_SND_HDA_POWER_SAVE
4852        spec->loopback.amplist = vt1718S_loopbacks;
4853#endif
4854
4855        return 0;
4856}
4857
4858/* Patch for VT1716S */
4859
4860static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
4861                            struct snd_ctl_elem_info *uinfo)
4862{
4863        uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4864        uinfo->count = 1;
4865        uinfo->value.integer.min = 0;
4866        uinfo->value.integer.max = 1;
4867        return 0;
4868}
4869
4870static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
4871                           struct snd_ctl_elem_value *ucontrol)
4872{
4873        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4874        int index = 0;
4875
4876        index = snd_hda_codec_read(codec, 0x26, 0,
4877                                               AC_VERB_GET_CONNECT_SEL, 0);
4878        if (index != -1)
4879                *ucontrol->value.integer.value = index;
4880
4881        return 0;
4882}
4883
4884static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4885                           struct snd_ctl_elem_value *ucontrol)
4886{
4887        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4888        struct via_spec *spec = codec->spec;
4889        int index = *ucontrol->value.integer.value;
4890
4891        snd_hda_codec_write(codec, 0x26, 0,
4892                                               AC_VERB_SET_CONNECT_SEL, index);
4893        spec->dmic_enabled = index;
4894        set_jack_power_state(codec);
4895
4896        return 1;
4897}
4898
4899/* capture mixer elements */
4900static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4901        HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4902        HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4903        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4904        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4905        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4906        HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4907                         HDA_INPUT),
4908        {
4909                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4910                .name = "Input Source",
4911                .count = 1,
4912                .info = via_mux_enum_info,
4913                .get = via_mux_enum_get,
4914                .put = via_mux_enum_put,
4915        },
4916        { } /* end */
4917};
4918
4919static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4920        HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4921        {
4922         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4923         .name = "Digital Mic Capture Switch",
4924         .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
4925         .count = 1,
4926         .info = vt1716s_dmic_info,
4927         .get = vt1716s_dmic_get,
4928         .put = vt1716s_dmic_put,
4929         },
4930        {}                      /* end */
4931};
4932
4933
4934/* mono-out mixer elements */
4935static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4936        HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
4937        { } /* end */
4938};
4939
4940static struct hda_verb vt1716S_volume_init_verbs[] = {
4941        /*
4942         * Unmute ADC0-1 and set the default input to mic-in
4943         */
4944        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4945        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4946
4947
4948        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4949         * mixer widget
4950         */
4951        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4952        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4953        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4954        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4955        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4956        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4957
4958        /* MUX Indices: Stereo Mixer = 5 */
4959        {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4960
4961        /* Setup default input of PW4 to MW0 */
4962        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4963
4964        /* Setup default input of SW1 as MW0 */
4965        {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4966
4967        /* Setup default input of SW4 as AOW0 */
4968        {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4969
4970        /* PW9 PW10 Output enable */
4971        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4972        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4973
4974        /* Unmute SW1, PW12 */
4975        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4976        {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4977        /* PW12 Output enable */
4978        {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4979        /* Enable Boost Volume backdoor */
4980        {0x1, 0xf8a, 0x80},
4981        /* don't bybass mixer */
4982        {0x1, 0xf88, 0xc0},
4983        /* Enable mono output */
4984        {0x1, 0xf90, 0x08},
4985        { }
4986};
4987
4988
4989static struct hda_verb vt1716S_uniwill_init_verbs[] = {
4990        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
4991         AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4992        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4993        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4994        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4995        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
4996         AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
4997        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4998        {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4999        { }
5000};
5001
5002static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5003        .substreams = 2,
5004        .channels_min = 2,
5005        .channels_max = 6,
5006        .nid = 0x10, /* NID to query formats and rates */
5007        .ops = {
5008                .open = via_playback_pcm_open,
5009                .prepare = via_playback_multi_pcm_prepare,
5010                .cleanup = via_playback_multi_pcm_cleanup,
5011                .close = via_pcm_open_close,
5012        },
5013};
5014
5015static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5016        .substreams = 2,
5017        .channels_min = 2,
5018        .channels_max = 2,
5019        .nid = 0x13, /* NID to query formats and rates */
5020        .ops = {
5021                .open = via_pcm_open_close,
5022                .prepare = via_capture_pcm_prepare,
5023                .cleanup = via_capture_pcm_cleanup,
5024                .close = via_pcm_open_close,
5025        },
5026};
5027
5028static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5029        .substreams = 2,
5030        .channels_min = 2,
5031        .channels_max = 2,
5032        /* NID is set in via_build_pcms */
5033        .ops = {
5034                .open = via_dig_playback_pcm_open,
5035                .close = via_dig_playback_pcm_close,
5036                .prepare = via_dig_playback_pcm_prepare,
5037                .cleanup = via_dig_playback_pcm_cleanup
5038        },
5039};
5040
5041/* fill in the dac_nids table from the parsed pin configuration */
5042static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5043                                      const struct auto_pin_cfg *cfg)
5044{       int i;
5045        hda_nid_t nid;
5046
5047        spec->multiout.num_dacs = cfg->line_outs;
5048
5049        spec->multiout.dac_nids = spec->private_dac_nids;
5050
5051        for (i = 0; i < 3; i++) {
5052                nid = cfg->line_out_pins[i];
5053                if (nid) {
5054                        /* config dac list */
5055                        switch (i) {
5056                        case AUTO_SEQ_FRONT:
5057                                spec->multiout.dac_nids[i] = 0x10;
5058                                break;
5059                        case AUTO_SEQ_CENLFE:
5060                                spec->multiout.dac_nids[i] = 0x25;
5061                                break;
5062                        case AUTO_SEQ_SURROUND:
5063                                spec->multiout.dac_nids[i] = 0x11;
5064                                break;
5065                        }
5066                }
5067        }
5068
5069        return 0;
5070}
5071
5072/* add playback controls from the parsed DAC table */
5073static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5074                                              const struct auto_pin_cfg *cfg)
5075{
5076        char name[32];
5077        static const char * const chname[3] = {
5078                "Front", "Surround", "C/LFE"
5079        };
5080        hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5081        hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5082        hda_nid_t nid, nid_vol, nid_mute;
5083        int i, err;
5084
5085        for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
5086                nid = cfg->line_out_pins[i];
5087
5088                if (!nid)
5089                        continue;
5090
5091                nid_vol = nid_vols[i];
5092                nid_mute = nid_mutes[i];
5093
5094                if (i == AUTO_SEQ_CENLFE) {
5095                        err = via_add_control(
5096                                spec, VIA_CTL_WIDGET_VOL,
5097                                "Center Playback Volume",
5098                                HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
5099                        if (err < 0)
5100                                return err;
5101                        err = via_add_control(
5102                                spec, VIA_CTL_WIDGET_VOL,
5103                                "LFE Playback Volume",
5104                                HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
5105                        if (err < 0)
5106                                return err;
5107                        err = via_add_control(
5108                                spec, VIA_CTL_WIDGET_MUTE,
5109                                "Center Playback Switch",
5110                                HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
5111                                                    HDA_OUTPUT));
5112                        if (err < 0)
5113                                return err;
5114                        err = via_add_control(
5115                                spec, VIA_CTL_WIDGET_MUTE,
5116                                "LFE Playback Switch",
5117                                HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
5118                                                    HDA_OUTPUT));
5119                        if (err < 0)
5120                                return err;
5121                } else if (i == AUTO_SEQ_FRONT) {
5122
5123                        err = via_add_control(
5124                                spec, VIA_CTL_WIDGET_VOL,
5125                                "Master Front Playback Volume",
5126                                HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5127                        if (err < 0)
5128                                return err;
5129                        err = via_add_control(
5130                                spec, VIA_CTL_WIDGET_MUTE,
5131                                "Master Front Playback Switch",
5132                                HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5133                        if (err < 0)
5134                                return err;
5135
5136                        sprintf(name, "%s Playback Volume", chname[i]);
5137                        err = via_add_control(
5138                                spec, VIA_CTL_WIDGET_VOL, name,
5139                                HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5140                        if (err < 0)
5141                                return err;
5142                        sprintf(name, "%s Playback Switch", chname[i]);
5143                        err = via_add_control(
5144                                spec, VIA_CTL_WIDGET_MUTE, name,
5145                                HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5146                                                    HDA_OUTPUT));
5147                        if (err < 0)
5148                                return err;
5149                } else {
5150                        sprintf(name, "%s Playback Volume", chname[i]);
5151                        err = via_add_control(
5152                                spec, VIA_CTL_WIDGET_VOL, name,
5153                                HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5154                        if (err < 0)
5155                                return err;
5156                        sprintf(name, "%s Playback Switch", chname[i]);
5157                        err = via_add_control(
5158                                spec, VIA_CTL_WIDGET_MUTE, name,
5159                                HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5160                                                    HDA_OUTPUT));
5161                        if (err < 0)
5162                                return err;
5163                }
5164        }
5165        return 0;
5166}
5167
5168static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5169{
5170        int err;
5171
5172        if (!pin)
5173                return 0;
5174
5175        spec->multiout.hp_nid = 0x25; /* AOW3 */
5176        spec->hp_independent_mode_index = 1;
5177
5178        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5179                              "Headphone Playback Volume",
5180                              HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5181        if (err < 0)
5182                return err;
5183
5184        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5185                              "Headphone Playback Switch",
5186                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5187        if (err < 0)
5188                return err;
5189
5190        create_hp_imux(spec);
5191        return 0;
5192}
5193
5194/* create playback/capture controls for input pins */
5195static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5196                                                const struct auto_pin_cfg *cfg)
5197{
5198        static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5199        return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5200                                                ARRAY_SIZE(pin_idxs));
5201}
5202
5203static int vt1716S_parse_auto_config(struct hda_codec *codec)
5204{
5205        struct via_spec *spec = codec->spec;
5206        int err;
5207
5208        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5209        if (err < 0)
5210                return err;
5211        err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5212        if (err < 0)
5213                return err;
5214        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5215                return 0; /* can't find valid BIOS pin config */
5216
5217        err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5218        if (err < 0)
5219                return err;
5220        err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5221        if (err < 0)
5222                return err;
5223        err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5224        if (err < 0)
5225                return err;
5226
5227        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5228
5229        fill_dig_outs(codec);
5230
5231        if (spec->kctls.list)
5232                spec->mixers[spec->num_mixers++] = spec->kctls.list;
5233
5234        spec->input_mux = &spec->private_imux[0];
5235
5236        if (spec->hp_mux)
5237                via_hp_build(codec);
5238
5239        via_smart51_build(spec);
5240
5241        return 1;
5242}
5243
5244#ifdef CONFIG_SND_HDA_POWER_SAVE
5245static struct hda_amp_list vt1716S_loopbacks[] = {
5246        { 0x16, HDA_INPUT, 1 },
5247        { 0x16, HDA_INPUT, 2 },
5248        { 0x16, HDA_INPUT, 3 },
5249        { 0x16, HDA_INPUT, 4 },
5250        { } /* end */
5251};
5252#endif
5253
5254static int patch_vt1716S(struct hda_codec *codec)
5255{
5256        struct via_spec *spec;
5257        int err;
5258
5259        /* create a codec specific record */
5260        spec = via_new_spec(codec);
5261        if (spec == NULL)
5262                return -ENOMEM;
5263
5264        /* automatic parse from the BIOS config */
5265        err = vt1716S_parse_auto_config(codec);
5266        if (err < 0) {
5267                via_free(codec);
5268                return err;
5269        } else if (!err) {
5270                printk(KERN_INFO "hda_codec: Cannot set up configuration "
5271                       "from BIOS.  Using genenic mode...\n");
5272        }
5273
5274        spec->init_verbs[spec->num_iverbs++]  = vt1716S_volume_init_verbs;
5275        spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5276
5277        spec->stream_name_analog = "VT1716S Analog";
5278        spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5279        spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5280
5281        spec->stream_name_digital = "VT1716S Digital";
5282        spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5283
5284        if (!spec->adc_nids && spec->input_mux) {
5285                spec->adc_nids = vt1716S_adc_nids;
5286                spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5287                get_mux_nids(codec);
5288                override_mic_boost(codec, 0x1a, 0, 3, 40);
5289                override_mic_boost(codec, 0x1e, 0, 3, 40);
5290                spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5291                spec->num_mixers++;
5292        }
5293
5294        spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5295        spec->num_mixers++;
5296
5297        spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
5298
5299        codec->patch_ops = via_patch_ops;
5300
5301        codec->patch_ops.init = via_auto_init;
5302        codec->patch_ops.unsol_event = via_unsol_event;
5303
5304#ifdef CONFIG_SND_HDA_POWER_SAVE
5305        spec->loopback.amplist = vt1716S_loopbacks;
5306#endif
5307
5308        return 0;
5309}
5310
5311/* for vt2002P */
5312
5313/* capture mixer elements */
5314static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5315        HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5316        HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5317        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5318        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5319        HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5320        HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5321                         HDA_INPUT),
5322        {
5323                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5324                /* The multiple "Capture Source" controls confuse alsamixer
5325                 * So call somewhat different..
5326                 */
5327                /* .name = "Capture Source", */
5328                .name = "Input Source",
5329                .count = 2,
5330                .info = via_mux_enum_info,
5331                .get = via_mux_enum_get,
5332                .put = via_mux_enum_put,
5333        },
5334        { } /* end */
5335};
5336
5337static struct hda_verb vt2002P_volume_init_verbs[] = {
5338        /*
5339         * Unmute ADC0-1 and set the default input to mic-in
5340         */
5341        {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5342        {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5343
5344
5345        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5346         * mixer widget
5347         */
5348        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5349        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5350        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5351        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5352        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5353        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5354
5355        /* MUX Indices: Mic = 0 */
5356        {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5357        {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5358
5359        /* PW9 Output enable */
5360        {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5361
5362        /* Enable Boost Volume backdoor */
5363        {0x1, 0xfb9, 0x24},
5364
5365        /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5366        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5367        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5368        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5369        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5370        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5371        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5372        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5373        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5374
5375        /* set MUX0/1/4/8 = 0 (AOW0) */
5376        {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5377        {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5378        {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5379        {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5380
5381        /* set PW0 index=0 (MW0) */
5382        {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5383
5384        /* Enable AOW0 to MW9 */
5385        {0x1, 0xfb8, 0x88},
5386        { }
5387};
5388
5389
5390static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5391        {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5392         AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5393        {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5394         AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5395        {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5396        {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5397        {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5398        { }
5399};
5400
5401static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5402        .substreams = 2,
5403        .channels_min = 2,
5404        .channels_max = 2,
5405        .nid = 0x8, /* NID to query formats and rates */
5406        .ops = {
5407                .open = via_playback_pcm_open,
5408                .prepare = via_playback_multi_pcm_prepare,
5409                .cleanup = via_playback_multi_pcm_cleanup,
5410                .close = via_pcm_open_close,
5411        },
5412};
5413
5414static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5415        .substreams = 2,
5416        .channels_min = 2,
5417        .channels_max = 2,
5418        .nid = 0x10, /* NID to query formats and rates */
5419        .ops = {
5420                .open = via_pcm_open_close,
5421                .prepare = via_capture_pcm_prepare,
5422                .cleanup = via_capture_pcm_cleanup,
5423                .close = via_pcm_open_close,
5424        },
5425};
5426
5427static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5428        .substreams = 1,
5429        .channels_min = 2,
5430        .channels_max = 2,
5431        /* NID is set in via_build_pcms */
5432        .ops = {
5433                .open = via_dig_playback_pcm_open,
5434                .close = via_dig_playback_pcm_close,
5435                .prepare = via_dig_playback_pcm_prepare,
5436                .cleanup = via_dig_playback_pcm_cleanup
5437        },
5438};
5439
5440/* fill in the dac_nids table from the parsed pin configuration */
5441static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5442                                      const struct auto_pin_cfg *cfg)
5443{
5444        spec->multiout.num_dacs = 1;
5445        spec->multiout.dac_nids = spec->private_dac_nids;
5446        if (cfg->line_out_pins[0])
5447                spec->multiout.dac_nids[0] = 0x8;
5448        return 0;
5449}
5450
5451/* add playback controls from the parsed DAC table */
5452static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5453                                             const struct auto_pin_cfg *cfg)
5454{
5455        int err;
5456
5457        if (!cfg->line_out_pins[0])
5458                return -1;
5459
5460
5461        /* Line-Out: PortE */
5462        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5463                              "Master Front Playback Volume",
5464                              HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5465        if (err < 0)
5466                return err;
5467        err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5468                              "Master Front Playback Switch",
5469                              HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
5470        if (err < 0)
5471                return err;
5472
5473        return 0;
5474}
5475
5476static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5477{
5478        int err;
5479
5480        if (!pin)
5481                return 0;
5482
5483        spec->multiout.hp_nid = 0x9;
5484        spec->hp_independent_mode_index = 1;
5485
5486        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5487                              "Headphone Playback Volume",
5488                              HDA_COMPOSE_AMP_VAL(
5489                                      spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5490        if (err < 0)
5491                return err;
5492
5493        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5494                              "Headphone Playback Switch",
5495                              HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5496        if (err < 0)
5497                return err;
5498
5499        create_hp_imux(spec);
5500        return 0;
5501}
5502
5503/* create playback/capture controls for input pins */
5504static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5505                                                const struct auto_pin_cfg *cfg)
5506{
5507        struct via_spec *spec = codec->spec;
5508        struct hda_input_mux *imux = &spec->private_imux[0];
5509        static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5510        int err;
5511
5512        err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5513                                               ARRAY_SIZE(pin_idxs));
5514        if (err < 0)
5515                return err;
5516        /* build volume/mute control of loopback */
5517        err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5518        if (err < 0)
5519                return err;
5520
5521        /* for digital mic select */
5522        snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5523
5524        return 0;
5525}
5526
5527static int vt2002P_parse_auto_config(struct hda_codec *codec)
5528{
5529        struct via_spec *spec = codec->spec;
5530        int err;
5531
5532
5533        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5534        if (err < 0)
5535                return err;
5536
5537        err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5538        if (err < 0)
5539                return err;
5540
5541        if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5542                return 0; /* can't find valid BIOS pin config */
5543
5544        err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5545        if (err < 0)
5546                return err;
5547        err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5548        if (err < 0)
5549                return err;
5550        err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5551        if (err < 0)
5552                return err;
5553
5554        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5555
5556        fill_dig_outs(codec);
5557
5558        if (spec->kctls.list)
5559                spec->mixers[spec->num_mixers++] = spec->kctls.list;
5560
5561        spec->input_mux = &spec->private_imux[0];
5562
5563        if (spec->hp_mux)
5564                via_hp_build(codec);
5565
5566        return 1;
5567}
5568
5569#ifdef CONFIG_SND_HDA_POWER_SAVE
5570static struct hda_amp_list vt2002P_loopbacks[] = {
5571        { 0x21, HDA_INPUT, 0 },
5572        { 0x21, HDA_INPUT, 1 },
5573        { 0x21, HDA_INPUT, 2 },
5574        { } /* end */
5575};
5576#endif
5577
5578
5579/* patch for vt2002P */
5580static int patch_vt2002P(struct hda_codec *codec)
5581{
5582        struct via_spec *spec;
5583        int err;
5584
5585        /* create a codec specific record */
5586        spec = via_new_spec(codec);
5587        if (spec == NULL)
5588                return -ENOMEM;
5589
5590        /* automatic parse from the BIOS config */
5591        err = vt2002P_parse_auto_config(codec);
5592        if (err < 0) {
5593                via_free(codec);
5594                return err;
5595        } else if (!err) {
5596                printk(KERN_INFO "hda_codec: Cannot set up configuration "
5597                       "from BIOS.  Using genenic mode...\n");
5598        }
5599
5600        spec->init_verbs[spec->num_iverbs++]  = vt2002P_volume_init_verbs;
5601        spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
5602
5603        spec->stream_name_analog = "VT2002P Analog";
5604        spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5605        spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5606
5607        spec->stream_name_digital = "VT2002P Digital";
5608        spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5609
5610        if (!spec->adc_nids && spec->input_mux) {
5611                spec->adc_nids = vt2002P_adc_nids;
5612                spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5613                get_mux_nids(codec);
5614                override_mic_boost(codec, 0x2b, 0, 3, 40);
5615                override_mic_boost(codec, 0x29, 0, 3, 40);
5616                spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5617                spec->num_mixers++;
5618        }
5619
5620        codec->patch_ops = via_patch_ops;
5621
5622        codec->patch_ops.init = via_auto_init;
5623        codec->patch_ops.unsol_event = via_unsol_event;
5624
5625#ifdef CONFIG_SND_HDA_POWER_SAVE
5626        spec->loopback.amplist = vt2002P_loopbacks;
5627#endif
5628
5629        return 0;
5630}
5631
5632/* for vt1812 */
5633
5634/* capture mixer elements */
5635static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5636        HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5637        HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5638        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5639        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5640        HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5641        HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5642                       HDA_INPUT),
5643        {
5644                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5645                /* The multiple "Capture Source" controls confuse alsamixer
5646                 * So call somewhat different..
5647                 */
5648                .name = "Input Source",
5649                .count = 2,
5650                .info = via_mux_enum_info,
5651                .get = via_mux_enum_get,
5652                .put = via_mux_enum_put,
5653        },
5654        { } /* end */
5655};
5656
5657static struct hda_verb vt1812_volume_init_verbs[] = {
5658        /*
5659         * Unmute ADC0-1 and set the default input to mic-in
5660         */
5661        {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5662        {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5663
5664
5665        /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5666         * mixer widget
5667         */
5668        /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5669        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5670        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5671        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5672        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5673        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5674
5675        /* MUX Indices: Mic = 0 */
5676        {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5677        {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5678
5679        /* PW9 Output enable */
5680        {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5681
5682        /* Enable Boost Volume backdoor */
5683        {0x1, 0xfb9, 0x24},
5684
5685        /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5686        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5687        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5688        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5689        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5690        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5691        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5692        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5693        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5694        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5695        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5696
5697        /* set MUX0/1/4/13/15 = 0 (AOW0) */
5698        {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5699        {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5700        {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5701        {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5702        {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5703
5704        /* Enable AOW0 to MW9 */
5705        {0x1, 0xfb8, 0xa8},
5706        { }
5707};
5708
5709
5710static struct hda_verb vt1812_uniwill_init_verbs[] = {
5711        {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5712         AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5713        {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5714        {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5715         AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5716        {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5717        {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5718        {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5719        { }
5720};
5721
5722static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5723        .substreams = 2,
5724        .channels_min = 2,
5725        .channels_max = 2,
5726        .nid = 0x8, /* NID to query formats and rates */
5727        .ops = {
5728                .open = via_playback_pcm_open,
5729                .prepare = via_playback_multi_pcm_prepare,
5730                .cleanup = via_playback_multi_pcm_cleanup,
5731                .close = via_pcm_open_close,
5732        },
5733};
5734
5735static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5736        .substreams = 2,
5737        .channels_min = 2,
5738        .channels_max = 2,
5739        .nid = 0x10, /* NID to query formats and rates */
5740        .ops = {
5741                .open = via_pcm_open_close,
5742                .prepare = via_capture_pcm_prepare,
5743                .cleanup = via_capture_pcm_cleanup,
5744                .close = via_pcm_open_close,
5745        },
5746};
5747
5748static struct hda_pcm_stream vt1812_pcm_digital_playback = {
5749        .substreams = 1,
5750        .channels_min = 2,
5751        .channels_max = 2,
5752        /* NID is set in via_build_pcms */
5753        .ops = {
5754                .open = via_dig_playback_pcm_open,
5755                .close = via_dig_playback_pcm_close,
5756                .prepare = via_dig_playback_pcm_prepare,
5757                .cleanup = via_dig_playback_pcm_cleanup
5758        },
5759};
5760/* fill in the dac_nids table from the parsed pin configuration */
5761static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5762                                     const struct auto_pin_cfg *cfg)
5763{
5764        spec->multiout.num_dacs = 1;
5765        spec->multiout.dac_nids = spec->private_dac_nids;
5766        if (cfg->line_out_pins[0])
5767                spec->multiout.dac_nids[0] = 0x8;
5768        return 0;
5769}
5770
5771
5772/* add playback controls from the parsed DAC table */
5773static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
5774                                             const struct auto_pin_cfg *cfg)
5775{
5776        int err;
5777
5778        if (!cfg->line_out_pins[0])
5779                return -1;
5780
5781        /* Line-Out: PortE */
5782        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5783                              "Front Playback Volume",
5784                              HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5785        if (err < 0)
5786                return err;
5787        err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5788                              "Front Playback Switch",
5789                              HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
5790        if (err < 0)
5791                return err;
5792
5793        return 0;
5794}
5795
5796static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5797{
5798        int err;
5799
5800        if (!pin)
5801                return 0;
5802
5803        spec->multiout.hp_nid = 0x9;
5804        spec->hp_independent_mode_index = 1;
5805
5806
5807        err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5808                              "Headphone Playback Volume",
5809                              HDA_COMPOSE_AMP_VAL(
5810                                      spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5811        if (err < 0)
5812                return err;
5813
5814        err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5815                              "Headphone Playback Switch",
5816                              HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5817        if (err < 0)
5818                return err;
5819
5820        create_hp_imux(spec);
5821        return 0;
5822}
5823
5824/* create playback/capture controls for input pins */
5825static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
5826                                                const struct auto_pin_cfg *cfg)
5827{
5828        struct via_spec *spec = codec->spec;
5829        struct hda_input_mux *imux = &spec->private_imux[0];
5830        static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5831        int err;
5832
5833        err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5834                                               ARRAY_SIZE(pin_idxs));
5835        if (err < 0)
5836                return err;
5837
5838        /* build volume/mute control of loopback */
5839        err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
5840        if (err < 0)
5841                return err;
5842
5843        /* for digital mic select */
5844        snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
5845
5846        return 0;
5847}
5848
5849static int vt1812_parse_auto_config(struct hda_codec *codec)
5850{
5851        struct via_spec *spec = codec->spec;
5852        int err;
5853
5854
5855        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5856        if (err < 0)
5857                return err;
5858        fill_dig_outs(codec);
5859        err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
5860        if (err < 0)
5861                return err;
5862
5863        if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
5864                return 0; /* can't find valid BIOS pin config */
5865
5866        err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
5867        if (err < 0)
5868                return err;
5869        err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5870        if (err < 0)
5871                return err;
5872        err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
5873        if (err < 0)
5874                return err;
5875
5876        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5877
5878        fill_dig_outs(codec);
5879
5880        if (spec->kctls.list)
5881                spec->mixers[spec->num_mixers++] = spec->kctls.list;
5882
5883        spec->input_mux = &spec->private_imux[0];
5884
5885        if (spec->hp_mux)
5886                via_hp_build(codec);
5887
5888        return 1;
5889}
5890
5891#ifdef CONFIG_SND_HDA_POWER_SAVE
5892static struct hda_amp_list vt1812_loopbacks[] = {
5893        { 0x21, HDA_INPUT, 0 },
5894        { 0x21, HDA_INPUT, 1 },
5895        { 0x21, HDA_INPUT, 2 },
5896        { } /* end */
5897};
5898#endif
5899
5900
5901/* patch for vt1812 */
5902static int patch_vt1812(struct hda_codec *codec)
5903{
5904        struct via_spec *spec;
5905        int err;
5906
5907        /* create a codec specific record */
5908        spec = via_new_spec(codec);
5909        if (spec == NULL)
5910                return -ENOMEM;
5911
5912        /* automatic parse from the BIOS config */
5913        err = vt1812_parse_auto_config(codec);
5914        if (err < 0) {
5915                via_free(codec);
5916                return err;
5917        } else if (!err) {
5918                printk(KERN_INFO "hda_codec: Cannot set up configuration "
5919                       "from BIOS.  Using genenic mode...\n");
5920        }
5921
5922
5923        spec->init_verbs[spec->num_iverbs++]  = vt1812_volume_init_verbs;
5924        spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
5925
5926        spec->stream_name_analog = "VT1812 Analog";
5927        spec->stream_analog_playback = &vt1812_pcm_analog_playback;
5928        spec->stream_analog_capture = &vt1812_pcm_analog_capture;
5929
5930        spec->stream_name_digital = "VT1812 Digital";
5931        spec->stream_digital_playback = &vt1812_pcm_digital_playback;
5932
5933
5934        if (!spec->adc_nids && spec->input_mux) {
5935                spec->adc_nids = vt1812_adc_nids;
5936                spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
5937                get_mux_nids(codec);
5938                override_mic_boost(codec, 0x2b, 0, 3, 40);
5939                override_mic_boost(codec, 0x29, 0, 3, 40);
5940                spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
5941                spec->num_mixers++;
5942        }
5943
5944        codec->patch_ops = via_patch_ops;
5945
5946        codec->patch_ops.init = via_auto_init;
5947        codec->patch_ops.unsol_event = via_unsol_event;
5948
5949#ifdef CONFIG_SND_HDA_POWER_SAVE
5950        spec->loopback.amplist = vt1812_loopbacks;
5951#endif
5952
5953        return 0;
5954}
5955
5956/*
5957 * patch entries
5958 */
5959static struct hda_codec_preset snd_hda_preset_via[] = {
5960        { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
5961        { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
5962        { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
5963        { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
5964        { .id = 0x1106e710, .name = "VT1709 10-Ch",
5965          .patch = patch_vt1709_10ch},
5966        { .id = 0x1106e711, .name = "VT1709 10-Ch",
5967          .patch = patch_vt1709_10ch},
5968        { .id = 0x1106e712, .name = "VT1709 10-Ch",
5969          .patch = patch_vt1709_10ch},
5970        { .id = 0x1106e713, .name = "VT1709 10-Ch",
5971          .patch = patch_vt1709_10ch},
5972        { .id = 0x1106e714, .name = "VT1709 6-Ch",
5973          .patch = patch_vt1709_6ch},
5974        { .id = 0x1106e715, .name = "VT1709 6-Ch",
5975          .patch = patch_vt1709_6ch},
5976        { .id = 0x1106e716, .name = "VT1709 6-Ch",
5977          .patch = patch_vt1709_6ch},
5978        { .id = 0x1106e717, .name = "VT1709 6-Ch",
5979          .patch = patch_vt1709_6ch},
5980        { .id = 0x1106e720, .name = "VT1708B 8-Ch",
5981          .patch = patch_vt1708B_8ch},
5982        { .id = 0x1106e721, .name = "VT1708B 8-Ch",
5983          .patch = patch_vt1708B_8ch},
5984        { .id = 0x1106e722, .name = "VT1708B 8-Ch",
5985          .patch = patch_vt1708B_8ch},
5986        { .id = 0x1106e723, .name = "VT1708B 8-Ch",
5987          .patch = patch_vt1708B_8ch},
5988        { .id = 0x1106e724, .name = "VT1708B 4-Ch",
5989          .patch = patch_vt1708B_4ch},
5990        { .id = 0x1106e725, .name = "VT1708B 4-Ch",
5991          .patch = patch_vt1708B_4ch},
5992        { .id = 0x1106e726, .name = "VT1708B 4-Ch",
5993          .patch = patch_vt1708B_4ch},
5994        { .id = 0x1106e727, .name = "VT1708B 4-Ch",
5995          .patch = patch_vt1708B_4ch},
5996        { .id = 0x11060397, .name = "VT1708S",
5997          .patch = patch_vt1708S},
5998        { .id = 0x11061397, .name = "VT1708S",
5999          .patch = patch_vt1708S},
6000        { .id = 0x11062397, .name = "VT1708S",
6001          .patch = patch_vt1708S},
6002        { .id = 0x11063397, .name = "VT1708S",
6003          .patch = patch_vt1708S},
6004        { .id = 0x11064397, .name = "VT1708S",
6005          .patch = patch_vt1708S},
6006        { .id = 0x11065397, .name = "VT1708S",
6007          .patch = patch_vt1708S},
6008        { .id = 0x11066397, .name = "VT1708S",
6009          .patch = patch_vt1708S},
6010        { .id = 0x11067397, .name = "VT1708S",
6011          .patch = patch_vt1708S},
6012        { .id = 0x11060398, .name = "VT1702",
6013          .patch = patch_vt1702},
6014        { .id = 0x11061398, .name = "VT1702",
6015          .patch = patch_vt1702},
6016        { .id = 0x11062398, .name = "VT1702",
6017          .patch = patch_vt1702},
6018        { .id = 0x11063398, .name = "VT1702",
6019          .patch = patch_vt1702},
6020        { .id = 0x11064398, .name = "VT1702",
6021          .patch = patch_vt1702},
6022        { .id = 0x11065398, .name = "VT1702",
6023          .patch = patch_vt1702},
6024        { .id = 0x11066398, .name = "VT1702",
6025          .patch = patch_vt1702},
6026        { .id = 0x11067398, .name = "VT1702",
6027          .patch = patch_vt1702},
6028        { .id = 0x11060428, .name = "VT1718S",
6029          .patch = patch_vt1718S},
6030        { .id = 0x11064428, .name = "VT1718S",
6031          .patch = patch_vt1718S},
6032        { .id = 0x11060441, .name = "VT2020",
6033          .patch = patch_vt1718S},
6034        { .id = 0x11064441, .name = "VT1828S",
6035          .patch = patch_vt1718S},
6036        { .id = 0x11060433, .name = "VT1716S",
6037          .patch = patch_vt1716S},
6038        { .id = 0x1106a721, .name = "VT1716S",
6039          .patch = patch_vt1716S},
6040        { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
6041        { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
6042        { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6043        { .id = 0x11060440, .name = "VT1818S",
6044          .patch = patch_vt1708S},
6045        {} /* terminator */
6046};
6047
6048MODULE_ALIAS("snd-hda-codec-id:1106*");
6049
6050static struct hda_codec_preset_list via_list = {
6051        .preset = snd_hda_preset_via,
6052        .owner = THIS_MODULE,
6053};
6054
6055MODULE_LICENSE("GPL");
6056MODULE_DESCRIPTION("VIA HD-audio codec");
6057
6058static int __init patch_via_init(void)
6059{
6060        return snd_hda_add_codec_preset(&via_list);
6061}
6062
6063static void __exit patch_via_exit(void)
6064{
6065        snd_hda_delete_codec_preset(&via_list);
6066}
6067
6068module_init(patch_via_init)
6069module_exit(patch_via_exit)
6070