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