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