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