ALSA: HDA patch_via.c: Fix inversion of surround and side channels
[linux-2.6-block.git] / sound / pci / hda / patch_via.c
CommitLineData
c577b8a1
JC
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for VIA VT1708 codec
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 */
c577b8a1
JC
34/* */
35/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
36
37
c577b8a1
JC
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <linux/slab.h>
c577b8a1
JC
41#include <sound/core.h>
42#include "hda_codec.h"
43#include "hda_local.h"
3c9a3203 44#include "hda_patch.h"
c577b8a1
JC
45
46/* amp values */
47#define AMP_VAL_IDX_SHIFT 19
48#define AMP_VAL_IDX_MASK (0x0f<<19)
49
50#define NUM_CONTROL_ALLOC 32
51#define NUM_VERB_ALLOC 32
52
53/* Pin Widget NID */
54#define VT1708_HP_NID 0x13
55#define VT1708_DIGOUT_NID 0x14
56#define VT1708_DIGIN_NID 0x16
f7278fd0 57#define VT1708_DIGIN_PIN 0x26
76d9b0dd
HW
58#define VT1708_HP_PIN_NID 0x20
59#define VT1708_CD_PIN_NID 0x24
c577b8a1
JC
60
61#define VT1709_HP_DAC_NID 0x28
62#define VT1709_DIGOUT_NID 0x13
63#define VT1709_DIGIN_NID 0x17
f7278fd0
JC
64#define VT1709_DIGIN_PIN 0x25
65
66#define VT1708B_HP_NID 0x25
67#define VT1708B_DIGOUT_NID 0x12
68#define VT1708B_DIGIN_NID 0x15
69#define VT1708B_DIGIN_PIN 0x21
c577b8a1
JC
70
71#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
72#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
73#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
f7278fd0
JC
74#define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723)
75#define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727)
c577b8a1
JC
76
77
78enum {
79 VIA_CTL_WIDGET_VOL,
80 VIA_CTL_WIDGET_MUTE,
81};
82
83enum {
eb14a46c 84 AUTO_SEQ_FRONT = 0,
c577b8a1
JC
85 AUTO_SEQ_SURROUND,
86 AUTO_SEQ_CENLFE,
87 AUTO_SEQ_SIDE
88};
89
90static struct snd_kcontrol_new vt1708_control_templates[] = {
91 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
92 HDA_CODEC_MUTE(NULL, 0, 0, 0),
93};
94
95
96struct via_spec {
97 /* codec parameterization */
98 struct snd_kcontrol_new *mixers[3];
99 unsigned int num_mixers;
100
101 struct hda_verb *init_verbs;
102
103 char *stream_name_analog;
104 struct hda_pcm_stream *stream_analog_playback;
105 struct hda_pcm_stream *stream_analog_capture;
106
107 char *stream_name_digital;
108 struct hda_pcm_stream *stream_digital_playback;
109 struct hda_pcm_stream *stream_digital_capture;
110
111 /* playback */
112 struct hda_multi_out multiout;
113
114 /* capture */
115 unsigned int num_adc_nids;
116 hda_nid_t *adc_nids;
117 hda_nid_t dig_in_nid;
118
119 /* capture source */
120 const struct hda_input_mux *input_mux;
121 unsigned int cur_mux[3];
122
123 /* PCM information */
124 struct hda_pcm pcm_rec[2];
125
126 /* dynamic controls, init_verbs and input_mux */
127 struct auto_pin_cfg autocfg;
128 unsigned int num_kctl_alloc, num_kctl_used;
129 struct snd_kcontrol_new *kctl_alloc;
130 struct hda_input_mux private_imux;
41923e44 131 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
cb53c626
TI
132
133#ifdef CONFIG_SND_HDA_POWER_SAVE
134 struct hda_loopback_check loopback;
135#endif
c577b8a1
JC
136};
137
138static hda_nid_t vt1708_adc_nids[2] = {
139 /* ADC1-2 */
140 0x15, 0x27
141};
142
143static hda_nid_t vt1709_adc_nids[3] = {
144 /* ADC1-2 */
145 0x14, 0x15, 0x16
146};
147
f7278fd0
JC
148static hda_nid_t vt1708B_adc_nids[2] = {
149 /* ADC1-2 */
150 0x13, 0x14
151};
152
c577b8a1
JC
153/* add dynamic controls */
154static int via_add_control(struct via_spec *spec, int type, const char *name,
155 unsigned long val)
156{
157 struct snd_kcontrol_new *knew;
158
159 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
160 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
161
162 /* array + terminator */
163 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
164 if (!knew)
165 return -ENOMEM;
166 if (spec->kctl_alloc) {
167 memcpy(knew, spec->kctl_alloc,
168 sizeof(*knew) * spec->num_kctl_alloc);
169 kfree(spec->kctl_alloc);
170 }
171 spec->kctl_alloc = knew;
172 spec->num_kctl_alloc = num;
173 }
174
175 knew = &spec->kctl_alloc[spec->num_kctl_used];
176 *knew = vt1708_control_templates[type];
177 knew->name = kstrdup(name, GFP_KERNEL);
178
179 if (!knew->name)
180 return -ENOMEM;
181 knew->private_value = val;
182 spec->num_kctl_used++;
183 return 0;
184}
185
186/* create input playback/capture controls for the given pin */
187static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
188 const char *ctlname, int idx, int mix_nid)
189{
190 char name[32];
191 int err;
192
193 sprintf(name, "%s Playback Volume", ctlname);
194 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
195 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
196 if (err < 0)
197 return err;
198 sprintf(name, "%s Playback Switch", ctlname);
199 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
200 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
201 if (err < 0)
202 return err;
203 return 0;
204}
205
206static void via_auto_set_output_and_unmute(struct hda_codec *codec,
207 hda_nid_t nid, int pin_type,
208 int dac_idx)
209{
210 /* set as output */
211 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
212 pin_type);
213 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
214 AMP_OUT_UNMUTE);
215}
216
217
218static void via_auto_init_multi_out(struct hda_codec *codec)
219{
220 struct via_spec *spec = codec->spec;
221 int i;
222
223 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
224 hda_nid_t nid = spec->autocfg.line_out_pins[i];
225 if (nid)
226 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
227 }
228}
229
230static void via_auto_init_hp_out(struct hda_codec *codec)
231{
232 struct via_spec *spec = codec->spec;
233 hda_nid_t pin;
234
235 pin = spec->autocfg.hp_pins[0];
236 if (pin) /* connect to front */
237 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
238}
239
240static void via_auto_init_analog_input(struct hda_codec *codec)
241{
242 struct via_spec *spec = codec->spec;
243 int i;
244
245 for (i = 0; i < AUTO_PIN_LAST; i++) {
246 hda_nid_t nid = spec->autocfg.input_pins[i];
247
248 snd_hda_codec_write(codec, nid, 0,
249 AC_VERB_SET_PIN_WIDGET_CONTROL,
250 (i <= AUTO_PIN_FRONT_MIC ?
251 PIN_VREF50 : PIN_IN));
252
253 }
254}
255/*
256 * input MUX handling
257 */
258static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_info *uinfo)
260{
261 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
262 struct via_spec *spec = codec->spec;
263 return snd_hda_input_mux_info(spec->input_mux, uinfo);
264}
265
266static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol)
268{
269 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
270 struct via_spec *spec = codec->spec;
271 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
272
273 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
274 return 0;
275}
276
277static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
278 struct snd_ctl_elem_value *ucontrol)
279{
280 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
281 struct via_spec *spec = codec->spec;
282 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
283 unsigned int vendor_id = codec->vendor_id;
284
285 /* AIW0 lydia 060801 add for correct sw0 input select */
286 if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
287 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
288 0x18, &spec->cur_mux[adc_idx]);
289 else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
eb14a46c 290 IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0))
c577b8a1
JC
291 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
292 0x19, &spec->cur_mux[adc_idx]);
f7278fd0 293 else if ((IS_VT1708B_8CH_VENDORID(vendor_id) ||
eb14a46c 294 IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0))
f7278fd0
JC
295 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
296 0x17, &spec->cur_mux[adc_idx]);
c577b8a1
JC
297 else
298 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
299 spec->adc_nids[adc_idx],
300 &spec->cur_mux[adc_idx]);
301}
302
303/* capture mixer elements */
304static struct snd_kcontrol_new vt1708_capture_mixer[] = {
305 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
306 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
307 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
308 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
309 {
310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
311 /* The multiple "Capture Source" controls confuse alsamixer
312 * So call somewhat different..
c577b8a1
JC
313 */
314 /* .name = "Capture Source", */
315 .name = "Input Source",
316 .count = 1,
317 .info = via_mux_enum_info,
318 .get = via_mux_enum_get,
319 .put = via_mux_enum_put,
320 },
321 { } /* end */
322};
323/*
324 * generic initialization of ADC, input mixers and output mixers
325 */
326static struct hda_verb vt1708_volume_init_verbs[] = {
327 /*
328 * Unmute ADC0-1 and set the default input to mic-in
329 */
330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
331 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
332
333
f7278fd0 334 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
c577b8a1
JC
335 * mixer widget
336 */
337 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
f7278fd0
JC
338 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
340 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
341 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
342 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
c577b8a1
JC
343
344 /*
345 * Set up output mixers (0x19 - 0x1b)
346 */
347 /* set vol=0 to output mixers */
348 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
349 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
350 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
351
352 /* Setup default input to PW4 */
353 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
c577b8a1
JC
354 /* PW9 Output enable */
355 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
f7278fd0 356 { }
c577b8a1
JC
357};
358
359static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
360 struct hda_codec *codec,
361 struct snd_pcm_substream *substream)
362{
363 struct via_spec *spec = codec->spec;
9a08160b
TI
364 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
365 hinfo);
c577b8a1
JC
366}
367
368static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
369 struct hda_codec *codec,
370 unsigned int stream_tag,
371 unsigned int format,
372 struct snd_pcm_substream *substream)
373{
374 struct via_spec *spec = codec->spec;
375 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
376 stream_tag, format, substream);
377}
378
379static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
380 struct hda_codec *codec,
381 struct snd_pcm_substream *substream)
382{
383 struct via_spec *spec = codec->spec;
384 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
385}
386
387/*
388 * Digital out
389 */
390static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
391 struct hda_codec *codec,
392 struct snd_pcm_substream *substream)
393{
394 struct via_spec *spec = codec->spec;
395 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
396}
397
398static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
399 struct hda_codec *codec,
400 struct snd_pcm_substream *substream)
401{
402 struct via_spec *spec = codec->spec;
403 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
404}
405
6b97eb45
TI
406static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
407 struct hda_codec *codec,
408 unsigned int stream_tag,
409 unsigned int format,
410 struct snd_pcm_substream *substream)
411{
412 struct via_spec *spec = codec->spec;
413 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
414 stream_tag, format, substream);
415}
416
c577b8a1
JC
417/*
418 * Analog capture
419 */
420static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
421 struct hda_codec *codec,
422 unsigned int stream_tag,
423 unsigned int format,
424 struct snd_pcm_substream *substream)
425{
426 struct via_spec *spec = codec->spec;
427
428 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
429 stream_tag, 0, format);
430 return 0;
431}
432
433static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
434 struct hda_codec *codec,
435 struct snd_pcm_substream *substream)
436{
437 struct via_spec *spec = codec->spec;
888afa15 438 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
c577b8a1
JC
439 return 0;
440}
441
442static struct hda_pcm_stream vt1708_pcm_analog_playback = {
443 .substreams = 1,
444 .channels_min = 2,
445 .channels_max = 8,
446 .nid = 0x10, /* NID to query formats and rates */
447 .ops = {
448 .open = via_playback_pcm_open,
449 .prepare = via_playback_pcm_prepare,
450 .cleanup = via_playback_pcm_cleanup
451 },
452};
453
bc9b5623
TI
454static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
455 .substreams = 1,
456 .channels_min = 2,
457 .channels_max = 8,
458 .nid = 0x10, /* NID to query formats and rates */
459 /* We got noisy outputs on the right channel on VT1708 when
460 * 24bit samples are used. Until any workaround is found,
461 * disable the 24bit format, so far.
462 */
463 .formats = SNDRV_PCM_FMTBIT_S16_LE,
464 .ops = {
465 .open = via_playback_pcm_open,
466 .prepare = via_playback_pcm_prepare,
467 .cleanup = via_playback_pcm_cleanup
468 },
469};
470
c577b8a1
JC
471static struct hda_pcm_stream vt1708_pcm_analog_capture = {
472 .substreams = 2,
473 .channels_min = 2,
474 .channels_max = 2,
475 .nid = 0x15, /* NID to query formats and rates */
476 .ops = {
477 .prepare = via_capture_pcm_prepare,
478 .cleanup = via_capture_pcm_cleanup
479 },
480};
481
482static struct hda_pcm_stream vt1708_pcm_digital_playback = {
483 .substreams = 1,
484 .channels_min = 2,
485 .channels_max = 2,
486 /* NID is set in via_build_pcms */
487 .ops = {
488 .open = via_dig_playback_pcm_open,
6b97eb45
TI
489 .close = via_dig_playback_pcm_close,
490 .prepare = via_dig_playback_pcm_prepare
c577b8a1
JC
491 },
492};
493
494static struct hda_pcm_stream vt1708_pcm_digital_capture = {
495 .substreams = 1,
496 .channels_min = 2,
497 .channels_max = 2,
498};
499
500static int via_build_controls(struct hda_codec *codec)
501{
502 struct via_spec *spec = codec->spec;
503 int err;
504 int i;
505
506 for (i = 0; i < spec->num_mixers; i++) {
507 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
508 if (err < 0)
509 return err;
510 }
511
512 if (spec->multiout.dig_out_nid) {
513 err = snd_hda_create_spdif_out_ctls(codec,
514 spec->multiout.dig_out_nid);
515 if (err < 0)
516 return err;
9a08160b
TI
517 err = snd_hda_create_spdif_share_sw(codec,
518 &spec->multiout);
519 if (err < 0)
520 return err;
521 spec->multiout.share_spdif = 1;
c577b8a1
JC
522 }
523 if (spec->dig_in_nid) {
524 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
525 if (err < 0)
526 return err;
527 }
528 return 0;
529}
530
531static int via_build_pcms(struct hda_codec *codec)
532{
533 struct via_spec *spec = codec->spec;
534 struct hda_pcm *info = spec->pcm_rec;
535
536 codec->num_pcms = 1;
537 codec->pcm_info = info;
538
539 info->name = spec->stream_name_analog;
540 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
541 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
542 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
543 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
544
545 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
546 spec->multiout.max_channels;
547
548 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
549 codec->num_pcms++;
550 info++;
551 info->name = spec->stream_name_digital;
7ba72ba1 552 info->pcm_type = HDA_PCM_TYPE_SPDIF;
c577b8a1
JC
553 if (spec->multiout.dig_out_nid) {
554 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
555 *(spec->stream_digital_playback);
556 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
557 spec->multiout.dig_out_nid;
558 }
559 if (spec->dig_in_nid) {
560 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
561 *(spec->stream_digital_capture);
562 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
563 spec->dig_in_nid;
564 }
565 }
566
567 return 0;
568}
569
570static void via_free(struct hda_codec *codec)
571{
572 struct via_spec *spec = codec->spec;
573 unsigned int i;
574
575 if (!spec)
576 return;
577
578 if (spec->kctl_alloc) {
579 for (i = 0; i < spec->num_kctl_used; i++)
580 kfree(spec->kctl_alloc[i].name);
581 kfree(spec->kctl_alloc);
582 }
583
584 kfree(codec->spec);
585}
586
587static int via_init(struct hda_codec *codec)
588{
589 struct via_spec *spec = codec->spec;
590 snd_hda_sequence_write(codec, spec->init_verbs);
f7278fd0
JC
591 /* Lydia Add for EAPD enable */
592 if (!spec->dig_in_nid) { /* No Digital In connection */
593 if (IS_VT1708_VENDORID(codec->vendor_id)) {
594 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
595 AC_VERB_SET_PIN_WIDGET_CONTROL,
12b74c80 596 PIN_OUT);
f7278fd0
JC
597 snd_hda_codec_write(codec, VT1708_DIGIN_PIN, 0,
598 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
599 } else if (IS_VT1709_10CH_VENDORID(codec->vendor_id) ||
600 IS_VT1709_6CH_VENDORID(codec->vendor_id)) {
601 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
602 AC_VERB_SET_PIN_WIDGET_CONTROL,
12b74c80 603 PIN_OUT);
f7278fd0
JC
604 snd_hda_codec_write(codec, VT1709_DIGIN_PIN, 0,
605 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
606 } else if (IS_VT1708B_8CH_VENDORID(codec->vendor_id) ||
607 IS_VT1708B_4CH_VENDORID(codec->vendor_id)) {
608 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
609 AC_VERB_SET_PIN_WIDGET_CONTROL,
12b74c80 610 PIN_OUT);
f7278fd0
JC
611 snd_hda_codec_write(codec, VT1708B_DIGIN_PIN, 0,
612 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
613 }
12b74c80
TI
614 } else /* enable SPDIF-input pin */
615 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
616 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
f7278fd0 617
c577b8a1
JC
618 return 0;
619}
620
cb53c626
TI
621#ifdef CONFIG_SND_HDA_POWER_SAVE
622static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
623{
624 struct via_spec *spec = codec->spec;
625 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
626}
627#endif
628
c577b8a1
JC
629/*
630 */
631static struct hda_codec_ops via_patch_ops = {
632 .build_controls = via_build_controls,
633 .build_pcms = via_build_pcms,
634 .init = via_init,
635 .free = via_free,
cb53c626
TI
636#ifdef CONFIG_SND_HDA_POWER_SAVE
637 .check_power_status = via_check_power_status,
638#endif
c577b8a1
JC
639};
640
641/* fill in the dac_nids table from the parsed pin configuration */
642static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
643 const struct auto_pin_cfg *cfg)
644{
645 int i;
646 hda_nid_t nid;
647
648 spec->multiout.num_dacs = cfg->line_outs;
649
650 spec->multiout.dac_nids = spec->private_dac_nids;
651
652 for(i = 0; i < 4; i++) {
653 nid = cfg->line_out_pins[i];
654 if (nid) {
655 /* config dac list */
656 switch (i) {
657 case AUTO_SEQ_FRONT:
658 spec->multiout.dac_nids[i] = 0x10;
659 break;
660 case AUTO_SEQ_CENLFE:
661 spec->multiout.dac_nids[i] = 0x12;
662 break;
663 case AUTO_SEQ_SURROUND:
fb4cb772 664 spec->multiout.dac_nids[i] = 0x11;
c577b8a1
JC
665 break;
666 case AUTO_SEQ_SIDE:
fb4cb772 667 spec->multiout.dac_nids[i] = 0x13;
c577b8a1
JC
668 break;
669 }
670 }
671 }
672
673 return 0;
674}
675
676/* add playback controls from the parsed DAC table */
677static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
678 const struct auto_pin_cfg *cfg)
679{
680 char name[32];
681 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
682 hda_nid_t nid, nid_vol = 0;
683 int i, err;
684
685 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
686 nid = cfg->line_out_pins[i];
687
688 if (!nid)
689 continue;
690
691 if (i != AUTO_SEQ_FRONT)
fb4cb772 692 nid_vol = 0x18 + i;
c577b8a1
JC
693
694 if (i == AUTO_SEQ_CENLFE) {
695 /* Center/LFE */
696 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
f7278fd0
JC
697 "Center Playback Volume",
698 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
699 HDA_OUTPUT));
c577b8a1
JC
700 if (err < 0)
701 return err;
702 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
703 "LFE Playback Volume",
f7278fd0
JC
704 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
705 HDA_OUTPUT));
c577b8a1
JC
706 if (err < 0)
707 return err;
708 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
709 "Center Playback Switch",
f7278fd0
JC
710 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
711 HDA_OUTPUT));
c577b8a1
JC
712 if (err < 0)
713 return err;
714 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
715 "LFE Playback Switch",
f7278fd0
JC
716 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
717 HDA_OUTPUT));
c577b8a1
JC
718 if (err < 0)
719 return err;
720 } else if (i == AUTO_SEQ_FRONT){
721 /* add control to mixer index 0 */
722 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
723 "Master Front Playback Volume",
f7278fd0
JC
724 HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
725 HDA_INPUT));
c577b8a1
JC
726 if (err < 0)
727 return err;
728 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
729 "Master Front Playback Switch",
f7278fd0
JC
730 HDA_COMPOSE_AMP_VAL(0x17, 3, 0,
731 HDA_INPUT));
c577b8a1
JC
732 if (err < 0)
733 return err;
734
735 /* add control to PW3 */
736 sprintf(name, "%s Playback Volume", chname[i]);
737 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
f7278fd0
JC
738 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
739 HDA_OUTPUT));
c577b8a1
JC
740 if (err < 0)
741 return err;
742 sprintf(name, "%s Playback Switch", chname[i]);
743 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
f7278fd0
JC
744 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
745 HDA_OUTPUT));
c577b8a1
JC
746 if (err < 0)
747 return err;
748 } else {
749 sprintf(name, "%s Playback Volume", chname[i]);
750 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
f7278fd0
JC
751 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
752 HDA_OUTPUT));
c577b8a1
JC
753 if (err < 0)
754 return err;
755 sprintf(name, "%s Playback Switch", chname[i]);
756 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
f7278fd0
JC
757 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
758 HDA_OUTPUT));
c577b8a1
JC
759 if (err < 0)
760 return err;
761 }
762 }
763
764 return 0;
765}
766
767static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
768{
769 int err;
770
771 if (!pin)
772 return 0;
773
774 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
775
776 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
777 "Headphone Playback Volume",
778 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
779 if (err < 0)
780 return err;
781 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
782 "Headphone Playback Switch",
783 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
784 if (err < 0)
785 return err;
786
787 return 0;
788}
789
790/* create playback/capture controls for input pins */
791static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
792 const struct auto_pin_cfg *cfg)
793{
794 static char *labels[] = {
795 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
796 };
797 struct hda_input_mux *imux = &spec->private_imux;
798 int i, err, idx = 0;
799
800 /* for internal loopback recording select */
801 imux->items[imux->num_items].label = "Stereo Mixer";
802 imux->items[imux->num_items].index = idx;
803 imux->num_items++;
804
805 for (i = 0; i < AUTO_PIN_LAST; i++) {
806 if (!cfg->input_pins[i])
807 continue;
808
809 switch (cfg->input_pins[i]) {
810 case 0x1d: /* Mic */
811 idx = 2;
812 break;
813
814 case 0x1e: /* Line In */
815 idx = 3;
816 break;
817
818 case 0x21: /* Front Mic */
819 idx = 4;
820 break;
821
822 case 0x24: /* CD */
823 idx = 1;
824 break;
825 }
826 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
827 idx, 0x17);
828 if (err < 0)
829 return err;
830 imux->items[imux->num_items].label = labels[i];
831 imux->items[imux->num_items].index = idx;
832 imux->num_items++;
833 }
834 return 0;
835}
836
cb53c626
TI
837#ifdef CONFIG_SND_HDA_POWER_SAVE
838static struct hda_amp_list vt1708_loopbacks[] = {
839 { 0x17, HDA_INPUT, 1 },
840 { 0x17, HDA_INPUT, 2 },
841 { 0x17, HDA_INPUT, 3 },
842 { 0x17, HDA_INPUT, 4 },
843 { } /* end */
844};
845#endif
846
76d9b0dd
HW
847static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
848{
849 unsigned int def_conf;
850 unsigned char seqassoc;
851
852 def_conf = snd_hda_codec_read(codec, nid, 0,
853 AC_VERB_GET_CONFIG_DEFAULT, 0);
854 seqassoc = (unsigned char) get_defcfg_association(def_conf);
855 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
856 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) {
857 if (seqassoc == 0xff) {
858 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
859 snd_hda_codec_write(codec, nid, 0,
860 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
861 def_conf >> 24);
862 }
863 }
864
865 return;
866}
867
c577b8a1
JC
868static int vt1708_parse_auto_config(struct hda_codec *codec)
869{
870 struct via_spec *spec = codec->spec;
871 int err;
872
76d9b0dd
HW
873 /* Add HP and CD pin config connect bit re-config action */
874 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
875 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
876
c577b8a1
JC
877 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
878 if (err < 0)
879 return err;
880 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
881 if (err < 0)
882 return err;
883 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
884 return 0; /* can't find valid BIOS pin config */
885
886 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
887 if (err < 0)
888 return err;
889 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
890 if (err < 0)
891 return err;
892 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
893 if (err < 0)
894 return err;
895
896 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
897
898 if (spec->autocfg.dig_out_pin)
899 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
900 if (spec->autocfg.dig_in_pin)
901 spec->dig_in_nid = VT1708_DIGIN_NID;
902
903 if (spec->kctl_alloc)
904 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
905
906 spec->init_verbs = vt1708_volume_init_verbs;
907
908 spec->input_mux = &spec->private_imux;
909
910 return 1;
911}
912
913/* init callback for auto-configuration model -- overriding the default init */
914static int via_auto_init(struct hda_codec *codec)
915{
916 via_init(codec);
917 via_auto_init_multi_out(codec);
918 via_auto_init_hp_out(codec);
919 via_auto_init_analog_input(codec);
920 return 0;
921}
922
923static int patch_vt1708(struct hda_codec *codec)
924{
925 struct via_spec *spec;
926 int err;
927
928 /* create a codec specific record */
eb14a46c 929 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
c577b8a1
JC
930 if (spec == NULL)
931 return -ENOMEM;
932
933 codec->spec = spec;
934
935 /* automatic parse from the BIOS config */
936 err = vt1708_parse_auto_config(codec);
937 if (err < 0) {
938 via_free(codec);
939 return err;
940 } else if (!err) {
941 printk(KERN_INFO "hda_codec: Cannot set up configuration "
942 "from BIOS. Using genenic mode...\n");
943 }
944
945
946 spec->stream_name_analog = "VT1708 Analog";
947 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
bc9b5623
TI
948 /* disable 32bit format on VT1708 */
949 if (codec->vendor_id == 0x11061708)
950 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
c577b8a1
JC
951 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
952
953 spec->stream_name_digital = "VT1708 Digital";
954 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
955 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
956
957
958 if (!spec->adc_nids && spec->input_mux) {
959 spec->adc_nids = vt1708_adc_nids;
960 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
961 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
962 spec->num_mixers++;
963 }
964
965 codec->patch_ops = via_patch_ops;
966
967 codec->patch_ops.init = via_auto_init;
cb53c626
TI
968#ifdef CONFIG_SND_HDA_POWER_SAVE
969 spec->loopback.amplist = vt1708_loopbacks;
970#endif
c577b8a1
JC
971
972 return 0;
973}
974
975/* capture mixer elements */
976static struct snd_kcontrol_new vt1709_capture_mixer[] = {
977 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
978 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
979 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
980 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
981 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
982 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
983 {
984 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
985 /* The multiple "Capture Source" controls confuse alsamixer
986 * So call somewhat different..
c577b8a1
JC
987 */
988 /* .name = "Capture Source", */
989 .name = "Input Source",
990 .count = 1,
991 .info = via_mux_enum_info,
992 .get = via_mux_enum_get,
993 .put = via_mux_enum_put,
994 },
995 { } /* end */
996};
997
998/*
999 * generic initialization of ADC, input mixers and output mixers
1000 */
1001static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
1002 /*
1003 * Unmute ADC0-2 and set the default input to mic-in
1004 */
1005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1008
1009
f7278fd0 1010 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
c577b8a1
JC
1011 * mixer widget
1012 */
1013 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
f7278fd0
JC
1014 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1016 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1017 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1018 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
c577b8a1
JC
1019
1020 /*
1021 * Set up output selector (0x1a, 0x1b, 0x29)
1022 */
1023 /* set vol=0 to output mixers */
1024 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1025 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1026 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1027
1028 /*
1029 * Unmute PW3 and PW4
1030 */
1031 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1032 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1033
1034 /* Set input of PW4 as AOW4 */
1035 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
c577b8a1
JC
1036 /* PW9 Output enable */
1037 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1038 { }
1039};
1040
1041static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
1042 .substreams = 1,
1043 .channels_min = 2,
1044 .channels_max = 10,
1045 .nid = 0x10, /* NID to query formats and rates */
1046 .ops = {
1047 .open = via_playback_pcm_open,
1048 .prepare = via_playback_pcm_prepare,
1049 .cleanup = via_playback_pcm_cleanup
1050 },
1051};
1052
1053static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
1054 .substreams = 1,
1055 .channels_min = 2,
1056 .channels_max = 6,
1057 .nid = 0x10, /* NID to query formats and rates */
1058 .ops = {
1059 .open = via_playback_pcm_open,
1060 .prepare = via_playback_pcm_prepare,
1061 .cleanup = via_playback_pcm_cleanup
1062 },
1063};
1064
1065static struct hda_pcm_stream vt1709_pcm_analog_capture = {
1066 .substreams = 2,
1067 .channels_min = 2,
1068 .channels_max = 2,
1069 .nid = 0x14, /* NID to query formats and rates */
1070 .ops = {
1071 .prepare = via_capture_pcm_prepare,
1072 .cleanup = via_capture_pcm_cleanup
1073 },
1074};
1075
1076static struct hda_pcm_stream vt1709_pcm_digital_playback = {
1077 .substreams = 1,
1078 .channels_min = 2,
1079 .channels_max = 2,
1080 /* NID is set in via_build_pcms */
1081 .ops = {
1082 .open = via_dig_playback_pcm_open,
1083 .close = via_dig_playback_pcm_close
1084 },
1085};
1086
1087static struct hda_pcm_stream vt1709_pcm_digital_capture = {
1088 .substreams = 1,
1089 .channels_min = 2,
1090 .channels_max = 2,
1091};
1092
1093static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
1094 const struct auto_pin_cfg *cfg)
1095{
1096 int i;
1097 hda_nid_t nid;
1098
1099 if (cfg->line_outs == 4) /* 10 channels */
1100 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
1101 else if (cfg->line_outs == 3) /* 6 channels */
1102 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
1103
1104 spec->multiout.dac_nids = spec->private_dac_nids;
1105
1106 if (cfg->line_outs == 4) { /* 10 channels */
1107 for (i = 0; i < cfg->line_outs; i++) {
1108 nid = cfg->line_out_pins[i];
1109 if (nid) {
1110 /* config dac list */
1111 switch (i) {
1112 case AUTO_SEQ_FRONT:
1113 /* AOW0 */
1114 spec->multiout.dac_nids[i] = 0x10;
1115 break;
1116 case AUTO_SEQ_CENLFE:
1117 /* AOW2 */
1118 spec->multiout.dac_nids[i] = 0x12;
1119 break;
1120 case AUTO_SEQ_SURROUND:
1121 /* AOW3 */
fb4cb772 1122 spec->multiout.dac_nids[i] = 0x11;
c577b8a1
JC
1123 break;
1124 case AUTO_SEQ_SIDE:
1125 /* AOW1 */
fb4cb772 1126 spec->multiout.dac_nids[i] = 0x27;
c577b8a1
JC
1127 break;
1128 default:
1129 break;
1130 }
1131 }
1132 }
1133 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1134
1135 } else if (cfg->line_outs == 3) { /* 6 channels */
1136 for(i = 0; i < cfg->line_outs; i++) {
1137 nid = cfg->line_out_pins[i];
1138 if (nid) {
1139 /* config dac list */
1140 switch(i) {
1141 case AUTO_SEQ_FRONT:
1142 /* AOW0 */
1143 spec->multiout.dac_nids[i] = 0x10;
1144 break;
1145 case AUTO_SEQ_CENLFE:
1146 /* AOW2 */
1147 spec->multiout.dac_nids[i] = 0x12;
1148 break;
1149 case AUTO_SEQ_SURROUND:
1150 /* AOW1 */
1151 spec->multiout.dac_nids[i] = 0x11;
1152 break;
1153 default:
1154 break;
1155 }
1156 }
1157 }
1158 }
1159
1160 return 0;
1161}
1162
1163/* add playback controls from the parsed DAC table */
1164static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1165 const struct auto_pin_cfg *cfg)
1166{
1167 char name[32];
1168 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1169 hda_nid_t nid = 0;
1170 int i, err;
1171
1172 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1173 nid = cfg->line_out_pins[i];
1174
1175 if (!nid)
1176 continue;
1177
1178 if (i == AUTO_SEQ_CENLFE) {
1179 /* Center/LFE */
1180 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1181 "Center Playback Volume",
f7278fd0
JC
1182 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1183 HDA_OUTPUT));
c577b8a1
JC
1184 if (err < 0)
1185 return err;
1186 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1187 "LFE Playback Volume",
f7278fd0
JC
1188 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1189 HDA_OUTPUT));
c577b8a1
JC
1190 if (err < 0)
1191 return err;
1192 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1193 "Center Playback Switch",
f7278fd0
JC
1194 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0,
1195 HDA_OUTPUT));
c577b8a1
JC
1196 if (err < 0)
1197 return err;
1198 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1199 "LFE Playback Switch",
f7278fd0
JC
1200 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0,
1201 HDA_OUTPUT));
c577b8a1
JC
1202 if (err < 0)
1203 return err;
1204 } else if (i == AUTO_SEQ_FRONT){
1205 /* add control to mixer index 0 */
1206 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1207 "Master Front Playback Volume",
f7278fd0
JC
1208 HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1209 HDA_INPUT));
c577b8a1
JC
1210 if (err < 0)
1211 return err;
1212 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1213 "Master Front Playback Switch",
f7278fd0
JC
1214 HDA_COMPOSE_AMP_VAL(0x18, 3, 0,
1215 HDA_INPUT));
c577b8a1
JC
1216 if (err < 0)
1217 return err;
1218
1219 /* add control to PW3 */
1220 sprintf(name, "%s Playback Volume", chname[i]);
1221 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
f7278fd0
JC
1222 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1223 HDA_OUTPUT));
c577b8a1
JC
1224 if (err < 0)
1225 return err;
1226 sprintf(name, "%s Playback Switch", chname[i]);
1227 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
f7278fd0
JC
1228 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1229 HDA_OUTPUT));
c577b8a1
JC
1230 if (err < 0)
1231 return err;
1232 } else if (i == AUTO_SEQ_SURROUND) {
1233 sprintf(name, "%s Playback Volume", chname[i]);
1234 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
fb4cb772 1235 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
f7278fd0 1236 HDA_OUTPUT));
c577b8a1
JC
1237 if (err < 0)
1238 return err;
1239 sprintf(name, "%s Playback Switch", chname[i]);
1240 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
fb4cb772 1241 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0,
f7278fd0 1242 HDA_OUTPUT));
c577b8a1
JC
1243 if (err < 0)
1244 return err;
1245 } else if (i == AUTO_SEQ_SIDE) {
1246 sprintf(name, "%s Playback Volume", chname[i]);
1247 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
fb4cb772 1248 HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
f7278fd0 1249 HDA_OUTPUT));
c577b8a1
JC
1250 if (err < 0)
1251 return err;
1252 sprintf(name, "%s Playback Switch", chname[i]);
1253 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
fb4cb772 1254 HDA_COMPOSE_AMP_VAL(0x29, 3, 0,
f7278fd0 1255 HDA_OUTPUT));
c577b8a1
JC
1256 if (err < 0)
1257 return err;
1258 }
1259 }
1260
1261 return 0;
1262}
1263
1264static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1265{
1266 int err;
1267
1268 if (!pin)
1269 return 0;
1270
1271 if (spec->multiout.num_dacs == 5) /* 10 channels */
1272 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1273 else if (spec->multiout.num_dacs == 3) /* 6 channels */
1274 spec->multiout.hp_nid = 0;
1275
1276 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1277 "Headphone Playback Volume",
1278 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1279 if (err < 0)
1280 return err;
1281 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1282 "Headphone Playback Switch",
1283 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1284 if (err < 0)
1285 return err;
1286
1287 return 0;
1288}
1289
1290/* create playback/capture controls for input pins */
1291static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1292 const struct auto_pin_cfg *cfg)
1293{
1294 static char *labels[] = {
1295 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1296 };
1297 struct hda_input_mux *imux = &spec->private_imux;
1298 int i, err, idx = 0;
1299
1300 /* for internal loopback recording select */
1301 imux->items[imux->num_items].label = "Stereo Mixer";
1302 imux->items[imux->num_items].index = idx;
1303 imux->num_items++;
1304
1305 for (i = 0; i < AUTO_PIN_LAST; i++) {
1306 if (!cfg->input_pins[i])
1307 continue;
1308
1309 switch (cfg->input_pins[i]) {
1310 case 0x1d: /* Mic */
1311 idx = 2;
1312 break;
1313
1314 case 0x1e: /* Line In */
1315 idx = 3;
1316 break;
1317
1318 case 0x21: /* Front Mic */
1319 idx = 4;
1320 break;
1321
1322 case 0x23: /* CD */
1323 idx = 1;
1324 break;
1325 }
1326 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1327 idx, 0x18);
1328 if (err < 0)
1329 return err;
1330 imux->items[imux->num_items].label = labels[i];
1331 imux->items[imux->num_items].index = idx;
1332 imux->num_items++;
1333 }
1334 return 0;
1335}
1336
1337static int vt1709_parse_auto_config(struct hda_codec *codec)
1338{
1339 struct via_spec *spec = codec->spec;
1340 int err;
1341
1342 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1343 if (err < 0)
1344 return err;
1345 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1346 if (err < 0)
1347 return err;
1348 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1349 return 0; /* can't find valid BIOS pin config */
1350
1351 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1352 if (err < 0)
1353 return err;
1354 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1355 if (err < 0)
1356 return err;
1357 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1358 if (err < 0)
1359 return err;
1360
1361 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1362
1363 if (spec->autocfg.dig_out_pin)
1364 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1365 if (spec->autocfg.dig_in_pin)
1366 spec->dig_in_nid = VT1709_DIGIN_NID;
1367
1368 if (spec->kctl_alloc)
1369 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1370
1371 spec->input_mux = &spec->private_imux;
1372
1373 return 1;
1374}
1375
cb53c626
TI
1376#ifdef CONFIG_SND_HDA_POWER_SAVE
1377static struct hda_amp_list vt1709_loopbacks[] = {
1378 { 0x18, HDA_INPUT, 1 },
1379 { 0x18, HDA_INPUT, 2 },
1380 { 0x18, HDA_INPUT, 3 },
1381 { 0x18, HDA_INPUT, 4 },
1382 { } /* end */
1383};
1384#endif
1385
c577b8a1
JC
1386static int patch_vt1709_10ch(struct hda_codec *codec)
1387{
1388 struct via_spec *spec;
1389 int err;
1390
1391 /* create a codec specific record */
eb14a46c 1392 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
c577b8a1
JC
1393 if (spec == NULL)
1394 return -ENOMEM;
1395
1396 codec->spec = spec;
1397
1398 err = vt1709_parse_auto_config(codec);
1399 if (err < 0) {
1400 via_free(codec);
1401 return err;
1402 } else if (!err) {
1403 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1404 "Using genenic mode...\n");
1405 }
1406
1407 spec->init_verbs = vt1709_10ch_volume_init_verbs;
1408
1409 spec->stream_name_analog = "VT1709 Analog";
1410 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1411 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1412
1413 spec->stream_name_digital = "VT1709 Digital";
1414 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1415 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1416
1417
1418 if (!spec->adc_nids && spec->input_mux) {
1419 spec->adc_nids = vt1709_adc_nids;
1420 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1421 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1422 spec->num_mixers++;
1423 }
1424
1425 codec->patch_ops = via_patch_ops;
1426
1427 codec->patch_ops.init = via_auto_init;
cb53c626
TI
1428#ifdef CONFIG_SND_HDA_POWER_SAVE
1429 spec->loopback.amplist = vt1709_loopbacks;
1430#endif
c577b8a1
JC
1431
1432 return 0;
1433}
1434/*
1435 * generic initialization of ADC, input mixers and output mixers
1436 */
1437static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1438 /*
1439 * Unmute ADC0-2 and set the default input to mic-in
1440 */
1441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1442 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444
1445
1446 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1447 * mixer widget
1448 */
1449 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1450 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1454 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1455
1456 /*
1457 * Set up output selector (0x1a, 0x1b, 0x29)
1458 */
1459 /* set vol=0 to output mixers */
1460 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1461 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1462 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1463
1464 /*
1465 * Unmute PW3 and PW4
1466 */
1467 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1468 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1469
1470 /* Set input of PW4 as MW0 */
1471 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
c577b8a1
JC
1472 /* PW9 Output enable */
1473 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1474 { }
1475};
1476
1477static int patch_vt1709_6ch(struct hda_codec *codec)
1478{
1479 struct via_spec *spec;
1480 int err;
1481
1482 /* create a codec specific record */
eb14a46c 1483 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
c577b8a1
JC
1484 if (spec == NULL)
1485 return -ENOMEM;
1486
1487 codec->spec = spec;
1488
1489 err = vt1709_parse_auto_config(codec);
1490 if (err < 0) {
1491 via_free(codec);
1492 return err;
1493 } else if (!err) {
1494 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1495 "Using genenic mode...\n");
1496 }
1497
1498 spec->init_verbs = vt1709_6ch_volume_init_verbs;
1499
1500 spec->stream_name_analog = "VT1709 Analog";
1501 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1502 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1503
1504 spec->stream_name_digital = "VT1709 Digital";
1505 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1506 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1507
1508
1509 if (!spec->adc_nids && spec->input_mux) {
1510 spec->adc_nids = vt1709_adc_nids;
1511 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1512 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1513 spec->num_mixers++;
1514 }
1515
1516 codec->patch_ops = via_patch_ops;
1517
1518 codec->patch_ops.init = via_auto_init;
cb53c626
TI
1519#ifdef CONFIG_SND_HDA_POWER_SAVE
1520 spec->loopback.amplist = vt1709_loopbacks;
1521#endif
f7278fd0
JC
1522 return 0;
1523}
1524
1525/* capture mixer elements */
1526static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
1527 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
1528 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
1529 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
1530 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
1531 {
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 /* The multiple "Capture Source" controls confuse alsamixer
1534 * So call somewhat different..
f7278fd0
JC
1535 */
1536 /* .name = "Capture Source", */
1537 .name = "Input Source",
1538 .count = 1,
1539 .info = via_mux_enum_info,
1540 .get = via_mux_enum_get,
1541 .put = via_mux_enum_put,
1542 },
1543 { } /* end */
1544};
1545/*
1546 * generic initialization of ADC, input mixers and output mixers
1547 */
1548static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
1549 /*
1550 * Unmute ADC0-1 and set the default input to mic-in
1551 */
1552 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1554
1555
1556 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1557 * mixer widget
1558 */
1559 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1560 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1561 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1564 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1565
1566 /*
1567 * Set up output mixers
1568 */
1569 /* set vol=0 to output mixers */
1570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1571 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1572 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1573
1574 /* Setup default input to PW4 */
1575 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
1576 /* PW9 Output enable */
1577 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1578 /* PW10 Input enable */
1579 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1580 { }
1581};
1582
1583static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
1584 /*
1585 * Unmute ADC0-1 and set the default input to mic-in
1586 */
1587 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1589
1590
1591 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1592 * mixer widget
1593 */
1594 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1597 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1599 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1600
1601 /*
1602 * Set up output mixers
1603 */
1604 /* set vol=0 to output mixers */
1605 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1606 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1607 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1608
1609 /* Setup default input of PW4 to MW0 */
1610 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
1611 /* PW9 Output enable */
1612 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1613 /* PW10 Input enable */
1614 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
1615 { }
1616};
1617
1618static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
1619 .substreams = 1,
1620 .channels_min = 2,
1621 .channels_max = 8,
1622 .nid = 0x10, /* NID to query formats and rates */
1623 .ops = {
1624 .open = via_playback_pcm_open,
1625 .prepare = via_playback_pcm_prepare,
1626 .cleanup = via_playback_pcm_cleanup
1627 },
1628};
1629
1630static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
1631 .substreams = 1,
1632 .channels_min = 2,
1633 .channels_max = 4,
1634 .nid = 0x10, /* NID to query formats and rates */
1635 .ops = {
1636 .open = via_playback_pcm_open,
1637 .prepare = via_playback_pcm_prepare,
1638 .cleanup = via_playback_pcm_cleanup
1639 },
1640};
1641
1642static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
1643 .substreams = 2,
1644 .channels_min = 2,
1645 .channels_max = 2,
1646 .nid = 0x13, /* NID to query formats and rates */
1647 .ops = {
1648 .prepare = via_capture_pcm_prepare,
1649 .cleanup = via_capture_pcm_cleanup
1650 },
1651};
1652
1653static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
1654 .substreams = 1,
1655 .channels_min = 2,
1656 .channels_max = 2,
1657 /* NID is set in via_build_pcms */
1658 .ops = {
1659 .open = via_dig_playback_pcm_open,
1660 .close = via_dig_playback_pcm_close,
1661 .prepare = via_dig_playback_pcm_prepare
1662 },
1663};
1664
1665static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
1666 .substreams = 1,
1667 .channels_min = 2,
1668 .channels_max = 2,
1669};
1670
1671/* fill in the dac_nids table from the parsed pin configuration */
1672static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
1673 const struct auto_pin_cfg *cfg)
1674{
1675 int i;
1676 hda_nid_t nid;
1677
1678 spec->multiout.num_dacs = cfg->line_outs;
1679
1680 spec->multiout.dac_nids = spec->private_dac_nids;
1681
1682 for (i = 0; i < 4; i++) {
1683 nid = cfg->line_out_pins[i];
1684 if (nid) {
1685 /* config dac list */
1686 switch (i) {
1687 case AUTO_SEQ_FRONT:
1688 spec->multiout.dac_nids[i] = 0x10;
1689 break;
1690 case AUTO_SEQ_CENLFE:
1691 spec->multiout.dac_nids[i] = 0x24;
1692 break;
1693 case AUTO_SEQ_SURROUND:
fb4cb772 1694 spec->multiout.dac_nids[i] = 0x11;
f7278fd0
JC
1695 break;
1696 case AUTO_SEQ_SIDE:
fb4cb772 1697 spec->multiout.dac_nids[i] = 0x25;
f7278fd0
JC
1698 break;
1699 }
1700 }
1701 }
1702
1703 return 0;
1704}
1705
1706/* add playback controls from the parsed DAC table */
1707static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
1708 const struct auto_pin_cfg *cfg)
1709{
1710 char name[32];
1711 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
fb4cb772 1712 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
f7278fd0
JC
1713 hda_nid_t nid, nid_vol = 0;
1714 int i, err;
1715
1716 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1717 nid = cfg->line_out_pins[i];
1718
1719 if (!nid)
1720 continue;
1721
1722 nid_vol = nid_vols[i];
1723
1724 if (i == AUTO_SEQ_CENLFE) {
1725 /* Center/LFE */
1726 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1727 "Center Playback Volume",
1728 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1729 HDA_OUTPUT));
1730 if (err < 0)
1731 return err;
1732 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1733 "LFE Playback Volume",
1734 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1735 HDA_OUTPUT));
1736 if (err < 0)
1737 return err;
1738 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1739 "Center Playback Switch",
1740 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1741 HDA_OUTPUT));
1742 if (err < 0)
1743 return err;
1744 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1745 "LFE Playback Switch",
1746 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1747 HDA_OUTPUT));
1748 if (err < 0)
1749 return err;
1750 } else if (i == AUTO_SEQ_FRONT) {
1751 /* add control to mixer index 0 */
1752 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1753 "Master Front Playback Volume",
1754 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1755 HDA_INPUT));
1756 if (err < 0)
1757 return err;
1758 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1759 "Master Front Playback Switch",
1760 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1761 HDA_INPUT));
1762 if (err < 0)
1763 return err;
1764
1765 /* add control to PW3 */
1766 sprintf(name, "%s Playback Volume", chname[i]);
1767 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1768 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1769 HDA_OUTPUT));
1770 if (err < 0)
1771 return err;
1772 sprintf(name, "%s Playback Switch", chname[i]);
1773 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1774 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1775 HDA_OUTPUT));
1776 if (err < 0)
1777 return err;
1778 } else {
1779 sprintf(name, "%s Playback Volume", chname[i]);
1780 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1781 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1782 HDA_OUTPUT));
1783 if (err < 0)
1784 return err;
1785 sprintf(name, "%s Playback Switch", chname[i]);
1786 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1787 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1788 HDA_OUTPUT));
1789 if (err < 0)
1790 return err;
1791 }
1792 }
1793
1794 return 0;
1795}
1796
1797static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1798{
1799 int err;
1800
1801 if (!pin)
1802 return 0;
1803
1804 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
1805
1806 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1807 "Headphone Playback Volume",
1808 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1809 if (err < 0)
1810 return err;
1811 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1812 "Headphone Playback Switch",
1813 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1814 if (err < 0)
1815 return err;
1816
1817 return 0;
1818}
1819
1820/* create playback/capture controls for input pins */
1821static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
1822 const struct auto_pin_cfg *cfg)
1823{
1824 static char *labels[] = {
1825 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1826 };
1827 struct hda_input_mux *imux = &spec->private_imux;
1828 int i, err, idx = 0;
1829
1830 /* for internal loopback recording select */
1831 imux->items[imux->num_items].label = "Stereo Mixer";
1832 imux->items[imux->num_items].index = idx;
1833 imux->num_items++;
1834
1835 for (i = 0; i < AUTO_PIN_LAST; i++) {
1836 if (!cfg->input_pins[i])
1837 continue;
1838
1839 switch (cfg->input_pins[i]) {
1840 case 0x1a: /* Mic */
1841 idx = 2;
1842 break;
1843
1844 case 0x1b: /* Line In */
1845 idx = 3;
1846 break;
1847
1848 case 0x1e: /* Front Mic */
1849 idx = 4;
1850 break;
1851
1852 case 0x1f: /* CD */
1853 idx = 1;
1854 break;
1855 }
1856 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1857 idx, 0x16);
1858 if (err < 0)
1859 return err;
1860 imux->items[imux->num_items].label = labels[i];
1861 imux->items[imux->num_items].index = idx;
1862 imux->num_items++;
1863 }
1864 return 0;
1865}
1866
1867static int vt1708B_parse_auto_config(struct hda_codec *codec)
1868{
1869 struct via_spec *spec = codec->spec;
1870 int err;
1871
1872 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1873 if (err < 0)
1874 return err;
1875 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
1876 if (err < 0)
1877 return err;
1878 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1879 return 0; /* can't find valid BIOS pin config */
1880
1881 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
1882 if (err < 0)
1883 return err;
1884 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1885 if (err < 0)
1886 return err;
1887 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
1888 if (err < 0)
1889 return err;
1890
1891 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1892
1893 if (spec->autocfg.dig_out_pin)
1894 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
1895 if (spec->autocfg.dig_in_pin)
1896 spec->dig_in_nid = VT1708B_DIGIN_NID;
1897
1898 if (spec->kctl_alloc)
1899 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1900
1901 spec->input_mux = &spec->private_imux;
1902
1903 return 1;
1904}
1905
1906#ifdef CONFIG_SND_HDA_POWER_SAVE
1907static struct hda_amp_list vt1708B_loopbacks[] = {
1908 { 0x16, HDA_INPUT, 1 },
1909 { 0x16, HDA_INPUT, 2 },
1910 { 0x16, HDA_INPUT, 3 },
1911 { 0x16, HDA_INPUT, 4 },
1912 { } /* end */
1913};
1914#endif
1915
1916static int patch_vt1708B_8ch(struct hda_codec *codec)
1917{
1918 struct via_spec *spec;
1919 int err;
1920
1921 /* create a codec specific record */
eb14a46c 1922 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
f7278fd0
JC
1923 if (spec == NULL)
1924 return -ENOMEM;
1925
1926 codec->spec = spec;
1927
1928 /* automatic parse from the BIOS config */
1929 err = vt1708B_parse_auto_config(codec);
1930 if (err < 0) {
1931 via_free(codec);
1932 return err;
1933 } else if (!err) {
1934 printk(KERN_INFO "hda_codec: Cannot set up configuration "
1935 "from BIOS. Using genenic mode...\n");
1936 }
1937
1938 spec->init_verbs = vt1708B_8ch_volume_init_verbs;
1939
1940 spec->stream_name_analog = "VT1708B Analog";
1941 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
1942 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
1943
1944 spec->stream_name_digital = "VT1708B Digital";
1945 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
1946 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
1947
1948 if (!spec->adc_nids && spec->input_mux) {
1949 spec->adc_nids = vt1708B_adc_nids;
1950 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
1951 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
1952 spec->num_mixers++;
1953 }
1954
1955 codec->patch_ops = via_patch_ops;
1956
1957 codec->patch_ops.init = via_auto_init;
1958#ifdef CONFIG_SND_HDA_POWER_SAVE
1959 spec->loopback.amplist = vt1708B_loopbacks;
1960#endif
1961
1962 return 0;
1963}
1964
1965static int patch_vt1708B_4ch(struct hda_codec *codec)
1966{
1967 struct via_spec *spec;
1968 int err;
1969
1970 /* create a codec specific record */
eb14a46c 1971 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
f7278fd0
JC
1972 if (spec == NULL)
1973 return -ENOMEM;
1974
1975 codec->spec = spec;
1976
1977 /* automatic parse from the BIOS config */
1978 err = vt1708B_parse_auto_config(codec);
1979 if (err < 0) {
1980 via_free(codec);
1981 return err;
1982 } else if (!err) {
1983 printk(KERN_INFO "hda_codec: Cannot set up configuration "
1984 "from BIOS. Using genenic mode...\n");
1985 }
1986
1987 spec->init_verbs = vt1708B_4ch_volume_init_verbs;
1988
1989 spec->stream_name_analog = "VT1708B Analog";
1990 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
1991 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
1992
1993 spec->stream_name_digital = "VT1708B Digital";
1994 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
1995 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
1996
1997 if (!spec->adc_nids && spec->input_mux) {
1998 spec->adc_nids = vt1708B_adc_nids;
1999 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
2000 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
2001 spec->num_mixers++;
2002 }
2003
2004 codec->patch_ops = via_patch_ops;
2005
2006 codec->patch_ops.init = via_auto_init;
2007#ifdef CONFIG_SND_HDA_POWER_SAVE
2008 spec->loopback.amplist = vt1708B_loopbacks;
2009#endif
c577b8a1
JC
2010
2011 return 0;
2012}
2013
2014/*
2015 * patch entries
2016 */
2017struct hda_codec_preset snd_hda_preset_via[] = {
2018 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
2019 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
2020 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
2021 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
f7278fd0
JC
2022 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch",
2023 .patch = patch_vt1709_10ch},
2024 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch",
2025 .patch = patch_vt1709_10ch},
2026 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch",
2027 .patch = patch_vt1709_10ch},
2028 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch",
2029 .patch = patch_vt1709_10ch},
2030 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch",
2031 .patch = patch_vt1709_6ch},
2032 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch",
2033 .patch = patch_vt1709_6ch},
2034 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch",
2035 .patch = patch_vt1709_6ch},
2036 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch",
2037 .patch = patch_vt1709_6ch},
2038 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch",
2039 .patch = patch_vt1708B_8ch},
2040 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch",
2041 .patch = patch_vt1708B_8ch},
2042 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch",
2043 .patch = patch_vt1708B_8ch},
2044 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch",
2045 .patch = patch_vt1708B_8ch},
2046 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch",
2047 .patch = patch_vt1708B_4ch},
2048 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch",
2049 .patch = patch_vt1708B_4ch},
2050 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch",
2051 .patch = patch_vt1708B_4ch},
2052 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch",
2053 .patch = patch_vt1708B_4ch},
c577b8a1
JC
2054 {} /* terminator */
2055};