2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
6 * (C) 2006-2009 VIA Technology, Inc.
7 * (C) 2006-2008 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 * * * * * * * * * * * * * * * * */
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 /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
33 /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
34 /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
35 /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36 /* 2008-04-09 Lydia Wang Add Independent HP feature */
37 /* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38 /* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
39 /* 2009-02-16 Logan Li Add support for VT1718S */
40 /* 2009-03-13 Logan Li Add support for VT1716S */
41 /* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */
42 /* 2009-07-08 Lydia Wang Add support for VT2002P */
43 /* 2009-07-21 Lydia Wang Add support for VT1812 */
44 /* 2009-09-19 Lydia Wang Add support for VT1818S */
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49 #include <linux/init.h>
50 #include <linux/delay.h>
51 #include <linux/slab.h>
52 #include <sound/core.h>
53 #include <sound/asoundef.h>
54 #include "hda_codec.h"
55 #include "hda_local.h"
57 #define NID_MAPPING (-1)
60 #define AMP_VAL_IDX_SHIFT 19
61 #define AMP_VAL_IDX_MASK (0x0f<<19)
64 #define VT1708_HP_NID 0x13
65 #define VT1708_DIGOUT_NID 0x14
66 #define VT1708_DIGIN_NID 0x16
67 #define VT1708_DIGIN_PIN 0x26
68 #define VT1708_HP_PIN_NID 0x20
69 #define VT1708_CD_PIN_NID 0x24
71 #define VT1709_HP_DAC_NID 0x28
72 #define VT1709_DIGOUT_NID 0x13
73 #define VT1709_DIGIN_NID 0x17
74 #define VT1709_DIGIN_PIN 0x25
76 #define VT1708B_HP_NID 0x25
77 #define VT1708B_DIGOUT_NID 0x12
78 #define VT1708B_DIGIN_NID 0x15
79 #define VT1708B_DIGIN_PIN 0x21
81 #define VT1708S_HP_NID 0x25
82 #define VT1708S_DIGOUT_NID 0x12
84 #define VT1702_HP_NID 0x17
85 #define VT1702_DIGOUT_NID 0x11
105 /* codec parameterization */
106 struct snd_kcontrol_new *mixers[6];
107 unsigned int num_mixers;
109 struct hda_verb *init_verbs[5];
110 unsigned int num_iverbs;
112 char *stream_name_analog;
113 struct hda_pcm_stream *stream_analog_playback;
114 struct hda_pcm_stream *stream_analog_capture;
116 char *stream_name_digital;
117 struct hda_pcm_stream *stream_digital_playback;
118 struct hda_pcm_stream *stream_digital_capture;
121 struct hda_multi_out multiout;
122 hda_nid_t slave_dig_outs[2];
125 unsigned int num_adc_nids;
127 hda_nid_t mux_nids[3];
128 hda_nid_t dig_in_nid;
129 hda_nid_t dig_in_pin;
132 const struct hda_input_mux *input_mux;
133 unsigned int cur_mux[3];
135 /* PCM information */
136 struct hda_pcm pcm_rec[3];
138 /* dynamic controls, init_verbs and input_mux */
139 struct auto_pin_cfg autocfg;
140 struct snd_array kctls;
141 struct hda_input_mux private_imux[2];
142 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
145 const struct hda_input_mux *hp_mux;
146 unsigned int hp_independent_mode;
147 unsigned int hp_independent_mode_index;
148 unsigned int smart51_enabled;
149 unsigned int dmic_enabled;
150 enum VIA_HDA_CODEC codec_type;
152 /* work to check hp jack state */
153 struct hda_codec *codec;
154 struct delayed_work vt1708_hp_work;
155 int vt1708_jack_detectect;
156 int vt1708_hp_present;
157 #ifdef CONFIG_SND_HDA_POWER_SAVE
158 struct hda_loopback_check loopback;
162 static struct via_spec * via_new_spec(struct hda_codec *codec)
164 struct via_spec *spec;
166 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
175 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
177 u32 vendor_id = codec->vendor_id;
178 u16 ven_id = vendor_id >> 16;
179 u16 dev_id = vendor_id & 0xffff;
180 enum VIA_HDA_CODEC codec_type;
183 if (ven_id != 0x1106)
184 codec_type = UNKNOWN;
185 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
187 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
188 codec_type = VT1709_10CH;
189 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
190 codec_type = VT1709_6CH;
191 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
192 codec_type = VT1708B_8CH;
193 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
194 codec_type = VT1708BCE;
195 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
196 codec_type = VT1708B_4CH;
197 else if ((dev_id & 0xfff) == 0x397
198 && (dev_id >> 12) < 8)
199 codec_type = VT1708S;
200 else if ((dev_id & 0xfff) == 0x398
201 && (dev_id >> 12) < 8)
203 else if ((dev_id & 0xfff) == 0x428
204 && (dev_id >> 12) < 8)
205 codec_type = VT1718S;
206 else if (dev_id == 0x0433 || dev_id == 0xa721)
207 codec_type = VT1716S;
208 else if (dev_id == 0x0441 || dev_id == 0x4441)
209 codec_type = VT1718S;
210 else if (dev_id == 0x0438 || dev_id == 0x4438)
211 codec_type = VT2002P;
212 else if (dev_id == 0x0448)
214 else if (dev_id == 0x0440)
215 codec_type = VT1708S;
217 codec_type = UNKNOWN;
221 #define VIA_HP_EVENT 0x01
222 #define VIA_GPIO_EVENT 0x02
223 #define VIA_JACK_EVENT 0x04
224 #define VIA_MONO_EVENT 0x08
225 #define VIA_SPEAKER_EVENT 0x10
226 #define VIA_BIND_HP_EVENT 0x20
231 VIA_CTL_WIDGET_ANALOG_MUTE,
232 VIA_CTL_WIDGET_BIND_PIN_MUTE,
242 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
243 static void set_jack_power_state(struct hda_codec *codec);
244 static int is_aa_path_mute(struct hda_codec *codec);
246 static void vt1708_start_hp_work(struct via_spec *spec)
248 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
250 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
251 !spec->vt1708_jack_detectect);
252 if (!delayed_work_pending(&spec->vt1708_hp_work))
253 schedule_delayed_work(&spec->vt1708_hp_work,
254 msecs_to_jiffies(100));
257 static void vt1708_stop_hp_work(struct via_spec *spec)
259 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
261 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
262 && !is_aa_path_mute(spec->codec))
264 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
265 !spec->vt1708_jack_detectect);
266 cancel_delayed_work(&spec->vt1708_hp_work);
267 flush_scheduled_work();
271 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
272 struct snd_ctl_elem_value *ucontrol)
274 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
275 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
277 set_jack_power_state(codec);
278 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
279 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
280 if (is_aa_path_mute(codec))
281 vt1708_start_hp_work(codec->spec);
283 vt1708_stop_hp_work(codec->spec);
288 /* modify .put = snd_hda_mixer_amp_switch_put */
289 #define ANALOG_INPUT_MUTE \
290 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
293 .info = snd_hda_mixer_amp_switch_info, \
294 .get = snd_hda_mixer_amp_switch_get, \
295 .put = analog_input_switch_put, \
296 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
298 static void via_hp_bind_automute(struct hda_codec *codec);
300 static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
301 struct snd_ctl_elem_value *ucontrol)
303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
304 struct via_spec *spec = codec->spec;
308 long *valp = ucontrol->value.integer.value;
310 if (strstr(kcontrol->id.name, "Switch") == NULL) {
311 snd_printd("Invalid control!\n");
314 change = snd_hda_mixer_amp_switch_put(kcontrol,
317 lmute = *valp ? 0 : HDA_AMP_MUTE;
319 rmute = *valp ? 0 : HDA_AMP_MUTE;
322 if (!spec->hp_independent_mode) {
323 for (i = 0; i < spec->autocfg.hp_outs; i++) {
324 snd_hda_codec_amp_update(
325 codec, spec->autocfg.hp_pins[i],
326 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
328 snd_hda_codec_amp_update(
329 codec, spec->autocfg.hp_pins[i],
330 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
335 if (!lmute && !rmute) {
337 for (i = 0; i < spec->autocfg.line_outs; i++)
338 snd_hda_codec_amp_stereo(
339 codec, spec->autocfg.line_out_pins[i],
340 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
342 for (i = 0; i < spec->autocfg.speaker_outs; i++)
343 snd_hda_codec_amp_stereo(
344 codec, spec->autocfg.speaker_pins[i],
345 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
347 via_hp_bind_automute(codec);
351 /* Mute all left channels */
352 for (i = 1; i < spec->autocfg.line_outs; i++)
353 snd_hda_codec_amp_update(
355 spec->autocfg.line_out_pins[i],
356 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
358 for (i = 0; i < spec->autocfg.speaker_outs; i++)
359 snd_hda_codec_amp_update(
361 spec->autocfg.speaker_pins[i],
362 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
366 /* mute all right channels */
367 for (i = 1; i < spec->autocfg.line_outs; i++)
368 snd_hda_codec_amp_update(
370 spec->autocfg.line_out_pins[i],
371 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
373 for (i = 0; i < spec->autocfg.speaker_outs; i++)
374 snd_hda_codec_amp_update(
376 spec->autocfg.speaker_pins[i],
377 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
384 #define BIND_PIN_MUTE \
385 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
388 .info = snd_hda_mixer_amp_switch_info, \
389 .get = snd_hda_mixer_amp_switch_get, \
390 .put = bind_pin_switch_put, \
391 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
393 static struct snd_kcontrol_new via_control_templates[] = {
394 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
395 HDA_CODEC_MUTE(NULL, 0, 0, 0),
400 static hda_nid_t vt1708_adc_nids[2] = {
405 static hda_nid_t vt1709_adc_nids[3] = {
410 static hda_nid_t vt1708B_adc_nids[2] = {
415 static hda_nid_t vt1708S_adc_nids[2] = {
420 static hda_nid_t vt1702_adc_nids[3] = {
425 static hda_nid_t vt1718S_adc_nids[2] = {
430 static hda_nid_t vt1716S_adc_nids[2] = {
435 static hda_nid_t vt2002P_adc_nids[2] = {
440 static hda_nid_t vt1812_adc_nids[2] = {
446 /* add dynamic controls */
447 static int via_add_control(struct via_spec *spec, int type, const char *name,
450 struct snd_kcontrol_new *knew;
452 snd_array_init(&spec->kctls, sizeof(*knew), 32);
453 knew = snd_array_new(&spec->kctls);
456 *knew = via_control_templates[type];
457 knew->name = kstrdup(name, GFP_KERNEL);
460 if (get_amp_nid_(val))
461 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
462 knew->private_value = val;
466 static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec,
467 struct snd_kcontrol_new *tmpl)
469 struct snd_kcontrol_new *knew;
471 snd_array_init(&spec->kctls, sizeof(*knew), 32);
472 knew = snd_array_new(&spec->kctls);
476 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
482 static void via_free_kctls(struct hda_codec *codec)
484 struct via_spec *spec = codec->spec;
486 if (spec->kctls.list) {
487 struct snd_kcontrol_new *kctl = spec->kctls.list;
489 for (i = 0; i < spec->kctls.used; i++)
492 snd_array_free(&spec->kctls);
495 /* create input playback/capture controls for the given pin */
496 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
497 int idx, int mix_nid)
502 sprintf(name, "%s Playback Volume", ctlname);
503 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
504 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
507 sprintf(name, "%s Playback Switch", ctlname);
508 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
515 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
516 hda_nid_t nid, int pin_type,
520 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
522 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
524 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
525 snd_hda_codec_write(codec, nid, 0,
526 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
530 static void via_auto_init_multi_out(struct hda_codec *codec)
532 struct via_spec *spec = codec->spec;
535 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
536 hda_nid_t nid = spec->autocfg.line_out_pins[i];
538 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
542 static void via_auto_init_hp_out(struct hda_codec *codec)
544 struct via_spec *spec = codec->spec;
548 for (i = 0; i < spec->autocfg.hp_outs; i++) {
549 pin = spec->autocfg.hp_pins[i];
550 if (pin) /* connect to front */
551 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
555 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
557 static void via_auto_init_analog_input(struct hda_codec *codec)
559 struct via_spec *spec = codec->spec;
563 for (i = 0; i < AUTO_PIN_LAST; i++) {
564 hda_nid_t nid = spec->autocfg.input_pins[i];
568 if (spec->smart51_enabled && is_smart51_pins(spec, nid))
570 else if (i <= AUTO_PIN_FRONT_MIC)
574 snd_hda_codec_write(codec, nid, 0,
575 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
579 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
580 unsigned int *affected_parm)
583 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
584 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
585 >> AC_DEFCFG_MISC_SHIFT
586 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
587 unsigned present = snd_hda_jack_detect(codec, nid);
588 struct via_spec *spec = codec->spec;
589 if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
590 || ((no_presence || present)
591 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
592 *affected_parm = AC_PWRST_D0; /* if it's connected */
597 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
600 static void set_jack_power_state(struct hda_codec *codec)
602 struct via_spec *spec = codec->spec;
606 if (spec->codec_type == VT1702) {
607 imux_is_smixer = snd_hda_codec_read(
608 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
610 /* PW 1/2/5 (14h/15h/18h) */
612 set_pin_power_state(codec, 0x14, &parm);
613 set_pin_power_state(codec, 0x15, &parm);
614 set_pin_power_state(codec, 0x18, &parm);
616 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
617 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
618 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
620 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
622 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
624 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
628 /* PW 3/4 (16h/17h) */
630 set_pin_power_state(codec, 0x16, &parm);
631 set_pin_power_state(codec, 0x17, &parm);
632 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
633 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
634 imux_is_smixer ? AC_PWRST_D0 : parm);
635 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
637 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
639 } else if (spec->codec_type == VT1708B_8CH
640 || spec->codec_type == VT1708B_4CH
641 || spec->codec_type == VT1708S) {
642 /* SW0 (17h) = stereo mixer */
643 int is_8ch = spec->codec_type != VT1708B_4CH;
644 imux_is_smixer = snd_hda_codec_read(
645 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
646 == ((spec->codec_type == VT1708S) ? 5 : 0);
648 /* PW 1/2/5 (1ah/1bh/1eh) */
650 set_pin_power_state(codec, 0x1a, &parm);
651 set_pin_power_state(codec, 0x1b, &parm);
652 set_pin_power_state(codec, 0x1e, &parm);
655 /* SW0 (17h), AIW 0/1 (13h/14h) */
656 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
658 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
660 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
664 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
666 set_pin_power_state(codec, 0x19, &parm);
667 if (spec->smart51_enabled)
669 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
671 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
674 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
677 set_pin_power_state(codec, 0x22, &parm);
678 if (spec->smart51_enabled)
680 snd_hda_codec_write(codec, 0x26, 0,
681 AC_VERB_SET_POWER_STATE, parm);
682 snd_hda_codec_write(codec, 0x24, 0,
683 AC_VERB_SET_POWER_STATE, parm);
686 /* PW 3/4/7 (1ch/1dh/23h) */
688 /* force to D0 for internal Speaker */
689 set_pin_power_state(codec, 0x1c, &parm);
690 set_pin_power_state(codec, 0x1d, &parm);
692 set_pin_power_state(codec, 0x23, &parm);
693 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
694 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
695 imux_is_smixer ? AC_PWRST_D0 : parm);
696 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
699 snd_hda_codec_write(codec, 0x25, 0,
700 AC_VERB_SET_POWER_STATE, parm);
701 snd_hda_codec_write(codec, 0x27, 0,
702 AC_VERB_SET_POWER_STATE, parm);
704 } else if (spec->codec_type == VT1718S) {
705 /* MUX6 (1eh) = stereo mixer */
706 imux_is_smixer = snd_hda_codec_read(
707 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
709 /* PW 5/6/7 (29h/2ah/2bh) */
711 set_pin_power_state(codec, 0x29, &parm);
712 set_pin_power_state(codec, 0x2a, &parm);
713 set_pin_power_state(codec, 0x2b, &parm);
716 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
717 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
719 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
721 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
723 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
727 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
729 set_pin_power_state(codec, 0x27, &parm);
730 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
732 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
735 /* PW2 (26h), AOW2 (ah) */
737 set_pin_power_state(codec, 0x26, &parm);
738 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
741 /* PW0/1 (24h/25h) */
743 set_pin_power_state(codec, 0x24, &parm);
744 set_pin_power_state(codec, 0x25, &parm);
745 if (!spec->hp_independent_mode) /* check for redirected HP */
746 set_pin_power_state(codec, 0x28, &parm);
747 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
749 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
751 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
752 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
753 imux_is_smixer ? AC_PWRST_D0 : parm);
754 if (spec->hp_independent_mode) {
755 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
757 set_pin_power_state(codec, 0x28, &parm);
758 snd_hda_codec_write(codec, 0x1b, 0,
759 AC_VERB_SET_POWER_STATE, parm);
760 snd_hda_codec_write(codec, 0x34, 0,
761 AC_VERB_SET_POWER_STATE, parm);
762 snd_hda_codec_write(codec, 0xc, 0,
763 AC_VERB_SET_POWER_STATE, parm);
765 } else if (spec->codec_type == VT1716S) {
766 unsigned int mono_out, present;
767 /* SW0 (17h) = stereo mixer */
768 imux_is_smixer = snd_hda_codec_read(
769 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
771 /* PW 1/2/5 (1ah/1bh/1eh) */
773 set_pin_power_state(codec, 0x1a, &parm);
774 set_pin_power_state(codec, 0x1b, &parm);
775 set_pin_power_state(codec, 0x1e, &parm);
778 /* SW0 (17h), AIW0(13h) */
779 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
781 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
785 set_pin_power_state(codec, 0x1e, &parm);
787 if (spec->dmic_enabled)
788 set_pin_power_state(codec, 0x22, &parm);
792 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
794 /* SW2(26h), AIW1(14h) */
795 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
797 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
801 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
803 set_pin_power_state(codec, 0x19, &parm);
804 /* Smart 5.1 PW2(1bh) */
805 if (spec->smart51_enabled)
806 set_pin_power_state(codec, 0x1b, &parm);
807 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
809 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
812 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
814 set_pin_power_state(codec, 0x23, &parm);
815 /* Smart 5.1 PW1(1ah) */
816 if (spec->smart51_enabled)
817 set_pin_power_state(codec, 0x1a, &parm);
818 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
821 /* Smart 5.1 PW5(1eh) */
822 if (spec->smart51_enabled)
823 set_pin_power_state(codec, 0x1e, &parm);
824 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
828 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
829 present = snd_hda_jack_detect(codec, 0x1c);
833 present = snd_hda_jack_detect(codec, 0x1d);
834 if (!spec->hp_independent_mode && present)
839 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
840 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
842 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
844 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
847 /* PW 3/4 (1ch/1dh) */
849 set_pin_power_state(codec, 0x1c, &parm);
850 set_pin_power_state(codec, 0x1d, &parm);
851 /* HP Independent Mode, power on AOW3 */
852 if (spec->hp_independent_mode)
853 snd_hda_codec_write(codec, 0x25, 0,
854 AC_VERB_SET_POWER_STATE, parm);
856 /* force to D0 for internal Speaker */
857 /* MW0 (16h), AOW0 (10h) */
858 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
859 imux_is_smixer ? AC_PWRST_D0 : parm);
860 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
861 mono_out ? AC_PWRST_D0 : parm);
862 } else if (spec->codec_type == VT2002P) {
863 unsigned int present;
864 /* MUX9 (1eh) = stereo mixer */
865 imux_is_smixer = snd_hda_codec_read(
866 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
868 /* PW 5/6/7 (29h/2ah/2bh) */
870 set_pin_power_state(codec, 0x29, &parm);
871 set_pin_power_state(codec, 0x2a, &parm);
872 set_pin_power_state(codec, 0x2b, &parm);
875 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
876 snd_hda_codec_write(codec, 0x1e, 0,
877 AC_VERB_SET_POWER_STATE, parm);
878 snd_hda_codec_write(codec, 0x1f, 0,
879 AC_VERB_SET_POWER_STATE, parm);
880 snd_hda_codec_write(codec, 0x10, 0,
881 AC_VERB_SET_POWER_STATE, parm);
882 snd_hda_codec_write(codec, 0x11, 0,
883 AC_VERB_SET_POWER_STATE, parm);
887 snd_hda_codec_write(codec, 0x8, 0,
888 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
890 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
892 set_pin_power_state(codec, 0x26, &parm);
893 snd_hda_codec_write(codec, 0x1c, 0,
894 AC_VERB_SET_POWER_STATE, parm);
895 snd_hda_codec_write(codec, 0x37,
896 0, AC_VERB_SET_POWER_STATE, parm);
898 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
900 set_pin_power_state(codec, 0x25, &parm);
901 snd_hda_codec_write(codec, 0x19, 0,
902 AC_VERB_SET_POWER_STATE, parm);
903 snd_hda_codec_write(codec, 0x35, 0,
904 AC_VERB_SET_POWER_STATE, parm);
905 if (spec->hp_independent_mode) {
906 snd_hda_codec_write(codec, 0x9, 0,
907 AC_VERB_SET_POWER_STATE, parm);
911 /* PW0 (24h), MW0(18h), MUX0(34h) */
912 present = snd_hda_jack_detect(codec, 0x25);
914 set_pin_power_state(codec, 0x24, &parm);
918 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
921 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
925 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
928 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
932 /* PW15 (31h), MW8(17h), MUX8(3bh) */
933 present = snd_hda_jack_detect(codec, 0x26);
935 set_pin_power_state(codec, 0x31, &parm);
939 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
942 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
946 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
949 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
953 if (imux_is_smixer || !is_aa_path_mute(codec))
956 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
960 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
961 } else if (spec->codec_type == VT1812) {
962 unsigned int present;
963 /* MUX10 (1eh) = stereo mixer */
964 imux_is_smixer = snd_hda_codec_read(
965 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
967 /* PW 5/6/7 (29h/2ah/2bh) */
969 set_pin_power_state(codec, 0x29, &parm);
970 set_pin_power_state(codec, 0x2a, &parm);
971 set_pin_power_state(codec, 0x2b, &parm);
974 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
975 snd_hda_codec_write(codec, 0x1e, 0,
976 AC_VERB_SET_POWER_STATE, parm);
977 snd_hda_codec_write(codec, 0x1f, 0,
978 AC_VERB_SET_POWER_STATE, parm);
979 snd_hda_codec_write(codec, 0x10, 0,
980 AC_VERB_SET_POWER_STATE, parm);
981 snd_hda_codec_write(codec, 0x11, 0,
982 AC_VERB_SET_POWER_STATE, parm);
986 snd_hda_codec_write(codec, 0x8, 0,
987 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
989 /* PW4 (28h), MW4 (18h), MUX4(38h) */
991 set_pin_power_state(codec, 0x28, &parm);
992 snd_hda_codec_write(codec, 0x18, 0,
993 AC_VERB_SET_POWER_STATE, parm);
994 snd_hda_codec_write(codec, 0x38, 0,
995 AC_VERB_SET_POWER_STATE, parm);
997 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
999 set_pin_power_state(codec, 0x25, &parm);
1000 snd_hda_codec_write(codec, 0x15, 0,
1001 AC_VERB_SET_POWER_STATE, parm);
1002 snd_hda_codec_write(codec, 0x35, 0,
1003 AC_VERB_SET_POWER_STATE, parm);
1004 if (spec->hp_independent_mode) {
1005 snd_hda_codec_write(codec, 0x9, 0,
1006 AC_VERB_SET_POWER_STATE, parm);
1009 /* Internal Speaker */
1010 /* PW0 (24h), MW0(14h), MUX0(34h) */
1011 present = snd_hda_jack_detect(codec, 0x25);
1013 set_pin_power_state(codec, 0x24, &parm);
1015 snd_hda_codec_write(codec, 0x14, 0,
1016 AC_VERB_SET_POWER_STATE,
1018 snd_hda_codec_write(codec, 0x34, 0,
1019 AC_VERB_SET_POWER_STATE,
1022 snd_hda_codec_write(codec, 0x14, 0,
1023 AC_VERB_SET_POWER_STATE,
1025 snd_hda_codec_write(codec, 0x34, 0,
1026 AC_VERB_SET_POWER_STATE,
1030 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1031 present = snd_hda_jack_detect(codec, 0x28);
1033 set_pin_power_state(codec, 0x31, &parm);
1035 snd_hda_codec_write(codec, 0x1c, 0,
1036 AC_VERB_SET_POWER_STATE,
1038 snd_hda_codec_write(codec, 0x3c, 0,
1039 AC_VERB_SET_POWER_STATE,
1041 snd_hda_codec_write(codec, 0x3e, 0,
1042 AC_VERB_SET_POWER_STATE,
1045 snd_hda_codec_write(codec, 0x1c, 0,
1046 AC_VERB_SET_POWER_STATE,
1048 snd_hda_codec_write(codec, 0x3c, 0,
1049 AC_VERB_SET_POWER_STATE,
1051 snd_hda_codec_write(codec, 0x3e, 0,
1052 AC_VERB_SET_POWER_STATE,
1056 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1058 set_pin_power_state(codec, 0x33, &parm);
1059 snd_hda_codec_write(codec, 0x1d, 0,
1060 AC_VERB_SET_POWER_STATE, parm);
1061 snd_hda_codec_write(codec, 0x3d, 0,
1062 AC_VERB_SET_POWER_STATE, parm);
1065 if (imux_is_smixer || !is_aa_path_mute(codec))
1066 snd_hda_codec_write(
1068 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1070 snd_hda_codec_write(
1072 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1077 * input MUX handling
1079 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
1080 struct snd_ctl_elem_info *uinfo)
1082 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1083 struct via_spec *spec = codec->spec;
1084 return snd_hda_input_mux_info(spec->input_mux, uinfo);
1087 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
1088 struct snd_ctl_elem_value *ucontrol)
1090 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1091 struct via_spec *spec = codec->spec;
1092 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1094 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
1098 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
1099 struct snd_ctl_elem_value *ucontrol)
1101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1102 struct via_spec *spec = codec->spec;
1103 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1105 if (!spec->mux_nids[adc_idx])
1107 /* switch to D0 beofre change index */
1108 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
1109 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
1110 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
1111 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
1112 /* update jack power state */
1113 set_jack_power_state(codec);
1115 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
1116 spec->mux_nids[adc_idx],
1117 &spec->cur_mux[adc_idx]);
1120 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
1121 struct snd_ctl_elem_info *uinfo)
1123 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1124 struct via_spec *spec = codec->spec;
1125 return snd_hda_input_mux_info(spec->hp_mux, uinfo);
1128 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
1129 struct snd_ctl_elem_value *ucontrol)
1131 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1132 hda_nid_t nid = kcontrol->private_value;
1133 unsigned int pinsel;
1135 /* use !! to translate conn sel 2 for VT1718S */
1136 pinsel = !!snd_hda_codec_read(codec, nid, 0,
1137 AC_VERB_GET_CONNECT_SEL,
1139 ucontrol->value.enumerated.item[0] = pinsel;
1144 static void activate_ctl(struct hda_codec *codec, const char *name, int active)
1146 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
1148 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1149 ctl->vd[0].access |= active
1150 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
1151 snd_ctl_notify(codec->bus->card,
1152 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
1156 static hda_nid_t side_mute_channel(struct via_spec *spec)
1158 switch (spec->codec_type) {
1159 case VT1708: return 0x1b;
1160 case VT1709_10CH: return 0x29;
1161 case VT1708B_8CH: /* fall thru */
1162 case VT1708S: return 0x27;
1167 static int update_side_mute_status(struct hda_codec *codec)
1169 /* mute side channel */
1170 struct via_spec *spec = codec->spec;
1171 unsigned int parm = spec->hp_independent_mode
1172 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
1173 hda_nid_t sw3 = side_mute_channel(spec);
1176 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1181 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
1182 struct snd_ctl_elem_value *ucontrol)
1184 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1185 struct via_spec *spec = codec->spec;
1186 hda_nid_t nid = kcontrol->private_value;
1187 unsigned int pinsel = ucontrol->value.enumerated.item[0];
1188 /* Get Independent Mode index of headphone pin widget */
1189 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
1191 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
1193 if (spec->multiout.hp_nid && spec->multiout.hp_nid
1194 != spec->multiout.dac_nids[HDA_FRONT])
1195 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
1198 update_side_mute_status(codec);
1199 /* update HP volume/swtich active state */
1200 if (spec->codec_type == VT1708S
1201 || spec->codec_type == VT1702
1202 || spec->codec_type == VT1718S
1203 || spec->codec_type == VT1716S
1204 || spec->codec_type == VT2002P
1205 || spec->codec_type == VT1812) {
1206 activate_ctl(codec, "Headphone Playback Volume",
1207 spec->hp_independent_mode);
1208 activate_ctl(codec, "Headphone Playback Switch",
1209 spec->hp_independent_mode);
1214 static struct snd_kcontrol_new via_hp_mixer[2] = {
1216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217 .name = "Independent HP",
1218 .info = via_independent_hp_info,
1219 .get = via_independent_hp_get,
1220 .put = via_independent_hp_put,
1223 .iface = NID_MAPPING,
1224 .name = "Independent HP",
1228 static int via_hp_build(struct hda_codec *codec)
1230 struct via_spec *spec = codec->spec;
1231 struct snd_kcontrol_new *knew;
1234 hda_nid_t conn[HDA_MAX_CONNECTIONS];
1236 switch (spec->codec_type) {
1247 nid = spec->autocfg.hp_pins[0];
1251 nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS);
1255 knew = via_clone_control(spec, &via_hp_mixer[0]);
1259 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
1260 knew->private_value = nid;
1262 knew = via_clone_control(spec, &via_hp_mixer[1]);
1265 knew->subdevice = side_mute_channel(spec);
1270 static void notify_aa_path_ctls(struct hda_codec *codec)
1273 struct snd_ctl_elem_id id;
1274 const char *labels[] = {"Mic", "Front Mic", "Line"};
1276 memset(&id, 0, sizeof(id));
1277 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1278 for (i = 0; i < ARRAY_SIZE(labels); i++) {
1279 sprintf(id.name, "%s Playback Volume", labels[i]);
1280 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1285 static void mute_aa_path(struct hda_codec *codec, int mute)
1287 struct via_spec *spec = codec->spec;
1288 hda_nid_t nid_mixer;
1292 /* get nid of MW0 and start & end index */
1293 switch (spec->codec_type) {
1316 /* check AA path's mute status */
1317 for (i = start_idx; i <= end_idx; i++) {
1318 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1319 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
1323 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
1327 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
1328 if (pin == spec->autocfg.input_pins[index]) {
1336 static int via_smart51_info(struct snd_kcontrol *kcontrol,
1337 struct snd_ctl_elem_info *uinfo)
1339 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1341 uinfo->value.integer.min = 0;
1342 uinfo->value.integer.max = 1;
1346 static int via_smart51_get(struct snd_kcontrol *kcontrol,
1347 struct snd_ctl_elem_value *ucontrol)
1349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1350 struct via_spec *spec = codec->spec;
1351 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1355 for (i = 0; i < ARRAY_SIZE(index); i++) {
1356 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1359 snd_hda_codec_read(codec, nid, 0,
1360 AC_VERB_GET_PIN_WIDGET_CONTROL,
1362 if (i == AUTO_PIN_FRONT_MIC
1363 && spec->hp_independent_mode
1364 && spec->codec_type != VT1718S)
1365 continue; /* ignore FMic for independent HP */
1366 if (ctl & AC_PINCTL_IN_EN
1367 && !(ctl & AC_PINCTL_OUT_EN))
1371 *ucontrol->value.integer.value = on;
1375 static int via_smart51_put(struct snd_kcontrol *kcontrol,
1376 struct snd_ctl_elem_value *ucontrol)
1378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1379 struct via_spec *spec = codec->spec;
1380 int out_in = *ucontrol->value.integer.value
1381 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1382 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1385 for (i = 0; i < ARRAY_SIZE(index); i++) {
1386 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
1387 if (i == AUTO_PIN_FRONT_MIC
1388 && spec->hp_independent_mode
1389 && spec->codec_type != VT1718S)
1390 continue; /* don't retask FMic for independent HP */
1392 unsigned int parm = snd_hda_codec_read(
1394 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1395 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1397 snd_hda_codec_write(codec, nid, 0,
1398 AC_VERB_SET_PIN_WIDGET_CONTROL,
1400 if (out_in == AC_PINCTL_OUT_EN) {
1401 mute_aa_path(codec, 1);
1402 notify_aa_path_ctls(codec);
1404 if (spec->codec_type == VT1718S)
1405 snd_hda_codec_amp_stereo(
1406 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1409 if (i == AUTO_PIN_FRONT_MIC) {
1410 if (spec->codec_type == VT1708S
1411 || spec->codec_type == VT1716S) {
1412 /* input = index 1 (AOW3) */
1413 snd_hda_codec_write(
1415 AC_VERB_SET_CONNECT_SEL, 1);
1416 snd_hda_codec_amp_stereo(
1417 codec, nid, HDA_OUTPUT,
1418 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1422 spec->smart51_enabled = *ucontrol->value.integer.value;
1423 set_jack_power_state(codec);
1427 static struct snd_kcontrol_new via_smart51_mixer[2] = {
1429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1430 .name = "Smart 5.1",
1432 .info = via_smart51_info,
1433 .get = via_smart51_get,
1434 .put = via_smart51_put,
1437 .iface = NID_MAPPING,
1438 .name = "Smart 5.1",
1442 static int via_smart51_build(struct via_spec *spec)
1444 struct snd_kcontrol_new *knew;
1445 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
1449 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1453 for (i = 0; i < ARRAY_SIZE(index); i++) {
1454 nid = spec->autocfg.input_pins[index[i]];
1456 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1459 knew->subdevice = nid;
1466 /* capture mixer elements */
1467 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1468 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1469 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1470 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1471 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1474 /* The multiple "Capture Source" controls confuse alsamixer
1475 * So call somewhat different..
1477 /* .name = "Capture Source", */
1478 .name = "Input Source",
1480 .info = via_mux_enum_info,
1481 .get = via_mux_enum_get,
1482 .put = via_mux_enum_put,
1487 /* check AA path's mute statue */
1488 static int is_aa_path_mute(struct hda_codec *codec)
1491 hda_nid_t nid_mixer;
1495 struct via_spec *spec = codec->spec;
1496 /* get nid of MW0 and start & end index */
1497 switch (spec->codec_type) {
1525 /* check AA path's mute status */
1526 for (i = start_idx; i <= end_idx; i++) {
1527 unsigned int con_list = snd_hda_codec_read(
1528 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1529 int shift = 8 * (i % 4);
1530 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1531 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1532 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1533 /* check mute status while the pin is connected */
1534 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1536 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1538 if (!mute_l || !mute_r) {
1547 /* enter/exit analog low-current mode */
1548 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1550 struct via_spec *spec = codec->spec;
1551 static int saved_stream_idle = 1; /* saved stream idle status */
1552 int enable = is_aa_path_mute(codec);
1553 unsigned int verb = 0;
1554 unsigned int parm = 0;
1556 if (stream_idle == -1) /* stream status did not change */
1557 enable = enable && saved_stream_idle;
1559 enable = enable && stream_idle;
1560 saved_stream_idle = stream_idle;
1563 /* decide low current mode's verb & parameter */
1564 switch (spec->codec_type) {
1568 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1574 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1578 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1583 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1586 return; /* other codecs are not supported */
1589 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1593 * generic initialization of ADC, input mixers and output mixers
1595 static struct hda_verb vt1708_volume_init_verbs[] = {
1597 * Unmute ADC0-1 and set the default input to mic-in
1599 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1600 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1603 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1606 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1608 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1609 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1610 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1611 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1614 * Set up output mixers (0x19 - 0x1b)
1616 /* set vol=0 to output mixers */
1617 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1619 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1621 /* Setup default input MW0 to PW4 */
1622 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1623 /* PW9 Output enable */
1624 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1628 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1629 struct hda_codec *codec,
1630 struct snd_pcm_substream *substream)
1632 struct via_spec *spec = codec->spec;
1633 int idle = substream->pstr->substream_opened == 1
1634 && substream->ref_count == 0;
1635 analog_low_current_mode(codec, idle);
1636 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1640 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1641 unsigned int stream_tag,
1642 unsigned int format,
1643 struct snd_pcm_substream *substream)
1645 struct via_spec *spec = codec->spec;
1646 struct hda_multi_out *mout = &spec->multiout;
1647 hda_nid_t *nids = mout->dac_nids;
1648 int chs = substream->runtime->channels;
1651 mutex_lock(&codec->spdif_mutex);
1652 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1654 snd_hda_is_supported_format(codec, mout->dig_out_nid,
1656 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1657 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1658 /* turn off SPDIF once; otherwise the IEC958 bits won't
1660 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1661 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1662 AC_VERB_SET_DIGI_CONVERT_1,
1664 ~AC_DIG1_ENABLE & 0xff);
1665 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1666 stream_tag, 0, format);
1667 /* turn on again (if needed) */
1668 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1669 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1670 AC_VERB_SET_DIGI_CONVERT_1,
1671 codec->spdif_ctls & 0xff);
1673 mout->dig_out_used = 0;
1674 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1678 mutex_unlock(&codec->spdif_mutex);
1681 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1684 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1685 && !spec->hp_independent_mode)
1686 /* headphone out will just decode front left/right (stereo) */
1687 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1690 /* extra outputs copied from front */
1691 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1692 if (mout->extra_out_nid[i])
1693 snd_hda_codec_setup_stream(codec,
1694 mout->extra_out_nid[i],
1695 stream_tag, 0, format);
1698 for (i = 1; i < mout->num_dacs; i++) {
1699 if (chs >= (i + 1) * 2) /* independent out */
1700 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1702 else /* copy front */
1703 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1708 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1709 struct hda_codec *codec,
1710 unsigned int stream_tag,
1711 unsigned int format,
1712 struct snd_pcm_substream *substream)
1714 struct via_spec *spec = codec->spec;
1715 struct hda_multi_out *mout = &spec->multiout;
1716 hda_nid_t *nids = mout->dac_nids;
1718 if (substream->number == 0)
1719 playback_multi_pcm_prep_0(codec, stream_tag, format,
1722 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1723 spec->hp_independent_mode)
1724 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1725 stream_tag, 0, format);
1727 vt1708_start_hp_work(spec);
1731 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1732 struct hda_codec *codec,
1733 struct snd_pcm_substream *substream)
1735 struct via_spec *spec = codec->spec;
1736 struct hda_multi_out *mout = &spec->multiout;
1737 hda_nid_t *nids = mout->dac_nids;
1740 if (substream->number == 0) {
1741 for (i = 0; i < mout->num_dacs; i++)
1742 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1744 if (mout->hp_nid && !spec->hp_independent_mode)
1745 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1748 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1749 if (mout->extra_out_nid[i])
1750 snd_hda_codec_setup_stream(codec,
1751 mout->extra_out_nid[i],
1753 mutex_lock(&codec->spdif_mutex);
1754 if (mout->dig_out_nid &&
1755 mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1756 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1758 mout->dig_out_used = 0;
1760 mutex_unlock(&codec->spdif_mutex);
1762 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1763 spec->hp_independent_mode)
1764 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1767 vt1708_stop_hp_work(spec);
1774 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1775 struct hda_codec *codec,
1776 struct snd_pcm_substream *substream)
1778 struct via_spec *spec = codec->spec;
1779 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1782 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1783 struct hda_codec *codec,
1784 struct snd_pcm_substream *substream)
1786 struct via_spec *spec = codec->spec;
1787 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1790 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1791 struct hda_codec *codec,
1792 unsigned int stream_tag,
1793 unsigned int format,
1794 struct snd_pcm_substream *substream)
1796 struct via_spec *spec = codec->spec;
1797 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1798 stream_tag, format, substream);
1801 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1802 struct hda_codec *codec,
1803 struct snd_pcm_substream *substream)
1805 struct via_spec *spec = codec->spec;
1806 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1813 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1814 struct hda_codec *codec,
1815 unsigned int stream_tag,
1816 unsigned int format,
1817 struct snd_pcm_substream *substream)
1819 struct via_spec *spec = codec->spec;
1821 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1822 stream_tag, 0, format);
1826 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1827 struct hda_codec *codec,
1828 struct snd_pcm_substream *substream)
1830 struct via_spec *spec = codec->spec;
1831 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1835 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1839 .nid = 0x10, /* NID to query formats and rates */
1841 .open = via_playback_pcm_open,
1842 .prepare = via_playback_multi_pcm_prepare,
1843 .cleanup = via_playback_multi_pcm_cleanup
1847 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1851 .nid = 0x10, /* NID to query formats and rates */
1852 /* We got noisy outputs on the right channel on VT1708 when
1853 * 24bit samples are used. Until any workaround is found,
1854 * disable the 24bit format, so far.
1856 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1858 .open = via_playback_pcm_open,
1859 .prepare = via_playback_multi_pcm_prepare,
1860 .cleanup = via_playback_multi_pcm_cleanup
1864 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1868 .nid = 0x15, /* NID to query formats and rates */
1870 .prepare = via_capture_pcm_prepare,
1871 .cleanup = via_capture_pcm_cleanup
1875 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1879 /* NID is set in via_build_pcms */
1881 .open = via_dig_playback_pcm_open,
1882 .close = via_dig_playback_pcm_close,
1883 .prepare = via_dig_playback_pcm_prepare,
1884 .cleanup = via_dig_playback_pcm_cleanup
1888 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1894 static int via_build_controls(struct hda_codec *codec)
1896 struct via_spec *spec = codec->spec;
1897 struct snd_kcontrol *kctl;
1898 struct snd_kcontrol_new *knew;
1901 for (i = 0; i < spec->num_mixers; i++) {
1902 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1907 if (spec->multiout.dig_out_nid) {
1908 err = snd_hda_create_spdif_out_ctls(codec,
1909 spec->multiout.dig_out_nid);
1912 err = snd_hda_create_spdif_share_sw(codec,
1916 spec->multiout.share_spdif = 1;
1918 if (spec->dig_in_nid) {
1919 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1924 /* assign Capture Source enums to NID */
1925 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1926 for (i = 0; kctl && i < kctl->count; i++) {
1927 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1932 /* other nid->control mapping */
1933 for (i = 0; i < spec->num_mixers; i++) {
1934 for (knew = spec->mixers[i]; knew->name; knew++) {
1935 if (knew->iface != NID_MAPPING)
1937 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1940 err = snd_hda_add_nid(codec, kctl, 0,
1945 /* init power states */
1946 set_jack_power_state(codec);
1947 analog_low_current_mode(codec, 1);
1949 via_free_kctls(codec); /* no longer needed */
1953 static int via_build_pcms(struct hda_codec *codec)
1955 struct via_spec *spec = codec->spec;
1956 struct hda_pcm *info = spec->pcm_rec;
1958 codec->num_pcms = 1;
1959 codec->pcm_info = info;
1961 info->name = spec->stream_name_analog;
1962 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1963 *(spec->stream_analog_playback);
1964 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1965 spec->multiout.dac_nids[0];
1966 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1967 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1969 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1970 spec->multiout.max_channels;
1972 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1975 info->name = spec->stream_name_digital;
1976 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1977 if (spec->multiout.dig_out_nid) {
1978 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1979 *(spec->stream_digital_playback);
1980 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1981 spec->multiout.dig_out_nid;
1983 if (spec->dig_in_nid) {
1984 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1985 *(spec->stream_digital_capture);
1986 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1994 static void via_free(struct hda_codec *codec)
1996 struct via_spec *spec = codec->spec;
2001 via_free_kctls(codec);
2002 vt1708_stop_hp_work(spec);
2006 /* mute internal speaker if HP is plugged */
2007 static void via_hp_automute(struct hda_codec *codec)
2009 unsigned int present = 0;
2010 struct via_spec *spec = codec->spec;
2012 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2014 if (!spec->hp_independent_mode) {
2015 struct snd_ctl_elem_id id;
2017 snd_hda_codec_amp_stereo(
2018 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
2019 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2021 memset(&id, 0, sizeof(id));
2022 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2023 strcpy(id.name, "Front Playback Switch");
2024 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2029 /* mute mono out if HP or Line out is plugged */
2030 static void via_mono_automute(struct hda_codec *codec)
2032 unsigned int hp_present, lineout_present;
2033 struct via_spec *spec = codec->spec;
2035 if (spec->codec_type != VT1716S)
2038 lineout_present = snd_hda_jack_detect(codec,
2039 spec->autocfg.line_out_pins[0]);
2041 /* Mute Mono Out if Line Out is plugged */
2042 if (lineout_present) {
2043 snd_hda_codec_amp_stereo(
2044 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
2048 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2050 if (!spec->hp_independent_mode)
2051 snd_hda_codec_amp_stereo(
2052 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
2053 hp_present ? HDA_AMP_MUTE : 0);
2056 static void via_gpio_control(struct hda_codec *codec)
2058 unsigned int gpio_data;
2059 unsigned int vol_counter;
2061 unsigned int master_vol;
2063 struct via_spec *spec = codec->spec;
2065 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
2066 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
2068 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
2069 0xF84, 0) & 0x3F0000) >> 16;
2071 vol = vol_counter & 0x1F;
2072 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
2073 AC_VERB_GET_AMP_GAIN_MUTE,
2076 if (gpio_data == 0x02) {
2077 /* unmute line out */
2078 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
2079 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
2081 if (vol_counter & 0x20) {
2082 /* decrease volume */
2083 if (vol > master_vol)
2085 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
2089 /* increase volume */
2090 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
2092 ((master_vol+vol) > 0x2A) ? 0x2A :
2095 } else if (!(gpio_data & 0x02)) {
2097 snd_hda_codec_amp_stereo(codec,
2098 spec->autocfg.line_out_pins[0],
2099 HDA_OUTPUT, 0, HDA_AMP_MUTE,
2104 /* mute Internal-Speaker if HP is plugged */
2105 static void via_speaker_automute(struct hda_codec *codec)
2107 unsigned int hp_present;
2108 struct via_spec *spec = codec->spec;
2110 if (spec->codec_type != VT2002P && spec->codec_type != VT1812)
2113 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2115 if (!spec->hp_independent_mode) {
2116 struct snd_ctl_elem_id id;
2117 snd_hda_codec_amp_stereo(
2118 codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
2119 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2121 memset(&id, 0, sizeof(id));
2122 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
2123 strcpy(id.name, "Speaker Playback Switch");
2124 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
2129 /* mute line-out and internal speaker if HP is plugged */
2130 static void via_hp_bind_automute(struct hda_codec *codec)
2132 /* use long instead of int below just to avoid an internal compiler
2133 * error with gcc 4.0.x
2135 unsigned long hp_present, present = 0;
2136 struct via_spec *spec = codec->spec;
2139 if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
2142 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
2144 present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
2146 if (!spec->hp_independent_mode) {
2147 /* Mute Line-Outs */
2148 for (i = 0; i < spec->autocfg.line_outs; i++)
2149 snd_hda_codec_amp_stereo(
2150 codec, spec->autocfg.line_out_pins[i],
2152 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
2154 present = hp_present;
2157 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2158 snd_hda_codec_amp_stereo(
2159 codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
2160 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2164 /* unsolicited event for jack sensing */
2165 static void via_unsol_event(struct hda_codec *codec,
2169 if (res & VIA_HP_EVENT)
2170 via_hp_automute(codec);
2171 if (res & VIA_GPIO_EVENT)
2172 via_gpio_control(codec);
2173 if (res & VIA_JACK_EVENT)
2174 set_jack_power_state(codec);
2175 if (res & VIA_MONO_EVENT)
2176 via_mono_automute(codec);
2177 if (res & VIA_SPEAKER_EVENT)
2178 via_speaker_automute(codec);
2179 if (res & VIA_BIND_HP_EVENT)
2180 via_hp_bind_automute(codec);
2183 static int via_init(struct hda_codec *codec)
2185 struct via_spec *spec = codec->spec;
2187 for (i = 0; i < spec->num_iverbs; i++)
2188 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2190 spec->codec_type = get_codec_type(codec);
2191 if (spec->codec_type == VT1708BCE)
2192 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
2194 /* Lydia Add for EAPD enable */
2195 if (!spec->dig_in_nid) { /* No Digital In connection */
2196 if (spec->dig_in_pin) {
2197 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2198 AC_VERB_SET_PIN_WIDGET_CONTROL,
2200 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
2201 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
2203 } else /* enable SPDIF-input pin */
2204 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2205 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2207 /* assign slave outs */
2208 if (spec->slave_dig_outs[0])
2209 codec->slave_dig_outs = spec->slave_dig_outs;
2214 #ifdef SND_HDA_NEEDS_RESUME
2215 static int via_suspend(struct hda_codec *codec, pm_message_t state)
2217 struct via_spec *spec = codec->spec;
2218 vt1708_stop_hp_work(spec);
2223 #ifdef CONFIG_SND_HDA_POWER_SAVE
2224 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2226 struct via_spec *spec = codec->spec;
2227 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2233 static struct hda_codec_ops via_patch_ops = {
2234 .build_controls = via_build_controls,
2235 .build_pcms = via_build_pcms,
2238 #ifdef SND_HDA_NEEDS_RESUME
2239 .suspend = via_suspend,
2241 #ifdef CONFIG_SND_HDA_POWER_SAVE
2242 .check_power_status = via_check_power_status,
2246 /* fill in the dac_nids table from the parsed pin configuration */
2247 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
2248 const struct auto_pin_cfg *cfg)
2253 spec->multiout.num_dacs = cfg->line_outs;
2255 spec->multiout.dac_nids = spec->private_dac_nids;
2257 for (i = 0; i < 4; i++) {
2258 nid = cfg->line_out_pins[i];
2260 /* config dac list */
2262 case AUTO_SEQ_FRONT:
2263 spec->multiout.dac_nids[i] = 0x10;
2265 case AUTO_SEQ_CENLFE:
2266 spec->multiout.dac_nids[i] = 0x12;
2268 case AUTO_SEQ_SURROUND:
2269 spec->multiout.dac_nids[i] = 0x11;
2272 spec->multiout.dac_nids[i] = 0x13;
2281 /* add playback controls from the parsed DAC table */
2282 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2283 const struct auto_pin_cfg *cfg)
2286 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2287 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2290 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2291 nid = cfg->line_out_pins[i];
2296 nid_vol = nid_vols[i];
2298 if (i == AUTO_SEQ_CENLFE) {
2300 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2301 "Center Playback Volume",
2302 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2306 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2307 "LFE Playback Volume",
2308 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2312 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2313 "Center Playback Switch",
2314 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2318 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2319 "LFE Playback Switch",
2320 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2324 } else if (i == AUTO_SEQ_FRONT) {
2325 /* add control to mixer index 0 */
2326 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2327 "Master Front Playback Volume",
2328 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2332 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2333 "Master Front Playback Switch",
2334 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2339 /* add control to PW3 */
2340 sprintf(name, "%s Playback Volume", chname[i]);
2341 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2342 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2346 sprintf(name, "%s Playback Switch", chname[i]);
2347 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2348 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2353 sprintf(name, "%s Playback Volume", chname[i]);
2354 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2355 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2359 sprintf(name, "%s Playback Switch", chname[i]);
2360 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2361 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2371 static void create_hp_imux(struct via_spec *spec)
2374 struct hda_input_mux *imux = &spec->private_imux[1];
2375 static const char *texts[] = { "OFF", "ON", NULL};
2377 /* for hp mode select */
2379 while (texts[i] != NULL) {
2380 imux->items[imux->num_items].label = texts[i];
2381 imux->items[imux->num_items].index = i;
2386 spec->hp_mux = &spec->private_imux[1];
2389 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2396 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
2397 spec->hp_independent_mode_index = 1;
2399 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2400 "Headphone Playback Volume",
2401 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2404 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2405 "Headphone Playback Switch",
2406 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2410 create_hp_imux(spec);
2415 /* create playback/capture controls for input pins */
2416 static int vt_auto_create_analog_input_ctls(struct via_spec *spec,
2417 const struct auto_pin_cfg *cfg,
2419 hda_nid_t pin_idxs[], int num_idxs)
2421 struct hda_input_mux *imux = &spec->private_imux[0];
2424 /* for internal loopback recording select */
2425 for (idx = 0; idx < num_idxs; idx++) {
2426 if (pin_idxs[idx] == 0xff) {
2427 imux->items[imux->num_items].label = "Stereo Mixer";
2428 imux->items[imux->num_items].index = idx;
2434 for (i = 0; i < AUTO_PIN_LAST; i++) {
2435 if (!cfg->input_pins[i])
2438 for (idx = 0; idx < num_idxs; idx++)
2439 if (pin_idxs[idx] == cfg->input_pins[i])
2441 if (idx >= num_idxs)
2443 err = via_new_analog_input(spec, auto_pin_cfg_labels[i],
2447 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
2448 imux->items[imux->num_items].index = idx;
2454 /* create playback/capture controls for input pins */
2455 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
2456 const struct auto_pin_cfg *cfg)
2458 static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 };
2459 return vt_auto_create_analog_input_ctls(spec, cfg, 0x17, pin_idxs,
2460 ARRAY_SIZE(pin_idxs));
2463 #ifdef CONFIG_SND_HDA_POWER_SAVE
2464 static struct hda_amp_list vt1708_loopbacks[] = {
2465 { 0x17, HDA_INPUT, 1 },
2466 { 0x17, HDA_INPUT, 2 },
2467 { 0x17, HDA_INPUT, 3 },
2468 { 0x17, HDA_INPUT, 4 },
2473 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2475 unsigned int def_conf;
2476 unsigned char seqassoc;
2478 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2479 seqassoc = (unsigned char) get_defcfg_association(def_conf);
2480 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2481 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2482 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2483 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2484 snd_hda_codec_set_pincfg(codec, nid, def_conf);
2490 static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2491 struct snd_ctl_elem_value *ucontrol)
2493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2494 struct via_spec *spec = codec->spec;
2496 if (spec->codec_type != VT1708)
2498 spec->vt1708_jack_detectect =
2499 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2500 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2504 static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2505 struct snd_ctl_elem_value *ucontrol)
2507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2508 struct via_spec *spec = codec->spec;
2511 if (spec->codec_type != VT1708)
2513 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
2514 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2515 == !spec->vt1708_jack_detectect;
2516 if (spec->vt1708_jack_detectect) {
2517 mute_aa_path(codec, 1);
2518 notify_aa_path_ctls(codec);
2523 static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2525 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2526 .name = "Jack Detect",
2528 .info = snd_ctl_boolean_mono_info,
2529 .get = vt1708_jack_detectect_get,
2530 .put = vt1708_jack_detectect_put,
2535 static int vt1708_parse_auto_config(struct hda_codec *codec)
2537 struct via_spec *spec = codec->spec;
2540 /* Add HP and CD pin config connect bit re-config action */
2541 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2542 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2544 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2547 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2550 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2551 return 0; /* can't find valid BIOS pin config */
2553 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2556 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2559 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
2562 /* add jack detect on/off control */
2563 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2567 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2569 if (spec->autocfg.dig_outs)
2570 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2571 spec->dig_in_pin = VT1708_DIGIN_PIN;
2572 if (spec->autocfg.dig_in_pin)
2573 spec->dig_in_nid = VT1708_DIGIN_NID;
2575 if (spec->kctls.list)
2576 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2578 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2580 spec->input_mux = &spec->private_imux[0];
2583 via_hp_build(codec);
2585 via_smart51_build(spec);
2589 /* init callback for auto-configuration model -- overriding the default init */
2590 static int via_auto_init(struct hda_codec *codec)
2592 struct via_spec *spec = codec->spec;
2595 via_auto_init_multi_out(codec);
2596 via_auto_init_hp_out(codec);
2597 via_auto_init_analog_input(codec);
2598 if (spec->codec_type == VT2002P || spec->codec_type == VT1812) {
2599 via_hp_bind_automute(codec);
2601 via_hp_automute(codec);
2602 via_speaker_automute(codec);
2608 static void vt1708_update_hp_jack_state(struct work_struct *work)
2610 struct via_spec *spec = container_of(work, struct via_spec,
2611 vt1708_hp_work.work);
2612 if (spec->codec_type != VT1708)
2614 /* if jack state toggled */
2615 if (spec->vt1708_hp_present
2616 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2617 spec->vt1708_hp_present ^= 1;
2618 via_hp_automute(spec->codec);
2620 vt1708_start_hp_work(spec);
2623 static int get_mux_nids(struct hda_codec *codec)
2625 struct via_spec *spec = codec->spec;
2626 hda_nid_t nid, conn[8];
2630 for (i = 0; i < spec->num_adc_nids; i++) {
2631 nid = spec->adc_nids[i];
2633 type = get_wcaps_type(get_wcaps(codec, nid));
2634 if (type == AC_WID_PIN)
2636 n = snd_hda_get_connections(codec, nid, conn,
2641 spec->mux_nids[i] = nid;
2650 static int patch_vt1708(struct hda_codec *codec)
2652 struct via_spec *spec;
2655 /* create a codec specific record */
2656 spec = via_new_spec(codec);
2660 /* automatic parse from the BIOS config */
2661 err = vt1708_parse_auto_config(codec);
2666 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2667 "from BIOS. Using genenic mode...\n");
2671 spec->stream_name_analog = "VT1708 Analog";
2672 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2673 /* disable 32bit format on VT1708 */
2674 if (codec->vendor_id == 0x11061708)
2675 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2676 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2678 spec->stream_name_digital = "VT1708 Digital";
2679 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2680 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2683 if (!spec->adc_nids && spec->input_mux) {
2684 spec->adc_nids = vt1708_adc_nids;
2685 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2686 get_mux_nids(codec);
2687 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2691 codec->patch_ops = via_patch_ops;
2693 codec->patch_ops.init = via_auto_init;
2694 #ifdef CONFIG_SND_HDA_POWER_SAVE
2695 spec->loopback.amplist = vt1708_loopbacks;
2697 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2701 /* capture mixer elements */
2702 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2703 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2704 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2705 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2706 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2707 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2708 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2710 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2711 /* The multiple "Capture Source" controls confuse alsamixer
2712 * So call somewhat different..
2714 /* .name = "Capture Source", */
2715 .name = "Input Source",
2717 .info = via_mux_enum_info,
2718 .get = via_mux_enum_get,
2719 .put = via_mux_enum_put,
2724 static struct hda_verb vt1709_uniwill_init_verbs[] = {
2725 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2726 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2731 * generic initialization of ADC, input mixers and output mixers
2733 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2735 * Unmute ADC0-2 and set the default input to mic-in
2737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2742 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2745 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2749 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2753 * Set up output selector (0x1a, 0x1b, 0x29)
2755 /* set vol=0 to output mixers */
2756 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2758 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2761 * Unmute PW3 and PW4
2763 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2764 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2766 /* Set input of PW4 as MW0 */
2767 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2768 /* PW9 Output enable */
2769 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2773 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2777 .nid = 0x10, /* NID to query formats and rates */
2779 .open = via_playback_pcm_open,
2780 .prepare = via_playback_multi_pcm_prepare,
2781 .cleanup = via_playback_multi_pcm_cleanup,
2785 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2789 .nid = 0x10, /* NID to query formats and rates */
2791 .open = via_playback_pcm_open,
2792 .prepare = via_playback_multi_pcm_prepare,
2793 .cleanup = via_playback_multi_pcm_cleanup,
2797 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2801 .nid = 0x14, /* NID to query formats and rates */
2803 .prepare = via_capture_pcm_prepare,
2804 .cleanup = via_capture_pcm_cleanup
2808 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2812 /* NID is set in via_build_pcms */
2814 .open = via_dig_playback_pcm_open,
2815 .close = via_dig_playback_pcm_close
2819 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2825 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2826 const struct auto_pin_cfg *cfg)
2831 if (cfg->line_outs == 4) /* 10 channels */
2832 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2833 else if (cfg->line_outs == 3) /* 6 channels */
2834 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2836 spec->multiout.dac_nids = spec->private_dac_nids;
2838 if (cfg->line_outs == 4) { /* 10 channels */
2839 for (i = 0; i < cfg->line_outs; i++) {
2840 nid = cfg->line_out_pins[i];
2842 /* config dac list */
2844 case AUTO_SEQ_FRONT:
2846 spec->multiout.dac_nids[i] = 0x10;
2848 case AUTO_SEQ_CENLFE:
2850 spec->multiout.dac_nids[i] = 0x12;
2852 case AUTO_SEQ_SURROUND:
2854 spec->multiout.dac_nids[i] = 0x11;
2858 spec->multiout.dac_nids[i] = 0x27;
2865 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2867 } else if (cfg->line_outs == 3) { /* 6 channels */
2868 for (i = 0; i < cfg->line_outs; i++) {
2869 nid = cfg->line_out_pins[i];
2871 /* config dac list */
2873 case AUTO_SEQ_FRONT:
2875 spec->multiout.dac_nids[i] = 0x10;
2877 case AUTO_SEQ_CENLFE:
2879 spec->multiout.dac_nids[i] = 0x12;
2881 case AUTO_SEQ_SURROUND:
2883 spec->multiout.dac_nids[i] = 0x11;
2895 /* add playback controls from the parsed DAC table */
2896 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2897 const struct auto_pin_cfg *cfg)
2900 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2901 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2904 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2905 nid = cfg->line_out_pins[i];
2910 nid_vol = nid_vols[i];
2912 if (i == AUTO_SEQ_CENLFE) {
2914 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2915 "Center Playback Volume",
2916 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2920 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2921 "LFE Playback Volume",
2922 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2926 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2927 "Center Playback Switch",
2928 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2932 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2933 "LFE Playback Switch",
2934 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2938 } else if (i == AUTO_SEQ_FRONT) {
2939 /* ADD control to mixer index 0 */
2940 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2941 "Master Front Playback Volume",
2942 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2946 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2947 "Master Front Playback Switch",
2948 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2953 /* add control to PW3 */
2954 sprintf(name, "%s Playback Volume", chname[i]);
2955 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2956 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2960 sprintf(name, "%s Playback Switch", chname[i]);
2961 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2962 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2966 } else if (i == AUTO_SEQ_SURROUND) {
2967 sprintf(name, "%s Playback Volume", chname[i]);
2968 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2969 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2973 sprintf(name, "%s Playback Switch", chname[i]);
2974 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2975 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2979 } else if (i == AUTO_SEQ_SIDE) {
2980 sprintf(name, "%s Playback Volume", chname[i]);
2981 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2982 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2986 sprintf(name, "%s Playback Switch", chname[i]);
2987 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2988 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2998 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3005 if (spec->multiout.num_dacs == 5) /* 10 channels */
3006 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
3007 else if (spec->multiout.num_dacs == 3) /* 6 channels */
3008 spec->multiout.hp_nid = 0;
3009 spec->hp_independent_mode_index = 1;
3011 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3012 "Headphone Playback Volume",
3013 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3016 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3017 "Headphone Playback Switch",
3018 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3025 /* create playback/capture controls for input pins */
3026 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
3027 const struct auto_pin_cfg *cfg)
3029 static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
3030 return vt_auto_create_analog_input_ctls(spec, cfg, 0x18, pin_idxs,
3031 ARRAY_SIZE(pin_idxs));
3034 static int vt1709_parse_auto_config(struct hda_codec *codec)
3036 struct via_spec *spec = codec->spec;
3039 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3042 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
3045 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3046 return 0; /* can't find valid BIOS pin config */
3048 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
3051 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3054 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
3058 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3060 if (spec->autocfg.dig_outs)
3061 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
3062 spec->dig_in_pin = VT1709_DIGIN_PIN;
3063 if (spec->autocfg.dig_in_pin)
3064 spec->dig_in_nid = VT1709_DIGIN_NID;
3066 if (spec->kctls.list)
3067 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3069 spec->input_mux = &spec->private_imux[0];
3072 via_hp_build(codec);
3074 via_smart51_build(spec);
3078 #ifdef CONFIG_SND_HDA_POWER_SAVE
3079 static struct hda_amp_list vt1709_loopbacks[] = {
3080 { 0x18, HDA_INPUT, 1 },
3081 { 0x18, HDA_INPUT, 2 },
3082 { 0x18, HDA_INPUT, 3 },
3083 { 0x18, HDA_INPUT, 4 },
3088 static int patch_vt1709_10ch(struct hda_codec *codec)
3090 struct via_spec *spec;
3093 /* create a codec specific record */
3094 spec = via_new_spec(codec);
3098 err = vt1709_parse_auto_config(codec);
3103 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
3104 "Using genenic mode...\n");
3107 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
3108 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3110 spec->stream_name_analog = "VT1709 Analog";
3111 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
3112 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3114 spec->stream_name_digital = "VT1709 Digital";
3115 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3116 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3119 if (!spec->adc_nids && spec->input_mux) {
3120 spec->adc_nids = vt1709_adc_nids;
3121 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3122 get_mux_nids(codec);
3123 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3127 codec->patch_ops = via_patch_ops;
3129 codec->patch_ops.init = via_auto_init;
3130 codec->patch_ops.unsol_event = via_unsol_event;
3131 #ifdef CONFIG_SND_HDA_POWER_SAVE
3132 spec->loopback.amplist = vt1709_loopbacks;
3138 * generic initialization of ADC, input mixers and output mixers
3140 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
3142 * Unmute ADC0-2 and set the default input to mic-in
3144 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3146 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3149 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3152 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3153 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3154 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3155 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3156 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3157 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3160 * Set up output selector (0x1a, 0x1b, 0x29)
3162 /* set vol=0 to output mixers */
3163 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3164 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3165 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3168 * Unmute PW3 and PW4
3170 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3171 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3173 /* Set input of PW4 as MW0 */
3174 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
3175 /* PW9 Output enable */
3176 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3180 static int patch_vt1709_6ch(struct hda_codec *codec)
3182 struct via_spec *spec;
3185 /* create a codec specific record */
3186 spec = via_new_spec(codec);
3190 err = vt1709_parse_auto_config(codec);
3195 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
3196 "Using genenic mode...\n");
3199 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
3200 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
3202 spec->stream_name_analog = "VT1709 Analog";
3203 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
3204 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
3206 spec->stream_name_digital = "VT1709 Digital";
3207 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
3208 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
3211 if (!spec->adc_nids && spec->input_mux) {
3212 spec->adc_nids = vt1709_adc_nids;
3213 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
3214 get_mux_nids(codec);
3215 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
3219 codec->patch_ops = via_patch_ops;
3221 codec->patch_ops.init = via_auto_init;
3222 codec->patch_ops.unsol_event = via_unsol_event;
3223 #ifdef CONFIG_SND_HDA_POWER_SAVE
3224 spec->loopback.amplist = vt1709_loopbacks;
3229 /* capture mixer elements */
3230 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
3231 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3232 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3233 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3234 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3237 /* The multiple "Capture Source" controls confuse alsamixer
3238 * So call somewhat different..
3240 /* .name = "Capture Source", */
3241 .name = "Input Source",
3243 .info = via_mux_enum_info,
3244 .get = via_mux_enum_get,
3245 .put = via_mux_enum_put,
3250 * generic initialization of ADC, input mixers and output mixers
3252 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
3254 * Unmute ADC0-1 and set the default input to mic-in
3256 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3260 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3263 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3266 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3267 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3268 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3271 * Set up output mixers
3273 /* set vol=0 to output mixers */
3274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3275 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3276 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3278 /* Setup default input to PW4 */
3279 {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
3280 /* PW9 Output enable */
3281 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3282 /* PW10 Input enable */
3283 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3287 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
3289 * Unmute ADC0-1 and set the default input to mic-in
3291 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3292 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3295 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3298 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3299 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3300 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3301 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3303 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3306 * Set up output mixers
3308 /* set vol=0 to output mixers */
3309 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3310 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3311 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3313 /* Setup default input of PW4 to MW0 */
3314 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3315 /* PW9 Output enable */
3316 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3317 /* PW10 Input enable */
3318 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3322 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
3323 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3324 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3325 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3326 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3327 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3328 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3329 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3330 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3331 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3335 static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
3336 struct hda_codec *codec,
3337 struct snd_pcm_substream *substream)
3339 int idle = substream->pstr->substream_opened == 1
3340 && substream->ref_count == 0;
3342 analog_low_current_mode(codec, idle);
3346 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
3350 .nid = 0x10, /* NID to query formats and rates */
3352 .open = via_playback_pcm_open,
3353 .prepare = via_playback_multi_pcm_prepare,
3354 .cleanup = via_playback_multi_pcm_cleanup,
3355 .close = via_pcm_open_close
3359 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
3363 .nid = 0x10, /* NID to query formats and rates */
3365 .open = via_playback_pcm_open,
3366 .prepare = via_playback_multi_pcm_prepare,
3367 .cleanup = via_playback_multi_pcm_cleanup
3371 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
3375 .nid = 0x13, /* NID to query formats and rates */
3377 .open = via_pcm_open_close,
3378 .prepare = via_capture_pcm_prepare,
3379 .cleanup = via_capture_pcm_cleanup,
3380 .close = via_pcm_open_close
3384 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
3388 /* NID is set in via_build_pcms */
3390 .open = via_dig_playback_pcm_open,
3391 .close = via_dig_playback_pcm_close,
3392 .prepare = via_dig_playback_pcm_prepare,
3393 .cleanup = via_dig_playback_pcm_cleanup
3397 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3403 /* fill in the dac_nids table from the parsed pin configuration */
3404 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3405 const struct auto_pin_cfg *cfg)
3410 spec->multiout.num_dacs = cfg->line_outs;
3412 spec->multiout.dac_nids = spec->private_dac_nids;
3414 for (i = 0; i < 4; i++) {
3415 nid = cfg->line_out_pins[i];
3417 /* config dac list */
3419 case AUTO_SEQ_FRONT:
3420 spec->multiout.dac_nids[i] = 0x10;
3422 case AUTO_SEQ_CENLFE:
3423 spec->multiout.dac_nids[i] = 0x24;
3425 case AUTO_SEQ_SURROUND:
3426 spec->multiout.dac_nids[i] = 0x11;
3429 spec->multiout.dac_nids[i] = 0x25;
3438 /* add playback controls from the parsed DAC table */
3439 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3440 const struct auto_pin_cfg *cfg)
3443 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
3444 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3445 hda_nid_t nid, nid_vol = 0;
3448 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3449 nid = cfg->line_out_pins[i];
3454 nid_vol = nid_vols[i];
3456 if (i == AUTO_SEQ_CENLFE) {
3458 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3459 "Center Playback Volume",
3460 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3464 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3465 "LFE Playback Volume",
3466 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3470 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3471 "Center Playback Switch",
3472 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3476 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3477 "LFE Playback Switch",
3478 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3482 } else if (i == AUTO_SEQ_FRONT) {
3483 /* add control to mixer index 0 */
3484 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3485 "Master Front Playback Volume",
3486 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3490 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3491 "Master Front Playback Switch",
3492 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3497 /* add control to PW3 */
3498 sprintf(name, "%s Playback Volume", chname[i]);
3499 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3500 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3504 sprintf(name, "%s Playback Switch", chname[i]);
3505 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3506 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3511 sprintf(name, "%s Playback Volume", chname[i]);
3512 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3513 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3517 sprintf(name, "%s Playback Switch", chname[i]);
3518 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3519 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3529 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3536 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3537 spec->hp_independent_mode_index = 1;
3539 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3540 "Headphone Playback Volume",
3541 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3544 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3545 "Headphone Playback Switch",
3546 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3550 create_hp_imux(spec);
3555 /* create playback/capture controls for input pins */
3556 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
3557 const struct auto_pin_cfg *cfg)
3559 static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3560 return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
3561 ARRAY_SIZE(pin_idxs));
3564 static int vt1708B_parse_auto_config(struct hda_codec *codec)
3566 struct via_spec *spec = codec->spec;
3569 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3572 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3575 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3576 return 0; /* can't find valid BIOS pin config */
3578 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3581 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3584 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
3588 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3590 if (spec->autocfg.dig_outs)
3591 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3592 spec->dig_in_pin = VT1708B_DIGIN_PIN;
3593 if (spec->autocfg.dig_in_pin)
3594 spec->dig_in_nid = VT1708B_DIGIN_NID;
3596 if (spec->kctls.list)
3597 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3599 spec->input_mux = &spec->private_imux[0];
3602 via_hp_build(codec);
3604 via_smart51_build(spec);
3608 #ifdef CONFIG_SND_HDA_POWER_SAVE
3609 static struct hda_amp_list vt1708B_loopbacks[] = {
3610 { 0x16, HDA_INPUT, 1 },
3611 { 0x16, HDA_INPUT, 2 },
3612 { 0x16, HDA_INPUT, 3 },
3613 { 0x16, HDA_INPUT, 4 },
3617 static int patch_vt1708S(struct hda_codec *codec);
3618 static int patch_vt1708B_8ch(struct hda_codec *codec)
3620 struct via_spec *spec;
3623 if (get_codec_type(codec) == VT1708BCE)
3624 return patch_vt1708S(codec);
3625 /* create a codec specific record */
3626 spec = via_new_spec(codec);
3630 /* automatic parse from the BIOS config */
3631 err = vt1708B_parse_auto_config(codec);
3636 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3637 "from BIOS. Using genenic mode...\n");
3640 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3641 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3643 spec->stream_name_analog = "VT1708B Analog";
3644 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3645 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3647 spec->stream_name_digital = "VT1708B Digital";
3648 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3649 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3651 if (!spec->adc_nids && spec->input_mux) {
3652 spec->adc_nids = vt1708B_adc_nids;
3653 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3654 get_mux_nids(codec);
3655 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3659 codec->patch_ops = via_patch_ops;
3661 codec->patch_ops.init = via_auto_init;
3662 codec->patch_ops.unsol_event = via_unsol_event;
3663 #ifdef CONFIG_SND_HDA_POWER_SAVE
3664 spec->loopback.amplist = vt1708B_loopbacks;
3670 static int patch_vt1708B_4ch(struct hda_codec *codec)
3672 struct via_spec *spec;
3675 /* create a codec specific record */
3676 spec = via_new_spec(codec);
3680 /* automatic parse from the BIOS config */
3681 err = vt1708B_parse_auto_config(codec);
3686 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3687 "from BIOS. Using genenic mode...\n");
3690 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3691 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3693 spec->stream_name_analog = "VT1708B Analog";
3694 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3695 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3697 spec->stream_name_digital = "VT1708B Digital";
3698 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3699 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3701 if (!spec->adc_nids && spec->input_mux) {
3702 spec->adc_nids = vt1708B_adc_nids;
3703 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3704 get_mux_nids(codec);
3705 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3709 codec->patch_ops = via_patch_ops;
3711 codec->patch_ops.init = via_auto_init;
3712 codec->patch_ops.unsol_event = via_unsol_event;
3713 #ifdef CONFIG_SND_HDA_POWER_SAVE
3714 spec->loopback.amplist = vt1708B_loopbacks;
3720 /* Patch for VT1708S */
3722 /* capture mixer elements */
3723 static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3724 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3725 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3726 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3727 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3728 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3729 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3732 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3733 /* The multiple "Capture Source" controls confuse alsamixer
3734 * So call somewhat different..
3736 /* .name = "Capture Source", */
3737 .name = "Input Source",
3739 .info = via_mux_enum_info,
3740 .get = via_mux_enum_get,
3741 .put = via_mux_enum_put,
3746 static struct hda_verb vt1708S_volume_init_verbs[] = {
3747 /* Unmute ADC0-1 and set the default input to mic-in */
3748 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3751 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3752 * analog-loopback mixer widget */
3753 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3754 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3755 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3756 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3758 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3760 /* Setup default input of PW4 to MW0 */
3761 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3762 /* PW9, PW10 Output enable */
3763 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3764 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3765 /* Enable Mic Boost Volume backdoor */
3767 /* don't bybass mixer */
3772 static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3773 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3774 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3775 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3776 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3777 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3778 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3779 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3780 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3781 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3785 static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3789 .nid = 0x10, /* NID to query formats and rates */
3791 .open = via_playback_pcm_open,
3792 .prepare = via_playback_multi_pcm_prepare,
3793 .cleanup = via_playback_multi_pcm_cleanup,
3794 .close = via_pcm_open_close
3798 static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3802 .nid = 0x13, /* NID to query formats and rates */
3804 .open = via_pcm_open_close,
3805 .prepare = via_capture_pcm_prepare,
3806 .cleanup = via_capture_pcm_cleanup,
3807 .close = via_pcm_open_close
3811 static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3815 /* NID is set in via_build_pcms */
3817 .open = via_dig_playback_pcm_open,
3818 .close = via_dig_playback_pcm_close,
3819 .prepare = via_dig_playback_pcm_prepare,
3820 .cleanup = via_dig_playback_pcm_cleanup
3824 /* fill in the dac_nids table from the parsed pin configuration */
3825 static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3826 const struct auto_pin_cfg *cfg)
3831 spec->multiout.num_dacs = cfg->line_outs;
3833 spec->multiout.dac_nids = spec->private_dac_nids;
3835 for (i = 0; i < 4; i++) {
3836 nid = cfg->line_out_pins[i];
3838 /* config dac list */
3840 case AUTO_SEQ_FRONT:
3841 spec->multiout.dac_nids[i] = 0x10;
3843 case AUTO_SEQ_CENLFE:
3844 spec->multiout.dac_nids[i] = 0x24;
3846 case AUTO_SEQ_SURROUND:
3847 spec->multiout.dac_nids[i] = 0x11;
3850 spec->multiout.dac_nids[i] = 0x25;
3856 /* for Smart 5.1, line/mic inputs double as output pins */
3857 if (cfg->line_outs == 1) {
3858 spec->multiout.num_dacs = 3;
3859 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3860 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3866 /* add playback controls from the parsed DAC table */
3867 static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3868 const struct auto_pin_cfg *cfg)
3871 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
3872 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3873 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3874 hda_nid_t nid, nid_vol, nid_mute;
3877 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3878 nid = cfg->line_out_pins[i];
3880 /* for Smart 5.1, there are always at least six channels */
3881 if (!nid && i > AUTO_SEQ_CENLFE)
3884 nid_vol = nid_vols[i];
3885 nid_mute = nid_mutes[i];
3887 if (i == AUTO_SEQ_CENLFE) {
3889 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3890 "Center Playback Volume",
3891 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3895 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3896 "LFE Playback Volume",
3897 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3901 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3902 "Center Playback Switch",
3903 HDA_COMPOSE_AMP_VAL(nid_mute,
3908 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3909 "LFE Playback Switch",
3910 HDA_COMPOSE_AMP_VAL(nid_mute,
3915 } else if (i == AUTO_SEQ_FRONT) {
3916 /* add control to mixer index 0 */
3917 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3918 "Master Front Playback Volume",
3919 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3923 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3924 "Master Front Playback Switch",
3925 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3931 sprintf(name, "%s Playback Volume", chname[i]);
3932 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3933 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3937 sprintf(name, "%s Playback Switch", chname[i]);
3938 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3939 HDA_COMPOSE_AMP_VAL(nid_mute,
3945 sprintf(name, "%s Playback Volume", chname[i]);
3946 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3947 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3951 sprintf(name, "%s Playback Switch", chname[i]);
3952 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3953 HDA_COMPOSE_AMP_VAL(nid_mute,
3964 static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3971 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3972 spec->hp_independent_mode_index = 1;
3974 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3975 "Headphone Playback Volume",
3976 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
3980 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3981 "Headphone Playback Switch",
3982 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3986 create_hp_imux(spec);
3991 /* create playback/capture controls for input pins */
3992 static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
3993 const struct auto_pin_cfg *cfg)
3995 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
3996 return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
3997 ARRAY_SIZE(pin_idxs));
4000 /* fill out digital output widgets; one for master and one for slave outputs */
4001 static void fill_dig_outs(struct hda_codec *codec)
4003 struct via_spec *spec = codec->spec;
4006 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4010 nid = spec->autocfg.dig_out_pins[i];
4013 conn = snd_hda_get_connections(codec, nid, &nid, 1);
4016 if (!spec->multiout.dig_out_nid)
4017 spec->multiout.dig_out_nid = nid;
4019 spec->slave_dig_outs[0] = nid;
4020 break; /* at most two dig outs */
4025 static int vt1708S_parse_auto_config(struct hda_codec *codec)
4027 struct via_spec *spec = codec->spec;
4030 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4033 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
4036 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4037 return 0; /* can't find valid BIOS pin config */
4039 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4042 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4045 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4049 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4051 fill_dig_outs(codec);
4053 if (spec->kctls.list)
4054 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4056 spec->input_mux = &spec->private_imux[0];
4059 via_hp_build(codec);
4061 via_smart51_build(spec);
4065 #ifdef CONFIG_SND_HDA_POWER_SAVE
4066 static struct hda_amp_list vt1708S_loopbacks[] = {
4067 { 0x16, HDA_INPUT, 1 },
4068 { 0x16, HDA_INPUT, 2 },
4069 { 0x16, HDA_INPUT, 3 },
4070 { 0x16, HDA_INPUT, 4 },
4075 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
4076 int offset, int num_steps, int step_size)
4078 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
4079 (offset << AC_AMPCAP_OFFSET_SHIFT) |
4080 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
4081 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
4082 (0 << AC_AMPCAP_MUTE_SHIFT));
4085 static int patch_vt1708S(struct hda_codec *codec)
4087 struct via_spec *spec;
4090 /* create a codec specific record */
4091 spec = via_new_spec(codec);
4095 /* automatic parse from the BIOS config */
4096 err = vt1708S_parse_auto_config(codec);
4101 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4102 "from BIOS. Using genenic mode...\n");
4105 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
4106 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
4108 if (codec->vendor_id == 0x11060440)
4109 spec->stream_name_analog = "VT1818S Analog";
4111 spec->stream_name_analog = "VT1708S Analog";
4112 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
4113 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
4115 if (codec->vendor_id == 0x11060440)
4116 spec->stream_name_digital = "VT1818S Digital";
4118 spec->stream_name_digital = "VT1708S Digital";
4119 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
4121 if (!spec->adc_nids && spec->input_mux) {
4122 spec->adc_nids = vt1708S_adc_nids;
4123 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
4124 get_mux_nids(codec);
4125 override_mic_boost(codec, 0x1a, 0, 3, 40);
4126 override_mic_boost(codec, 0x1e, 0, 3, 40);
4127 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
4131 codec->patch_ops = via_patch_ops;
4133 codec->patch_ops.init = via_auto_init;
4134 codec->patch_ops.unsol_event = via_unsol_event;
4135 #ifdef CONFIG_SND_HDA_POWER_SAVE
4136 spec->loopback.amplist = vt1708S_loopbacks;
4139 /* correct names for VT1708BCE */
4140 if (get_codec_type(codec) == VT1708BCE) {
4141 kfree(codec->chip_name);
4142 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
4143 snprintf(codec->bus->card->mixername,
4144 sizeof(codec->bus->card->mixername),
4145 "%s %s", codec->vendor_name, codec->chip_name);
4146 spec->stream_name_analog = "VT1708BCE Analog";
4147 spec->stream_name_digital = "VT1708BCE Digital";
4152 /* Patch for VT1702 */
4154 /* capture mixer elements */
4155 static struct snd_kcontrol_new vt1702_capture_mixer[] = {
4156 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
4157 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
4158 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
4159 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
4160 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
4161 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
4162 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
4165 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4166 /* The multiple "Capture Source" controls confuse alsamixer
4167 * So call somewhat different..
4169 /* .name = "Capture Source", */
4170 .name = "Input Source",
4172 .info = via_mux_enum_info,
4173 .get = via_mux_enum_get,
4174 .put = via_mux_enum_put,
4179 static struct hda_verb vt1702_volume_init_verbs[] = {
4181 * Unmute ADC0-1 and set the default input to mic-in
4183 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4184 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4185 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4188 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4191 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
4192 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4193 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4194 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
4195 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
4196 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4198 /* Setup default input of PW4 to MW0 */
4199 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
4200 /* PW6 PW7 Output enable */
4201 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4202 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4210 static struct hda_verb vt1702_uniwill_init_verbs[] = {
4211 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
4212 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4214 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4215 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4216 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4220 static struct hda_pcm_stream vt1702_pcm_analog_playback = {
4224 .nid = 0x10, /* NID to query formats and rates */
4226 .open = via_playback_pcm_open,
4227 .prepare = via_playback_multi_pcm_prepare,
4228 .cleanup = via_playback_multi_pcm_cleanup,
4229 .close = via_pcm_open_close
4233 static struct hda_pcm_stream vt1702_pcm_analog_capture = {
4237 .nid = 0x12, /* NID to query formats and rates */
4239 .open = via_pcm_open_close,
4240 .prepare = via_capture_pcm_prepare,
4241 .cleanup = via_capture_pcm_cleanup,
4242 .close = via_pcm_open_close
4246 static struct hda_pcm_stream vt1702_pcm_digital_playback = {
4250 /* NID is set in via_build_pcms */
4252 .open = via_dig_playback_pcm_open,
4253 .close = via_dig_playback_pcm_close,
4254 .prepare = via_dig_playback_pcm_prepare,
4255 .cleanup = via_dig_playback_pcm_cleanup
4259 /* fill in the dac_nids table from the parsed pin configuration */
4260 static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4261 const struct auto_pin_cfg *cfg)
4263 spec->multiout.num_dacs = 1;
4264 spec->multiout.dac_nids = spec->private_dac_nids;
4266 if (cfg->line_out_pins[0]) {
4267 /* config dac list */
4268 spec->multiout.dac_nids[0] = 0x10;
4274 /* add playback controls from the parsed DAC table */
4275 static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4276 const struct auto_pin_cfg *cfg)
4280 if (!cfg->line_out_pins[0])
4283 /* add control to mixer index 0 */
4284 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4285 "Master Front Playback Volume",
4286 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4289 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4290 "Master Front Playback Switch",
4291 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4296 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4297 "Front Playback Volume",
4298 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4301 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4302 "Front Playback Switch",
4303 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4310 static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4313 struct hda_input_mux *imux;
4314 static const char *texts[] = { "ON", "OFF", NULL};
4317 spec->multiout.hp_nid = 0x1D;
4318 spec->hp_independent_mode_index = 0;
4320 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4321 "Headphone Playback Volume",
4322 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4326 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4327 "Headphone Playback Switch",
4328 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4332 imux = &spec->private_imux[1];
4334 /* for hp mode select */
4336 while (texts[i] != NULL) {
4337 imux->items[imux->num_items].label = texts[i];
4338 imux->items[imux->num_items].index = i;
4343 spec->hp_mux = &spec->private_imux[1];
4347 /* create playback/capture controls for input pins */
4348 static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
4349 const struct auto_pin_cfg *cfg)
4351 static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4352 return vt_auto_create_analog_input_ctls(spec, cfg, 0x1a, pin_idxs,
4353 ARRAY_SIZE(pin_idxs));
4356 static int vt1702_parse_auto_config(struct hda_codec *codec)
4358 struct via_spec *spec = codec->spec;
4361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4364 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4367 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4368 return 0; /* can't find valid BIOS pin config */
4370 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4373 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4376 /* limit AA path volume to 0 dB */
4377 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4378 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4379 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4380 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4381 (1 << AC_AMPCAP_MUTE_SHIFT));
4382 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
4386 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4388 fill_dig_outs(codec);
4390 if (spec->kctls.list)
4391 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4393 spec->input_mux = &spec->private_imux[0];
4396 via_hp_build(codec);
4401 #ifdef CONFIG_SND_HDA_POWER_SAVE
4402 static struct hda_amp_list vt1702_loopbacks[] = {
4403 { 0x1A, HDA_INPUT, 1 },
4404 { 0x1A, HDA_INPUT, 2 },
4405 { 0x1A, HDA_INPUT, 3 },
4406 { 0x1A, HDA_INPUT, 4 },
4411 static int patch_vt1702(struct hda_codec *codec)
4413 struct via_spec *spec;
4416 /* create a codec specific record */
4417 spec = via_new_spec(codec);
4421 /* automatic parse from the BIOS config */
4422 err = vt1702_parse_auto_config(codec);
4427 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4428 "from BIOS. Using genenic mode...\n");
4431 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
4432 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4434 spec->stream_name_analog = "VT1702 Analog";
4435 spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4436 spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4438 spec->stream_name_digital = "VT1702 Digital";
4439 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4441 if (!spec->adc_nids && spec->input_mux) {
4442 spec->adc_nids = vt1702_adc_nids;
4443 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4444 get_mux_nids(codec);
4445 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4449 codec->patch_ops = via_patch_ops;
4451 codec->patch_ops.init = via_auto_init;
4452 codec->patch_ops.unsol_event = via_unsol_event;
4453 #ifdef CONFIG_SND_HDA_POWER_SAVE
4454 spec->loopback.amplist = vt1702_loopbacks;
4460 /* Patch for VT1718S */
4462 /* capture mixer elements */
4463 static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4464 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4465 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4466 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4467 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4468 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4469 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4473 /* The multiple "Capture Source" controls confuse alsamixer
4474 * So call somewhat different..
4476 .name = "Input Source",
4478 .info = via_mux_enum_info,
4479 .get = via_mux_enum_get,
4480 .put = via_mux_enum_put,
4485 static struct hda_verb vt1718S_volume_init_verbs[] = {
4487 * Unmute ADC0-1 and set the default input to mic-in
4489 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4490 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4493 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4496 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4497 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4498 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4499 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4500 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4501 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4503 /* Setup default input of Front HP to MW9 */
4504 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4505 /* PW9 PW10 Output enable */
4506 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4507 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4508 /* PW11 Input enable */
4509 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4510 /* Enable Boost Volume backdoor */
4512 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4514 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4516 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4517 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4518 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4519 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4521 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4522 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4523 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4524 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4525 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4526 /* Unmute MW4's index 0 */
4527 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4532 static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4533 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4534 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4535 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4536 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4537 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4538 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4539 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4540 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4541 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4545 static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4549 .nid = 0x8, /* NID to query formats and rates */
4551 .open = via_playback_pcm_open,
4552 .prepare = via_playback_multi_pcm_prepare,
4553 .cleanup = via_playback_multi_pcm_cleanup,
4554 .close = via_pcm_open_close,
4558 static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4562 .nid = 0x10, /* NID to query formats and rates */
4564 .open = via_pcm_open_close,
4565 .prepare = via_capture_pcm_prepare,
4566 .cleanup = via_capture_pcm_cleanup,
4567 .close = via_pcm_open_close,
4571 static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4575 /* NID is set in via_build_pcms */
4577 .open = via_dig_playback_pcm_open,
4578 .close = via_dig_playback_pcm_close,
4579 .prepare = via_dig_playback_pcm_prepare,
4580 .cleanup = via_dig_playback_pcm_cleanup
4584 static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4590 /* fill in the dac_nids table from the parsed pin configuration */
4591 static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4592 const struct auto_pin_cfg *cfg)
4597 spec->multiout.num_dacs = cfg->line_outs;
4599 spec->multiout.dac_nids = spec->private_dac_nids;
4601 for (i = 0; i < 4; i++) {
4602 nid = cfg->line_out_pins[i];
4604 /* config dac list */
4606 case AUTO_SEQ_FRONT:
4607 spec->multiout.dac_nids[i] = 0x8;
4609 case AUTO_SEQ_CENLFE:
4610 spec->multiout.dac_nids[i] = 0xa;
4612 case AUTO_SEQ_SURROUND:
4613 spec->multiout.dac_nids[i] = 0x9;
4616 spec->multiout.dac_nids[i] = 0xb;
4625 /* add playback controls from the parsed DAC table */
4626 static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4627 const struct auto_pin_cfg *cfg)
4630 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
4631 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4632 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4633 hda_nid_t nid, nid_vol, nid_mute = 0;
4636 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4637 nid = cfg->line_out_pins[i];
4641 nid_vol = nid_vols[i];
4642 nid_mute = nid_mutes[i];
4644 if (i == AUTO_SEQ_CENLFE) {
4646 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4647 "Center Playback Volume",
4648 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4652 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4653 "LFE Playback Volume",
4654 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4658 err = via_add_control(
4659 spec, VIA_CTL_WIDGET_MUTE,
4660 "Center Playback Switch",
4661 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4665 err = via_add_control(
4666 spec, VIA_CTL_WIDGET_MUTE,
4667 "LFE Playback Switch",
4668 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4672 } else if (i == AUTO_SEQ_FRONT) {
4674 sprintf(name, "%s Playback Volume", chname[i]);
4675 err = via_add_control(
4676 spec, VIA_CTL_WIDGET_VOL, name,
4677 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4680 sprintf(name, "%s Playback Switch", chname[i]);
4681 err = via_add_control(
4682 spec, VIA_CTL_WIDGET_MUTE, name,
4683 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4688 sprintf(name, "%s Playback Volume", chname[i]);
4689 err = via_add_control(
4690 spec, VIA_CTL_WIDGET_VOL, name,
4691 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4694 sprintf(name, "%s Playback Switch", chname[i]);
4695 err = via_add_control(
4696 spec, VIA_CTL_WIDGET_MUTE, name,
4697 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4706 static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4713 spec->multiout.hp_nid = 0xc; /* AOW4 */
4714 spec->hp_independent_mode_index = 1;
4716 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4717 "Headphone Playback Volume",
4718 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4722 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4723 "Headphone Playback Switch",
4724 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4728 create_hp_imux(spec);
4732 /* create playback/capture controls for input pins */
4733 static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
4734 const struct auto_pin_cfg *cfg)
4736 static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4737 return vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
4738 ARRAY_SIZE(pin_idxs));
4741 static int vt1718S_parse_auto_config(struct hda_codec *codec)
4743 struct via_spec *spec = codec->spec;
4746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4750 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4753 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4754 return 0; /* can't find valid BIOS pin config */
4756 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4759 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4762 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4766 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4768 fill_dig_outs(codec);
4770 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4771 spec->dig_in_nid = 0x13;
4773 if (spec->kctls.list)
4774 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4776 spec->input_mux = &spec->private_imux[0];
4779 via_hp_build(codec);
4781 via_smart51_build(spec);
4786 #ifdef CONFIG_SND_HDA_POWER_SAVE
4787 static struct hda_amp_list vt1718S_loopbacks[] = {
4788 { 0x21, HDA_INPUT, 1 },
4789 { 0x21, HDA_INPUT, 2 },
4790 { 0x21, HDA_INPUT, 3 },
4791 { 0x21, HDA_INPUT, 4 },
4796 static int patch_vt1718S(struct hda_codec *codec)
4798 struct via_spec *spec;
4801 /* create a codec specific record */
4802 spec = via_new_spec(codec);
4806 /* automatic parse from the BIOS config */
4807 err = vt1718S_parse_auto_config(codec);
4812 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4813 "from BIOS. Using genenic mode...\n");
4816 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4817 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4819 if (codec->vendor_id == 0x11060441)
4820 spec->stream_name_analog = "VT2020 Analog";
4821 else if (codec->vendor_id == 0x11064441)
4822 spec->stream_name_analog = "VT1828S Analog";
4824 spec->stream_name_analog = "VT1718S Analog";
4825 spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4826 spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4828 if (codec->vendor_id == 0x11060441)
4829 spec->stream_name_digital = "VT2020 Digital";
4830 else if (codec->vendor_id == 0x11064441)
4831 spec->stream_name_digital = "VT1828S Digital";
4833 spec->stream_name_digital = "VT1718S Digital";
4834 spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4835 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4836 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4838 if (!spec->adc_nids && spec->input_mux) {
4839 spec->adc_nids = vt1718S_adc_nids;
4840 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4841 get_mux_nids(codec);
4842 override_mic_boost(codec, 0x2b, 0, 3, 40);
4843 override_mic_boost(codec, 0x29, 0, 3, 40);
4844 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4848 codec->patch_ops = via_patch_ops;
4850 codec->patch_ops.init = via_auto_init;
4851 codec->patch_ops.unsol_event = via_unsol_event;
4853 #ifdef CONFIG_SND_HDA_POWER_SAVE
4854 spec->loopback.amplist = vt1718S_loopbacks;
4860 /* Patch for VT1716S */
4862 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
4863 struct snd_ctl_elem_info *uinfo)
4865 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4867 uinfo->value.integer.min = 0;
4868 uinfo->value.integer.max = 1;
4872 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
4873 struct snd_ctl_elem_value *ucontrol)
4875 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4878 index = snd_hda_codec_read(codec, 0x26, 0,
4879 AC_VERB_GET_CONNECT_SEL, 0);
4881 *ucontrol->value.integer.value = index;
4886 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4887 struct snd_ctl_elem_value *ucontrol)
4889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4890 struct via_spec *spec = codec->spec;
4891 int index = *ucontrol->value.integer.value;
4893 snd_hda_codec_write(codec, 0x26, 0,
4894 AC_VERB_SET_CONNECT_SEL, index);
4895 spec->dmic_enabled = index;
4896 set_jack_power_state(codec);
4901 /* capture mixer elements */
4902 static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4903 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4904 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4905 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4906 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4907 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4908 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4912 .name = "Input Source",
4914 .info = via_mux_enum_info,
4915 .get = via_mux_enum_get,
4916 .put = via_mux_enum_put,
4921 static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4922 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4925 .name = "Digital Mic Capture Switch",
4926 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
4928 .info = vt1716s_dmic_info,
4929 .get = vt1716s_dmic_get,
4930 .put = vt1716s_dmic_put,
4936 /* mono-out mixer elements */
4937 static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4938 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
4942 static struct hda_verb vt1716S_volume_init_verbs[] = {
4944 * Unmute ADC0-1 and set the default input to mic-in
4946 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4947 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4950 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4953 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4954 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4955 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4956 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4957 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4958 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4960 /* MUX Indices: Stereo Mixer = 5 */
4961 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4963 /* Setup default input of PW4 to MW0 */
4964 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4966 /* Setup default input of SW1 as MW0 */
4967 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4969 /* Setup default input of SW4 as AOW0 */
4970 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4972 /* PW9 PW10 Output enable */
4973 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4974 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4976 /* Unmute SW1, PW12 */
4977 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4978 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4979 /* PW12 Output enable */
4980 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4981 /* Enable Boost Volume backdoor */
4983 /* don't bybass mixer */
4985 /* Enable mono output */
4991 static struct hda_verb vt1716S_uniwill_init_verbs[] = {
4992 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
4993 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4994 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4995 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4996 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4997 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
4998 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
4999 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5000 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5004 static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
5008 .nid = 0x10, /* NID to query formats and rates */
5010 .open = via_playback_pcm_open,
5011 .prepare = via_playback_multi_pcm_prepare,
5012 .cleanup = via_playback_multi_pcm_cleanup,
5013 .close = via_pcm_open_close,
5017 static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
5021 .nid = 0x13, /* NID to query formats and rates */
5023 .open = via_pcm_open_close,
5024 .prepare = via_capture_pcm_prepare,
5025 .cleanup = via_capture_pcm_cleanup,
5026 .close = via_pcm_open_close,
5030 static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
5034 /* NID is set in via_build_pcms */
5036 .open = via_dig_playback_pcm_open,
5037 .close = via_dig_playback_pcm_close,
5038 .prepare = via_dig_playback_pcm_prepare,
5039 .cleanup = via_dig_playback_pcm_cleanup
5043 /* fill in the dac_nids table from the parsed pin configuration */
5044 static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
5045 const struct auto_pin_cfg *cfg)
5049 spec->multiout.num_dacs = cfg->line_outs;
5051 spec->multiout.dac_nids = spec->private_dac_nids;
5053 for (i = 0; i < 3; i++) {
5054 nid = cfg->line_out_pins[i];
5056 /* config dac list */
5058 case AUTO_SEQ_FRONT:
5059 spec->multiout.dac_nids[i] = 0x10;
5061 case AUTO_SEQ_CENLFE:
5062 spec->multiout.dac_nids[i] = 0x25;
5064 case AUTO_SEQ_SURROUND:
5065 spec->multiout.dac_nids[i] = 0x11;
5074 /* add playback controls from the parsed DAC table */
5075 static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5076 const struct auto_pin_cfg *cfg)
5079 static const char *chname[3] = { "Front", "Surround", "C/LFE" };
5080 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5081 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5082 hda_nid_t nid, nid_vol, nid_mute;
5085 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
5086 nid = cfg->line_out_pins[i];
5091 nid_vol = nid_vols[i];
5092 nid_mute = nid_mutes[i];
5094 if (i == AUTO_SEQ_CENLFE) {
5095 err = via_add_control(
5096 spec, VIA_CTL_WIDGET_VOL,
5097 "Center Playback Volume",
5098 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
5101 err = via_add_control(
5102 spec, VIA_CTL_WIDGET_VOL,
5103 "LFE Playback Volume",
5104 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
5107 err = via_add_control(
5108 spec, VIA_CTL_WIDGET_MUTE,
5109 "Center Playback Switch",
5110 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
5114 err = via_add_control(
5115 spec, VIA_CTL_WIDGET_MUTE,
5116 "LFE Playback Switch",
5117 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
5121 } else if (i == AUTO_SEQ_FRONT) {
5123 err = via_add_control(
5124 spec, VIA_CTL_WIDGET_VOL,
5125 "Master Front Playback Volume",
5126 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5129 err = via_add_control(
5130 spec, VIA_CTL_WIDGET_MUTE,
5131 "Master Front Playback Switch",
5132 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5136 sprintf(name, "%s Playback Volume", chname[i]);
5137 err = via_add_control(
5138 spec, VIA_CTL_WIDGET_VOL, name,
5139 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5142 sprintf(name, "%s Playback Switch", chname[i]);
5143 err = via_add_control(
5144 spec, VIA_CTL_WIDGET_MUTE, name,
5145 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5150 sprintf(name, "%s Playback Volume", chname[i]);
5151 err = via_add_control(
5152 spec, VIA_CTL_WIDGET_VOL, name,
5153 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5156 sprintf(name, "%s Playback Switch", chname[i]);
5157 err = via_add_control(
5158 spec, VIA_CTL_WIDGET_MUTE, name,
5159 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5168 static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5175 spec->multiout.hp_nid = 0x25; /* AOW3 */
5176 spec->hp_independent_mode_index = 1;
5178 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5179 "Headphone Playback Volume",
5180 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5184 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5185 "Headphone Playback Switch",
5186 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5190 create_hp_imux(spec);
5194 /* create playback/capture controls for input pins */
5195 static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
5196 const struct auto_pin_cfg *cfg)
5198 static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5199 return vt_auto_create_analog_input_ctls(spec, cfg, 0x16, pin_idxs,
5200 ARRAY_SIZE(pin_idxs));
5203 static int vt1716S_parse_auto_config(struct hda_codec *codec)
5205 struct via_spec *spec = codec->spec;
5208 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5211 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5214 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5215 return 0; /* can't find valid BIOS pin config */
5217 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5220 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5223 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg);
5227 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5229 fill_dig_outs(codec);
5231 if (spec->kctls.list)
5232 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5234 spec->input_mux = &spec->private_imux[0];
5237 via_hp_build(codec);
5239 via_smart51_build(spec);
5244 #ifdef CONFIG_SND_HDA_POWER_SAVE
5245 static struct hda_amp_list vt1716S_loopbacks[] = {
5246 { 0x16, HDA_INPUT, 1 },
5247 { 0x16, HDA_INPUT, 2 },
5248 { 0x16, HDA_INPUT, 3 },
5249 { 0x16, HDA_INPUT, 4 },
5254 static int patch_vt1716S(struct hda_codec *codec)
5256 struct via_spec *spec;
5259 /* create a codec specific record */
5260 spec = via_new_spec(codec);
5264 /* automatic parse from the BIOS config */
5265 err = vt1716S_parse_auto_config(codec);
5270 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5271 "from BIOS. Using genenic mode...\n");
5274 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs;
5275 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5277 spec->stream_name_analog = "VT1716S Analog";
5278 spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5279 spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5281 spec->stream_name_digital = "VT1716S Digital";
5282 spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5284 if (!spec->adc_nids && spec->input_mux) {
5285 spec->adc_nids = vt1716S_adc_nids;
5286 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5287 get_mux_nids(codec);
5288 override_mic_boost(codec, 0x1a, 0, 3, 40);
5289 override_mic_boost(codec, 0x1e, 0, 3, 40);
5290 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5294 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5297 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
5299 codec->patch_ops = via_patch_ops;
5301 codec->patch_ops.init = via_auto_init;
5302 codec->patch_ops.unsol_event = via_unsol_event;
5304 #ifdef CONFIG_SND_HDA_POWER_SAVE
5305 spec->loopback.amplist = vt1716S_loopbacks;
5313 /* capture mixer elements */
5314 static struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5315 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5316 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5317 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5318 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5319 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5320 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5324 /* The multiple "Capture Source" controls confuse alsamixer
5325 * So call somewhat different..
5327 /* .name = "Capture Source", */
5328 .name = "Input Source",
5330 .info = via_mux_enum_info,
5331 .get = via_mux_enum_get,
5332 .put = via_mux_enum_put,
5337 static struct hda_verb vt2002P_volume_init_verbs[] = {
5339 * Unmute ADC0-1 and set the default input to mic-in
5341 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5342 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5345 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5348 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5349 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5350 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5351 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5352 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5353 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5355 /* MUX Indices: Mic = 0 */
5356 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5357 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5359 /* PW9 Output enable */
5360 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5362 /* Enable Boost Volume backdoor */
5365 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5366 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5367 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5368 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5369 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5370 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5371 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5372 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5373 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5375 /* set MUX0/1/4/8 = 0 (AOW0) */
5376 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5377 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5378 {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5379 {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5381 /* set PW0 index=0 (MW0) */
5382 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5384 /* Enable AOW0 to MW9 */
5390 static struct hda_verb vt2002P_uniwill_init_verbs[] = {
5391 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5392 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5393 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5394 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5395 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5396 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5397 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5401 static struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5405 .nid = 0x8, /* NID to query formats and rates */
5407 .open = via_playback_pcm_open,
5408 .prepare = via_playback_multi_pcm_prepare,
5409 .cleanup = via_playback_multi_pcm_cleanup,
5410 .close = via_pcm_open_close,
5414 static struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5418 .nid = 0x10, /* NID to query formats and rates */
5420 .open = via_pcm_open_close,
5421 .prepare = via_capture_pcm_prepare,
5422 .cleanup = via_capture_pcm_cleanup,
5423 .close = via_pcm_open_close,
5427 static struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5431 /* NID is set in via_build_pcms */
5433 .open = via_dig_playback_pcm_open,
5434 .close = via_dig_playback_pcm_close,
5435 .prepare = via_dig_playback_pcm_prepare,
5436 .cleanup = via_dig_playback_pcm_cleanup
5440 /* fill in the dac_nids table from the parsed pin configuration */
5441 static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5442 const struct auto_pin_cfg *cfg)
5444 spec->multiout.num_dacs = 1;
5445 spec->multiout.dac_nids = spec->private_dac_nids;
5446 if (cfg->line_out_pins[0])
5447 spec->multiout.dac_nids[0] = 0x8;
5451 /* add playback controls from the parsed DAC table */
5452 static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5453 const struct auto_pin_cfg *cfg)
5457 if (!cfg->line_out_pins[0])
5461 /* Line-Out: PortE */
5462 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5463 "Master Front Playback Volume",
5464 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5467 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5468 "Master Front Playback Switch",
5469 HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT));
5476 static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5483 spec->multiout.hp_nid = 0x9;
5484 spec->hp_independent_mode_index = 1;
5486 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5487 "Headphone Playback Volume",
5488 HDA_COMPOSE_AMP_VAL(
5489 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5493 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5494 "Headphone Playback Switch",
5495 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5499 create_hp_imux(spec);
5503 /* create playback/capture controls for input pins */
5504 static int vt2002P_auto_create_analog_input_ctls(struct via_spec *spec,
5505 const struct auto_pin_cfg *cfg)
5507 struct hda_input_mux *imux = &spec->private_imux[0];
5508 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5511 err = vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
5512 ARRAY_SIZE(pin_idxs));
5515 /* build volume/mute control of loopback */
5516 err = via_new_analog_input(spec, "Stereo Mixer", 3, 0x21);
5520 /* for digital mic select */
5521 imux->items[imux->num_items].label = "Digital Mic";
5522 imux->items[imux->num_items].index = 4;
5528 static int vt2002P_parse_auto_config(struct hda_codec *codec)
5530 struct via_spec *spec = codec->spec;
5534 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5538 err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5542 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5543 return 0; /* can't find valid BIOS pin config */
5545 err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5548 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5551 err = vt2002P_auto_create_analog_input_ctls(spec, &spec->autocfg);
5555 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5557 fill_dig_outs(codec);
5559 if (spec->kctls.list)
5560 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5562 spec->input_mux = &spec->private_imux[0];
5565 via_hp_build(codec);
5570 #ifdef CONFIG_SND_HDA_POWER_SAVE
5571 static struct hda_amp_list vt2002P_loopbacks[] = {
5572 { 0x21, HDA_INPUT, 0 },
5573 { 0x21, HDA_INPUT, 1 },
5574 { 0x21, HDA_INPUT, 2 },
5580 /* patch for vt2002P */
5581 static int patch_vt2002P(struct hda_codec *codec)
5583 struct via_spec *spec;
5586 /* create a codec specific record */
5587 spec = via_new_spec(codec);
5591 /* automatic parse from the BIOS config */
5592 err = vt2002P_parse_auto_config(codec);
5597 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5598 "from BIOS. Using genenic mode...\n");
5601 spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs;
5602 spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs;
5604 spec->stream_name_analog = "VT2002P Analog";
5605 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5606 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5608 spec->stream_name_digital = "VT2002P Digital";
5609 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5611 if (!spec->adc_nids && spec->input_mux) {
5612 spec->adc_nids = vt2002P_adc_nids;
5613 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5614 get_mux_nids(codec);
5615 override_mic_boost(codec, 0x2b, 0, 3, 40);
5616 override_mic_boost(codec, 0x29, 0, 3, 40);
5617 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5621 codec->patch_ops = via_patch_ops;
5623 codec->patch_ops.init = via_auto_init;
5624 codec->patch_ops.unsol_event = via_unsol_event;
5626 #ifdef CONFIG_SND_HDA_POWER_SAVE
5627 spec->loopback.amplist = vt2002P_loopbacks;
5635 /* capture mixer elements */
5636 static struct snd_kcontrol_new vt1812_capture_mixer[] = {
5637 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5638 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5639 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5640 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5641 HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5642 HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5646 /* The multiple "Capture Source" controls confuse alsamixer
5647 * So call somewhat different..
5649 .name = "Input Source",
5651 .info = via_mux_enum_info,
5652 .get = via_mux_enum_get,
5653 .put = via_mux_enum_put,
5658 static struct hda_verb vt1812_volume_init_verbs[] = {
5660 * Unmute ADC0-1 and set the default input to mic-in
5662 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5663 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5666 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5669 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5670 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5671 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5672 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5673 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5674 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5676 /* MUX Indices: Mic = 0 */
5677 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5678 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5680 /* PW9 Output enable */
5681 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5683 /* Enable Boost Volume backdoor */
5686 /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5687 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5690 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5691 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5695 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5696 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5698 /* set MUX0/1/4/13/15 = 0 (AOW0) */
5699 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5700 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5701 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5702 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5703 {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5705 /* Enable AOW0 to MW9 */
5711 static struct hda_verb vt1812_uniwill_init_verbs[] = {
5712 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5713 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5714 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5715 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5716 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5717 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5718 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5719 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5723 static struct hda_pcm_stream vt1812_pcm_analog_playback = {
5727 .nid = 0x8, /* NID to query formats and rates */
5729 .open = via_playback_pcm_open,
5730 .prepare = via_playback_multi_pcm_prepare,
5731 .cleanup = via_playback_multi_pcm_cleanup,
5732 .close = via_pcm_open_close,
5736 static struct hda_pcm_stream vt1812_pcm_analog_capture = {
5740 .nid = 0x10, /* NID to query formats and rates */
5742 .open = via_pcm_open_close,
5743 .prepare = via_capture_pcm_prepare,
5744 .cleanup = via_capture_pcm_cleanup,
5745 .close = via_pcm_open_close,
5749 static struct hda_pcm_stream vt1812_pcm_digital_playback = {
5753 /* NID is set in via_build_pcms */
5755 .open = via_dig_playback_pcm_open,
5756 .close = via_dig_playback_pcm_close,
5757 .prepare = via_dig_playback_pcm_prepare,
5758 .cleanup = via_dig_playback_pcm_cleanup
5761 /* fill in the dac_nids table from the parsed pin configuration */
5762 static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5763 const struct auto_pin_cfg *cfg)
5765 spec->multiout.num_dacs = 1;
5766 spec->multiout.dac_nids = spec->private_dac_nids;
5767 if (cfg->line_out_pins[0])
5768 spec->multiout.dac_nids[0] = 0x8;
5773 /* add playback controls from the parsed DAC table */
5774 static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
5775 const struct auto_pin_cfg *cfg)
5779 if (!cfg->line_out_pins[0])
5782 /* Line-Out: PortE */
5783 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5784 "Front Playback Volume",
5785 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5788 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5789 "Front Playback Switch",
5790 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
5797 static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5804 spec->multiout.hp_nid = 0x9;
5805 spec->hp_independent_mode_index = 1;
5808 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5809 "Headphone Playback Volume",
5810 HDA_COMPOSE_AMP_VAL(
5811 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5815 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5816 "Headphone Playback Switch",
5817 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5821 create_hp_imux(spec);
5825 /* create playback/capture controls for input pins */
5826 static int vt1812_auto_create_analog_input_ctls(struct via_spec *spec,
5827 const struct auto_pin_cfg *cfg)
5829 struct hda_input_mux *imux = &spec->private_imux[0];
5830 static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5833 err = vt_auto_create_analog_input_ctls(spec, cfg, 0x21, pin_idxs,
5834 ARRAY_SIZE(pin_idxs));
5838 /* build volume/mute control of loopback */
5839 err = via_new_analog_input(spec, "Stereo Mixer", 5, 0x21);
5843 /* for digital mic select */
5844 imux->items[imux->num_items].label = "Digital Mic";
5845 imux->items[imux->num_items].index = 6;
5851 static int vt1812_parse_auto_config(struct hda_codec *codec)
5853 struct via_spec *spec = codec->spec;
5857 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5860 fill_dig_outs(codec);
5861 err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
5865 if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
5866 return 0; /* can't find valid BIOS pin config */
5868 err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
5871 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5874 err = vt1812_auto_create_analog_input_ctls(spec, &spec->autocfg);
5878 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5880 fill_dig_outs(codec);
5882 if (spec->kctls.list)
5883 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5885 spec->input_mux = &spec->private_imux[0];
5888 via_hp_build(codec);
5893 #ifdef CONFIG_SND_HDA_POWER_SAVE
5894 static struct hda_amp_list vt1812_loopbacks[] = {
5895 { 0x21, HDA_INPUT, 0 },
5896 { 0x21, HDA_INPUT, 1 },
5897 { 0x21, HDA_INPUT, 2 },
5903 /* patch for vt1812 */
5904 static int patch_vt1812(struct hda_codec *codec)
5906 struct via_spec *spec;
5909 /* create a codec specific record */
5910 spec = via_new_spec(codec);
5914 /* automatic parse from the BIOS config */
5915 err = vt1812_parse_auto_config(codec);
5920 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5921 "from BIOS. Using genenic mode...\n");
5925 spec->init_verbs[spec->num_iverbs++] = vt1812_volume_init_verbs;
5926 spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
5928 spec->stream_name_analog = "VT1812 Analog";
5929 spec->stream_analog_playback = &vt1812_pcm_analog_playback;
5930 spec->stream_analog_capture = &vt1812_pcm_analog_capture;
5932 spec->stream_name_digital = "VT1812 Digital";
5933 spec->stream_digital_playback = &vt1812_pcm_digital_playback;
5936 if (!spec->adc_nids && spec->input_mux) {
5937 spec->adc_nids = vt1812_adc_nids;
5938 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
5939 get_mux_nids(codec);
5940 override_mic_boost(codec, 0x2b, 0, 3, 40);
5941 override_mic_boost(codec, 0x29, 0, 3, 40);
5942 spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
5946 codec->patch_ops = via_patch_ops;
5948 codec->patch_ops.init = via_auto_init;
5949 codec->patch_ops.unsol_event = via_unsol_event;
5951 #ifdef CONFIG_SND_HDA_POWER_SAVE
5952 spec->loopback.amplist = vt1812_loopbacks;
5961 static struct hda_codec_preset snd_hda_preset_via[] = {
5962 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
5963 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
5964 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
5965 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
5966 { .id = 0x1106e710, .name = "VT1709 10-Ch",
5967 .patch = patch_vt1709_10ch},
5968 { .id = 0x1106e711, .name = "VT1709 10-Ch",
5969 .patch = patch_vt1709_10ch},
5970 { .id = 0x1106e712, .name = "VT1709 10-Ch",
5971 .patch = patch_vt1709_10ch},
5972 { .id = 0x1106e713, .name = "VT1709 10-Ch",
5973 .patch = patch_vt1709_10ch},
5974 { .id = 0x1106e714, .name = "VT1709 6-Ch",
5975 .patch = patch_vt1709_6ch},
5976 { .id = 0x1106e715, .name = "VT1709 6-Ch",
5977 .patch = patch_vt1709_6ch},
5978 { .id = 0x1106e716, .name = "VT1709 6-Ch",
5979 .patch = patch_vt1709_6ch},
5980 { .id = 0x1106e717, .name = "VT1709 6-Ch",
5981 .patch = patch_vt1709_6ch},
5982 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
5983 .patch = patch_vt1708B_8ch},
5984 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
5985 .patch = patch_vt1708B_8ch},
5986 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
5987 .patch = patch_vt1708B_8ch},
5988 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
5989 .patch = patch_vt1708B_8ch},
5990 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
5991 .patch = patch_vt1708B_4ch},
5992 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
5993 .patch = patch_vt1708B_4ch},
5994 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
5995 .patch = patch_vt1708B_4ch},
5996 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
5997 .patch = patch_vt1708B_4ch},
5998 { .id = 0x11060397, .name = "VT1708S",
5999 .patch = patch_vt1708S},
6000 { .id = 0x11061397, .name = "VT1708S",
6001 .patch = patch_vt1708S},
6002 { .id = 0x11062397, .name = "VT1708S",
6003 .patch = patch_vt1708S},
6004 { .id = 0x11063397, .name = "VT1708S",
6005 .patch = patch_vt1708S},
6006 { .id = 0x11064397, .name = "VT1708S",
6007 .patch = patch_vt1708S},
6008 { .id = 0x11065397, .name = "VT1708S",
6009 .patch = patch_vt1708S},
6010 { .id = 0x11066397, .name = "VT1708S",
6011 .patch = patch_vt1708S},
6012 { .id = 0x11067397, .name = "VT1708S",
6013 .patch = patch_vt1708S},
6014 { .id = 0x11060398, .name = "VT1702",
6015 .patch = patch_vt1702},
6016 { .id = 0x11061398, .name = "VT1702",
6017 .patch = patch_vt1702},
6018 { .id = 0x11062398, .name = "VT1702",
6019 .patch = patch_vt1702},
6020 { .id = 0x11063398, .name = "VT1702",
6021 .patch = patch_vt1702},
6022 { .id = 0x11064398, .name = "VT1702",
6023 .patch = patch_vt1702},
6024 { .id = 0x11065398, .name = "VT1702",
6025 .patch = patch_vt1702},
6026 { .id = 0x11066398, .name = "VT1702",
6027 .patch = patch_vt1702},
6028 { .id = 0x11067398, .name = "VT1702",
6029 .patch = patch_vt1702},
6030 { .id = 0x11060428, .name = "VT1718S",
6031 .patch = patch_vt1718S},
6032 { .id = 0x11064428, .name = "VT1718S",
6033 .patch = patch_vt1718S},
6034 { .id = 0x11060441, .name = "VT2020",
6035 .patch = patch_vt1718S},
6036 { .id = 0x11064441, .name = "VT1828S",
6037 .patch = patch_vt1718S},
6038 { .id = 0x11060433, .name = "VT1716S",
6039 .patch = patch_vt1716S},
6040 { .id = 0x1106a721, .name = "VT1716S",
6041 .patch = patch_vt1716S},
6042 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
6043 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
6044 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
6045 { .id = 0x11060440, .name = "VT1818S",
6046 .patch = patch_vt1708S},
6050 MODULE_ALIAS("snd-hda-codec-id:1106*");
6052 static struct hda_codec_preset_list via_list = {
6053 .preset = snd_hda_preset_via,
6054 .owner = THIS_MODULE,
6057 MODULE_LICENSE("GPL");
6058 MODULE_DESCRIPTION("VIA HD-audio codec");
6060 static int __init patch_via_init(void)
6062 return snd_hda_add_codec_preset(&via_list);
6065 static void __exit patch_via_exit(void)
6067 snd_hda_delete_codec_preset(&via_list);
6070 module_init(patch_via_init)
6071 module_exit(patch_via_exit)