~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/hda/patch_via.c

Version: ~ [ linux-2.6.33-rc7-ccs-1.7.1 ] ~ [ linux-2.6.32.7-ccs-1.7.1 ] ~ [ linux-2.4.37.9-ccs-1.7.1 ] ~ [ ccs-tools-1.7.1 ] ~ [ policy-sample ] ~ [ apparmor-mainline ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 /* amp values */
 58 #define AMP_VAL_IDX_SHIFT       19
 59 #define AMP_VAL_IDX_MASK        (0x0f<<19)
 60 
 61 /* Pin Widget NID */
 62 #define VT1708_HP_NID           0x13
 63 #define VT1708_DIGOUT_NID       0x14
 64 #define VT1708_DIGIN_NID        0x16
 65 #define VT1708_DIGIN_PIN        0x26
 66 #define VT1708_HP_PIN_NID       0x20
 67 #define VT1708_CD_PIN_NID       0x24
 68 
 69 #define VT1709_HP_DAC_NID       0x28
 70 #define VT1709_DIGOUT_NID       0x13
 71 #define VT1709_DIGIN_NID        0x17
 72 #define VT1709_DIGIN_PIN        0x25
 73 
 74 #define VT1708B_HP_NID          0x25
 75 #define VT1708B_DIGOUT_NID      0x12
 76 #define VT1708B_DIGIN_NID       0x15
 77 #define VT1708B_DIGIN_PIN       0x21
 78 
 79 #define VT1708S_HP_NID          0x25
 80 #define VT1708S_DIGOUT_NID      0x12
 81 
 82 #define VT1702_HP_NID           0x17
 83 #define VT1702_DIGOUT_NID       0x11
 84 
 85 enum VIA_HDA_CODEC {
 86         UNKNOWN = -1,
 87         VT1708,
 88         VT1709_10CH,
 89         VT1709_6CH,
 90         VT1708B_8CH,
 91         VT1708B_4CH,
 92         VT1708S,
 93         VT1708BCE,
 94         VT1702,
 95         VT1718S,
 96         VT1716S,
 97         VT2002P,
 98         VT1812,
 99         CODEC_TYPES,
100 };
101 
102 struct via_spec {
103         /* codec parameterization */
104         struct snd_kcontrol_new *mixers[6];
105         unsigned int num_mixers;
106 
107         struct hda_verb *init_verbs[5];
108         unsigned int num_iverbs;
109 
110         char *stream_name_analog;
111         struct hda_pcm_stream *stream_analog_playback;
112         struct hda_pcm_stream *stream_analog_capture;
113 
114         char *stream_name_digital;
115         struct hda_pcm_stream *stream_digital_playback;
116         struct hda_pcm_stream *stream_digital_capture;
117 
118         /* playback */
119         struct hda_multi_out multiout;
120         hda_nid_t slave_dig_outs[2];
121 
122         /* capture */
123         unsigned int num_adc_nids;
124         hda_nid_t *adc_nids;
125         hda_nid_t mux_nids[3];
126         hda_nid_t dig_in_nid;
127         hda_nid_t dig_in_pin;
128 
129         /* capture source */
130         const struct hda_input_mux *input_mux;
131         unsigned int cur_mux[3];
132 
133         /* PCM information */
134         struct hda_pcm pcm_rec[3];
135 
136         /* dynamic controls, init_verbs and input_mux */
137         struct auto_pin_cfg autocfg;
138         struct snd_array kctls;
139         struct hda_input_mux private_imux[2];
140         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
141 
142         /* HP mode source */
143         const struct hda_input_mux *hp_mux;
144         unsigned int hp_independent_mode;
145         unsigned int hp_independent_mode_index;
146         unsigned int smart51_enabled;
147         unsigned int dmic_enabled;
148         enum VIA_HDA_CODEC codec_type;
149 
150         /* work to check hp jack state */
151         struct hda_codec *codec;
152         struct delayed_work vt1708_hp_work;
153         int vt1708_jack_detectect;
154         int vt1708_hp_present;
155 #ifdef CONFIG_SND_HDA_POWER_SAVE
156         struct hda_loopback_check loopback;
157 #endif
158 };
159 
160 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
161 {
162         u32 vendor_id = codec->vendor_id;
163         u16 ven_id = vendor_id >> 16;
164         u16 dev_id = vendor_id & 0xffff;
165         enum VIA_HDA_CODEC codec_type;
166 
167         /* get codec type */
168         if (ven_id != 0x1106)
169                 codec_type = UNKNOWN;
170         else if (dev_id >= 0x1708 && dev_id <= 0x170b)
171                 codec_type = VT1708;
172         else if (dev_id >= 0xe710 && dev_id <= 0xe713)
173                 codec_type = VT1709_10CH;
174         else if (dev_id >= 0xe714 && dev_id <= 0xe717)
175                 codec_type = VT1709_6CH;
176         else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
177                 codec_type = VT1708B_8CH;
178                 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
179                         codec_type = VT1708BCE;
180         } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
181                 codec_type = VT1708B_4CH;
182         else if ((dev_id & 0xfff) == 0x397
183                  && (dev_id >> 12) < 8)
184                 codec_type = VT1708S;
185         else if ((dev_id & 0xfff) == 0x398
186                  && (dev_id >> 12) < 8)
187                 codec_type = VT1702;
188         else if ((dev_id & 0xfff) == 0x428
189                  && (dev_id >> 12) < 8)
190                 codec_type = VT1718S;
191         else if (dev_id == 0x0433 || dev_id == 0xa721)
192                 codec_type = VT1716S;
193         else if (dev_id == 0x0441 || dev_id == 0x4441)
194                 codec_type = VT1718S;
195         else if (dev_id == 0x0438 || dev_id == 0x4438)
196                 codec_type = VT2002P;
197         else if (dev_id == 0x0448)
198                 codec_type = VT1812;
199         else if (dev_id == 0x0440)
200                 codec_type = VT1708S;
201         else
202                 codec_type = UNKNOWN;
203         return codec_type;
204 };
205 
206 #define VIA_HP_EVENT            0x01
207 #define VIA_GPIO_EVENT          0x02
208 #define VIA_JACK_EVENT          0x04
209 #define VIA_MONO_EVENT          0x08
210 #define VIA_SPEAKER_EVENT       0x10
211 #define VIA_BIND_HP_EVENT       0x20
212 
213 enum {
214         VIA_CTL_WIDGET_VOL,
215         VIA_CTL_WIDGET_MUTE,
216         VIA_CTL_WIDGET_ANALOG_MUTE,
217         VIA_CTL_WIDGET_BIND_PIN_MUTE,
218 };
219 
220 enum {
221         AUTO_SEQ_FRONT = 0,
222         AUTO_SEQ_SURROUND,
223         AUTO_SEQ_CENLFE,
224         AUTO_SEQ_SIDE
225 };
226 
227 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
228 static void set_jack_power_state(struct hda_codec *codec);
229 static int is_aa_path_mute(struct hda_codec *codec);
230 
231 static void vt1708_start_hp_work(struct via_spec *spec)
232 {
233         if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
234                 return;
235         snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
236                             !spec->vt1708_jack_detectect);
237         if (!delayed_work_pending(&spec->vt1708_hp_work))
238                 schedule_delayed_work(&spec->vt1708_hp_work,
239                                       msecs_to_jiffies(100));
240 }
241 
242 static void vt1708_stop_hp_work(struct via_spec *spec)
243 {
244         if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
245                 return;
246         if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
247             && !is_aa_path_mute(spec->codec))
248                 return;
249         snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
250                             !spec->vt1708_jack_detectect);
251         cancel_delayed_work(&spec->vt1708_hp_work);
252         flush_scheduled_work();
253 }
254 
255 
256 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
257                                    struct snd_ctl_elem_value *ucontrol)
258 {
259         int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
260         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
261 
262         set_jack_power_state(codec);
263         analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
264         if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
265                 if (is_aa_path_mute(codec))
266                         vt1708_start_hp_work(codec->spec);
267                 else
268                         vt1708_stop_hp_work(codec->spec);
269         }
270         return change;
271 }
272 
273 /* modify .put = snd_hda_mixer_amp_switch_put */
274 #define ANALOG_INPUT_MUTE                                               \
275         {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
276                         .name = NULL,                                   \
277                         .index = 0,                                     \
278                         .info = snd_hda_mixer_amp_switch_info,          \
279                         .get = snd_hda_mixer_amp_switch_get,            \
280                         .put = analog_input_switch_put,                 \
281                         .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
282 
283 static void via_hp_bind_automute(struct hda_codec *codec);
284 
285 static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
286                                struct snd_ctl_elem_value *ucontrol)
287 {
288         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
289         struct via_spec *spec = codec->spec;
290         int i;
291         int change = 0;
292 
293         long *valp = ucontrol->value.integer.value;
294         int lmute, rmute;
295         if (strstr(kcontrol->id.name, "Switch") == NULL) {
296                 snd_printd("Invalid control!\n");
297                 return change;
298         }
299         change = snd_hda_mixer_amp_switch_put(kcontrol,
300                                               ucontrol);
301         /* Get mute value */
302         lmute = *valp ? 0 : HDA_AMP_MUTE;
303         valp++;
304         rmute = *valp ? 0 : HDA_AMP_MUTE;
305 
306         /* Set hp pins */
307         if (!spec->hp_independent_mode) {
308                 for (i = 0; i < spec->autocfg.hp_outs; i++) {
309                         snd_hda_codec_amp_update(
310                                 codec, spec->autocfg.hp_pins[i],
311                                 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
312                                 lmute);
313                         snd_hda_codec_amp_update(
314                                 codec, spec->autocfg.hp_pins[i],
315                                 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
316                                 rmute);
317                 }
318         }
319 
320         if (!lmute && !rmute) {
321                 /* Line Outs */
322                 for (i = 0; i < spec->autocfg.line_outs; i++)
323                         snd_hda_codec_amp_stereo(
324                                 codec, spec->autocfg.line_out_pins[i],
325                                 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
326                 /* Speakers */
327                 for (i = 0; i < spec->autocfg.speaker_outs; i++)
328                         snd_hda_codec_amp_stereo(
329                                 codec, spec->autocfg.speaker_pins[i],
330                                 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
331                 /* unmute */
332                 via_hp_bind_automute(codec);
333 
334         } else {
335                 if (lmute) {
336                         /* Mute all left channels */
337                         for (i = 1; i < spec->autocfg.line_outs; i++)
338                                 snd_hda_codec_amp_update(
339                                         codec,
340                                         spec->autocfg.line_out_pins[i],
341                                         0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
342                                         lmute);
343                         for (i = 0; i < spec->autocfg.speaker_outs; i++)
344                                 snd_hda_codec_amp_update(
345                                         codec,
346                                         spec->autocfg.speaker_pins[i],
347                                         0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
348                                         lmute);
349                 }
350                 if (rmute) {
351                         /* mute all right channels */
352                         for (i = 1; i < spec->autocfg.line_outs; i++)
353                                 snd_hda_codec_amp_update(
354                                         codec,
355                                         spec->autocfg.line_out_pins[i],
356                                         1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
357                                         rmute);
358                         for (i = 0; i < spec->autocfg.speaker_outs; i++)
359                                 snd_hda_codec_amp_update(
360                                         codec,
361                                         spec->autocfg.speaker_pins[i],
362                                         1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
363                                         rmute);
364                 }
365         }
366         return change;
367 }
368 
369 #define BIND_PIN_MUTE                                                   \
370         {               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,            \
371                         .name = NULL,                                   \
372                         .index = 0,                                     \
373                         .info = snd_hda_mixer_amp_switch_info,          \
374                         .get = snd_hda_mixer_amp_switch_get,            \
375                         .put = bind_pin_switch_put,                     \
376                         .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
377 
378 static struct snd_kcontrol_new via_control_templates[] = {
379         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
380         HDA_CODEC_MUTE(NULL, 0, 0, 0),
381         ANALOG_INPUT_MUTE,
382         BIND_PIN_MUTE,
383 };
384 
385 static hda_nid_t vt1708_adc_nids[2] = {
386         /* ADC1-2 */
387         0x15, 0x27
388 };
389 
390 static hda_nid_t vt1709_adc_nids[3] = {
391         /* ADC1-2 */
392         0x14, 0x15, 0x16
393 };
394 
395 static hda_nid_t vt1708B_adc_nids[2] = {
396         /* ADC1-2 */
397         0x13, 0x14
398 };
399 
400 static hda_nid_t vt1708S_adc_nids[2] = {
401         /* ADC1-2 */
402         0x13, 0x14
403 };
404 
405 static hda_nid_t vt1702_adc_nids[3] = {
406         /* ADC1-2 */
407         0x12, 0x20, 0x1F
408 };
409 
410 static hda_nid_t vt1718S_adc_nids[2] = {
411         /* ADC1-2 */
412         0x10, 0x11
413 };
414 
415 static hda_nid_t vt1716S_adc_nids[2] = {
416         /* ADC1-2 */
417         0x13, 0x14
418 };
419 
420 static hda_nid_t vt2002P_adc_nids[2] = {
421         /* ADC1-2 */
422         0x10, 0x11
423 };
424 
425 static hda_nid_t vt1812_adc_nids[2] = {
426         /* ADC1-2 */
427         0x10, 0x11
428 };
429 
430 
431 /* add dynamic controls */
432 static int via_add_control(struct via_spec *spec, int type, const char *name,
433                            unsigned long val)
434 {
435         struct snd_kcontrol_new *knew;
436 
437         snd_array_init(&spec->kctls, sizeof(*knew), 32);
438         knew = snd_array_new(&spec->kctls);
439         if (!knew)
440                 return -ENOMEM;
441         *knew = via_control_templates[type];
442         knew->name = kstrdup(name, GFP_KERNEL);
443         if (!knew->name)
444                 return -ENOMEM;
445         if (get_amp_nid_(val))
446                 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val);
447         knew->private_value = val;
448         return 0;
449 }
450 
451 static void via_free_kctls(struct hda_codec *codec)
452 {
453         struct via_spec *spec = codec->spec;
454 
455         if (spec->kctls.list) {
456                 struct snd_kcontrol_new *kctl = spec->kctls.list;
457                 int i;
458                 for (i = 0; i < spec->kctls.used; i++)
459                         kfree(kctl[i].name);
460         }
461         snd_array_free(&spec->kctls);
462 }
463 
464 /* create input playback/capture controls for the given pin */
465 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
466                                 int idx, int mix_nid)
467 {
468         char name[32];
469         int err;
470 
471         sprintf(name, "%s Playback Volume", ctlname);
472         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
473                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
474         if (err < 0)
475                 return err;
476         sprintf(name, "%s Playback Switch", ctlname);
477         err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
478                               HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
479         if (err < 0)
480                 return err;
481         return 0;
482 }
483 
484 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
485                                            hda_nid_t nid, int pin_type,
486                                            int dac_idx)
487 {
488         /* set as output */
489         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
490                             pin_type);
491         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
492                             AMP_OUT_UNMUTE);
493         if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
494                 snd_hda_codec_write(codec, nid, 0,
495                                     AC_VERB_SET_EAPD_BTLENABLE, 0x02);
496 }
497 
498 
499 static void via_auto_init_multi_out(struct hda_codec *codec)
500 {
501         struct via_spec *spec = codec->spec;
502         int i;
503 
504         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
505                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
506                 if (nid)
507                         via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
508         }
509 }
510 
511 static void via_auto_init_hp_out(struct hda_codec *codec)
512 {
513         struct via_spec *spec = codec->spec;
514         hda_nid_t pin;
515         int i;
516 
517         for (i = 0; i < spec->autocfg.hp_outs; i++) {
518                 pin = spec->autocfg.hp_pins[i];
519                 if (pin) /* connect to front */
520                         via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
521         }
522 }
523 
524 static void via_auto_init_analog_input(struct hda_codec *codec)
525 {
526         struct via_spec *spec = codec->spec;
527         int i;
528 
529         for (i = 0; i < AUTO_PIN_LAST; i++) {
530                 hda_nid_t nid = spec->autocfg.input_pins[i];
531 
532                 snd_hda_codec_write(codec, nid, 0,
533                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
534                                     (i <= AUTO_PIN_FRONT_MIC ?
535                                      PIN_VREF50 : PIN_IN));
536 
537         }
538 }
539 
540 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
541 
542 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
543                                 unsigned int *affected_parm)
544 {
545         unsigned parm;
546         unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
547         unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
548                 >> AC_DEFCFG_MISC_SHIFT
549                 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
550         unsigned present = snd_hda_jack_detect(codec, nid);
551         struct via_spec *spec = codec->spec;
552         if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
553             || ((no_presence || present)
554                 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
555                 *affected_parm = AC_PWRST_D0; /* if it's connected */
556                 parm = AC_PWRST_D0;
557         } else
558                 parm = AC_PWRST_D3;
559 
560         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
561 }
562 
563 static void set_jack_power_state(struct hda_codec *codec)
564 {
565         struct via_spec *spec = codec->spec;
566         int imux_is_smixer;
567         unsigned int parm;
568 
569         if (spec->codec_type == VT1702) {
570                 imux_is_smixer = snd_hda_codec_read(
571                         codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
572                 /* inputs */
573                 /* PW 1/2/5 (14h/15h/18h) */
574                 parm = AC_PWRST_D3;
575                 set_pin_power_state(codec, 0x14, &parm);
576                 set_pin_power_state(codec, 0x15, &parm);
577                 set_pin_power_state(codec, 0x18, &parm);
578                 if (imux_is_smixer)
579                         parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
580                 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
581                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
582                                     parm);
583                 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
584                                     parm);
585                 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
586                                     parm);
587                 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
588                                     parm);
589 
590                 /* outputs */
591                 /* PW 3/4 (16h/17h) */
592                 parm = AC_PWRST_D3;
593                 set_pin_power_state(codec, 0x16, &parm);
594                 set_pin_power_state(codec, 0x17, &parm);
595                 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
596                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
597                                     imux_is_smixer ? AC_PWRST_D0 : parm);
598                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
599                                     parm);
600                 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
601                                     parm);
602         } else if (spec->codec_type == VT1708B_8CH
603                    || spec->codec_type == VT1708B_4CH
604                    || spec->codec_type == VT1708S) {
605                 /* SW0 (17h) = stereo mixer */
606                 int is_8ch = spec->codec_type != VT1708B_4CH;
607                 imux_is_smixer = snd_hda_codec_read(
608                         codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
609                         == ((spec->codec_type == VT1708S)  ? 5 : 0);
610                 /* inputs */
611                 /* PW 1/2/5 (1ah/1bh/1eh) */
612                 parm = AC_PWRST_D3;
613                 set_pin_power_state(codec, 0x1a, &parm);
614                 set_pin_power_state(codec, 0x1b, &parm);
615                 set_pin_power_state(codec, 0x1e, &parm);
616                 if (imux_is_smixer)
617                         parm = AC_PWRST_D0;
618                 /* SW0 (17h), AIW 0/1 (13h/14h) */
619                 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
620                                     parm);
621                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
622                                     parm);
623                 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
624                                     parm);
625 
626                 /* outputs */
627                 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
628                 parm = AC_PWRST_D3;
629                 set_pin_power_state(codec, 0x19, &parm);
630                 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
631                                     parm);
632                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
633                                     parm);
634 
635                 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
636                 if (is_8ch) {
637                         parm = AC_PWRST_D3;
638                         set_pin_power_state(codec, 0x22, &parm);
639                         snd_hda_codec_write(codec, 0x26, 0,
640                                             AC_VERB_SET_POWER_STATE, parm);
641                         snd_hda_codec_write(codec, 0x24, 0,
642                                             AC_VERB_SET_POWER_STATE, parm);
643                 }
644 
645                 /* PW 3/4/7 (1ch/1dh/23h) */
646                 parm = AC_PWRST_D3;
647                 /* force to D0 for internal Speaker */
648                 set_pin_power_state(codec, 0x1c, &parm);
649                 set_pin_power_state(codec, 0x1d, &parm);
650                 if (is_8ch)
651                         set_pin_power_state(codec, 0x23, &parm);
652                 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
653                 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
654                                     imux_is_smixer ? AC_PWRST_D0 : parm);
655                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
656                                     parm);
657                 if (is_8ch) {
658                         snd_hda_codec_write(codec, 0x25, 0,
659                                             AC_VERB_SET_POWER_STATE, parm);
660                         snd_hda_codec_write(codec, 0x27, 0,
661                                             AC_VERB_SET_POWER_STATE, parm);
662                 }
663         }  else if (spec->codec_type == VT1718S) {
664                 /* MUX6 (1eh) = stereo mixer */
665                 imux_is_smixer = snd_hda_codec_read(
666                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
667                 /* inputs */
668                 /* PW 5/6/7 (29h/2ah/2bh) */
669                 parm = AC_PWRST_D3;
670                 set_pin_power_state(codec, 0x29, &parm);
671                 set_pin_power_state(codec, 0x2a, &parm);
672                 set_pin_power_state(codec, 0x2b, &parm);
673                 if (imux_is_smixer)
674                         parm = AC_PWRST_D0;
675                 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
676                 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
677                                     parm);
678                 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
679                                     parm);
680                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
681                                     parm);
682                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
683                                     parm);
684 
685                 /* outputs */
686                 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
687                 parm = AC_PWRST_D3;
688                 set_pin_power_state(codec, 0x27, &parm);
689                 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
690                                     parm);
691                 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
692                                     parm);
693 
694                 /* PW2 (26h), AOW2 (ah) */
695                 parm = AC_PWRST_D3;
696                 set_pin_power_state(codec, 0x26, &parm);
697                 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
698                                     parm);
699 
700                 /* PW0/1 (24h/25h) */
701                 parm = AC_PWRST_D3;
702                 set_pin_power_state(codec, 0x24, &parm);
703                 set_pin_power_state(codec, 0x25, &parm);
704                 if (!spec->hp_independent_mode) /* check for redirected HP */
705                         set_pin_power_state(codec, 0x28, &parm);
706                 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
707                                     parm);
708                 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
709                                     parm);
710                 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
711                 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
712                                     imux_is_smixer ? AC_PWRST_D0 : parm);
713                 if (spec->hp_independent_mode) {
714                         /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
715                         parm = AC_PWRST_D3;
716                         set_pin_power_state(codec, 0x28, &parm);
717                         snd_hda_codec_write(codec, 0x1b, 0,
718                                             AC_VERB_SET_POWER_STATE, parm);
719                         snd_hda_codec_write(codec, 0x34, 0,
720                                             AC_VERB_SET_POWER_STATE, parm);
721                         snd_hda_codec_write(codec, 0xc, 0,
722                                             AC_VERB_SET_POWER_STATE, parm);
723                 }
724         } else if (spec->codec_type == VT1716S) {
725                 unsigned int mono_out, present;
726                 /* SW0 (17h) = stereo mixer */
727                 imux_is_smixer = snd_hda_codec_read(
728                         codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) ==  5;
729                 /* inputs */
730                 /* PW 1/2/5 (1ah/1bh/1eh) */
731                 parm = AC_PWRST_D3;
732                 set_pin_power_state(codec, 0x1a, &parm);
733                 set_pin_power_state(codec, 0x1b, &parm);
734                 set_pin_power_state(codec, 0x1e, &parm);
735                 if (imux_is_smixer)
736                         parm = AC_PWRST_D0;
737                 /* SW0 (17h), AIW0(13h) */
738                 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
739                                     parm);
740                 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
741                                     parm);
742 
743                 parm = AC_PWRST_D3;
744                 set_pin_power_state(codec, 0x1e, &parm);
745                 /* PW11 (22h) */
746                 if (spec->dmic_enabled)
747                         set_pin_power_state(codec, 0x22, &parm);
748                 else
749                         snd_hda_codec_write(
750                                 codec, 0x22, 0,
751                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
752 
753                 /* SW2(26h), AIW1(14h) */
754                 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
755                                     parm);
756                 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
757                                     parm);
758 
759                 /* outputs */
760                 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
761                 parm = AC_PWRST_D3;
762                 set_pin_power_state(codec, 0x19, &parm);
763                 /* Smart 5.1 PW2(1bh) */
764                 if (spec->smart51_enabled)
765                         set_pin_power_state(codec, 0x1b, &parm);
766                 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
767                                     parm);
768                 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
769                                     parm);
770 
771                 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
772                 parm = AC_PWRST_D3;
773                 set_pin_power_state(codec, 0x23, &parm);
774                 /* Smart 5.1 PW1(1ah) */
775                 if (spec->smart51_enabled)
776                         set_pin_power_state(codec, 0x1a, &parm);
777                 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
778                                     parm);
779 
780                 /* Smart 5.1 PW5(1eh) */
781                 if (spec->smart51_enabled)
782                         set_pin_power_state(codec, 0x1e, &parm);
783                 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
784                                     parm);
785 
786                 /* Mono out */
787                 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
788                 present = snd_hda_jack_detect(codec, 0x1c);
789                 if (present)
790                         mono_out = 0;
791                 else {
792                         present = snd_hda_jack_detect(codec, 0x1d);
793                         if (!spec->hp_independent_mode && present)
794                                 mono_out = 0;
795                         else
796                                 mono_out = 1;
797                 }
798                 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
799                 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
800                                     parm);
801                 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
802                                     parm);
803                 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
804                                     parm);
805 
806                 /* PW 3/4 (1ch/1dh) */
807                 parm = AC_PWRST_D3;
808                 set_pin_power_state(codec, 0x1c, &parm);
809                 set_pin_power_state(codec, 0x1d, &parm);
810                 /* HP Independent Mode, power on AOW3 */
811                 if (spec->hp_independent_mode)
812                         snd_hda_codec_write(codec, 0x25, 0,
813                                             AC_VERB_SET_POWER_STATE, parm);
814 
815                 /* force to D0 for internal Speaker */
816                 /* MW0 (16h), AOW0 (10h) */
817                 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
818                                     imux_is_smixer ? AC_PWRST_D0 : parm);
819                 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
820                                     mono_out ? AC_PWRST_D0 : parm);
821         } else if (spec->codec_type == VT2002P) {
822                 unsigned int present;
823                 /* MUX9 (1eh) = stereo mixer */
824                 imux_is_smixer = snd_hda_codec_read(
825                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
826                 /* inputs */
827                 /* PW 5/6/7 (29h/2ah/2bh) */
828                 parm = AC_PWRST_D3;
829                 set_pin_power_state(codec, 0x29, &parm);
830                 set_pin_power_state(codec, 0x2a, &parm);
831                 set_pin_power_state(codec, 0x2b, &parm);
832                 if (imux_is_smixer)
833                         parm = AC_PWRST_D0;
834                 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
835                 snd_hda_codec_write(codec, 0x1e, 0,
836                                     AC_VERB_SET_POWER_STATE, parm);
837                 snd_hda_codec_write(codec, 0x1f, 0,
838                                     AC_VERB_SET_POWER_STATE, parm);
839                 snd_hda_codec_write(codec, 0x10, 0,
840                                     AC_VERB_SET_POWER_STATE, parm);
841                 snd_hda_codec_write(codec, 0x11, 0,
842                                     AC_VERB_SET_POWER_STATE, parm);
843 
844                 /* outputs */
845                 /* AOW0 (8h)*/
846                 snd_hda_codec_write(codec, 0x8, 0,
847                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
848 
849                 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
850                 parm = AC_PWRST_D3;
851                 set_pin_power_state(codec, 0x26, &parm);
852                 snd_hda_codec_write(codec, 0x1c, 0,
853                                     AC_VERB_SET_POWER_STATE, parm);
854                 snd_hda_codec_write(codec, 0x37,
855                                     0, AC_VERB_SET_POWER_STATE, parm);
856 
857                 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
858                 parm = AC_PWRST_D3;
859                 set_pin_power_state(codec, 0x25, &parm);
860                 snd_hda_codec_write(codec, 0x19, 0,
861                                     AC_VERB_SET_POWER_STATE, parm);
862                 snd_hda_codec_write(codec, 0x35, 0,
863                                     AC_VERB_SET_POWER_STATE, parm);
864                 if (spec->hp_independent_mode)  {
865                         snd_hda_codec_write(codec, 0x9, 0,
866                                             AC_VERB_SET_POWER_STATE, parm);
867                 }
868 
869                 /* Class-D */
870                 /* PW0 (24h), MW0(18h), MUX0(34h) */
871                 present = snd_hda_jack_detect(codec, 0x25);
872                 parm = AC_PWRST_D3;
873                 set_pin_power_state(codec, 0x24, &parm);
874                 if (present) {
875                         snd_hda_codec_write(
876                                 codec, 0x18, 0,
877                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
878                         snd_hda_codec_write(
879                                 codec, 0x34, 0,
880                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
881                 } else {
882                         snd_hda_codec_write(
883                                 codec, 0x18, 0,
884                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
885                         snd_hda_codec_write(
886                                 codec, 0x34, 0,
887                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
888                 }
889 
890                 /* Mono Out */
891                 /* PW15 (31h), MW8(17h), MUX8(3bh) */
892                 present = snd_hda_jack_detect(codec, 0x26);
893                 parm = AC_PWRST_D3;
894                 set_pin_power_state(codec, 0x31, &parm);
895                 if (present) {
896                         snd_hda_codec_write(
897                                 codec, 0x17, 0,
898                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
899                         snd_hda_codec_write(
900                                 codec, 0x3b, 0,
901                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
902                 } else {
903                         snd_hda_codec_write(
904                                 codec, 0x17, 0,
905                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
906                         snd_hda_codec_write(
907                                 codec, 0x3b, 0,
908                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
909                 }
910 
911                 /* MW9 (21h) */
912                 if (imux_is_smixer || !is_aa_path_mute(codec))
913                         snd_hda_codec_write(
914                                 codec, 0x21, 0,
915                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
916                 else
917                         snd_hda_codec_write(
918                                 codec, 0x21, 0,
919                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
920         } else if (spec->codec_type == VT1812) {
921                 unsigned int present;
922                 /* MUX10 (1eh) = stereo mixer */
923                 imux_is_smixer = snd_hda_codec_read(
924                         codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
925                 /* inputs */
926                 /* PW 5/6/7 (29h/2ah/2bh) */
927                 parm = AC_PWRST_D3;
928                 set_pin_power_state(codec, 0x29, &parm);
929                 set_pin_power_state(codec, 0x2a, &parm);
930                 set_pin_power_state(codec, 0x2b, &parm);
931                 if (imux_is_smixer)
932                         parm = AC_PWRST_D0;
933                 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
934                 snd_hda_codec_write(codec, 0x1e, 0,
935                                     AC_VERB_SET_POWER_STATE, parm);
936                 snd_hda_codec_write(codec, 0x1f, 0,
937                                     AC_VERB_SET_POWER_STATE, parm);
938                 snd_hda_codec_write(codec, 0x10, 0,
939                                     AC_VERB_SET_POWER_STATE, parm);
940                 snd_hda_codec_write(codec, 0x11, 0,
941                                     AC_VERB_SET_POWER_STATE, parm);
942 
943                 /* outputs */
944                 /* AOW0 (8h)*/
945                 snd_hda_codec_write(codec, 0x8, 0,
946                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
947 
948                 /* PW4 (28h), MW4 (18h), MUX4(38h) */
949                 parm = AC_PWRST_D3;
950                 set_pin_power_state(codec, 0x28, &parm);
951                 snd_hda_codec_write(codec, 0x18, 0,
952                                     AC_VERB_SET_POWER_STATE, parm);
953                 snd_hda_codec_write(codec, 0x38, 0,
954                                     AC_VERB_SET_POWER_STATE, parm);
955 
956                 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
957                 parm = AC_PWRST_D3;
958                 set_pin_power_state(codec, 0x25, &parm);
959                 snd_hda_codec_write(codec, 0x15, 0,
960                                     AC_VERB_SET_POWER_STATE, parm);
961                 snd_hda_codec_write(codec, 0x35, 0,
962                                     AC_VERB_SET_POWER_STATE, parm);
963                 if (spec->hp_independent_mode)  {
964                         snd_hda_codec_write(codec, 0x9, 0,
965                                             AC_VERB_SET_POWER_STATE, parm);
966                 }
967 
968                 /* Internal Speaker */
969                 /* PW0 (24h), MW0(14h), MUX0(34h) */
970                 present = snd_hda_jack_detect(codec, 0x25);
971                 parm = AC_PWRST_D3;
972                 set_pin_power_state(codec, 0x24, &parm);
973                 if (present) {
974                         snd_hda_codec_write(codec, 0x14, 0,
975                                             AC_VERB_SET_POWER_STATE,
976                                             AC_PWRST_D3);
977                         snd_hda_codec_write(codec, 0x34, 0,
978                                             AC_VERB_SET_POWER_STATE,
979                                             AC_PWRST_D3);
980                 } else {
981                         snd_hda_codec_write(codec, 0x14, 0,
982                                             AC_VERB_SET_POWER_STATE,
983                                             AC_PWRST_D0);
984                         snd_hda_codec_write(codec, 0x34, 0,
985                                             AC_VERB_SET_POWER_STATE,
986                                             AC_PWRST_D0);
987                 }
988                 /* Mono Out */
989                 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
990                 present = snd_hda_jack_detect(codec, 0x28);
991                 parm = AC_PWRST_D3;
992                 set_pin_power_state(codec, 0x31, &parm);
993                 if (present) {
994                         snd_hda_codec_write(codec, 0x1c, 0,
995                                             AC_VERB_SET_POWER_STATE,
996                                             AC_PWRST_D3);
997                         snd_hda_codec_write(codec, 0x3c, 0,
998                                             AC_VERB_SET_POWER_STATE,
999                                             AC_PWRST_D3);
1000                         snd_hda_codec_write(codec, 0x3e, 0,
1001                                             AC_VERB_SET_POWER_STATE,
1002                                             AC_PWRST_D3);
1003                 } else {
1004                         snd_hda_codec_write(codec, 0x1c, 0,
1005                                             AC_VERB_SET_POWER_STATE,
1006                                             AC_PWRST_D0);
1007                         snd_hda_codec_write(codec, 0x3c, 0,
1008                                             AC_VERB_SET_POWER_STATE,
1009                                             AC_PWRST_D0);
1010                         snd_hda_codec_write(codec, 0x3e, 0,
1011                                             AC_VERB_SET_POWER_STATE,
1012                                             AC_PWRST_D0);
1013                 }
1014 
1015                 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1016                 parm = AC_PWRST_D3;
1017                 set_pin_power_state(codec, 0x33, &parm);
1018                 snd_hda_codec_write(codec, 0x1d, 0,
1019                                     AC_VERB_SET_POWER_STATE, parm);
1020                 snd_hda_codec_write(codec, 0x3d, 0,
1021                                     AC_VERB_SET_POWER_STATE, parm);
1022 
1023                 /* MW9 (21h) */
1024                 if (imux_is_smixer || !is_aa_path_mute(codec))
1025                         snd_hda_codec_write(
1026                                 codec, 0x21, 0,
1027                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1028                 else
1029                         snd_hda_codec_write(
1030                                 codec, 0x21, 0,
1031                                 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1032         }
1033 }
1034 
1035 /*
1036  * input MUX handling
1037  */
1038 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1039                              struct snd_ctl_elem_info *uinfo)
1040 {
1041         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1042         struct via_spec *spec = codec->spec;
1043         return snd_hda_input_mux_info(spec->input_mux, uinfo);
1044 }
1045 
1046 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1047                             struct snd_ctl_elem_value *ucontrol)
1048 {
1049         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1050         struct via_spec *spec = codec->spec;
1051         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1052 
1053         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1054         return 0;
1055 }
1056 
1057 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1058                             struct snd_ctl_elem_value *ucontrol)
1059 {
1060         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1061         struct via_spec *spec = codec->spec;
1062         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1063 
1064         if (!spec->mux_nids[adc_idx])
1065                 return -EINVAL;
1066         /* switch to D0 beofre change index */
1067         if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1068                                AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1069                 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1070                                     AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1071         /* update jack power state */
1072         set_jack_power_state(codec);
1073 
1074         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1075                                      spec->mux_nids[adc_idx],
1076                                      &spec->cur_mux[adc_idx]);
1077 }
1078 
1079 static int via_independent_hp_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->hp_mux, uinfo);
1085 }
1086 
1087 static int via_independent_hp_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         hda_nid_t nid;
1093         unsigned int pinsel;
1094 
1095         switch (spec->codec_type) {
1096         case VT1718S:
1097                 nid = 0x34;
1098                 break;
1099         case VT2002P:
1100                 nid = 0x35;
1101                 break;
1102         case VT1812:
1103                 nid = 0x3d;
1104                 break;
1105         default:
1106                 nid = spec->autocfg.hp_pins[0];
1107                 break;
1108         }
1109         /* use !! to translate conn sel 2 for VT1718S */
1110         pinsel = !!snd_hda_codec_read(codec, nid, 0,
1111                                       AC_VERB_GET_CONNECT_SEL,
1112                                       0x00);
1113         ucontrol->value.enumerated.item[0] = pinsel;
1114 
1115         return 0;
1116 }
1117 
1118 static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1119 {
1120         struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1121         if (ctl) {
1122                 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1123                 ctl->vd[0].access |= active
1124                         ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1125                 snd_ctl_notify(codec->bus->card,
1126                                SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1127         }
1128 }
1129 
1130 static int update_side_mute_status(struct hda_codec *codec)
1131 {
1132         /* mute side channel */
1133         struct via_spec *spec = codec->spec;
1134         unsigned int parm = spec->hp_independent_mode
1135                 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1136         hda_nid_t sw3;
1137 
1138         switch (spec->codec_type) {
1139         case VT1708:
1140                 sw3 = 0x1b;
1141                 break;
1142         case VT1709_10CH:
1143                 sw3 = 0x29;
1144                 break;
1145         case VT1708B_8CH:
1146         case VT1708S:
1147                 sw3 = 0x27;
1148                 break;
1149         default:
1150                 sw3 = 0;
1151                 break;
1152         }
1153 
1154         if (sw3)
1155                 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1156                                     parm);
1157         return 0;
1158 }
1159 
1160 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1161                                   struct snd_ctl_elem_value *ucontrol)
1162 {
1163         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1164         struct via_spec *spec = codec->spec;
1165         hda_nid_t nid = spec->autocfg.hp_pins[0];
1166         unsigned int pinsel = ucontrol->value.enumerated.item[0];
1167         /* Get Independent Mode index of headphone pin widget */
1168         spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1169                 ? 1 : 0;
1170 
1171         switch (spec->codec_type) {
1172         case VT1718S:
1173                 nid = 0x34;
1174                 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
1175                 spec->multiout.num_dacs = 4;
1176                 break;
1177         case VT2002P:
1178                 nid = 0x35;
1179                 break;
1180         case VT1812:
1181                 nid = 0x3d;
1182                 break;
1183         default:
1184                 nid = spec->autocfg.hp_pins[0];
1185                 break;
1186         }
1187         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1188 
1189         if (spec->multiout.hp_nid && spec->multiout.hp_nid
1190             != spec->multiout.dac_nids[HDA_FRONT])
1191                 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1192                                            0, 0, 0);
1193 
1194         update_side_mute_status(codec);
1195         /* update HP volume/swtich active state */
1196         if (spec->codec_type == VT1708S
1197             || spec->codec_type == VT1702
1198             || spec->codec_type == VT1718S
1199             || spec->codec_type == VT1716S
1200             || spec->codec_type == VT2002P
1201             || spec->codec_type == VT1812) {
1202                 activate_ctl(codec, "Headphone Playback Volume",
1203                              spec->hp_independent_mode);
1204                 activate_ctl(codec, "Headphone Playback Switch",
1205                              spec->hp_independent_mode);
1206         }
1207         return 0;
1208 }
1209 
1210 static struct snd_kcontrol_new via_hp_mixer[] = {
1211         {
1212                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213                 .name = "Independent HP",
1214                 .count = 1,
1215                 .info = via_independent_hp_info,
1216                 .get = via_independent_hp_get,
1217                 .put = via_independent_hp_put,
1218         },
1219         { } /* end */
1220 };
1221 
1222 static void notify_aa_path_ctls(struct hda_codec *codec)
1223 {
1224         int i;
1225         struct snd_ctl_elem_id id;
1226         const char *labels[] = {"Mic", "Front Mic", "Line"};
1227 
1228         memset(&id, 0, sizeof(id));
1229         id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1230         for (i = 0; i < ARRAY_SIZE(labels); i++) {
1231                 sprintf(id.name, "%s Playback Volume", labels[i]);
1232                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1233                                &id);
1234         }
1235 }
1236 
1237 static void mute_aa_path(struct hda_codec *codec, int mute)
1238 {
1239         struct via_spec *spec = codec->spec;
1240         hda_nid_t  nid_mixer;
1241         int start_idx;
1242         int end_idx;
1243         int i;
1244         /* get nid of MW0 and start & end index */
1245         switch (spec->codec_type) {
1246         case VT1708:
1247                 nid_mixer = 0x17;
1248                 start_idx = 2;
1249                 end_idx = 4;
1250                 break;
1251         case VT1709_10CH:
1252         case VT1709_6CH:
1253                 nid_mixer = 0x18;
1254                 start_idx = 2;
1255                 end_idx = 4;
1256                 break;
1257         case VT1708B_8CH:
1258         case VT1708B_4CH:
1259         case VT1708S:
1260         case VT1716S:
1261                 nid_mixer = 0x16;
1262                 start_idx = 2;
1263                 end_idx = 4;
1264                 break;
1265         default:
1266                 return;
1267         }
1268         /* check AA path's mute status */
1269         for (i = start_idx; i <= end_idx; i++) {
1270                 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1271                 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1272                                          HDA_AMP_MUTE, val);
1273         }
1274 }
1275 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1276 {
1277         int res = 0;
1278         int index;
1279         for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
1280                 if (pin == spec->autocfg.input_pins[index]) {
1281                         res = 1;
1282                         break;
1283                 }
1284         }
1285         return res;
1286 }
1287 
1288 static int via_smart51_info(struct snd_kcontrol *kcontrol,
1289                             struct snd_ctl_elem_info *uinfo)
1290 {
1291         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1292         uinfo->count = 1;
1293         uinfo->value.integer.min = 0;
1294         uinfo->value.integer.max = 1;
1295         return 0;
1296 }
1297 
1298 static int via_smart51_get(struct snd_kcontrol *kcontrol,
1299                            struct snd_ctl_elem_value *ucontrol)
1300 {
1301         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1302         struct via_spec *spec = codec->spec;
1303         int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1304         int on = 1;
1305         int i;
1306 
1307         for (i = 0; i < ARRAY_SIZE(index); i++) {
1308                 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1309                 if (nid) {
1310                         int ctl =
1311                             snd_hda_codec_read(codec, nid, 0,
1312                                                AC_VERB_GET_PIN_WIDGET_CONTROL,
1313                                                0);
1314                         if (i == AUTO_PIN_FRONT_MIC
1315                             && spec->hp_independent_mode
1316                             && spec->codec_type != VT1718S)
1317                                 continue; /* ignore FMic for independent HP */
1318                         if (ctl & AC_PINCTL_IN_EN
1319                             && !(ctl & AC_PINCTL_OUT_EN))
1320                                 on = 0;
1321                 }
1322         }
1323         *ucontrol->value.integer.value = on;
1324         return 0;
1325 }
1326 
1327 static int via_smart51_put(struct snd_kcontrol *kcontrol,
1328                            struct snd_ctl_elem_value *ucontrol)
1329 {
1330         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1331         struct via_spec *spec = codec->spec;
1332         int out_in = *ucontrol->value.integer.value
1333                 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1334         int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1335         int i;
1336 
1337         for (i = 0; i < ARRAY_SIZE(index); i++) {
1338                 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1339                 if (i == AUTO_PIN_FRONT_MIC
1340                     && spec->hp_independent_mode
1341                     && spec->codec_type != VT1718S)
1342                         continue; /* don't retask FMic for independent HP */
1343                 if (nid) {
1344                         unsigned int parm = snd_hda_codec_read(
1345                                 codec, nid, 0,
1346                                 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1347                         parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1348                         parm |= out_in;
1349                         snd_hda_codec_write(codec, nid, 0,
1350                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
1351                                             parm);
1352                         if (out_in == AC_PINCTL_OUT_EN) {
1353                                 mute_aa_path(codec, 1);
1354                                 notify_aa_path_ctls(codec);
1355                         }
1356                         if (spec->codec_type == VT1718S)
1357                                 snd_hda_codec_amp_stereo(
1358                                         codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1359                                         HDA_AMP_UNMUTE);
1360                 }
1361                 if (i == AUTO_PIN_FRONT_MIC) {
1362                         if (spec->codec_type == VT1708S
1363                             || spec->codec_type == VT1716S) {
1364                                 /* input = index 1 (AOW3) */
1365                                 snd_hda_codec_write(
1366                                         codec, nid, 0,
1367                                         AC_VERB_SET_CONNECT_SEL, 1);
1368                                 snd_hda_codec_amp_stereo(
1369                                         codec, nid, HDA_OUTPUT,
1370                                         0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1371                         }
1372                 }
1373         }
1374         spec->smart51_enabled = *ucontrol->value.integer.value;
1375         set_jack_power_state(codec);
1376         return 1;
1377 }
1378 
1379 static struct snd_kcontrol_new via_smart51_mixer[] = {
1380         {
1381          .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1382          .name = "Smart 5.1",
1383          .count = 1,
1384          .info = via_smart51_info,
1385          .get = via_smart51_get,
1386          .put = via_smart51_put,
1387          },
1388         {}                      /* end */
1389 };
1390 
1391 /* capture mixer elements */
1392 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1393         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1394         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1395         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1396         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1397         {
1398                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1399                 /* The multiple "Capture Source" controls confuse alsamixer
1400                  * So call somewhat different..
1401                  */
1402                 /* .name = "Capture Source", */
1403                 .name = "Input Source",
1404                 .count = 1,
1405                 .info = via_mux_enum_info,
1406                 .get = via_mux_enum_get,
1407                 .put = via_mux_enum_put,
1408         },
1409         { } /* end */
1410 };
1411 
1412 /* check AA path's mute statue */
1413 static int is_aa_path_mute(struct hda_codec *codec)
1414 {
1415         int mute = 1;
1416         hda_nid_t  nid_mixer;
1417         int start_idx;
1418         int end_idx;
1419         int i;
1420         struct via_spec *spec = codec->spec;
1421         /* get nid of MW0 and start & end index */
1422         switch (spec->codec_type) {
1423         case VT1708B_8CH:
1424         case VT1708B_4CH:
1425         case VT1708S:
1426         case VT1716S:
1427                 nid_mixer = 0x16;
1428                 start_idx = 2;
1429                 end_idx = 4;
1430                 break;
1431         case VT1702:
1432                 nid_mixer = 0x1a;
1433                 start_idx = 1;
1434                 end_idx = 3;
1435                 break;
1436         case VT1718S:
1437                 nid_mixer = 0x21;
1438                 start_idx = 1;
1439                 end_idx = 3;
1440                 break;
1441         case VT2002P:
1442         case VT1812:
1443                 nid_mixer = 0x21;
1444                 start_idx = 0;
1445                 end_idx = 2;
1446                 break;
1447         default:
1448                 return 0;
1449         }
1450         /* check AA path's mute status */
1451         for (i = start_idx; i <= end_idx; i++) {
1452                 unsigned int con_list = snd_hda_codec_read(
1453                         codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1454                 int shift = 8 * (i % 4);
1455                 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1456                 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1457                 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1458                         /* check mute status while the pin is connected */
1459                         int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1460                                                             HDA_INPUT, i) >> 7;
1461                         int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1462                                                             HDA_INPUT, i) >> 7;
1463                         if (!mute_l || !mute_r) {
1464                                 mute = 0;
1465                                 break;
1466                         }
1467                 }
1468         }
1469         return mute;
1470 }
1471 
1472 /* enter/exit analog low-current mode */
1473 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1474 {
1475         struct via_spec *spec = codec->spec;
1476         static int saved_stream_idle = 1; /* saved stream idle status */
1477         int enable = is_aa_path_mute(codec);
1478         unsigned int verb = 0;
1479         unsigned int parm = 0;
1480 
1481         if (stream_idle == -1)  /* stream status did not change */
1482                 enable = enable && saved_stream_idle;
1483         else {
1484                 enable = enable && stream_idle;
1485                 saved_stream_idle = stream_idle;
1486         }
1487 
1488         /* decide low current mode's verb & parameter */
1489         switch (spec->codec_type) {
1490         case VT1708B_8CH:
1491         case VT1708B_4CH:
1492                 verb = 0xf70;
1493                 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1494                 break;
1495         case VT1708S:
1496         case VT1718S:
1497         case VT1716S:
1498                 verb = 0xf73;
1499                 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1500                 break;
1501         case VT1702:
1502                 verb = 0xf73;
1503                 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1504                 break;
1505         case VT2002P:
1506         case VT1812:
1507                 verb = 0xf93;
1508                 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1509                 break;
1510         default:
1511                 return;         /* other codecs are not supported */
1512         }
1513         /* send verb */
1514         snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1515 }
1516 
1517 /*
1518  * generic initialization of ADC, input mixers and output mixers
1519  */
1520 static struct hda_verb vt1708_volume_init_verbs[] = {
1521         /*
1522          * Unmute ADC0-1 and set the default input to mic-in
1523          */
1524         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1525         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1526 
1527 
1528         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1529          * mixer widget
1530          */
1531         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1532         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1533         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1534         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1535         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1536         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1537 
1538         /*
1539          * Set up output mixers (0x19 - 0x1b)
1540          */
1541         /* set vol=0 to output mixers */
1542         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1543         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1544         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1545 
1546         /* Setup default input MW0 to PW4 */
1547         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1548         /* PW9 Output enable */
1549         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1550         { }
1551 };
1552 
1553 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1554                                  struct hda_codec *codec,
1555                                  struct snd_pcm_substream *substream)
1556 {
1557         struct via_spec *spec = codec->spec;
1558         int idle = substream->pstr->substream_opened == 1
1559                 && substream->ref_count == 0;
1560         analog_low_current_mode(codec, idle);
1561         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1562                                              hinfo);
1563 }
1564 
1565 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1566                                       unsigned int stream_tag,
1567                                       unsigned int format,
1568                                       struct snd_pcm_substream *substream)
1569 {
1570         struct via_spec *spec = codec->spec;
1571         struct hda_multi_out *mout = &spec->multiout;
1572         hda_nid_t *nids = mout->dac_nids;
1573         int chs = substream->runtime->channels;
1574         int i;
1575 
1576         mutex_lock(&codec->spdif_mutex);
1577         if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1578                 if (chs == 2 &&
1579                     snd_hda_is_supported_format(codec, mout->dig_out_nid,
1580                                                 format) &&
1581                     !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1582                         mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1583                         /* turn off SPDIF once; otherwise the IEC958 bits won't
1584                          * be updated */
1585                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
1586                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1587                                                     AC_VERB_SET_DIGI_CONVERT_1,
1588                                                     codec->spdif_ctls &
1589                                                         ~AC_DIG1_ENABLE & 0xff);
1590                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1591                                                    stream_tag, 0, format);
1592                         /* turn on again (if needed) */
1593                         if (codec->spdif_ctls & AC_DIG1_ENABLE)
1594                                 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1595                                                     AC_VERB_SET_DIGI_CONVERT_1,
1596                                                     codec->spdif_ctls & 0xff);
1597                 } else {
1598                         mout->dig_out_used = 0;
1599                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1600                                                    0, 0, 0);
1601                 }
1602         }
1603         mutex_unlock(&codec->spdif_mutex);
1604 
1605         /* front */
1606         snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1607                                    0, format);
1608 
1609         if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1610             && !spec->hp_independent_mode)
1611                 /* headphone out will just decode front left/right (stereo) */
1612                 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1613                                            0, format);
1614 
1615         /* extra outputs copied from front */
1616         for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1617                 if (mout->extra_out_nid[i])
1618                         snd_hda_codec_setup_stream(codec,
1619                                                    mout->extra_out_nid[i],
1620                                                    stream_tag, 0, format);
1621 
1622         /* surrounds */
1623         for (i = 1; i < mout->num_dacs; i++) {
1624                 if (chs >= (i + 1) * 2) /* independent out */
1625                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1626                                                    i * 2, format);
1627                 else /* copy front */
1628                         snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1629                                                    0, format);
1630         }
1631 }
1632 
1633 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1634                                           struct hda_codec *codec,
1635                                           unsigned int stream_tag,
1636                                           unsigned int format,
1637                                           struct snd_pcm_substream *substream)
1638 {
1639         struct via_spec *spec = codec->spec;
1640         struct hda_multi_out *mout = &spec->multiout;
1641         hda_nid_t *nids = mout->dac_nids;
1642 
1643         if (substream->number == 0)
1644                 playback_multi_pcm_prep_0(codec, stream_tag, format,
1645                                           substream);
1646         else {
1647                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1648                     spec->hp_independent_mode)
1649                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1650                                                    stream_tag, 0, format);
1651         }
1652         vt1708_start_hp_work(spec);
1653         return 0;
1654 }
1655 
1656 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1657                                     struct hda_codec *codec,
1658                                     struct snd_pcm_substream *substream)
1659 {
1660         struct via_spec *spec = codec->spec;
1661         struct hda_multi_out *mout = &spec->multiout;
1662         hda_nid_t *nids = mout->dac_nids;
1663         int i;
1664 
1665         if (substream->number == 0) {
1666                 for (i = 0; i < mout->num_dacs; i++)
1667                         snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1668 
1669                 if (mout->hp_nid && !spec->hp_independent_mode)
1670                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1671                                                    0, 0, 0);
1672 
1673                 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1674                         if (mout->extra_out_nid[i])
1675                                 snd_hda_codec_setup_stream(codec,
1676                                                         mout->extra_out_nid[i],
1677                                                         0, 0, 0);
1678                 mutex_lock(&codec->spdif_mutex);
1679                 if (mout->dig_out_nid &&
1680                     mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1681                         snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1682                                                    0, 0, 0);
1683                         mout->dig_out_used = 0;
1684                 }
1685                 mutex_unlock(&codec->spdif_mutex);
1686         } else {
1687                 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1688                     spec->hp_independent_mode)
1689                         snd_hda_codec_setup_stream(codec, mout->hp_nid,
1690                                                    0, 0, 0);
1691         }
1692         vt1708_stop_hp_work(spec);
1693         return 0;
1694 }
1695 
1696 /*
1697  * Digital out
1698  */
1699 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1700                                      struct hda_codec *codec,
1701                                      struct snd_pcm_substream *substream)
1702 {
1703         struct via_spec *spec = codec->spec;
1704         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1705 }
1706 
1707 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1708                                       struct hda_codec *codec,
1709                                       struct snd_pcm_substream *substream)
1710 {
1711         struct via_spec *spec = codec->spec;
1712         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1713 }
1714 
1715 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1716                                         struct hda_codec *codec,
1717                                         unsigned int stream_tag,
1718                                         unsigned int format,
1719                                         struct snd_pcm_substream *substream)
1720 {
1721         struct via_spec *spec = codec->spec;
1722         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1723                                              stream_tag, format, substream);
1724 }
1725 
1726 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1727                                         struct hda_codec *codec,
1728                                         struct snd_pcm_substream *substream)
1729 {
1730         struct via_spec *spec = codec->spec;
1731         snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1732         return 0;
1733 }
1734 
1735 /*
1736  * Analog capture
1737  */
1738 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1739                                    struct hda_codec *codec,
1740                                    unsigned int stream_tag,
1741                                    unsigned int format,
1742                                    struct snd_pcm_substream *substream)
1743 {
1744         struct via_spec *spec = codec->spec;
1745 
1746         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1747                                    stream_tag, 0, format);
1748         return 0;
1749 }
1750 
1751 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1752                                    struct hda_codec *codec,
1753                                    struct snd_pcm_substream *substream)
1754 {
1755         struct via_spec *spec = codec->spec;
1756         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1757         return 0;
1758 }
1759 
1760 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1761         .substreams = 2,
1762         .channels_min = 2,
1763         .channels_max = 8,
1764         .nid = 0x10, /* NID to query formats and rates */
1765         .ops = {
1766                 .open = via_playback_pcm_open,
1767                 .prepare = via_playback_multi_pcm_prepare,
1768                 .cleanup = via_playback_multi_pcm_cleanup
1769         },
1770 };
1771 
1772 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1773         .substreams = 2,
1774         .channels_min = 2,
1775         .channels_max = 8,
1776         .nid = 0x10, /* NID to query formats and rates */
1777         /* We got noisy outputs on the right channel on VT1708 when
1778          * 24bit samples are used.  Until any workaround is found,
1779          * disable the 24bit format, so far.
1780          */
1781         .formats = SNDRV_PCM_FMTBIT_S16_LE,
1782         .ops = {
1783                 .open = via_playback_pcm_open,
1784                 .prepare = via_playback_multi_pcm_prepare,
1785                 .cleanup = via_playback_multi_pcm_cleanup
1786         },
1787 };
1788 
1789 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1790         .substreams = 2,
1791         .channels_min = 2,
1792         .channels_max = 2,
1793         .nid = 0x15, /* NID to query formats and rates */
1794         .ops = {
1795                 .prepare = via_capture_pcm_prepare,
1796                 .cleanup = via_capture_pcm_cleanup
1797         },
1798 };
1799 
1800 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1801         .substreams = 1,
1802         .channels_min = 2,
1803         .channels_max = 2,
1804         /* NID is set in via_build_pcms */
1805         .ops = {
1806                 .open = via_dig_playback_pcm_open,
1807                 .close = via_dig_playback_pcm_close,
1808                 .prepare = via_dig_playback_pcm_prepare,
1809                 .cleanup = via_dig_playback_pcm_cleanup
1810         },
1811 };
1812 
1813 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1814         .substreams = 1,
1815         .channels_min = 2,
1816         .channels_max = 2,
1817 };
1818 
1819 static int via_build_controls(struct hda_codec *codec)
1820 {
1821         struct via_spec *spec = codec->spec;
1822         int err;
1823         int i;
1824 
1825         for (i = 0; i < spec->num_mixers; i++) {
1826                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1827                 if (err < 0)
1828                         return err;
1829         }
1830 
1831         if (spec->multiout.dig_out_nid) {
1832                 err = snd_hda_create_spdif_out_ctls(codec,
1833                                                     spec->multiout.dig_out_nid);
1834                 if (err < 0)
1835                         return err;
1836                 err = snd_hda_create_spdif_share_sw(codec,
1837                                                     &spec->multiout);
1838                 if (err < 0)
1839                         return err;
1840                 spec->multiout.share_spdif = 1;
1841         }
1842         if (spec->dig_in_nid) {
1843                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1844                 if (err < 0)
1845                         return err;
1846         }
1847 
1848         /* init power states */
1849         set_jack_power_state(codec);
1850         analog_low_current_mode(codec, 1);
1851 
1852         via_free_kctls(codec); /* no longer needed */
1853         return 0;
1854 }
1855 
1856 static int via_build_pcms(struct hda_codec *codec)
1857 {
1858         struct via_spec *spec = codec->spec;
1859         struct hda_pcm *info = spec->pcm_rec;
1860 
1861         codec->num_pcms = 1;
1862         codec->pcm_info = info;
1863 
1864         info->name = spec->stream_name_analog;
1865         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1866                 *(spec->stream_analog_playback);
1867         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1868                 spec->multiout.dac_nids[0];
1869         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1870         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1871 
1872         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1873                 spec->multiout.max_channels;
1874 
1875         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1876                 codec->num_pcms++;
1877                 info++;
1878                 info->name = spec->stream_name_digital;
1879                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1880                 if (spec->multiout.dig_out_nid) {
1881                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1882                                 *(spec->stream_digital_playback);
1883                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1884                                 spec->multiout.dig_out_nid;
1885                 }
1886                 if (spec->dig_in_nid) {
1887                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1888                                 *(spec->stream_digital_capture);
1889                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1890                                 spec->dig_in_nid;
1891                 }
1892         }
1893 
1894         return 0;
1895 }
1896 
1897 static void via_free(struct hda_codec *codec)
1898 {
1899         struct via_spec *spec = codec->spec;
1900 
1901         if (!spec)
1902                 return;
1903 
1904         via_free_kctls(codec);
1905         vt1708_stop_hp_work(spec);
1906         kfree(codec->spec);
1907 }
1908 
1909 /* mute internal speaker if HP is plugged */
1910 static void via_hp_automute(struct hda_codec *codec)
1911 {
1912         unsigned int present = 0;
1913         struct via_spec *spec = codec->spec;
1914 
1915         present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1916 
1917         if (!spec->hp_independent_mode) {
1918                 struct snd_ctl_elem_id id;
1919                 /* auto mute */
1920                 snd_hda_codec_amp_stereo(
1921                         codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
1922                         HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1923                 /* notify change */
1924                 memset(&id, 0, sizeof(id));
1925                 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1926                 strcpy(id.name, "Front Playback Switch");
1927                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1928                                &id);
1929         }
1930 }
1931 
1932 /* mute mono out if HP or Line out is plugged */
1933 static void via_mono_automute(struct hda_codec *codec)
1934 {
1935         unsigned int hp_present, lineout_present;
1936         struct via_spec *spec = codec->spec;
1937 
1938         if (spec->codec_type != VT1716S)
1939                 return;
1940 
1941         lineout_present = snd_hda_jack_detect(codec,
1942                                               spec->autocfg.line_out_pins[0]);
1943 
1944         /* Mute Mono Out if Line Out is plugged */
1945         if (lineout_present) {
1946                 snd_hda_codec_amp_stereo(
1947                         codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
1948                 return;
1949         }
1950 
1951         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1952 
1953         if (!spec->hp_independent_mode)
1954                 snd_hda_codec_amp_stereo(
1955                         codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1956                         hp_present ? HDA_AMP_MUTE : 0);
1957 }
1958 
1959 static void via_gpio_control(struct hda_codec *codec)
1960 {
1961         unsigned int gpio_data;
1962         unsigned int vol_counter;
1963         unsigned int vol;
1964         unsigned int master_vol;
1965 
1966         struct via_spec *spec = codec->spec;
1967 
1968         gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
1969                                        AC_VERB_GET_GPIO_DATA, 0) & 0x03;
1970 
1971         vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
1972                                           0xF84, 0) & 0x3F0000) >> 16;
1973 
1974         vol = vol_counter & 0x1F;
1975         master_vol = snd_hda_codec_read(codec, 0x1A, 0,
1976                                         AC_VERB_GET_AMP_GAIN_MUTE,
1977                                         AC_AMP_GET_INPUT);
1978 
1979         if (gpio_data == 0x02) {
1980                 /* unmute line out */
1981                 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
1982                                          HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
1983 
1984                 if (vol_counter & 0x20) {
1985                         /* decrease volume */
1986                         if (vol > master_vol)
1987                                 vol = master_vol;
1988                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1989                                                  0, HDA_AMP_VOLMASK,
1990                                                  master_vol-vol);
1991                 } else {
1992                         /* increase volume */
1993                         snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1994                                          HDA_AMP_VOLMASK,
1995                                          ((master_vol+vol) > 0x2A) ? 0x2A :
1996                                           (master_vol+vol));
1997                 }
1998         } else if (!(gpio_data & 0x02)) {
1999                 /* mute line out */
2000                 snd_hda_codec_amp_stereo(codec,
2001                                          spec->autocfg.line_out_pins[0],
2002                                          HDA_OUTPUT, 0, HDA_AMP_MUTE,
2003                                          HDA_AMP_MUTE);
2004         }
2005 }
2006 
2007 /* mute Internal-Speaker if HP is plugged */
2008 static void via_speaker_automute(struct hda_codec *codec)
2009 {
2010         unsigned int hp_present;
2011         struct via_spec *spec = codec->spec;
2012 
2013         if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2014                 return;
2015 
2016         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2017 
2018         if (!spec->hp_independent_mode) {
2019                 struct snd_ctl_elem_id id;
2020                 snd_hda_codec_amp_stereo(
2021                         codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2022                         HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2023                 /* notify change */
2024                 memset(&id, 0, sizeof(id));
2025                 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2026                 strcpy(id.name, "Speaker Playback Switch");
2027                 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2028                                &id);
2029         }
2030 }
2031 
2032 /* mute line-out and internal speaker if HP is plugged */
2033 static void via_hp_bind_automute(struct hda_codec *codec)
2034 {
2035         /* use long instead of int below just to avoid an internal compiler
2036          * error with gcc 4.0.x
2037          */
2038         unsigned long hp_present, present = 0;
2039         struct via_spec *spec = codec->spec;
2040         int i;
2041 
2042         if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2043                 return;
2044 
2045         hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2046 
2047         present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2048 
2049         if (!spec->hp_independent_mode) {
2050                 /* Mute Line-Outs */
2051                 for (i = 0; i < spec->autocfg.line_outs; i++)
2052                         snd_hda_codec_amp_stereo(
2053                                 codec, spec->autocfg.line_out_pins[i],
2054                                 HDA_OUTPUT, 0,
2055                                 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2056                 if (hp_present)
2057                         present = hp_present;
2058         }
2059         /* Speakers */
2060         for (i = 0; i < spec->autocfg.speaker_outs; i++)
2061                 snd_hda_codec_amp_stereo(
2062                         codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2063                         HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2064 }
2065 
2066 
2067 /* unsolicited event for jack sensing */
2068 static void via_unsol_event(struct hda_codec *codec,
2069                                   unsigned int res)
2070 {
2071         res >>= 26;
2072         if (res & VIA_HP_EVENT)
2073                 via_hp_automute(codec);
2074         if (res & VIA_GPIO_EVENT)
2075                 via_gpio_control(codec);
2076         if (res & VIA_JACK_EVENT)
2077                 set_jack_power_state(codec);
2078         if (res & VIA_MONO_EVENT)
2079                 via_mono_automute(codec);
2080         if (res & VIA_SPEAKER_EVENT)
2081                 via_speaker_automute(codec);
2082         if (res & VIA_BIND_HP_EVENT)
2083                 via_hp_bind_automute(codec);
2084 }
2085 
2086 static int via_init(struct hda_codec *codec)
2087 {
2088         struct via_spec *spec = codec->spec;
2089         int i;
2090         for (i = 0; i < spec->num_iverbs; i++)
2091                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2092 
2093         spec->codec_type = get_codec_type(codec);
2094         if (spec->codec_type == VT1708BCE)
2095                 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2096                                                same */
2097         /* Lydia Add for EAPD enable */
2098         if (!spec->dig_in_nid) { /* No Digital In connection */
2099                 if (spec->dig_in_pin) {
2100                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2101                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
2102                                             PIN_OUT);
2103                         snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2104                                             AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2105                 }
2106         } else /* enable SPDIF-input pin */
2107                 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2108                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2109 
2110         /* assign slave outs */
2111         if (spec->slave_dig_outs[0])
2112                 codec->slave_dig_outs = spec->slave_dig_outs;
2113 
2114         return 0;
2115 }
2116 
2117 #ifdef SND_HDA_NEEDS_RESUME
2118 static int via_suspend(struct hda_codec *codec, pm_message_t state)
2119 {
2120         struct via_spec *spec = codec->spec;
2121         vt1708_stop_hp_work(spec);
2122         return 0;
2123 }
2124 #endif
2125 
2126 #ifdef CONFIG_SND_HDA_POWER_SAVE
2127 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2128 {
2129         struct via_spec *spec = codec->spec;
2130         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2131 }
2132 #endif
2133 
2134 /*
2135  */
2136 static struct hda_codec_ops via_patch_ops = {
2137         .build_controls = via_build_controls,
2138         .build_pcms = via_build_pcms,
2139         .init = via_init,
2140         .free = via_free,
2141 #ifdef SND_HDA_NEEDS_RESUME
2142         .suspend = via_suspend,
2143 #endif
2144 #ifdef CONFIG_SND_HDA_POWER_SAVE
2145         .check_power_status = via_check_power_status,
2146 #endif
2147 };
2148 
2149 /* fill in the dac_nids table from the parsed pin configuration */
2150 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2151                                      const struct auto_pin_cfg *cfg)
2152 {
2153         int i;
2154         hda_nid_t nid;
2155 
2156         spec->multiout.num_dacs = cfg->line_outs;
2157 
2158         spec->multiout.dac_nids = spec->private_dac_nids;
2159 
2160         for (i = 0; i < 4; i++) {
2161                 nid = cfg->line_out_pins[i];
2162                 if (nid) {
2163                         /* config dac list */
2164                         switch (i) {
2165                         case AUTO_SEQ_FRONT:
2166                                 spec->multiout.dac_nids[i] = 0x10;
2167                                 break;
2168                         case AUTO_SEQ_CENLFE:
2169                                 spec->multiout.dac_nids[i] = 0x12;
2170                                 break;
2171                         case AUTO_SEQ_SURROUND:
2172                                 spec->multiout.dac_nids[i] = 0x11;
2173                                 break;
2174                         case AUTO_SEQ_SIDE:
2175                                 spec->multiout.dac_nids[i] = 0x13;
2176                                 break;
2177                         }
2178                 }
2179         }
2180 
2181         return 0;
2182 }
2183 
2184 /* add playback controls from the parsed DAC table */
2185 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2186                                              const struct auto_pin_cfg *cfg)
2187 {
2188         char name[32];
2189         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2190         hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2191         int i, err;
2192 
2193         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2194                 nid = cfg->line_out_pins[i];
2195 
2196                 if (!nid)
2197                         continue;
2198 
2199                 nid_vol = nid_vols[i];
2200 
2201                 if (i == AUTO_SEQ_CENLFE) {
2202                         /* Center/LFE */
2203                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2204                                         "Center Playback Volume",
2205                                         HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2206                                                             HDA_OUTPUT));
2207                         if (err < 0)
2208                                 return err;
2209                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2210                                               "LFE Playback Volume",
2211                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2212                                                                   HDA_OUTPUT));
2213                         if (err < 0)
2214                                 return err;
2215                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2216                                               "Center Playback Switch",
2217                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2218                                                                   HDA_OUTPUT));
2219                         if (err < 0)
2220                                 return err;
2221                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2222                                               "LFE Playback Switch",
2223                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2224                                                                   HDA_OUTPUT));
2225                         if (err < 0)
2226                                 return err;
2227                 } else if (i == AUTO_SEQ_FRONT) {
2228                         /* add control to mixer index 0 */
2229                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2230                                               "Master Front Playback Volume",
2231                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2232                                                                   HDA_INPUT));
2233                         if (err < 0)
2234                                 return err;
2235                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2236                                               "Master Front Playback Switch",
2237                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2238                                                                   HDA_INPUT));
2239                         if (err < 0)
2240                                 return err;
2241 
2242                         /* add control to PW3 */
2243                         sprintf(name, "%s Playback Volume", chname[i]);
2244                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2245                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2246                                                                   HDA_OUTPUT));
2247                         if (err < 0)
2248                                 return err;
2249                         sprintf(name, "%s Playback Switch", chname[i]);
2250                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2251                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2252                                                                   HDA_OUTPUT));
2253                         if (err < 0)
2254                                 return err;
2255                 } else {
2256                         sprintf(name, "%s Playback Volume", chname[i]);
2257                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2258                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2259                                                                   HDA_OUTPUT));
2260                         if (err < 0)
2261                                 return err;
2262                         sprintf(name, "%s Playback Switch", chname[i]);
2263                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2264                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2265                                                                   HDA_OUTPUT));
2266                         if (err < 0)
2267                                 return err;
2268                 }
2269         }
2270 
2271         return 0;
2272 }
2273 
2274 static void create_hp_imux(struct via_spec *spec)
2275 {
2276         int i;
2277         struct hda_input_mux *imux = &spec->private_imux[1];
2278         static const char *texts[] = { "OFF", "ON", NULL};
2279 
2280         /* for hp mode select */
2281         i = 0;
2282         while (texts[i] != NULL) {
2283                 imux->items[imux->num_items].label =  texts[i];
2284                 imux->items[imux->num_items].index = i;
2285                 imux->num_items++;
2286                 i++;
2287         }
2288 
2289         spec->hp_mux = &spec->private_imux[1];
2290 }
2291 
2292 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2293 {
2294         int err;
2295 
2296         if (!pin)
2297                 return 0;
2298 
2299         spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2300         spec->hp_independent_mode_index = 1;
2301 
2302         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2303                               "Headphone Playback Volume",
2304                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2305         if (err < 0)
2306                 return err;
2307         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2308                               "Headphone Playback Switch",
2309                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2310         if (err < 0)
2311                 return err;
2312 
2313         create_hp_imux(spec);
2314 
2315         return 0;
2316 }
2317 
2318 /* create playback/capture controls for input pins */
2319 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
2320                                                 const struct auto_pin_cfg *cfg)
2321 {
2322         static char *labels[] = {
2323                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2324         };
2325         struct hda_input_mux *imux = &spec->private_imux[0];
2326         int i, err, idx = 0;
2327 
2328         /* for internal loopback recording select */
2329         imux->items[imux->num_items].label = "Stereo Mixer";
2330         imux->items[imux->num_items].index = idx;
2331         imux->num_items++;
2332 
2333         for (i = 0; i < AUTO_PIN_LAST; i++) {
2334                 if (!cfg->input_pins[i])
2335                         continue;
2336 
2337                 switch (cfg->input_pins[i]) {
2338                 case 0x1d: /* Mic */
2339                         idx = 2;
2340                         break;
2341 
2342                 case 0x1e: /* Line In */
2343                         idx = 3;
2344                         break;
2345 
2346                 case 0x21: /* Front Mic */
2347                         idx = 4;
2348                         break;
2349 
2350                 case 0x24: /* CD */
2351                         idx = 1;
2352                         break;
2353                 }
2354                 err = via_new_analog_input(spec, labels[i], idx, 0x17);
2355                 if (err < 0)
2356                         return err;
2357                 imux->items[imux->num_items].label = labels[i];
2358                 imux->items[imux->num_items].index = idx;
2359                 imux->num_items++;
2360         }
2361         return 0;
2362 }
2363 
2364 #ifdef CONFIG_SND_HDA_POWER_SAVE
2365 static struct hda_amp_list vt1708_loopbacks[] = {
2366         { 0x17, HDA_INPUT, 1 },
2367         { 0x17, HDA_INPUT, 2 },
2368         { 0x17, HDA_INPUT, 3 },
2369         { 0x17, HDA_INPUT, 4 },
2370         { } /* end */
2371 };
2372 #endif
2373 
2374 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2375 {
2376         unsigned int def_conf;
2377         unsigned char seqassoc;
2378 
2379         def_conf = snd_hda_codec_get_pincfg(codec, nid);
2380         seqassoc = (unsigned char) get_defcfg_association(def_conf);
2381         seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2382         if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2383             && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2384                 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2385                 snd_hda_codec_set_pincfg(codec, nid, def_conf);
2386         }
2387 
2388         return;
2389 }
2390 
2391 static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2392                                      struct snd_ctl_elem_value *ucontrol)
2393 {
2394         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2395         struct via_spec *spec = codec->spec;
2396 
2397         if (spec->codec_type != VT1708)
2398                 return 0;
2399         spec->vt1708_jack_detectect =
2400                 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2401         ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2402         return 0;
2403 }
2404 
2405 static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2406                                      struct snd_ctl_elem_value *ucontrol)
2407 {
2408         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2409         struct via_spec *spec = codec->spec;
2410         int change;
2411 
2412         if (spec->codec_type != VT1708)
2413                 return 0;
2414         spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2415         change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2416                 == !spec->vt1708_jack_detectect;
2417         if (spec->vt1708_jack_detectect) {
2418                 mute_aa_path(codec, 1);
2419                 notify_aa_path_ctls(codec);
2420         }
2421         return change;
2422 }
2423 
2424 static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2425         {
2426                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2427                 .name = "Jack Detect",
2428                 .count = 1,
2429                 .info = snd_ctl_boolean_mono_info,
2430                 .get = vt1708_jack_detectect_get,
2431                 .put = vt1708_jack_detectect_put,
2432         },
2433         {} /* end */
2434 };
2435 
2436 static int vt1708_parse_auto_config(struct hda_codec *codec)
2437 {
2438         struct via_spec *spec = codec->spec;
2439         int err;
2440 
2441         /* Add HP and CD pin config connect bit re-config action */
2442         vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2443         vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2444 
2445         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2446         if (err < 0)
2447                 return err;
2448         err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2449         if (err < 0)
2450                 return err;
2451         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2452                 return 0; /* can't find valid BIOS pin config */
2453 
2454         err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2455         if (err < 0)
2456                 return err;
2457         err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2458         if (err < 0)
2459                 return err;
2460         err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
2461         if (err < 0)
2462                 return err;
2463         /* add jack detect on/off control */
2464         err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2465         if (err < 0)
2466                 return err;
2467 
2468         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2469 
2470         if (spec->autocfg.dig_outs)
2471                 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2472         spec->dig_in_pin = VT1708_DIGIN_PIN;
2473         if (spec->autocfg.dig_in_pin)
2474                 spec->dig_in_nid = VT1708_DIGIN_NID;
2475 
2476         if (spec->kctls.list)
2477                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2478 
2479         spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2480 
2481         spec->input_mux = &spec->private_imux[0];
2482 
2483         if (spec->hp_mux)
2484                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2485 
2486         spec->mixers[spec->num_mixers++] = via_smart51_mixer;
2487         return 1;
2488 }
2489 
2490 /* init callback for auto-configuration model -- overriding the default init */
2491 static int via_auto_init(struct hda_codec *codec)
2492 {
2493         struct via_spec *spec = codec->spec;
2494 
2495         via_init(codec);
2496         via_auto_init_multi_out(codec);
2497         via_auto_init_hp_out(codec);
2498         via_auto_init_analog_input(codec);
2499         if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2500                 via_hp_bind_automute(codec);
2501         } else {
2502                 via_hp_automute(codec);
2503                 via_speaker_automute(codec);
2504         }
2505 
2506         return 0;
2507 }
2508 
2509 static void vt1708_update_hp_jack_state(struct work_struct *work)
2510 {
2511         struct via_spec *spec = container_of(work, struct via_spec,
2512                                              vt1708_hp_work.work);
2513         if (spec->codec_type != VT1708)
2514                 return;
2515         /* if jack state toggled */
2516         if (spec->vt1708_hp_present
2517             != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2518                 spec->vt1708_hp_present ^= 1;
2519                 via_hp_automute(spec->codec);
2520         }
2521         vt1708_start_hp_work(spec);
2522 }
2523 
2524 static int get_mux_nids(struct hda_codec *codec)
2525 {
2526         struct via_spec *spec = codec->spec;
2527         hda_nid_t nid, conn[8];
2528         unsigned int type;
2529         int i, n;
2530 
2531         for (i = 0; i < spec->num_adc_nids; i++) {
2532                 nid = spec->adc_nids[i];
2533                 while (nid) {
2534                         type = get_wcaps_type(get_wcaps(codec, nid));
2535                         if (type == AC_WID_PIN)
2536                                 break;
2537                         n = snd_hda_get_connections(codec, nid, conn,
2538                                                     ARRAY_SIZE(conn));
2539                         if (n <= 0)
2540                                 break;
2541                         if (n > 1) {
2542                                 spec->mux_nids[i] = nid;
2543                                 break;
2544                         }
2545                         nid = conn[0];
2546                 }
2547         }
2548         return 0;
2549 }
2550 
2551 static int patch_vt1708(struct hda_codec *codec)
2552 {
2553         struct via_spec *spec;
2554         int err;
2555 
2556         /* create a codec specific record */
2557         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2558         if (spec == NULL)
2559                 return -ENOMEM;
2560 
2561         codec->spec = spec;
2562 
2563         /* automatic parse from the BIOS config */
2564         err = vt1708_parse_auto_config(codec);
2565         if (err < 0) {
2566                 via_free(codec);
2567                 return err;
2568         } else if (!err) {
2569                 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2570                        "from BIOS.  Using genenic mode...\n");
2571         }
2572 
2573 
2574         spec->stream_name_analog = "VT1708 Analog";
2575         spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2576         /* disable 32bit format on VT1708 */
2577         if (codec->vendor_id == 0x11061708)
2578                 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2579         spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2580 
2581         spec->stream_name_digital = "VT1708 Digital";
2582         spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2583         spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2584 
2585 
2586         if (!spec->adc_nids && spec->input_mux) {
2587                 spec->adc_nids = vt1708_adc_nids;
2588                 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2589                 get_mux_nids(codec);
2590                 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2591                 spec->num_mixers++;
2592         }
2593 
2594         codec->patch_ops = via_patch_ops;
2595 
2596         codec->patch_ops.init = via_auto_init;
2597 #ifdef CONFIG_SND_HDA_POWER_SAVE
2598         spec->loopback.amplist = vt1708_loopbacks;
2599 #endif
2600         spec->codec = codec;
2601         INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2602         return 0;
2603 }
2604 
2605 /* capture mixer elements */
2606 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2607         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2608         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2609         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2610         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2611         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2612         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2613         {
2614                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2615                 /* The multiple "Capture Source" controls confuse alsamixer
2616                  * So call somewhat different..
2617                  */
2618                 /* .name = "Capture Source", */
2619                 .name = "Input Source",
2620                 .count = 1,
2621                 .info = via_mux_enum_info,
2622                 .get = via_mux_enum_get,
2623                 .put = via_mux_enum_put,
2624         },
2625         { } /* end */
2626 };
2627 
2628 static struct hda_verb vt1709_uniwill_init_verbs[] = {
2629         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2630          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2631         { }
2632 };
2633 
2634 /*
2635  * generic initialization of ADC, input mixers and output mixers
2636  */
2637 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2638         /*
2639          * Unmute ADC0-2 and set the default input to mic-in
2640          */
2641         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2642         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2643         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2644 
2645 
2646         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2647          * mixer widget
2648          */
2649         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2650         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2651         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2652         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2653         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2654         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2655 
2656         /*
2657          * Set up output selector (0x1a, 0x1b, 0x29)
2658          */
2659         /* set vol=0 to output mixers */
2660         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2661         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2662         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2663 
2664         /*
2665          *  Unmute PW3 and PW4
2666          */
2667         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2668         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2669 
2670         /* Set input of PW4 as MW0 */
2671         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2672         /* PW9 Output enable */
2673         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2674         { }
2675 };
2676 
2677 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2678         .substreams = 1,
2679         .channels_min = 2,
2680         .channels_max = 10,
2681         .nid = 0x10, /* NID to query formats and rates */
2682         .ops = {
2683                 .open = via_playback_pcm_open,
2684                 .prepare = via_playback_multi_pcm_prepare,
2685                 .cleanup = via_playback_multi_pcm_cleanup,
2686         },
2687 };
2688 
2689 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2690         .substreams = 1,
2691         .channels_min = 2,
2692         .channels_max = 6,
2693         .nid = 0x10, /* NID to query formats and rates */
2694         .ops = {
2695                 .open = via_playback_pcm_open,
2696                 .prepare = via_playback_multi_pcm_prepare,
2697                 .cleanup = via_playback_multi_pcm_cleanup,
2698         },
2699 };
2700 
2701 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2702         .substreams = 2,
2703         .channels_min = 2,
2704         .channels_max = 2,
2705         .nid = 0x14, /* NID to query formats and rates */
2706         .ops = {
2707                 .prepare = via_capture_pcm_prepare,
2708                 .cleanup = via_capture_pcm_cleanup
2709         },
2710 };
2711 
2712 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2713         .substreams = 1,
2714         .channels_min = 2,
2715         .channels_max = 2,
2716         /* NID is set in via_build_pcms */
2717         .ops = {
2718                 .open = via_dig_playback_pcm_open,
2719                 .close = via_dig_playback_pcm_close
2720         },
2721 };
2722 
2723 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2724         .substreams = 1,
2725         .channels_min = 2,
2726         .channels_max = 2,
2727 };
2728 
2729 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2730                                      const struct auto_pin_cfg *cfg)
2731 {
2732         int i;
2733         hda_nid_t nid;
2734 
2735         if (cfg->line_outs == 4)  /* 10 channels */
2736                 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2737         else if (cfg->line_outs == 3) /* 6 channels */
2738                 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2739 
2740         spec->multiout.dac_nids = spec->private_dac_nids;
2741 
2742         if (cfg->line_outs == 4) { /* 10 channels */
2743                 for (i = 0; i < cfg->line_outs; i++) {
2744                         nid = cfg->line_out_pins[i];
2745                         if (nid) {
2746                                 /* config dac list */
2747                                 switch (i) {
2748                                 case AUTO_SEQ_FRONT:
2749                                         /* AOW0 */
2750                                         spec->multiout.dac_nids[i] = 0x10;
2751                                         break;
2752                                 case AUTO_SEQ_CENLFE:
2753                                         /* AOW2 */
2754                                         spec->multiout.dac_nids[i] = 0x12;
2755                                         break;
2756                                 case AUTO_SEQ_SURROUND:
2757                                         /* AOW3 */
2758                                         spec->multiout.dac_nids[i] = 0x11;
2759                                         break;
2760                                 case AUTO_SEQ_SIDE:
2761                                         /* AOW1 */
2762                                         spec->multiout.dac_nids[i] = 0x27;
2763                                         break;
2764                                 default:
2765                                         break;
2766                                 }
2767                         }
2768                 }
2769                 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2770 
2771         } else if (cfg->line_outs == 3) { /* 6 channels */
2772                 for (i = 0; i < cfg->line_outs; i++) {
2773                         nid = cfg->line_out_pins[i];
2774                         if (nid) {
2775                                 /* config dac list */
2776                                 switch (i) {
2777                                 case AUTO_SEQ_FRONT:
2778                                         /* AOW0 */
2779                                         spec->multiout.dac_nids[i] = 0x10;
2780                                         break;
2781                                 case AUTO_SEQ_CENLFE:
2782                                         /* AOW2 */
2783                                         spec->multiout.dac_nids[i] = 0x12;
2784                                         break;
2785                                 case AUTO_SEQ_SURROUND:
2786                                         /* AOW1 */
2787                                         spec->multiout.dac_nids[i] = 0x11;
2788                                         break;
2789                                 default:
2790                                         break;
2791                                 }
2792                         }
2793                 }
2794         }
2795 
2796         return 0;
2797 }
2798 
2799 /* add playback controls from the parsed DAC table */
2800 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2801                                              const struct auto_pin_cfg *cfg)
2802 {
2803         char name[32];
2804         static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2805         hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2806         int i, err;
2807 
2808         for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2809                 nid = cfg->line_out_pins[i];
2810 
2811                 if (!nid)
2812                         continue;
2813 
2814                 nid_vol = nid_vols[i];
2815 
2816                 if (i == AUTO_SEQ_CENLFE) {
2817                         /* Center/LFE */
2818                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2819                                               "Center Playback Volume",
2820                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2821                                                                   HDA_OUTPUT));
2822                         if (err < 0)
2823                                 return err;
2824                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2825                                               "LFE Playback Volume",
2826                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2827                                                                   HDA_OUTPUT));
2828                         if (err < 0)
2829                                 return err;
2830                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2831                                               "Center Playback Switch",
2832                                               HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2833                                                                   HDA_OUTPUT));
2834                         if (err < 0)
2835                                 return err;
2836                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2837                                               "LFE Playback Switch",
2838                                               HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2839                                                                   HDA_OUTPUT));
2840                         if (err < 0)
2841                                 return err;
2842                 } else if (i == AUTO_SEQ_FRONT) {
2843                         /* ADD control to mixer index 0 */
2844                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2845                                               "Master Front Playback Volume",
2846                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2847                                                                   HDA_INPUT));
2848                         if (err < 0)
2849                                 return err;
2850                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2851                                               "Master Front Playback Switch",
2852                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2853                                                                   HDA_INPUT));
2854                         if (err < 0)
2855                                 return err;
2856 
2857                         /* add control to PW3 */
2858                         sprintf(name, "%s Playback Volume", chname[i]);
2859                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2860                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2861                                                                   HDA_OUTPUT));
2862                         if (err < 0)
2863                                 return err;
2864                         sprintf(name, "%s Playback Switch", chname[i]);
2865                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2866                                               HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2867                                                                   HDA_OUTPUT));
2868                         if (err < 0)
2869                                 return err;
2870                 } else if (i == AUTO_SEQ_SURROUND) {
2871                         sprintf(name, "%s Playback Volume", chname[i]);
2872                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2873                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2874                                                                   HDA_OUTPUT));
2875                         if (err < 0)
2876                                 return err;
2877                         sprintf(name, "%s Playback Switch", chname[i]);
2878                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2879                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2880                                                                   HDA_OUTPUT));
2881                         if (err < 0)
2882                                 return err;
2883                 } else if (i == AUTO_SEQ_SIDE) {
2884                         sprintf(name, "%s Playback Volume", chname[i]);
2885                         err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2886                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2887                                                                   HDA_OUTPUT));
2888                         if (err < 0)
2889                                 return err;
2890                         sprintf(name, "%s Playback Switch", chname[i]);
2891                         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2892                                               HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2893                                                                   HDA_OUTPUT));
2894                         if (err < 0)
2895                                 return err;
2896                 }
2897         }
2898 
2899         return 0;
2900 }
2901 
2902 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2903 {
2904         int err;
2905 
2906         if (!pin)
2907                 return 0;
2908 
2909         if (spec->multiout.num_dacs == 5) /* 10 channels */
2910                 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
2911         else if (spec->multiout.num_dacs == 3) /* 6 channels */
2912                 spec->multiout.hp_nid = 0;
2913         spec->hp_independent_mode_index = 1;
2914 
2915         err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2916                               "Headphone Playback Volume",
2917                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2918         if (err < 0)
2919                 return err;
2920         err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2921                               "Headphone Playback Switch",
2922                               HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2923         if (err < 0)
2924                 return err;
2925 
2926         return 0;
2927 }
2928 
2929 /* create playback/capture controls for input pins */
2930 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
2931                                                 const struct auto_pin_cfg *cfg)
2932 {
2933         static char *labels[] = {
2934                 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2935         };
2936         struct hda_input_mux *imux = &spec->private_imux[0];
2937         int i, err, idx = 0;
2938 
2939         /* for internal loopback recording select */
2940         imux->items[imux->num_items].label = "Stereo Mixer";
2941         imux->items[imux->num_items].index = idx;
2942         imux->num_items++;
2943 
2944         for (i = 0; i < AUTO_PIN_LAST; i++) {
2945                 if (!cfg->input_pins[i])
2946                         continue;
2947 
2948                 switch (cfg->input_pins[i]) {
2949                 case 0x1d: /* Mic */
2950                         idx = 2;
2951                         break;
2952 
2953                 case 0x1e: /* Line In */
2954                         idx = 3;
2955                         break;
2956 
2957                 case 0x21: /* Front Mic */
2958                         idx = 4;
2959                         break;
2960 
2961                 case 0x23: /* CD */
2962                         idx = 1;
2963                         break;
2964                 }
2965                 err = via_new_analog_input(spec, labels[i], idx, 0x18);
2966                 if (err < 0)
2967                         return err;
2968                 imux->items[imux->num_items].label = labels[i];
2969                 imux->items[imux->num_items].index = idx;
2970                 imux->num_items++;
2971         }
2972         return 0;
2973 }
2974 
2975 static int vt1709_parse_auto_config(struct hda_codec *codec)
2976 {
2977         struct via_spec *spec = codec->spec;
2978         int err;
2979 
2980         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2981         if (err < 0)
2982                 return err;
2983         err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
2984         if (err < 0)
2985                 return err;
2986         if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2987                 return 0; /* can't find valid BIOS pin config */
2988 
2989         err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
2990         if (err < 0)
2991                 return err;
2992         err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2993         if (err < 0)
2994                 return err;
2995         err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
2996         if (err < 0)
2997                 return err;
2998 
2999         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3000 
3001         if (spec->autocfg.dig_outs)
3002                 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3003         spec->dig_in_pin = VT1709_DIGIN_PIN;
3004         if (spec->autocfg.dig_in_pin)
3005                 spec->dig_in_nid = VT1709_DIGIN_NID;
3006 
3007         if (spec->kctls.list)
3008                 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3009 
3010         spec->input_mux = &spec->private_imux[0];
3011 
3012         if (spec->hp_mux)
3013                 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3014 
3015         spec->mixers[spec->num_mixers++] = via_smart51_mixer;
3016         return 1;
3017 }
3018 
3019 #ifdef CONFIG_SND_HDA_POWER_SAVE
3020 static struct hda_amp_list vt1709_loopbacks[] = {
3021         { 0x18, HDA_INPUT, 1 },
3022         { 0x18, HDA_INPUT, 2 },
3023         { 0x18, HDA_INPUT, 3 },
3024         { 0x18, HDA_INPUT, 4 },
3025         { } /* end */
3026 };
3027 #endif
3028 
3029 static int patch_vt1709_10ch(struct hda_codec *codec)
3030 {
3031         struct via_spec *spec;
3032         int err;
3033 
3034         /* create a codec specific record */
3035         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3036         if (spec == NULL)
3037                 return -ENOMEM;
3038 
3039         codec->spec = spec;
3040 
3041         err = vt1709_parse_auto_config(codec);
3042         if (err < 0) {
3043                 via_free(codec);
3044                 return err;
3045         } else if (!err) {
3046                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3047                        "Using genenic mode...\n");
3048         }
3049 
3050         spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3051         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3052 
3053         spec->stream_name_analog = "VT1709 Analog";
3054         spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3055         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3056 
3057         spec->stream_name_digital = "VT1709 Digital";
3058         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3059         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3060 
3061 
3062         if (!spec->adc_nids && spec->input_mux) {
3063                 spec->adc_nids = vt1709_adc_nids;
3064                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3065                 get_mux_nids(codec);
3066                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3067                 spec->num_mixers++;
3068         }
3069 
3070         codec->patch_ops = via_patch_ops;
3071 
3072         codec->patch_ops.init = via_auto_init;
3073         codec->patch_ops.unsol_event = via_unsol_event;
3074 #ifdef CONFIG_SND_HDA_POWER_SAVE
3075         spec->loopback.amplist = vt1709_loopbacks;
3076 #endif
3077 
3078         return 0;
3079 }
3080 /*
3081  * generic initialization of ADC, input mixers and output mixers
3082  */
3083 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3084         /*
3085          * Unmute ADC0-2 and set the default input to mic-in
3086          */
3087         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3088         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3089         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3090 
3091 
3092         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3093          * mixer widget
3094          */
3095         /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3096         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3097         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3098         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3099         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3100         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3101 
3102         /*
3103          * Set up output selector (0x1a, 0x1b, 0x29)
3104          */
3105         /* set vol=0 to output mixers */
3106         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3107         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3108         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3109 
3110         /*
3111          *  Unmute PW3 and PW4
3112          */
3113         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3114         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3115 
3116         /* Set input of PW4 as MW0 */
3117         {0x20, AC_VERB_SET_CONNECT_SEL, 0},
3118         /* PW9 Output enable */
3119         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3120         { }
3121 };
3122 
3123 static int patch_vt1709_6ch(struct hda_codec *codec)
3124 {
3125         struct via_spec *spec;
3126         int err;
3127 
3128         /* create a codec specific record */
3129         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3130         if (spec == NULL)
3131                 return -ENOMEM;
3132 
3133         codec->spec = spec;
3134 
3135         err = vt1709_parse_auto_config(codec);
3136         if (err < 0) {
3137                 via_free(codec);
3138                 return err;
3139         } else if (!err) {
3140                 printk(KERN_INFO "hda_codec: Cannot set up configuration.  "
3141                        "Using genenic mode...\n");
3142         }
3143 
3144         spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3145         spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3146 
3147         spec->stream_name_analog = "VT1709 Analog";
3148         spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3149         spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3150 
3151         spec->stream_name_digital = "VT1709 Digital";
3152         spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3153         spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3154 
3155 
3156         if (!spec->adc_nids && spec->input_mux) {
3157                 spec->adc_nids = vt1709_adc_nids;
3158                 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3159                 get_mux_nids(codec);
3160                 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3161                 spec->num_mixers++;
3162         }
3163 
3164         codec->patch_ops = via_patch_ops;
3165 
3166         codec->patch_ops.init = via_auto_init;
3167         codec->patch_ops.unsol_event = via_unsol_event;
3168 #ifdef CONFIG_SND_HDA_POWER_SAVE
3169         spec->loopback.amplist = vt1709_loopbacks;
3170 #endif
3171         return 0;
3172 }
3173 
3174 /* capture mixer elements */
3175 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3176         HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3177         HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3178         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3179         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3180         {
3181                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3182                 /* The multiple "Capture Source" controls confuse alsamixer
3183                  * So call somewhat different..
3184                  */
3185                 /* .name = "Capture Source", */
3186                 .name = "Input Source",
3187                 .count = 1,
3188                 .info = via_mux_enum_info,
3189                 .get = via_mux_enum_get,
3190                 .put = via_mux_enum_put,
3191         },
3192         { } /* end */
3193 };
3194 /*
3195  * generic initialization of ADC, input mixers and output mixers
3196  */
3197 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3198         /*
3199          * Unmute ADC0-1 and set the default input to mic-in
3200          */
3201         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3202         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3203 
3204 
3205         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3206          * mixer widget
3207          */
3208         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3209         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3212         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3213         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3214 
3215         /*
3216          * Set up output mixers
3217          */
3218         /* set vol=0 to output mixers */
3219         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3220         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3221         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3222 
3223         /* Setup default input to PW4 */
3224         {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3225         /* PW9 Output enable */
3226         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3227         /* PW10 Input enable */
3228         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3229         { }
3230 };
3231 
3232 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3233         /*
3234          * Unmute ADC0-1 and set the default input to mic-in
3235          */
3236         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3237         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3238 
3239 
3240         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3241          * mixer widget
3242          */
3243         /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3244         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3245         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3246         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3247         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3248         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3249 
3250         /*
3251          * Set up output mixers
3252          */
3253         /* set vol=0 to output mixers */
3254         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3255         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3256         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3257 
3258         /* Setup default input of PW4 to MW0 */
3259         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3260         /* PW9 Output enable */
3261         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3262         /* PW10 Input enable */
3263         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3264         { }
3265 };
3266 
3267 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3268         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3269          AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3270         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3271         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3272         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3273         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3274         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3275         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3276         {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3277         { }
3278 };
3279 
3280 static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3281                               struct hda_codec *codec,
3282                               struct snd_pcm_substream *substream)
3283 {
3284         int idle = substream->pstr->substream_opened == 1
3285                 && substream->ref_count == 0;
3286 
3287         analog_low_current_mode(codec, idle);
3288         return 0;
3289 }
3290 
3291 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3292         .substreams = 2,
3293         .channels_min = 2,
3294         .channels_max = 8,
3295         .nid = 0x10, /* NID to query formats and rates */
3296         .ops = {
3297                 .open = via_playback_pcm_open,
3298                 .prepare = via_playback_multi_pcm_prepare,
3299                 .cleanup = via_playback_multi_pcm_cleanup,
3300                 .close = via_pcm_open_close
3301         },
3302 };
3303 
3304 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3305         .substreams = 2,
3306         .channels_min = 2,
3307         .channels_max = 4,
3308         .nid = 0x10, /* NID to query formats and rates */
3309         .ops = {
3310                 .open = via_playback_pcm_open,
3311                 .prepare = via_playback_multi_pcm_prepare,
3312                 .cleanup = via_playback_multi_pcm_cleanup
3313         },
3314 };
3315 
3316 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3317         .substreams = 2,
3318         .channels_min = 2,
3319         .channels_max = 2,
3320         .nid = 0x13, /* NID to query formats and rates */
3321         .ops = {
3322                 .open = via_pcm_open_close,
3323                 .prepare = via_capture_pcm_prepare,
3324                 .cleanup = via_capture_pcm_cleanup,
3325                 .close = via_pcm_open_close
3326         },
3327 };
3328 
3329 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3330         .substreams = 1,
3331         .channels_min = 2,
3332         .channels_max = 2,
3333         /* NID is set in via_build_pcms */
3334         .ops = {
3335                 .open = via_dig_playback_pcm_open,
3336                 .close = via_dig_playback_pcm_close,
3337                 .prepare = via_dig_playback_pcm_prepare,
3338                 .cleanup = via_dig_playback_pcm_cleanup
3339         },
3340 };
3341 
3342 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3343         .substreams = 1,
3344         .channels_min = 2,
3345         .channels_max = 2,
3346 };
3347 
3348 /* fill in the dac_nids table from the parsed pin configuration */
3349 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3350                                      const struct auto_pin_cfg *cfg)
3351 {
3352         int i;
3353         hda_nid_t nid;
3354 
3355         spec->multiout.num_dacs = cfg->line_outs;
3356 
3357         spec->multiout.dac_nids = spec->private_dac_nids;
3358 
3359         for (i = 0; i < 4; i++) {
3360                 nid = cfg->line_out_pins[i];
3361                 if (nid) {
3362                         /* config