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