x86: remove rogue default m in drivers/video/Kconfig
[linux-2.6/s3c2410-cpufreq.git] / sound / pci / hda / patch_via.c
blob33b5e1ffa8175d27e6c739a4bcdcb9a3562007c9
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT1708 codec
6 * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com>
7 * Takashi Iwai <tiwai@suse.de>
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.
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.
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
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 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
34 #include <sound/driver.h>
35 #include <linux/init.h>
36 #include <linux/delay.h>
37 #include <linux/slab.h>
38 #include <sound/core.h>
39 #include "hda_codec.h"
40 #include "hda_local.h"
43 /* amp values */
44 #define AMP_VAL_IDX_SHIFT 19
45 #define AMP_VAL_IDX_MASK (0x0f<<19)
47 #define NUM_CONTROL_ALLOC 32
48 #define NUM_VERB_ALLOC 32
50 /* Pin Widget NID */
51 #define VT1708_HP_NID 0x13
52 #define VT1708_DIGOUT_NID 0x14
53 #define VT1708_DIGIN_NID 0x16
55 #define VT1709_HP_DAC_NID 0x28
56 #define VT1709_DIGOUT_NID 0x13
57 #define VT1709_DIGIN_NID 0x17
59 #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
60 #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
61 #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
64 enum {
65 VIA_CTL_WIDGET_VOL,
66 VIA_CTL_WIDGET_MUTE,
69 enum {
70 AUTO_SEQ_FRONT,
71 AUTO_SEQ_SURROUND,
72 AUTO_SEQ_CENLFE,
73 AUTO_SEQ_SIDE
76 static struct snd_kcontrol_new vt1708_control_templates[] = {
77 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
78 HDA_CODEC_MUTE(NULL, 0, 0, 0),
82 struct via_spec {
83 /* codec parameterization */
84 struct snd_kcontrol_new *mixers[3];
85 unsigned int num_mixers;
87 struct hda_verb *init_verbs;
89 char *stream_name_analog;
90 struct hda_pcm_stream *stream_analog_playback;
91 struct hda_pcm_stream *stream_analog_capture;
93 char *stream_name_digital;
94 struct hda_pcm_stream *stream_digital_playback;
95 struct hda_pcm_stream *stream_digital_capture;
97 /* playback */
98 struct hda_multi_out multiout;
100 /* capture */
101 unsigned int num_adc_nids;
102 hda_nid_t *adc_nids;
103 hda_nid_t dig_in_nid;
105 /* capture source */
106 const struct hda_input_mux *input_mux;
107 unsigned int cur_mux[3];
109 /* PCM information */
110 struct hda_pcm pcm_rec[2];
112 /* dynamic controls, init_verbs and input_mux */
113 struct auto_pin_cfg autocfg;
114 unsigned int num_kctl_alloc, num_kctl_used;
115 struct snd_kcontrol_new *kctl_alloc;
116 struct hda_input_mux private_imux;
117 hda_nid_t private_dac_nids[4];
119 #ifdef CONFIG_SND_HDA_POWER_SAVE
120 struct hda_loopback_check loopback;
121 #endif
124 static hda_nid_t vt1708_adc_nids[2] = {
125 /* ADC1-2 */
126 0x15, 0x27
129 static hda_nid_t vt1709_adc_nids[3] = {
130 /* ADC1-2 */
131 0x14, 0x15, 0x16
134 /* add dynamic controls */
135 static int via_add_control(struct via_spec *spec, int type, const char *name,
136 unsigned long val)
138 struct snd_kcontrol_new *knew;
140 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
141 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
143 /* array + terminator */
144 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
145 if (!knew)
146 return -ENOMEM;
147 if (spec->kctl_alloc) {
148 memcpy(knew, spec->kctl_alloc,
149 sizeof(*knew) * spec->num_kctl_alloc);
150 kfree(spec->kctl_alloc);
152 spec->kctl_alloc = knew;
153 spec->num_kctl_alloc = num;
156 knew = &spec->kctl_alloc[spec->num_kctl_used];
157 *knew = vt1708_control_templates[type];
158 knew->name = kstrdup(name, GFP_KERNEL);
160 if (!knew->name)
161 return -ENOMEM;
162 knew->private_value = val;
163 spec->num_kctl_used++;
164 return 0;
167 /* create input playback/capture controls for the given pin */
168 static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
169 const char *ctlname, int idx, int mix_nid)
171 char name[32];
172 int err;
174 sprintf(name, "%s Playback Volume", ctlname);
175 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
176 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
177 if (err < 0)
178 return err;
179 sprintf(name, "%s Playback Switch", ctlname);
180 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
181 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
182 if (err < 0)
183 return err;
184 return 0;
187 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
188 hda_nid_t nid, int pin_type,
189 int dac_idx)
191 /* set as output */
192 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
193 pin_type);
194 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
195 AMP_OUT_UNMUTE);
199 static void via_auto_init_multi_out(struct hda_codec *codec)
201 struct via_spec *spec = codec->spec;
202 int i;
204 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
205 hda_nid_t nid = spec->autocfg.line_out_pins[i];
206 if (nid)
207 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
211 static void via_auto_init_hp_out(struct hda_codec *codec)
213 struct via_spec *spec = codec->spec;
214 hda_nid_t pin;
216 pin = spec->autocfg.hp_pins[0];
217 if (pin) /* connect to front */
218 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
221 static void via_auto_init_analog_input(struct hda_codec *codec)
223 struct via_spec *spec = codec->spec;
224 int i;
226 for (i = 0; i < AUTO_PIN_LAST; i++) {
227 hda_nid_t nid = spec->autocfg.input_pins[i];
229 snd_hda_codec_write(codec, nid, 0,
230 AC_VERB_SET_PIN_WIDGET_CONTROL,
231 (i <= AUTO_PIN_FRONT_MIC ?
232 PIN_VREF50 : PIN_IN));
237 * input MUX handling
239 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
240 struct snd_ctl_elem_info *uinfo)
242 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
243 struct via_spec *spec = codec->spec;
244 return snd_hda_input_mux_info(spec->input_mux, uinfo);
247 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
248 struct snd_ctl_elem_value *ucontrol)
250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
251 struct via_spec *spec = codec->spec;
252 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
254 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
255 return 0;
258 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
259 struct snd_ctl_elem_value *ucontrol)
261 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
262 struct via_spec *spec = codec->spec;
263 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
264 unsigned int vendor_id = codec->vendor_id;
266 /* AIW0 lydia 060801 add for correct sw0 input select */
267 if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
268 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
269 0x18, &spec->cur_mux[adc_idx]);
270 else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
271 IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0) )
272 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
273 0x19, &spec->cur_mux[adc_idx]);
274 else
275 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
276 spec->adc_nids[adc_idx],
277 &spec->cur_mux[adc_idx]);
280 /* capture mixer elements */
281 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
282 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
283 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
284 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
285 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
288 /* The multiple "Capture Source" controls confuse alsamixer
289 * So call somewhat different..
290 * FIXME: the controls appear in the "playback" view!
292 /* .name = "Capture Source", */
293 .name = "Input Source",
294 .count = 1,
295 .info = via_mux_enum_info,
296 .get = via_mux_enum_get,
297 .put = via_mux_enum_put,
299 { } /* end */
302 * generic initialization of ADC, input mixers and output mixers
304 static struct hda_verb vt1708_volume_init_verbs[] = {
306 * Unmute ADC0-1 and set the default input to mic-in
308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
309 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
312 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
313 * mixer widget
315 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* master */
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
318 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
319 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
320 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
323 * Set up output mixers (0x19 - 0x1b)
325 /* set vol=0 to output mixers */
326 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
327 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
328 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
330 /* Setup default input to PW4 */
331 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
332 /* Set mic as default input of sw0 */
333 {0x18, AC_VERB_SET_CONNECT_SEL, 0x2},
334 /* PW9 Output enable */
335 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
338 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
339 struct hda_codec *codec,
340 struct snd_pcm_substream *substream)
342 struct via_spec *spec = codec->spec;
343 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
346 static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
347 struct hda_codec *codec,
348 unsigned int stream_tag,
349 unsigned int format,
350 struct snd_pcm_substream *substream)
352 struct via_spec *spec = codec->spec;
353 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
354 stream_tag, format, substream);
357 static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
358 struct hda_codec *codec,
359 struct snd_pcm_substream *substream)
361 struct via_spec *spec = codec->spec;
362 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
366 * Digital out
368 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
369 struct hda_codec *codec,
370 struct snd_pcm_substream *substream)
372 struct via_spec *spec = codec->spec;
373 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
376 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
377 struct hda_codec *codec,
378 struct snd_pcm_substream *substream)
380 struct via_spec *spec = codec->spec;
381 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
384 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
385 struct hda_codec *codec,
386 unsigned int stream_tag,
387 unsigned int format,
388 struct snd_pcm_substream *substream)
390 struct via_spec *spec = codec->spec;
391 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
392 stream_tag, format, substream);
396 * Analog capture
398 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
399 struct hda_codec *codec,
400 unsigned int stream_tag,
401 unsigned int format,
402 struct snd_pcm_substream *substream)
404 struct via_spec *spec = codec->spec;
406 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
407 stream_tag, 0, format);
408 return 0;
411 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
412 struct hda_codec *codec,
413 struct snd_pcm_substream *substream)
415 struct via_spec *spec = codec->spec;
416 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
417 0, 0, 0);
418 return 0;
421 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
422 .substreams = 1,
423 .channels_min = 2,
424 .channels_max = 8,
425 .nid = 0x10, /* NID to query formats and rates */
426 .ops = {
427 .open = via_playback_pcm_open,
428 .prepare = via_playback_pcm_prepare,
429 .cleanup = via_playback_pcm_cleanup
433 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
434 .substreams = 2,
435 .channels_min = 2,
436 .channels_max = 2,
437 .nid = 0x15, /* NID to query formats and rates */
438 .ops = {
439 .prepare = via_capture_pcm_prepare,
440 .cleanup = via_capture_pcm_cleanup
444 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
445 .substreams = 1,
446 .channels_min = 2,
447 .channels_max = 2,
448 /* NID is set in via_build_pcms */
449 .ops = {
450 .open = via_dig_playback_pcm_open,
451 .close = via_dig_playback_pcm_close,
452 .prepare = via_dig_playback_pcm_prepare
456 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
457 .substreams = 1,
458 .channels_min = 2,
459 .channels_max = 2,
462 static int via_build_controls(struct hda_codec *codec)
464 struct via_spec *spec = codec->spec;
465 int err;
466 int i;
468 for (i = 0; i < spec->num_mixers; i++) {
469 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
470 if (err < 0)
471 return err;
474 if (spec->multiout.dig_out_nid) {
475 err = snd_hda_create_spdif_out_ctls(codec,
476 spec->multiout.dig_out_nid);
477 if (err < 0)
478 return err;
480 if (spec->dig_in_nid) {
481 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
482 if (err < 0)
483 return err;
485 return 0;
488 static int via_build_pcms(struct hda_codec *codec)
490 struct via_spec *spec = codec->spec;
491 struct hda_pcm *info = spec->pcm_rec;
493 codec->num_pcms = 1;
494 codec->pcm_info = info;
496 info->name = spec->stream_name_analog;
497 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
498 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
499 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
500 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
502 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
503 spec->multiout.max_channels;
505 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
506 codec->num_pcms++;
507 info++;
508 info->name = spec->stream_name_digital;
509 if (spec->multiout.dig_out_nid) {
510 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
511 *(spec->stream_digital_playback);
512 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
513 spec->multiout.dig_out_nid;
515 if (spec->dig_in_nid) {
516 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
517 *(spec->stream_digital_capture);
518 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
519 spec->dig_in_nid;
523 return 0;
526 static void via_free(struct hda_codec *codec)
528 struct via_spec *spec = codec->spec;
529 unsigned int i;
531 if (!spec)
532 return;
534 if (spec->kctl_alloc) {
535 for (i = 0; i < spec->num_kctl_used; i++)
536 kfree(spec->kctl_alloc[i].name);
537 kfree(spec->kctl_alloc);
540 kfree(codec->spec);
543 static int via_init(struct hda_codec *codec)
545 struct via_spec *spec = codec->spec;
546 snd_hda_sequence_write(codec, spec->init_verbs);
547 return 0;
550 #ifdef CONFIG_SND_HDA_POWER_SAVE
551 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
553 struct via_spec *spec = codec->spec;
554 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
556 #endif
560 static struct hda_codec_ops via_patch_ops = {
561 .build_controls = via_build_controls,
562 .build_pcms = via_build_pcms,
563 .init = via_init,
564 .free = via_free,
565 #ifdef CONFIG_SND_HDA_POWER_SAVE
566 .check_power_status = via_check_power_status,
567 #endif
570 /* fill in the dac_nids table from the parsed pin configuration */
571 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
572 const struct auto_pin_cfg *cfg)
574 int i;
575 hda_nid_t nid;
577 spec->multiout.num_dacs = cfg->line_outs;
579 spec->multiout.dac_nids = spec->private_dac_nids;
581 for(i = 0; i < 4; i++) {
582 nid = cfg->line_out_pins[i];
583 if (nid) {
584 /* config dac list */
585 switch (i) {
586 case AUTO_SEQ_FRONT:
587 spec->multiout.dac_nids[i] = 0x10;
588 break;
589 case AUTO_SEQ_CENLFE:
590 spec->multiout.dac_nids[i] = 0x12;
591 break;
592 case AUTO_SEQ_SURROUND:
593 spec->multiout.dac_nids[i] = 0x13;
594 break;
595 case AUTO_SEQ_SIDE:
596 spec->multiout.dac_nids[i] = 0x11;
597 break;
602 return 0;
605 /* add playback controls from the parsed DAC table */
606 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
607 const struct auto_pin_cfg *cfg)
609 char name[32];
610 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
611 hda_nid_t nid, nid_vol = 0;
612 int i, err;
614 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
615 nid = cfg->line_out_pins[i];
617 if (!nid)
618 continue;
620 if (i != AUTO_SEQ_FRONT)
621 nid_vol = 0x1b - i + 1;
623 if (i == AUTO_SEQ_CENLFE) {
624 /* Center/LFE */
625 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
626 "Center Playback Volume",
627 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
628 if (err < 0)
629 return err;
630 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
631 "LFE Playback Volume",
632 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
633 if (err < 0)
634 return err;
635 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
636 "Center Playback Switch",
637 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
638 if (err < 0)
639 return err;
640 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
641 "LFE Playback Switch",
642 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
643 if (err < 0)
644 return err;
645 } else if (i == AUTO_SEQ_FRONT){
646 /* add control to mixer index 0 */
647 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
648 "Master Front Playback Volume",
649 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
650 if (err < 0)
651 return err;
652 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
653 "Master Front Playback Switch",
654 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
655 if (err < 0)
656 return err;
658 /* add control to PW3 */
659 sprintf(name, "%s Playback Volume", chname[i]);
660 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
661 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
662 if (err < 0)
663 return err;
664 sprintf(name, "%s Playback Switch", chname[i]);
665 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
666 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
667 if (err < 0)
668 return err;
669 } else {
670 sprintf(name, "%s Playback Volume", chname[i]);
671 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
672 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
673 if (err < 0)
674 return err;
675 sprintf(name, "%s Playback Switch", chname[i]);
676 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
677 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
678 if (err < 0)
679 return err;
683 return 0;
686 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
688 int err;
690 if (!pin)
691 return 0;
693 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
695 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
696 "Headphone Playback Volume",
697 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
698 if (err < 0)
699 return err;
700 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
701 "Headphone Playback Switch",
702 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
703 if (err < 0)
704 return err;
706 return 0;
709 /* create playback/capture controls for input pins */
710 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
711 const struct auto_pin_cfg *cfg)
713 static char *labels[] = {
714 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
716 struct hda_input_mux *imux = &spec->private_imux;
717 int i, err, idx = 0;
719 /* for internal loopback recording select */
720 imux->items[imux->num_items].label = "Stereo Mixer";
721 imux->items[imux->num_items].index = idx;
722 imux->num_items++;
724 for (i = 0; i < AUTO_PIN_LAST; i++) {
725 if (!cfg->input_pins[i])
726 continue;
728 switch (cfg->input_pins[i]) {
729 case 0x1d: /* Mic */
730 idx = 2;
731 break;
733 case 0x1e: /* Line In */
734 idx = 3;
735 break;
737 case 0x21: /* Front Mic */
738 idx = 4;
739 break;
741 case 0x24: /* CD */
742 idx = 1;
743 break;
745 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
746 idx, 0x17);
747 if (err < 0)
748 return err;
749 imux->items[imux->num_items].label = labels[i];
750 imux->items[imux->num_items].index = idx;
751 imux->num_items++;
753 return 0;
756 #ifdef CONFIG_SND_HDA_POWER_SAVE
757 static struct hda_amp_list vt1708_loopbacks[] = {
758 { 0x17, HDA_INPUT, 1 },
759 { 0x17, HDA_INPUT, 2 },
760 { 0x17, HDA_INPUT, 3 },
761 { 0x17, HDA_INPUT, 4 },
762 { } /* end */
764 #endif
766 static int vt1708_parse_auto_config(struct hda_codec *codec)
768 struct via_spec *spec = codec->spec;
769 int err;
771 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
772 if (err < 0)
773 return err;
774 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
775 if (err < 0)
776 return err;
777 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
778 return 0; /* can't find valid BIOS pin config */
780 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
781 if (err < 0)
782 return err;
783 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
784 if (err < 0)
785 return err;
786 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
787 if (err < 0)
788 return err;
790 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
792 if (spec->autocfg.dig_out_pin)
793 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
794 if (spec->autocfg.dig_in_pin)
795 spec->dig_in_nid = VT1708_DIGIN_NID;
797 if (spec->kctl_alloc)
798 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
800 spec->init_verbs = vt1708_volume_init_verbs;
802 spec->input_mux = &spec->private_imux;
804 return 1;
807 /* init callback for auto-configuration model -- overriding the default init */
808 static int via_auto_init(struct hda_codec *codec)
810 via_init(codec);
811 via_auto_init_multi_out(codec);
812 via_auto_init_hp_out(codec);
813 via_auto_init_analog_input(codec);
814 return 0;
817 static int patch_vt1708(struct hda_codec *codec)
819 struct via_spec *spec;
820 int err;
822 /* create a codec specific record */
823 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
824 if (spec == NULL)
825 return -ENOMEM;
827 codec->spec = spec;
829 /* automatic parse from the BIOS config */
830 err = vt1708_parse_auto_config(codec);
831 if (err < 0) {
832 via_free(codec);
833 return err;
834 } else if (!err) {
835 printk(KERN_INFO "hda_codec: Cannot set up configuration "
836 "from BIOS. Using genenic mode...\n");
840 spec->stream_name_analog = "VT1708 Analog";
841 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
842 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
844 spec->stream_name_digital = "VT1708 Digital";
845 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
846 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
849 if (!spec->adc_nids && spec->input_mux) {
850 spec->adc_nids = vt1708_adc_nids;
851 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
852 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
853 spec->num_mixers++;
856 codec->patch_ops = via_patch_ops;
858 codec->patch_ops.init = via_auto_init;
859 #ifdef CONFIG_SND_HDA_POWER_SAVE
860 spec->loopback.amplist = vt1708_loopbacks;
861 #endif
863 return 0;
866 /* capture mixer elements */
867 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
868 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
869 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
870 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
871 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
872 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
873 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
876 /* The multiple "Capture Source" controls confuse alsamixer
877 * So call somewhat different..
878 * FIXME: the controls appear in the "playback" view!
880 /* .name = "Capture Source", */
881 .name = "Input Source",
882 .count = 1,
883 .info = via_mux_enum_info,
884 .get = via_mux_enum_get,
885 .put = via_mux_enum_put,
887 { } /* end */
891 * generic initialization of ADC, input mixers and output mixers
893 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
895 * Unmute ADC0-2 and set the default input to mic-in
897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
899 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
902 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
903 * mixer widget
905 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* unmute master */
907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
909 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
910 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
913 * Set up output selector (0x1a, 0x1b, 0x29)
915 /* set vol=0 to output mixers */
916 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
918 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
921 * Unmute PW3 and PW4
923 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
924 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
926 /* Set input of PW4 as AOW4 */
927 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
928 /* Set mic as default input of sw0 */
929 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
930 /* PW9 Output enable */
931 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
935 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
936 .substreams = 1,
937 .channels_min = 2,
938 .channels_max = 10,
939 .nid = 0x10, /* NID to query formats and rates */
940 .ops = {
941 .open = via_playback_pcm_open,
942 .prepare = via_playback_pcm_prepare,
943 .cleanup = via_playback_pcm_cleanup
947 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
948 .substreams = 1,
949 .channels_min = 2,
950 .channels_max = 6,
951 .nid = 0x10, /* NID to query formats and rates */
952 .ops = {
953 .open = via_playback_pcm_open,
954 .prepare = via_playback_pcm_prepare,
955 .cleanup = via_playback_pcm_cleanup
959 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
960 .substreams = 2,
961 .channels_min = 2,
962 .channels_max = 2,
963 .nid = 0x14, /* NID to query formats and rates */
964 .ops = {
965 .prepare = via_capture_pcm_prepare,
966 .cleanup = via_capture_pcm_cleanup
970 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
971 .substreams = 1,
972 .channels_min = 2,
973 .channels_max = 2,
974 /* NID is set in via_build_pcms */
975 .ops = {
976 .open = via_dig_playback_pcm_open,
977 .close = via_dig_playback_pcm_close
981 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
982 .substreams = 1,
983 .channels_min = 2,
984 .channels_max = 2,
987 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
988 const struct auto_pin_cfg *cfg)
990 int i;
991 hda_nid_t nid;
993 if (cfg->line_outs == 4) /* 10 channels */
994 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
995 else if (cfg->line_outs == 3) /* 6 channels */
996 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
998 spec->multiout.dac_nids = spec->private_dac_nids;
1000 if (cfg->line_outs == 4) { /* 10 channels */
1001 for (i = 0; i < cfg->line_outs; i++) {
1002 nid = cfg->line_out_pins[i];
1003 if (nid) {
1004 /* config dac list */
1005 switch (i) {
1006 case AUTO_SEQ_FRONT:
1007 /* AOW0 */
1008 spec->multiout.dac_nids[i] = 0x10;
1009 break;
1010 case AUTO_SEQ_CENLFE:
1011 /* AOW2 */
1012 spec->multiout.dac_nids[i] = 0x12;
1013 break;
1014 case AUTO_SEQ_SURROUND:
1015 /* AOW3 */
1016 spec->multiout.dac_nids[i] = 0x27;
1017 break;
1018 case AUTO_SEQ_SIDE:
1019 /* AOW1 */
1020 spec->multiout.dac_nids[i] = 0x11;
1021 break;
1022 default:
1023 break;
1027 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1029 } else if (cfg->line_outs == 3) { /* 6 channels */
1030 for(i = 0; i < cfg->line_outs; i++) {
1031 nid = cfg->line_out_pins[i];
1032 if (nid) {
1033 /* config dac list */
1034 switch(i) {
1035 case AUTO_SEQ_FRONT:
1036 /* AOW0 */
1037 spec->multiout.dac_nids[i] = 0x10;
1038 break;
1039 case AUTO_SEQ_CENLFE:
1040 /* AOW2 */
1041 spec->multiout.dac_nids[i] = 0x12;
1042 break;
1043 case AUTO_SEQ_SURROUND:
1044 /* AOW1 */
1045 spec->multiout.dac_nids[i] = 0x11;
1046 break;
1047 default:
1048 break;
1054 return 0;
1057 /* add playback controls from the parsed DAC table */
1058 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1059 const struct auto_pin_cfg *cfg)
1061 char name[32];
1062 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1063 hda_nid_t nid = 0;
1064 int i, err;
1066 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1067 nid = cfg->line_out_pins[i];
1069 if (!nid)
1070 continue;
1072 if (i == AUTO_SEQ_CENLFE) {
1073 /* Center/LFE */
1074 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1075 "Center Playback Volume",
1076 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1077 if (err < 0)
1078 return err;
1079 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1080 "LFE Playback Volume",
1081 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1082 if (err < 0)
1083 return err;
1084 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1085 "Center Playback Switch",
1086 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1087 if (err < 0)
1088 return err;
1089 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1090 "LFE Playback Switch",
1091 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1092 if (err < 0)
1093 return err;
1094 } else if (i == AUTO_SEQ_FRONT){
1095 /* add control to mixer index 0 */
1096 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1097 "Master Front Playback Volume",
1098 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1099 if (err < 0)
1100 return err;
1101 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1102 "Master Front Playback Switch",
1103 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1104 if (err < 0)
1105 return err;
1107 /* add control to PW3 */
1108 sprintf(name, "%s Playback Volume", chname[i]);
1109 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1110 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1111 if (err < 0)
1112 return err;
1113 sprintf(name, "%s Playback Switch", chname[i]);
1114 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1115 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1116 if (err < 0)
1117 return err;
1118 } else if (i == AUTO_SEQ_SURROUND) {
1119 sprintf(name, "%s Playback Volume", chname[i]);
1120 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1121 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1122 if (err < 0)
1123 return err;
1124 sprintf(name, "%s Playback Switch", chname[i]);
1125 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1126 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1127 if (err < 0)
1128 return err;
1129 } else if (i == AUTO_SEQ_SIDE) {
1130 sprintf(name, "%s Playback Volume", chname[i]);
1131 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1132 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1133 if (err < 0)
1134 return err;
1135 sprintf(name, "%s Playback Switch", chname[i]);
1136 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1137 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1138 if (err < 0)
1139 return err;
1143 return 0;
1146 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1148 int err;
1150 if (!pin)
1151 return 0;
1153 if (spec->multiout.num_dacs == 5) /* 10 channels */
1154 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1155 else if (spec->multiout.num_dacs == 3) /* 6 channels */
1156 spec->multiout.hp_nid = 0;
1158 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1159 "Headphone Playback Volume",
1160 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1161 if (err < 0)
1162 return err;
1163 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1164 "Headphone Playback Switch",
1165 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1166 if (err < 0)
1167 return err;
1169 return 0;
1172 /* create playback/capture controls for input pins */
1173 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1174 const struct auto_pin_cfg *cfg)
1176 static char *labels[] = {
1177 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1179 struct hda_input_mux *imux = &spec->private_imux;
1180 int i, err, idx = 0;
1182 /* for internal loopback recording select */
1183 imux->items[imux->num_items].label = "Stereo Mixer";
1184 imux->items[imux->num_items].index = idx;
1185 imux->num_items++;
1187 for (i = 0; i < AUTO_PIN_LAST; i++) {
1188 if (!cfg->input_pins[i])
1189 continue;
1191 switch (cfg->input_pins[i]) {
1192 case 0x1d: /* Mic */
1193 idx = 2;
1194 break;
1196 case 0x1e: /* Line In */
1197 idx = 3;
1198 break;
1200 case 0x21: /* Front Mic */
1201 idx = 4;
1202 break;
1204 case 0x23: /* CD */
1205 idx = 1;
1206 break;
1208 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1209 idx, 0x18);
1210 if (err < 0)
1211 return err;
1212 imux->items[imux->num_items].label = labels[i];
1213 imux->items[imux->num_items].index = idx;
1214 imux->num_items++;
1216 return 0;
1219 static int vt1709_parse_auto_config(struct hda_codec *codec)
1221 struct via_spec *spec = codec->spec;
1222 int err;
1224 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1225 if (err < 0)
1226 return err;
1227 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1228 if (err < 0)
1229 return err;
1230 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1231 return 0; /* can't find valid BIOS pin config */
1233 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1234 if (err < 0)
1235 return err;
1236 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1237 if (err < 0)
1238 return err;
1239 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1240 if (err < 0)
1241 return err;
1243 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1245 if (spec->autocfg.dig_out_pin)
1246 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1247 if (spec->autocfg.dig_in_pin)
1248 spec->dig_in_nid = VT1709_DIGIN_NID;
1250 if (spec->kctl_alloc)
1251 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1253 spec->input_mux = &spec->private_imux;
1255 return 1;
1258 #ifdef CONFIG_SND_HDA_POWER_SAVE
1259 static struct hda_amp_list vt1709_loopbacks[] = {
1260 { 0x18, HDA_INPUT, 1 },
1261 { 0x18, HDA_INPUT, 2 },
1262 { 0x18, HDA_INPUT, 3 },
1263 { 0x18, HDA_INPUT, 4 },
1264 { } /* end */
1266 #endif
1268 static int patch_vt1709_10ch(struct hda_codec *codec)
1270 struct via_spec *spec;
1271 int err;
1273 /* create a codec specific record */
1274 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1275 if (spec == NULL)
1276 return -ENOMEM;
1278 codec->spec = spec;
1280 err = vt1709_parse_auto_config(codec);
1281 if (err < 0) {
1282 via_free(codec);
1283 return err;
1284 } else if (!err) {
1285 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1286 "Using genenic mode...\n");
1289 spec->init_verbs = vt1709_10ch_volume_init_verbs;
1291 spec->stream_name_analog = "VT1709 Analog";
1292 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1293 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1295 spec->stream_name_digital = "VT1709 Digital";
1296 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1297 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1300 if (!spec->adc_nids && spec->input_mux) {
1301 spec->adc_nids = vt1709_adc_nids;
1302 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1303 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1304 spec->num_mixers++;
1307 codec->patch_ops = via_patch_ops;
1309 codec->patch_ops.init = via_auto_init;
1310 #ifdef CONFIG_SND_HDA_POWER_SAVE
1311 spec->loopback.amplist = vt1709_loopbacks;
1312 #endif
1314 return 0;
1317 * generic initialization of ADC, input mixers and output mixers
1319 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1321 * Unmute ADC0-2 and set the default input to mic-in
1323 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1324 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1325 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1328 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1329 * mixer widget
1331 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1333 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1335 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1336 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1339 * Set up output selector (0x1a, 0x1b, 0x29)
1341 /* set vol=0 to output mixers */
1342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1343 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1344 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1347 * Unmute PW3 and PW4
1349 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1350 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1352 /* Set input of PW4 as MW0 */
1353 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1354 /* Set mic as default input of sw0 */
1355 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
1356 /* PW9 Output enable */
1357 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1361 static int patch_vt1709_6ch(struct hda_codec *codec)
1363 struct via_spec *spec;
1364 int err;
1366 /* create a codec specific record */
1367 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1368 if (spec == NULL)
1369 return -ENOMEM;
1371 codec->spec = spec;
1373 err = vt1709_parse_auto_config(codec);
1374 if (err < 0) {
1375 via_free(codec);
1376 return err;
1377 } else if (!err) {
1378 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1379 "Using genenic mode...\n");
1382 spec->init_verbs = vt1709_6ch_volume_init_verbs;
1384 spec->stream_name_analog = "VT1709 Analog";
1385 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1386 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1388 spec->stream_name_digital = "VT1709 Digital";
1389 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1390 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1393 if (!spec->adc_nids && spec->input_mux) {
1394 spec->adc_nids = vt1709_adc_nids;
1395 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1396 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1397 spec->num_mixers++;
1400 codec->patch_ops = via_patch_ops;
1402 codec->patch_ops.init = via_auto_init;
1403 #ifdef CONFIG_SND_HDA_POWER_SAVE
1404 spec->loopback.amplist = vt1709_loopbacks;
1405 #endif
1407 return 0;
1411 * patch entries
1413 struct hda_codec_preset snd_hda_preset_via[] = {
1414 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
1415 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
1416 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
1417 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
1418 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1419 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1420 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1421 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1422 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1423 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1424 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1425 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1426 {} /* terminator */