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