2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec
6 * Copyright (c) 2006-2008 Lydia Wang <lydiawang@viatech.com>
7 * Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
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 */
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43 #include <linux/init.h>
44 #include <linux/delay.h>
45 #include <linux/slab.h>
46 #include <sound/core.h>
47 #include <sound/asoundef.h>
48 #include "hda_codec.h"
49 #include "hda_local.h"
52 #define AMP_VAL_IDX_SHIFT 19
53 #define AMP_VAL_IDX_MASK (0x0f<<19)
56 #define VT1708_HP_NID 0x13
57 #define VT1708_DIGOUT_NID 0x14
58 #define VT1708_DIGIN_NID 0x16
59 #define VT1708_DIGIN_PIN 0x26
60 #define VT1708_HP_PIN_NID 0x20
61 #define VT1708_CD_PIN_NID 0x24
63 #define VT1709_HP_DAC_NID 0x28
64 #define VT1709_DIGOUT_NID 0x13
65 #define VT1709_DIGIN_NID 0x17
66 #define VT1709_DIGIN_PIN 0x25
68 #define VT1708B_HP_NID 0x25
69 #define VT1708B_DIGOUT_NID 0x12
70 #define VT1708B_DIGIN_NID 0x15
71 #define VT1708B_DIGIN_PIN 0x21
73 #define VT1708S_HP_NID 0x25
74 #define VT1708S_DIGOUT_NID 0x12
76 #define VT1702_HP_NID 0x17
77 #define VT1702_DIGOUT_NID 0x11
95 /* codec parameterization */
96 struct snd_kcontrol_new *mixers[6];
97 unsigned int num_mixers;
99 struct hda_verb *init_verbs[5];
100 unsigned int num_iverbs;
102 char *stream_name_analog;
103 struct hda_pcm_stream *stream_analog_playback;
104 struct hda_pcm_stream *stream_analog_capture;
106 char *stream_name_digital;
107 struct hda_pcm_stream *stream_digital_playback;
108 struct hda_pcm_stream *stream_digital_capture;
111 struct hda_multi_out multiout;
112 hda_nid_t slave_dig_outs[2];
115 unsigned int num_adc_nids;
117 hda_nid_t mux_nids[3];
118 hda_nid_t dig_in_nid;
119 hda_nid_t dig_in_pin;
122 const struct hda_input_mux *input_mux;
123 unsigned int cur_mux[3];
125 /* PCM information */
126 struct hda_pcm pcm_rec[3];
128 /* dynamic controls, init_verbs and input_mux */
129 struct auto_pin_cfg autocfg;
130 struct snd_array kctls;
131 struct hda_input_mux private_imux[2];
132 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
135 const struct hda_input_mux *hp_mux;
136 unsigned int hp_independent_mode;
137 unsigned int hp_independent_mode_index;
138 unsigned int smart51_enabled;
139 unsigned int dmic_enabled;
140 enum VIA_HDA_CODEC codec_type;
142 /* work to check hp jack state */
143 struct hda_codec *codec;
144 struct delayed_work vt1708_hp_work;
145 int vt1708_jack_detectect;
146 int vt1708_hp_present;
147 #ifdef CONFIG_SND_HDA_POWER_SAVE
148 struct hda_loopback_check loopback;
152 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
154 u32 vendor_id = codec->vendor_id;
155 u16 ven_id = vendor_id >> 16;
156 u16 dev_id = vendor_id & 0xffff;
157 enum VIA_HDA_CODEC codec_type;
160 if (ven_id != 0x1106)
161 codec_type = UNKNOWN;
162 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
164 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
165 codec_type = VT1709_10CH;
166 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
167 codec_type = VT1709_6CH;
168 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
169 codec_type = VT1708B_8CH;
170 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
171 codec_type = VT1708BCE;
172 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
173 codec_type = VT1708B_4CH;
174 else if ((dev_id & 0xfff) == 0x397
175 && (dev_id >> 12) < 8)
176 codec_type = VT1708S;
177 else if ((dev_id & 0xfff) == 0x398
178 && (dev_id >> 12) < 8)
180 else if ((dev_id & 0xfff) == 0x428
181 && (dev_id >> 12) < 8)
182 codec_type = VT1718S;
183 else if (dev_id == 0x0433 || dev_id == 0xa721)
184 codec_type = VT1716S;
185 else if (dev_id == 0x0441 || dev_id == 0x4441)
186 codec_type = VT1718S;
188 codec_type = UNKNOWN;
192 #define VIA_HP_EVENT 0x01
193 #define VIA_GPIO_EVENT 0x02
194 #define VIA_JACK_EVENT 0x04
195 #define VIA_MONO_EVENT 0x08
200 VIA_CTL_WIDGET_ANALOG_MUTE,
210 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
211 static void set_jack_power_state(struct hda_codec *codec);
212 static int is_aa_path_mute(struct hda_codec *codec);
214 static void vt1708_start_hp_work(struct via_spec *spec)
216 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
218 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
219 !spec->vt1708_jack_detectect);
220 if (!delayed_work_pending(&spec->vt1708_hp_work))
221 schedule_delayed_work(&spec->vt1708_hp_work,
222 msecs_to_jiffies(100));
225 static void vt1708_stop_hp_work(struct via_spec *spec)
227 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
229 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
230 && !is_aa_path_mute(spec->codec))
232 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
233 !spec->vt1708_jack_detectect);
234 cancel_delayed_work(&spec->vt1708_hp_work);
235 flush_scheduled_work();
238 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
239 struct snd_ctl_elem_value *ucontrol)
241 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
242 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
244 set_jack_power_state(codec);
245 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
246 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
247 if (is_aa_path_mute(codec))
248 vt1708_start_hp_work(codec->spec);
250 vt1708_stop_hp_work(codec->spec);
255 /* modify .put = snd_hda_mixer_amp_switch_put */
256 #define ANALOG_INPUT_MUTE \
257 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
260 .info = snd_hda_mixer_amp_switch_info, \
261 .get = snd_hda_mixer_amp_switch_get, \
262 .put = analog_input_switch_put, \
263 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
265 static struct snd_kcontrol_new vt1708_control_templates[] = {
266 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
267 HDA_CODEC_MUTE(NULL, 0, 0, 0),
272 static hda_nid_t vt1708_adc_nids[2] = {
277 static hda_nid_t vt1709_adc_nids[3] = {
282 static hda_nid_t vt1708B_adc_nids[2] = {
287 static hda_nid_t vt1708S_adc_nids[2] = {
292 static hda_nid_t vt1702_adc_nids[3] = {
297 static hda_nid_t vt1718S_adc_nids[2] = {
302 static hda_nid_t vt1716S_adc_nids[2] = {
307 /* add dynamic controls */
308 static int via_add_control(struct via_spec *spec, int type, const char *name,
311 struct snd_kcontrol_new *knew;
313 snd_array_init(&spec->kctls, sizeof(*knew), 32);
314 knew = snd_array_new(&spec->kctls);
317 *knew = vt1708_control_templates[type];
318 knew->name = kstrdup(name, GFP_KERNEL);
321 knew->private_value = val;
325 static void via_free_kctls(struct hda_codec *codec)
327 struct via_spec *spec = codec->spec;
329 if (spec->kctls.list) {
330 struct snd_kcontrol_new *kctl = spec->kctls.list;
332 for (i = 0; i < spec->kctls.used; i++)
335 snd_array_free(&spec->kctls);
338 /* create input playback/capture controls for the given pin */
339 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
340 int idx, int mix_nid)
345 sprintf(name, "%s Playback Volume", ctlname);
346 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
347 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
350 sprintf(name, "%s Playback Switch", ctlname);
351 err = via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name,
352 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
358 static void via_auto_set_output_and_unmute(struct hda_codec *codec,
359 hda_nid_t nid, int pin_type,
363 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
365 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
367 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
368 snd_hda_codec_write(codec, nid, 0,
369 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
373 static void via_auto_init_multi_out(struct hda_codec *codec)
375 struct via_spec *spec = codec->spec;
378 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
379 hda_nid_t nid = spec->autocfg.line_out_pins[i];
381 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
385 static void via_auto_init_hp_out(struct hda_codec *codec)
387 struct via_spec *spec = codec->spec;
390 pin = spec->autocfg.hp_pins[0];
391 if (pin) /* connect to front */
392 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
395 static void via_auto_init_analog_input(struct hda_codec *codec)
397 struct via_spec *spec = codec->spec;
400 for (i = 0; i < AUTO_PIN_LAST; i++) {
401 hda_nid_t nid = spec->autocfg.input_pins[i];
403 snd_hda_codec_write(codec, nid, 0,
404 AC_VERB_SET_PIN_WIDGET_CONTROL,
405 (i <= AUTO_PIN_FRONT_MIC ?
406 PIN_VREF50 : PIN_IN));
411 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
413 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
414 unsigned int *affected_parm)
417 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
418 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
419 >> AC_DEFCFG_MISC_SHIFT
420 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
421 unsigned present = snd_hda_codec_read(codec, nid, 0,
422 AC_VERB_GET_PIN_SENSE, 0) >> 31;
423 struct via_spec *spec = codec->spec;
424 if ((spec->smart51_enabled && is_smart51_pins(spec, nid))
425 || ((no_presence || present)
426 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
427 *affected_parm = AC_PWRST_D0; /* if it's connected */
432 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
435 static void set_jack_power_state(struct hda_codec *codec)
437 struct via_spec *spec = codec->spec;
441 if (spec->codec_type == VT1702) {
442 imux_is_smixer = snd_hda_codec_read(
443 codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
445 /* PW 1/2/5 (14h/15h/18h) */
447 set_pin_power_state(codec, 0x14, &parm);
448 set_pin_power_state(codec, 0x15, &parm);
449 set_pin_power_state(codec, 0x18, &parm);
451 parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */
452 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
453 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
455 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE,
457 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
459 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE,
463 /* PW 3/4 (16h/17h) */
465 set_pin_power_state(codec, 0x16, &parm);
466 set_pin_power_state(codec, 0x17, &parm);
467 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
468 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
469 imux_is_smixer ? AC_PWRST_D0 : parm);
470 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
472 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE,
474 } else if (spec->codec_type == VT1708B_8CH
475 || spec->codec_type == VT1708B_4CH
476 || spec->codec_type == VT1708S) {
477 /* SW0 (17h) = stereo mixer */
478 int is_8ch = spec->codec_type != VT1708B_4CH;
479 imux_is_smixer = snd_hda_codec_read(
480 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
481 == ((spec->codec_type == VT1708S) ? 5 : 0);
483 /* PW 1/2/5 (1ah/1bh/1eh) */
485 set_pin_power_state(codec, 0x1a, &parm);
486 set_pin_power_state(codec, 0x1b, &parm);
487 set_pin_power_state(codec, 0x1e, &parm);
490 /* SW0 (17h), AIW 0/1 (13h/14h) */
491 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
493 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
495 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
499 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
501 set_pin_power_state(codec, 0x19, &parm);
502 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
504 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
507 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
510 set_pin_power_state(codec, 0x22, &parm);
511 snd_hda_codec_write(codec, 0x26, 0,
512 AC_VERB_SET_POWER_STATE, parm);
513 snd_hda_codec_write(codec, 0x24, 0,
514 AC_VERB_SET_POWER_STATE, parm);
517 /* PW 3/4/7 (1ch/1dh/23h) */
519 /* force to D0 for internal Speaker */
520 set_pin_power_state(codec, 0x1c, &parm);
521 set_pin_power_state(codec, 0x1d, &parm);
523 set_pin_power_state(codec, 0x23, &parm);
524 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
525 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
526 imux_is_smixer ? AC_PWRST_D0 : parm);
527 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
530 snd_hda_codec_write(codec, 0x25, 0,
531 AC_VERB_SET_POWER_STATE, parm);
532 snd_hda_codec_write(codec, 0x27, 0,
533 AC_VERB_SET_POWER_STATE, parm);
535 } else if (spec->codec_type == VT1718S) {
536 /* MUX6 (1eh) = stereo mixer */
537 imux_is_smixer = snd_hda_codec_read(
538 codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
540 /* PW 5/6/7 (29h/2ah/2bh) */
542 set_pin_power_state(codec, 0x29, &parm);
543 set_pin_power_state(codec, 0x2a, &parm);
544 set_pin_power_state(codec, 0x2b, &parm);
547 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
548 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE,
550 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE,
552 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
554 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
558 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
560 set_pin_power_state(codec, 0x27, &parm);
561 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
563 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE,
566 /* PW2 (26h), AOW2 (ah) */
568 set_pin_power_state(codec, 0x26, &parm);
569 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE,
572 /* PW0/1 (24h/25h) */
574 set_pin_power_state(codec, 0x24, &parm);
575 set_pin_power_state(codec, 0x25, &parm);
576 if (!spec->hp_independent_mode) /* check for redirected HP */
577 set_pin_power_state(codec, 0x28, &parm);
578 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE,
580 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE,
582 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
583 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
584 imux_is_smixer ? AC_PWRST_D0 : parm);
585 if (spec->hp_independent_mode) {
586 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
588 set_pin_power_state(codec, 0x28, &parm);
589 snd_hda_codec_write(codec, 0x1b, 0,
590 AC_VERB_SET_POWER_STATE, parm);
591 snd_hda_codec_write(codec, 0x34, 0,
592 AC_VERB_SET_POWER_STATE, parm);
593 snd_hda_codec_write(codec, 0xc, 0,
594 AC_VERB_SET_POWER_STATE, parm);
596 } else if (spec->codec_type == VT1716S) {
597 unsigned int mono_out, present;
598 /* SW0 (17h) = stereo mixer */
599 imux_is_smixer = snd_hda_codec_read(
600 codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
602 /* PW 1/2/5 (1ah/1bh/1eh) */
604 set_pin_power_state(codec, 0x1a, &parm);
605 set_pin_power_state(codec, 0x1b, &parm);
606 set_pin_power_state(codec, 0x1e, &parm);
609 /* SW0 (17h), AIW0(13h) */
610 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE,
612 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE,
616 set_pin_power_state(codec, 0x1e, &parm);
618 if (spec->dmic_enabled)
619 set_pin_power_state(codec, 0x22, &parm);
623 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
625 /* SW2(26h), AIW1(14h) */
626 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE,
628 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE,
632 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
634 set_pin_power_state(codec, 0x19, &parm);
635 /* Smart 5.1 PW2(1bh) */
636 if (spec->smart51_enabled)
637 set_pin_power_state(codec, 0x1b, &parm);
638 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
640 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
643 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
645 set_pin_power_state(codec, 0x23, &parm);
646 /* Smart 5.1 PW1(1ah) */
647 if (spec->smart51_enabled)
648 set_pin_power_state(codec, 0x1a, &parm);
649 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE,
652 /* Smart 5.1 PW5(1eh) */
653 if (spec->smart51_enabled)
654 set_pin_power_state(codec, 0x1e, &parm);
655 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE,
659 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
660 present = snd_hda_codec_read(
661 codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
665 present = snd_hda_codec_read(
666 codec, 0x1d, 0, AC_VERB_GET_PIN_SENSE, 0)
668 if (!spec->hp_independent_mode && present)
673 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
674 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE,
676 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE,
678 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE,
681 /* PW 3/4 (1ch/1dh) */
683 set_pin_power_state(codec, 0x1c, &parm);
684 set_pin_power_state(codec, 0x1d, &parm);
685 /* HP Independent Mode, power on AOW3 */
686 if (spec->hp_independent_mode)
687 snd_hda_codec_write(codec, 0x25, 0,
688 AC_VERB_SET_POWER_STATE, parm);
690 /* force to D0 for internal Speaker */
691 /* MW0 (16h), AOW0 (10h) */
692 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
693 imux_is_smixer ? AC_PWRST_D0 : parm);
694 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
695 mono_out ? AC_PWRST_D0 : parm);
702 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_info *uinfo)
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 struct via_spec *spec = codec->spec;
707 return snd_hda_input_mux_info(spec->input_mux, uinfo);
710 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
711 struct snd_ctl_elem_value *ucontrol)
713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
714 struct via_spec *spec = codec->spec;
715 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
717 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
721 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol)
724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
725 struct via_spec *spec = codec->spec;
726 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
728 if (!spec->mux_nids[adc_idx])
730 /* switch to D0 beofre change index */
731 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
732 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
733 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
734 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
735 /* update jack power state */
736 set_jack_power_state(codec);
738 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
739 spec->mux_nids[adc_idx],
740 &spec->cur_mux[adc_idx]);
743 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
744 struct snd_ctl_elem_info *uinfo)
746 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
747 struct via_spec *spec = codec->spec;
748 return snd_hda_input_mux_info(spec->hp_mux, uinfo);
751 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct via_spec *spec = codec->spec;
759 switch (spec->codec_type) {
764 nid = spec->autocfg.hp_pins[0];
767 /* use !! to translate conn sel 2 for VT1718S */
768 pinsel = !!snd_hda_codec_read(codec, nid, 0,
769 AC_VERB_GET_CONNECT_SEL,
771 ucontrol->value.enumerated.item[0] = pinsel;
776 static void activate_ctl(struct hda_codec *codec, const char *name, int active)
778 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
780 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
781 ctl->vd[0].access |= active
782 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
783 snd_ctl_notify(codec->bus->card,
784 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
788 static int update_side_mute_status(struct hda_codec *codec)
790 /* mute side channel */
791 struct via_spec *spec = codec->spec;
792 unsigned int parm = spec->hp_independent_mode
793 ? AMP_OUT_MUTE : AMP_OUT_UNMUTE;
796 switch (spec->codec_type) {
813 snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE,
818 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
819 struct snd_ctl_elem_value *ucontrol)
821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
822 struct via_spec *spec = codec->spec;
823 hda_nid_t nid = spec->autocfg.hp_pins[0];
824 unsigned int pinsel = ucontrol->value.enumerated.item[0];
825 /* Get Independent Mode index of headphone pin widget */
826 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
829 switch (spec->codec_type) {
832 pinsel = pinsel ? 2 : 0; /* indep HP use AOW4 (index 2) */
833 spec->multiout.num_dacs = 4;
836 nid = spec->autocfg.hp_pins[0];
839 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
841 if (spec->multiout.hp_nid && spec->multiout.hp_nid
842 != spec->multiout.dac_nids[HDA_FRONT])
843 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
846 update_side_mute_status(codec);
847 /* update HP volume/swtich active state */
848 if (spec->codec_type == VT1708S
849 || spec->codec_type == VT1702
850 || spec->codec_type == VT1718S
851 || spec->codec_type == VT1716S) {
852 activate_ctl(codec, "Headphone Playback Volume",
853 spec->hp_independent_mode);
854 activate_ctl(codec, "Headphone Playback Switch",
855 spec->hp_independent_mode);
860 static struct snd_kcontrol_new via_hp_mixer[] = {
862 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863 .name = "Independent HP",
865 .info = via_independent_hp_info,
866 .get = via_independent_hp_get,
867 .put = via_independent_hp_put,
872 static void notify_aa_path_ctls(struct hda_codec *codec)
875 struct snd_ctl_elem_id id;
876 const char *labels[] = {"Mic", "Front Mic", "Line"};
878 memset(&id, 0, sizeof(id));
879 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
880 for (i = 0; i < ARRAY_SIZE(labels); i++) {
881 sprintf(id.name, "%s Playback Volume", labels[i]);
882 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
887 static void mute_aa_path(struct hda_codec *codec, int mute)
889 struct via_spec *spec = codec->spec;
894 /* get nid of MW0 and start & end index */
895 switch (spec->codec_type) {
918 /* check AA path's mute status */
919 for (i = start_idx; i <= end_idx; i++) {
920 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
921 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i,
925 static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin)
929 for (index = AUTO_PIN_MIC; index < AUTO_PIN_FRONT_LINE; index++) {
930 if (pin == spec->autocfg.input_pins[index]) {
938 static int via_smart51_info(struct snd_kcontrol *kcontrol,
939 struct snd_ctl_elem_info *uinfo)
941 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
943 uinfo->value.integer.min = 0;
944 uinfo->value.integer.max = 1;
948 static int via_smart51_get(struct snd_kcontrol *kcontrol,
949 struct snd_ctl_elem_value *ucontrol)
951 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
952 struct via_spec *spec = codec->spec;
953 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
957 for (i = 0; i < ARRAY_SIZE(index); i++) {
958 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
961 snd_hda_codec_read(codec, nid, 0,
962 AC_VERB_GET_PIN_WIDGET_CONTROL,
964 if (i == AUTO_PIN_FRONT_MIC
965 && spec->hp_independent_mode
966 && spec->codec_type != VT1718S)
967 continue; /* ignore FMic for independent HP */
968 if (ctl & AC_PINCTL_IN_EN
969 && !(ctl & AC_PINCTL_OUT_EN))
973 *ucontrol->value.integer.value = on;
977 static int via_smart51_put(struct snd_kcontrol *kcontrol,
978 struct snd_ctl_elem_value *ucontrol)
980 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
981 struct via_spec *spec = codec->spec;
982 int out_in = *ucontrol->value.integer.value
983 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
984 int index[] = { AUTO_PIN_MIC, AUTO_PIN_FRONT_MIC, AUTO_PIN_LINE };
987 for (i = 0; i < ARRAY_SIZE(index); i++) {
988 hda_nid_t nid = spec->autocfg.input_pins[index[i]];
989 if (i == AUTO_PIN_FRONT_MIC
990 && spec->hp_independent_mode
991 && spec->codec_type != VT1718S)
992 continue; /* don't retask FMic for independent HP */
994 unsigned int parm = snd_hda_codec_read(
996 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
997 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
999 snd_hda_codec_write(codec, nid, 0,
1000 AC_VERB_SET_PIN_WIDGET_CONTROL,
1002 if (out_in == AC_PINCTL_OUT_EN) {
1003 mute_aa_path(codec, 1);
1004 notify_aa_path_ctls(codec);
1006 if (spec->codec_type == VT1718S)
1007 snd_hda_codec_amp_stereo(
1008 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1011 if (i == AUTO_PIN_FRONT_MIC) {
1012 if (spec->codec_type == VT1708S
1013 || spec->codec_type == VT1716S) {
1014 /* input = index 1 (AOW3) */
1015 snd_hda_codec_write(
1017 AC_VERB_SET_CONNECT_SEL, 1);
1018 snd_hda_codec_amp_stereo(
1019 codec, nid, HDA_OUTPUT,
1020 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1024 spec->smart51_enabled = *ucontrol->value.integer.value;
1025 set_jack_power_state(codec);
1029 static struct snd_kcontrol_new via_smart51_mixer[] = {
1031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1032 .name = "Smart 5.1",
1034 .info = via_smart51_info,
1035 .get = via_smart51_get,
1036 .put = via_smart51_put,
1041 /* capture mixer elements */
1042 static struct snd_kcontrol_new vt1708_capture_mixer[] = {
1043 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1044 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1045 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1046 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1049 /* The multiple "Capture Source" controls confuse alsamixer
1050 * So call somewhat different..
1052 /* .name = "Capture Source", */
1053 .name = "Input Source",
1055 .info = via_mux_enum_info,
1056 .get = via_mux_enum_get,
1057 .put = via_mux_enum_put,
1062 /* check AA path's mute statue */
1063 static int is_aa_path_mute(struct hda_codec *codec)
1066 hda_nid_t nid_mixer;
1070 struct via_spec *spec = codec->spec;
1071 /* get nid of MW0 and start & end index */
1072 switch (spec->codec_type) {
1094 /* check AA path's mute status */
1095 for (i = start_idx; i <= end_idx; i++) {
1096 unsigned int con_list = snd_hda_codec_read(
1097 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1098 int shift = 8 * (i % 4);
1099 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1100 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1101 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1102 /* check mute status while the pin is connected */
1103 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1105 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1107 if (!mute_l || !mute_r) {
1116 /* enter/exit analog low-current mode */
1117 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1119 struct via_spec *spec = codec->spec;
1120 static int saved_stream_idle = 1; /* saved stream idle status */
1121 int enable = is_aa_path_mute(codec);
1122 unsigned int verb = 0;
1123 unsigned int parm = 0;
1125 if (stream_idle == -1) /* stream status did not change */
1126 enable = enable && saved_stream_idle;
1128 enable = enable && stream_idle;
1129 saved_stream_idle = stream_idle;
1132 /* decide low current mode's verb & parameter */
1133 switch (spec->codec_type) {
1137 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1143 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1147 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1150 return; /* other codecs are not supported */
1153 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1157 * generic initialization of ADC, input mixers and output mixers
1159 static struct hda_verb vt1708_volume_init_verbs[] = {
1161 * Unmute ADC0-1 and set the default input to mic-in
1163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1164 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1167 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1170 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1171 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1172 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1173 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1174 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1175 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1178 * Set up output mixers (0x19 - 0x1b)
1180 /* set vol=0 to output mixers */
1181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1185 /* Setup default input to PW4 */
1186 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
1187 /* PW9 Output enable */
1188 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1192 static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
1193 struct hda_codec *codec,
1194 struct snd_pcm_substream *substream)
1196 struct via_spec *spec = codec->spec;
1197 int idle = substream->pstr->substream_opened == 1
1198 && substream->ref_count == 0;
1199 analog_low_current_mode(codec, idle);
1200 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1204 static void playback_multi_pcm_prep_0(struct hda_codec *codec,
1205 unsigned int stream_tag,
1206 unsigned int format,
1207 struct snd_pcm_substream *substream)
1209 struct via_spec *spec = codec->spec;
1210 struct hda_multi_out *mout = &spec->multiout;
1211 hda_nid_t *nids = mout->dac_nids;
1212 int chs = substream->runtime->channels;
1215 mutex_lock(&codec->spdif_mutex);
1216 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
1218 snd_hda_is_supported_format(codec, mout->dig_out_nid,
1220 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
1221 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
1222 /* turn off SPDIF once; otherwise the IEC958 bits won't
1224 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1225 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1226 AC_VERB_SET_DIGI_CONVERT_1,
1228 ~AC_DIG1_ENABLE & 0xff);
1229 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1230 stream_tag, 0, format);
1231 /* turn on again (if needed) */
1232 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1233 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1234 AC_VERB_SET_DIGI_CONVERT_1,
1235 codec->spdif_ctls & 0xff);
1237 mout->dig_out_used = 0;
1238 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1242 mutex_unlock(&codec->spdif_mutex);
1245 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1248 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1249 && !spec->hp_independent_mode)
1250 /* headphone out will just decode front left/right (stereo) */
1251 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1254 /* extra outputs copied from front */
1255 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1256 if (mout->extra_out_nid[i])
1257 snd_hda_codec_setup_stream(codec,
1258 mout->extra_out_nid[i],
1259 stream_tag, 0, format);
1262 for (i = 1; i < mout->num_dacs; i++) {
1263 if (chs >= (i + 1) * 2) /* independent out */
1264 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1266 else /* copy front */
1267 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1272 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1273 struct hda_codec *codec,
1274 unsigned int stream_tag,
1275 unsigned int format,
1276 struct snd_pcm_substream *substream)
1278 struct via_spec *spec = codec->spec;
1279 struct hda_multi_out *mout = &spec->multiout;
1280 hda_nid_t *nids = mout->dac_nids;
1282 if (substream->number == 0)
1283 playback_multi_pcm_prep_0(codec, stream_tag, format,
1286 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1287 spec->hp_independent_mode)
1288 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1289 stream_tag, 0, format);
1291 vt1708_start_hp_work(spec);
1295 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1296 struct hda_codec *codec,
1297 struct snd_pcm_substream *substream)
1299 struct via_spec *spec = codec->spec;
1300 struct hda_multi_out *mout = &spec->multiout;
1301 hda_nid_t *nids = mout->dac_nids;
1304 if (substream->number == 0) {
1305 for (i = 0; i < mout->num_dacs; i++)
1306 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0);
1308 if (mout->hp_nid && !spec->hp_independent_mode)
1309 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1312 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1313 if (mout->extra_out_nid[i])
1314 snd_hda_codec_setup_stream(codec,
1315 mout->extra_out_nid[i],
1317 mutex_lock(&codec->spdif_mutex);
1318 if (mout->dig_out_nid &&
1319 mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
1320 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1322 mout->dig_out_used = 0;
1324 mutex_unlock(&codec->spdif_mutex);
1326 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1327 spec->hp_independent_mode)
1328 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1331 vt1708_stop_hp_work(spec);
1338 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1339 struct hda_codec *codec,
1340 struct snd_pcm_substream *substream)
1342 struct via_spec *spec = codec->spec;
1343 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1346 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1347 struct hda_codec *codec,
1348 struct snd_pcm_substream *substream)
1350 struct via_spec *spec = codec->spec;
1351 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1354 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1355 struct hda_codec *codec,
1356 unsigned int stream_tag,
1357 unsigned int format,
1358 struct snd_pcm_substream *substream)
1360 struct via_spec *spec = codec->spec;
1361 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1362 stream_tag, format, substream);
1365 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1366 struct hda_codec *codec,
1367 struct snd_pcm_substream *substream)
1369 struct via_spec *spec = codec->spec;
1370 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1377 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1378 struct hda_codec *codec,
1379 unsigned int stream_tag,
1380 unsigned int format,
1381 struct snd_pcm_substream *substream)
1383 struct via_spec *spec = codec->spec;
1385 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1386 stream_tag, 0, format);
1390 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1391 struct hda_codec *codec,
1392 struct snd_pcm_substream *substream)
1394 struct via_spec *spec = codec->spec;
1395 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1399 static struct hda_pcm_stream vt1708_pcm_analog_playback = {
1403 .nid = 0x10, /* NID to query formats and rates */
1405 .open = via_playback_pcm_open,
1406 .prepare = via_playback_multi_pcm_prepare,
1407 .cleanup = via_playback_multi_pcm_cleanup
1411 static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1415 .nid = 0x10, /* NID to query formats and rates */
1416 /* We got noisy outputs on the right channel on VT1708 when
1417 * 24bit samples are used. Until any workaround is found,
1418 * disable the 24bit format, so far.
1420 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1422 .open = via_playback_pcm_open,
1423 .prepare = via_playback_multi_pcm_prepare,
1424 .cleanup = via_playback_multi_pcm_cleanup
1428 static struct hda_pcm_stream vt1708_pcm_analog_capture = {
1432 .nid = 0x15, /* NID to query formats and rates */
1434 .prepare = via_capture_pcm_prepare,
1435 .cleanup = via_capture_pcm_cleanup
1439 static struct hda_pcm_stream vt1708_pcm_digital_playback = {
1443 /* NID is set in via_build_pcms */
1445 .open = via_dig_playback_pcm_open,
1446 .close = via_dig_playback_pcm_close,
1447 .prepare = via_dig_playback_pcm_prepare,
1448 .cleanup = via_dig_playback_pcm_cleanup
1452 static struct hda_pcm_stream vt1708_pcm_digital_capture = {
1458 static int via_build_controls(struct hda_codec *codec)
1460 struct via_spec *spec = codec->spec;
1464 for (i = 0; i < spec->num_mixers; i++) {
1465 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1470 if (spec->multiout.dig_out_nid) {
1471 err = snd_hda_create_spdif_out_ctls(codec,
1472 spec->multiout.dig_out_nid);
1475 err = snd_hda_create_spdif_share_sw(codec,
1479 spec->multiout.share_spdif = 1;
1481 if (spec->dig_in_nid) {
1482 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1487 /* init power states */
1488 set_jack_power_state(codec);
1489 analog_low_current_mode(codec, 1);
1491 via_free_kctls(codec); /* no longer needed */
1495 static int via_build_pcms(struct hda_codec *codec)
1497 struct via_spec *spec = codec->spec;
1498 struct hda_pcm *info = spec->pcm_rec;
1500 codec->num_pcms = 1;
1501 codec->pcm_info = info;
1503 info->name = spec->stream_name_analog;
1504 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
1505 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
1506 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1507 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1509 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1510 spec->multiout.max_channels;
1512 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1515 info->name = spec->stream_name_digital;
1516 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1517 if (spec->multiout.dig_out_nid) {
1518 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1519 *(spec->stream_digital_playback);
1520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1521 spec->multiout.dig_out_nid;
1523 if (spec->dig_in_nid) {
1524 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1525 *(spec->stream_digital_capture);
1526 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1534 static void via_free(struct hda_codec *codec)
1536 struct via_spec *spec = codec->spec;
1541 via_free_kctls(codec);
1542 vt1708_stop_hp_work(spec);
1546 /* mute internal speaker if HP is plugged */
1547 static void via_hp_automute(struct hda_codec *codec)
1549 unsigned int present = 0;
1550 struct via_spec *spec = codec->spec;
1552 present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0,
1553 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1555 if (!spec->hp_independent_mode) {
1556 struct snd_ctl_elem_id id;
1558 snd_hda_codec_amp_stereo(
1559 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0,
1560 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1562 memset(&id, 0, sizeof(id));
1563 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1564 strcpy(id.name, "Front Playback Switch");
1565 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1570 /* mute mono out if HP or Line out is plugged */
1571 static void via_mono_automute(struct hda_codec *codec)
1573 unsigned int hp_present, lineout_present;
1574 struct via_spec *spec = codec->spec;
1576 if (spec->codec_type != VT1716S)
1579 lineout_present = snd_hda_codec_read(
1580 codec, spec->autocfg.line_out_pins[0], 0,
1581 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1583 /* Mute Mono Out if Line Out is plugged */
1584 if (lineout_present) {
1585 snd_hda_codec_amp_stereo(
1586 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE);
1590 hp_present = snd_hda_codec_read(
1591 codec, spec->autocfg.hp_pins[0], 0,
1592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1594 if (!spec->hp_independent_mode)
1595 snd_hda_codec_amp_stereo(
1596 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1597 hp_present ? HDA_AMP_MUTE : 0);
1600 static void via_gpio_control(struct hda_codec *codec)
1602 unsigned int gpio_data;
1603 unsigned int vol_counter;
1605 unsigned int master_vol;
1607 struct via_spec *spec = codec->spec;
1609 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
1610 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
1612 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
1613 0xF84, 0) & 0x3F0000) >> 16;
1615 vol = vol_counter & 0x1F;
1616 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
1617 AC_VERB_GET_AMP_GAIN_MUTE,
1620 if (gpio_data == 0x02) {
1621 /* unmute line out */
1622 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0],
1623 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
1625 if (vol_counter & 0x20) {
1626 /* decrease volume */
1627 if (vol > master_vol)
1629 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1633 /* increase volume */
1634 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1636 ((master_vol+vol) > 0x2A) ? 0x2A :
1639 } else if (!(gpio_data & 0x02)) {
1641 snd_hda_codec_amp_stereo(codec,
1642 spec->autocfg.line_out_pins[0],
1643 HDA_OUTPUT, 0, HDA_AMP_MUTE,
1648 /* unsolicited event for jack sensing */
1649 static void via_unsol_event(struct hda_codec *codec,
1653 if (res & VIA_HP_EVENT)
1654 via_hp_automute(codec);
1655 if (res & VIA_GPIO_EVENT)
1656 via_gpio_control(codec);
1657 if (res & VIA_JACK_EVENT)
1658 set_jack_power_state(codec);
1659 if (res & VIA_MONO_EVENT)
1660 via_mono_automute(codec);
1663 static int via_init(struct hda_codec *codec)
1665 struct via_spec *spec = codec->spec;
1667 for (i = 0; i < spec->num_iverbs; i++)
1668 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1670 spec->codec_type = get_codec_type(codec);
1671 if (spec->codec_type == VT1708BCE)
1672 spec->codec_type = VT1708S; /* VT1708BCE & VT1708S are almost
1674 /* Lydia Add for EAPD enable */
1675 if (!spec->dig_in_nid) { /* No Digital In connection */
1676 if (spec->dig_in_pin) {
1677 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1678 AC_VERB_SET_PIN_WIDGET_CONTROL,
1680 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1681 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1683 } else /* enable SPDIF-input pin */
1684 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1685 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1687 /* assign slave outs */
1688 if (spec->slave_dig_outs[0])
1689 codec->slave_dig_outs = spec->slave_dig_outs;
1694 #ifdef SND_HDA_NEEDS_RESUME
1695 static int via_suspend(struct hda_codec *codec, pm_message_t state)
1697 struct via_spec *spec = codec->spec;
1698 vt1708_stop_hp_work(spec);
1703 #ifdef CONFIG_SND_HDA_POWER_SAVE
1704 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1706 struct via_spec *spec = codec->spec;
1707 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1713 static struct hda_codec_ops via_patch_ops = {
1714 .build_controls = via_build_controls,
1715 .build_pcms = via_build_pcms,
1718 #ifdef SND_HDA_NEEDS_RESUME
1719 .suspend = via_suspend,
1721 #ifdef CONFIG_SND_HDA_POWER_SAVE
1722 .check_power_status = via_check_power_status,
1726 /* fill in the dac_nids table from the parsed pin configuration */
1727 static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1728 const struct auto_pin_cfg *cfg)
1733 spec->multiout.num_dacs = cfg->line_outs;
1735 spec->multiout.dac_nids = spec->private_dac_nids;
1737 for(i = 0; i < 4; i++) {
1738 nid = cfg->line_out_pins[i];
1740 /* config dac list */
1742 case AUTO_SEQ_FRONT:
1743 spec->multiout.dac_nids[i] = 0x10;
1745 case AUTO_SEQ_CENLFE:
1746 spec->multiout.dac_nids[i] = 0x12;
1748 case AUTO_SEQ_SURROUND:
1749 spec->multiout.dac_nids[i] = 0x11;
1752 spec->multiout.dac_nids[i] = 0x13;
1761 /* add playback controls from the parsed DAC table */
1762 static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
1763 const struct auto_pin_cfg *cfg)
1766 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1767 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
1770 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1771 nid = cfg->line_out_pins[i];
1776 nid_vol = nid_vols[i];
1778 if (i == AUTO_SEQ_CENLFE) {
1780 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1781 "Center Playback Volume",
1782 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1786 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1787 "LFE Playback Volume",
1788 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1792 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1793 "Center Playback Switch",
1794 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1798 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1799 "LFE Playback Switch",
1800 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1804 } else if (i == AUTO_SEQ_FRONT){
1805 /* add control to mixer index 0 */
1806 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1807 "Master Front Playback Volume",
1808 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1812 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1813 "Master Front Playback Switch",
1814 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1819 /* add control to PW3 */
1820 sprintf(name, "%s Playback Volume", chname[i]);
1821 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1822 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1826 sprintf(name, "%s Playback Switch", chname[i]);
1827 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1828 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1833 sprintf(name, "%s Playback Volume", chname[i]);
1834 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1835 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1839 sprintf(name, "%s Playback Switch", chname[i]);
1840 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1841 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1851 static void create_hp_imux(struct via_spec *spec)
1854 struct hda_input_mux *imux = &spec->private_imux[1];
1855 static const char *texts[] = { "OFF", "ON", NULL};
1857 /* for hp mode select */
1859 while (texts[i] != NULL) {
1860 imux->items[imux->num_items].label = texts[i];
1861 imux->items[imux->num_items].index = i;
1866 spec->hp_mux = &spec->private_imux[1];
1869 static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1876 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
1877 spec->hp_independent_mode_index = 1;
1879 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1880 "Headphone Playback Volume",
1881 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1884 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1885 "Headphone Playback Switch",
1886 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1890 create_hp_imux(spec);
1895 /* create playback/capture controls for input pins */
1896 static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
1897 const struct auto_pin_cfg *cfg)
1899 static char *labels[] = {
1900 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1902 struct hda_input_mux *imux = &spec->private_imux[0];
1903 int i, err, idx = 0;
1905 /* for internal loopback recording select */
1906 imux->items[imux->num_items].label = "Stereo Mixer";
1907 imux->items[imux->num_items].index = idx;
1910 for (i = 0; i < AUTO_PIN_LAST; i++) {
1911 if (!cfg->input_pins[i])
1914 switch (cfg->input_pins[i]) {
1915 case 0x1d: /* Mic */
1919 case 0x1e: /* Line In */
1923 case 0x21: /* Front Mic */
1931 err = via_new_analog_input(spec, labels[i], idx, 0x17);
1934 imux->items[imux->num_items].label = labels[i];
1935 imux->items[imux->num_items].index = idx;
1941 #ifdef CONFIG_SND_HDA_POWER_SAVE
1942 static struct hda_amp_list vt1708_loopbacks[] = {
1943 { 0x17, HDA_INPUT, 1 },
1944 { 0x17, HDA_INPUT, 2 },
1945 { 0x17, HDA_INPUT, 3 },
1946 { 0x17, HDA_INPUT, 4 },
1951 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
1953 unsigned int def_conf;
1954 unsigned char seqassoc;
1956 def_conf = snd_hda_codec_get_pincfg(codec, nid);
1957 seqassoc = (unsigned char) get_defcfg_association(def_conf);
1958 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
1959 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
1960 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
1961 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
1962 snd_hda_codec_set_pincfg(codec, nid, def_conf);
1968 static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
1969 struct snd_ctl_elem_value *ucontrol)
1971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1972 struct via_spec *spec = codec->spec;
1974 if (spec->codec_type != VT1708)
1976 spec->vt1708_jack_detectect =
1977 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
1978 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
1982 static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
1983 struct snd_ctl_elem_value *ucontrol)
1985 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1986 struct via_spec *spec = codec->spec;
1989 if (spec->codec_type != VT1708)
1991 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0];
1992 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
1993 == !spec->vt1708_jack_detectect;
1994 if (spec->vt1708_jack_detectect) {
1995 mute_aa_path(codec, 1);
1996 notify_aa_path_ctls(codec);
2001 static struct snd_kcontrol_new vt1708_jack_detectect[] = {
2003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2004 .name = "Jack Detect",
2006 .info = snd_ctl_boolean_mono_info,
2007 .get = vt1708_jack_detectect_get,
2008 .put = vt1708_jack_detectect_put,
2013 static int vt1708_parse_auto_config(struct hda_codec *codec)
2015 struct via_spec *spec = codec->spec;
2018 /* Add HP and CD pin config connect bit re-config action */
2019 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2020 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2022 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2025 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2028 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2029 return 0; /* can't find valid BIOS pin config */
2031 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
2034 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2037 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
2040 /* add jack detect on/off control */
2041 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect);
2045 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2047 if (spec->autocfg.dig_outs)
2048 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
2049 spec->dig_in_pin = VT1708_DIGIN_PIN;
2050 if (spec->autocfg.dig_in_pin)
2051 spec->dig_in_nid = VT1708_DIGIN_NID;
2053 if (spec->kctls.list)
2054 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2056 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2058 spec->input_mux = &spec->private_imux[0];
2061 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2063 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
2067 /* init callback for auto-configuration model -- overriding the default init */
2068 static int via_auto_init(struct hda_codec *codec)
2071 via_auto_init_multi_out(codec);
2072 via_auto_init_hp_out(codec);
2073 via_auto_init_analog_input(codec);
2077 static void vt1708_update_hp_jack_state(struct work_struct *work)
2079 struct via_spec *spec = container_of(work, struct via_spec,
2080 vt1708_hp_work.work);
2081 if (spec->codec_type != VT1708)
2083 /* if jack state toggled */
2084 if (spec->vt1708_hp_present
2085 != (snd_hda_codec_read(spec->codec, spec->autocfg.hp_pins[0], 0,
2086 AC_VERB_GET_PIN_SENSE, 0) >> 31)) {
2087 spec->vt1708_hp_present ^= 1;
2088 via_hp_automute(spec->codec);
2090 vt1708_start_hp_work(spec);
2093 static int get_mux_nids(struct hda_codec *codec)
2095 struct via_spec *spec = codec->spec;
2096 hda_nid_t nid, conn[8];
2100 for (i = 0; i < spec->num_adc_nids; i++) {
2101 nid = spec->adc_nids[i];
2103 type = get_wcaps_type(get_wcaps(codec, nid));
2104 if (type == AC_WID_PIN)
2106 n = snd_hda_get_connections(codec, nid, conn,
2111 spec->mux_nids[i] = nid;
2120 static int patch_vt1708(struct hda_codec *codec)
2122 struct via_spec *spec;
2125 /* create a codec specific record */
2126 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2132 /* automatic parse from the BIOS config */
2133 err = vt1708_parse_auto_config(codec);
2138 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2139 "from BIOS. Using genenic mode...\n");
2143 spec->stream_name_analog = "VT1708 Analog";
2144 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2145 /* disable 32bit format on VT1708 */
2146 if (codec->vendor_id == 0x11061708)
2147 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2148 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2150 spec->stream_name_digital = "VT1708 Digital";
2151 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2152 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2155 if (!spec->adc_nids && spec->input_mux) {
2156 spec->adc_nids = vt1708_adc_nids;
2157 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2158 get_mux_nids(codec);
2159 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2163 codec->patch_ops = via_patch_ops;
2165 codec->patch_ops.init = via_auto_init;
2166 #ifdef CONFIG_SND_HDA_POWER_SAVE
2167 spec->loopback.amplist = vt1708_loopbacks;
2169 spec->codec = codec;
2170 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2174 /* capture mixer elements */
2175 static struct snd_kcontrol_new vt1709_capture_mixer[] = {
2176 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2177 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2180 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2181 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2184 /* The multiple "Capture Source" controls confuse alsamixer
2185 * So call somewhat different..
2187 /* .name = "Capture Source", */
2188 .name = "Input Source",
2190 .info = via_mux_enum_info,
2191 .get = via_mux_enum_get,
2192 .put = via_mux_enum_put,
2197 static struct hda_verb vt1709_uniwill_init_verbs[] = {
2198 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2199 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2204 * generic initialization of ADC, input mixers and output mixers
2206 static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2208 * Unmute ADC0-2 and set the default input to mic-in
2210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2211 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2212 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2215 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2218 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2219 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2221 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2222 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2223 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2226 * Set up output selector (0x1a, 0x1b, 0x29)
2228 /* set vol=0 to output mixers */
2229 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2230 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2231 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2234 * Unmute PW3 and PW4
2236 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2237 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2239 /* Set input of PW4 as AOW4 */
2240 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
2241 /* PW9 Output enable */
2242 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2246 static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2250 .nid = 0x10, /* NID to query formats and rates */
2252 .open = via_playback_pcm_open,
2253 .prepare = via_playback_multi_pcm_prepare,
2254 .cleanup = via_playback_multi_pcm_cleanup,
2258 static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2262 .nid = 0x10, /* NID to query formats and rates */
2264 .open = via_playback_pcm_open,
2265 .prepare = via_playback_multi_pcm_prepare,
2266 .cleanup = via_playback_multi_pcm_cleanup,
2270 static struct hda_pcm_stream vt1709_pcm_analog_capture = {
2274 .nid = 0x14, /* NID to query formats and rates */
2276 .prepare = via_capture_pcm_prepare,
2277 .cleanup = via_capture_pcm_cleanup
2281 static struct hda_pcm_stream vt1709_pcm_digital_playback = {
2285 /* NID is set in via_build_pcms */
2287 .open = via_dig_playback_pcm_open,
2288 .close = via_dig_playback_pcm_close
2292 static struct hda_pcm_stream vt1709_pcm_digital_capture = {
2298 static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2299 const struct auto_pin_cfg *cfg)
2304 if (cfg->line_outs == 4) /* 10 channels */
2305 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2306 else if (cfg->line_outs == 3) /* 6 channels */
2307 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2309 spec->multiout.dac_nids = spec->private_dac_nids;
2311 if (cfg->line_outs == 4) { /* 10 channels */
2312 for (i = 0; i < cfg->line_outs; i++) {
2313 nid = cfg->line_out_pins[i];
2315 /* config dac list */
2317 case AUTO_SEQ_FRONT:
2319 spec->multiout.dac_nids[i] = 0x10;
2321 case AUTO_SEQ_CENLFE:
2323 spec->multiout.dac_nids[i] = 0x12;
2325 case AUTO_SEQ_SURROUND:
2327 spec->multiout.dac_nids[i] = 0x11;
2331 spec->multiout.dac_nids[i] = 0x27;
2338 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2340 } else if (cfg->line_outs == 3) { /* 6 channels */
2341 for(i = 0; i < cfg->line_outs; i++) {
2342 nid = cfg->line_out_pins[i];
2344 /* config dac list */
2346 case AUTO_SEQ_FRONT:
2348 spec->multiout.dac_nids[i] = 0x10;
2350 case AUTO_SEQ_CENLFE:
2352 spec->multiout.dac_nids[i] = 0x12;
2354 case AUTO_SEQ_SURROUND:
2356 spec->multiout.dac_nids[i] = 0x11;
2368 /* add playback controls from the parsed DAC table */
2369 static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2370 const struct auto_pin_cfg *cfg)
2373 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2374 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2377 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2378 nid = cfg->line_out_pins[i];
2383 nid_vol = nid_vols[i];
2385 if (i == AUTO_SEQ_CENLFE) {
2387 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2388 "Center Playback Volume",
2389 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2393 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2394 "LFE Playback Volume",
2395 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2399 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2400 "Center Playback Switch",
2401 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2405 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2406 "LFE Playback Switch",
2407 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2411 } else if (i == AUTO_SEQ_FRONT){
2412 /* ADD control to mixer index 0 */
2413 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2414 "Master Front Playback Volume",
2415 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2419 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2420 "Master Front Playback Switch",
2421 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2426 /* add control to PW3 */
2427 sprintf(name, "%s Playback Volume", chname[i]);
2428 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2429 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2433 sprintf(name, "%s Playback Switch", chname[i]);
2434 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2435 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2439 } else if (i == AUTO_SEQ_SURROUND) {
2440 sprintf(name, "%s Playback Volume", chname[i]);
2441 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2442 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2446 sprintf(name, "%s Playback Switch", chname[i]);
2447 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2448 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2452 } else if (i == AUTO_SEQ_SIDE) {
2453 sprintf(name, "%s Playback Volume", chname[i]);
2454 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2455 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2459 sprintf(name, "%s Playback Switch", chname[i]);
2460 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2461 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2471 static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2478 if (spec->multiout.num_dacs == 5) /* 10 channels */
2479 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
2480 else if (spec->multiout.num_dacs == 3) /* 6 channels */
2481 spec->multiout.hp_nid = 0;
2482 spec->hp_independent_mode_index = 1;
2484 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2485 "Headphone Playback Volume",
2486 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2489 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2490 "Headphone Playback Switch",
2491 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2498 /* create playback/capture controls for input pins */
2499 static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
2500 const struct auto_pin_cfg *cfg)
2502 static char *labels[] = {
2503 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
2505 struct hda_input_mux *imux = &spec->private_imux[0];
2506 int i, err, idx = 0;
2508 /* for internal loopback recording select */
2509 imux->items[imux->num_items].label = "Stereo Mixer";
2510 imux->items[imux->num_items].index = idx;
2513 for (i = 0; i < AUTO_PIN_LAST; i++) {
2514 if (!cfg->input_pins[i])
2517 switch (cfg->input_pins[i]) {
2518 case 0x1d: /* Mic */
2522 case 0x1e: /* Line In */
2526 case 0x21: /* Front Mic */
2534 err = via_new_analog_input(spec, labels[i], idx, 0x18);
2537 imux->items[imux->num_items].label = labels[i];
2538 imux->items[imux->num_items].index = idx;
2544 static int vt1709_parse_auto_config(struct hda_codec *codec)
2546 struct via_spec *spec = codec->spec;
2549 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2552 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
2555 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2556 return 0; /* can't find valid BIOS pin config */
2558 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
2561 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2564 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
2568 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2570 if (spec->autocfg.dig_outs)
2571 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
2572 spec->dig_in_pin = VT1709_DIGIN_PIN;
2573 if (spec->autocfg.dig_in_pin)
2574 spec->dig_in_nid = VT1709_DIGIN_NID;
2576 if (spec->kctls.list)
2577 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2579 spec->input_mux = &spec->private_imux[0];
2582 spec->mixers[spec->num_mixers++] = via_hp_mixer;
2584 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
2588 #ifdef CONFIG_SND_HDA_POWER_SAVE
2589 static struct hda_amp_list vt1709_loopbacks[] = {
2590 { 0x18, HDA_INPUT, 1 },
2591 { 0x18, HDA_INPUT, 2 },
2592 { 0x18, HDA_INPUT, 3 },
2593 { 0x18, HDA_INPUT, 4 },
2598 static int patch_vt1709_10ch(struct hda_codec *codec)
2600 struct via_spec *spec;
2603 /* create a codec specific record */
2604 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2610 err = vt1709_parse_auto_config(codec);
2615 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2616 "Using genenic mode...\n");
2619 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
2620 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2622 spec->stream_name_analog = "VT1709 Analog";
2623 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
2624 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2626 spec->stream_name_digital = "VT1709 Digital";
2627 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2628 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2631 if (!spec->adc_nids && spec->input_mux) {
2632 spec->adc_nids = vt1709_adc_nids;
2633 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2634 get_mux_nids(codec);
2635 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2639 codec->patch_ops = via_patch_ops;
2641 codec->patch_ops.init = via_auto_init;
2642 codec->patch_ops.unsol_event = via_unsol_event;
2643 #ifdef CONFIG_SND_HDA_POWER_SAVE
2644 spec->loopback.amplist = vt1709_loopbacks;
2650 * generic initialization of ADC, input mixers and output mixers
2652 static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
2654 * Unmute ADC0-2 and set the default input to mic-in
2656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2658 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2661 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2664 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2666 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2667 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2672 * Set up output selector (0x1a, 0x1b, 0x29)
2674 /* set vol=0 to output mixers */
2675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2677 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2680 * Unmute PW3 and PW4
2682 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2683 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2685 /* Set input of PW4 as MW0 */
2686 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2687 /* PW9 Output enable */
2688 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2692 static int patch_vt1709_6ch(struct hda_codec *codec)
2694 struct via_spec *spec;
2697 /* create a codec specific record */
2698 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2704 err = vt1709_parse_auto_config(codec);
2709 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2710 "Using genenic mode...\n");
2713 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
2714 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2716 spec->stream_name_analog = "VT1709 Analog";
2717 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
2718 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2720 spec->stream_name_digital = "VT1709 Digital";
2721 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2722 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2725 if (!spec->adc_nids && spec->input_mux) {
2726 spec->adc_nids = vt1709_adc_nids;
2727 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2728 get_mux_nids(codec);
2729 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2733 codec->patch_ops = via_patch_ops;
2735 codec->patch_ops.init = via_auto_init;
2736 codec->patch_ops.unsol_event = via_unsol_event;
2737 #ifdef CONFIG_SND_HDA_POWER_SAVE
2738 spec->loopback.amplist = vt1709_loopbacks;
2743 /* capture mixer elements */
2744 static struct snd_kcontrol_new vt1708B_capture_mixer[] = {
2745 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2746 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2747 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2748 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2751 /* The multiple "Capture Source" controls confuse alsamixer
2752 * So call somewhat different..
2754 /* .name = "Capture Source", */
2755 .name = "Input Source",
2757 .info = via_mux_enum_info,
2758 .get = via_mux_enum_get,
2759 .put = via_mux_enum_put,
2764 * generic initialization of ADC, input mixers and output mixers
2766 static struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
2768 * Unmute ADC0-1 and set the default input to mic-in
2770 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2774 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2777 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2778 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2779 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2781 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2782 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2785 * Set up output mixers
2787 /* set vol=0 to output mixers */
2788 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2789 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2790 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2792 /* Setup default input to PW4 */
2793 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1},
2794 /* PW9 Output enable */
2795 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2796 /* PW10 Input enable */
2797 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2801 static struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2803 * Unmute ADC0-1 and set the default input to mic-in
2805 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2809 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2812 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2813 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2815 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2816 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2820 * Set up output mixers
2822 /* set vol=0 to output mixers */
2823 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2824 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2825 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2827 /* Setup default input of PW4 to MW0 */
2828 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2829 /* PW9 Output enable */
2830 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2831 /* PW10 Input enable */
2832 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2836 static struct hda_verb vt1708B_uniwill_init_verbs[] = {
2837 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
2838 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2839 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2840 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2841 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2842 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2843 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2844 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2845 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2849 static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
2850 struct hda_codec *codec,
2851 struct snd_pcm_substream *substream)
2853 int idle = substream->pstr->substream_opened == 1
2854 && substream->ref_count == 0;
2856 analog_low_current_mode(codec, idle);
2860 static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2864 .nid = 0x10, /* NID to query formats and rates */
2866 .open = via_playback_pcm_open,
2867 .prepare = via_playback_multi_pcm_prepare,
2868 .cleanup = via_playback_multi_pcm_cleanup,
2869 .close = via_pcm_open_close
2873 static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2877 .nid = 0x10, /* NID to query formats and rates */
2879 .open = via_playback_pcm_open,
2880 .prepare = via_playback_multi_pcm_prepare,
2881 .cleanup = via_playback_multi_pcm_cleanup
2885 static struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2889 .nid = 0x13, /* NID to query formats and rates */
2891 .open = via_pcm_open_close,
2892 .prepare = via_capture_pcm_prepare,
2893 .cleanup = via_capture_pcm_cleanup,
2894 .close = via_pcm_open_close
2898 static struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2902 /* NID is set in via_build_pcms */
2904 .open = via_dig_playback_pcm_open,
2905 .close = via_dig_playback_pcm_close,
2906 .prepare = via_dig_playback_pcm_prepare,
2907 .cleanup = via_dig_playback_pcm_cleanup
2911 static struct hda_pcm_stream vt1708B_pcm_digital_capture = {
2917 /* fill in the dac_nids table from the parsed pin configuration */
2918 static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
2919 const struct auto_pin_cfg *cfg)
2924 spec->multiout.num_dacs = cfg->line_outs;
2926 spec->multiout.dac_nids = spec->private_dac_nids;
2928 for (i = 0; i < 4; i++) {
2929 nid = cfg->line_out_pins[i];
2931 /* config dac list */
2933 case AUTO_SEQ_FRONT:
2934 spec->multiout.dac_nids[i] = 0x10;
2936 case AUTO_SEQ_CENLFE:
2937 spec->multiout.dac_nids[i] = 0x24;
2939 case AUTO_SEQ_SURROUND:
2940 spec->multiout.dac_nids[i] = 0x11;
2943 spec->multiout.dac_nids[i] = 0x25;
2952 /* add playback controls from the parsed DAC table */
2953 static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
2954 const struct auto_pin_cfg *cfg)
2957 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
2958 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
2959 hda_nid_t nid, nid_vol = 0;
2962 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2963 nid = cfg->line_out_pins[i];
2968 nid_vol = nid_vols[i];
2970 if (i == AUTO_SEQ_CENLFE) {
2972 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2973 "Center Playback Volume",
2974 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2978 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2979 "LFE Playback Volume",
2980 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2984 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2985 "Center Playback Switch",
2986 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2990 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2991 "LFE Playback Switch",
2992 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2996 } else if (i == AUTO_SEQ_FRONT) {
2997 /* add control to mixer index 0 */
2998 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2999 "Master Front Playback Volume",
3000 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3004 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3005 "Master Front Playback Switch",
3006 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3011 /* add control to PW3 */
3012 sprintf(name, "%s Playback Volume", chname[i]);
3013 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3014 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3018 sprintf(name, "%s Playback Switch", chname[i]);
3019 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3020 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3025 sprintf(name, "%s Playback Volume", chname[i]);
3026 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3027 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3031 sprintf(name, "%s Playback Switch", chname[i]);
3032 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3033 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3043 static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3050 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3051 spec->hp_independent_mode_index = 1;
3053 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3054 "Headphone Playback Volume",
3055 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3058 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3059 "Headphone Playback Switch",
3060 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3064 create_hp_imux(spec);
3069 /* create playback/capture controls for input pins */
3070 static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec,
3071 const struct auto_pin_cfg *cfg)
3073 static char *labels[] = {
3074 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3076 struct hda_input_mux *imux = &spec->private_imux[0];
3077 int i, err, idx = 0;
3079 /* for internal loopback recording select */
3080 imux->items[imux->num_items].label = "Stereo Mixer";
3081 imux->items[imux->num_items].index = idx;
3084 for (i = 0; i < AUTO_PIN_LAST; i++) {
3085 if (!cfg->input_pins[i])
3088 switch (cfg->input_pins[i]) {
3089 case 0x1a: /* Mic */
3093 case 0x1b: /* Line In */
3097 case 0x1e: /* Front Mic */
3105 err = via_new_analog_input(spec, labels[i], idx, 0x16);
3108 imux->items[imux->num_items].label = labels[i];
3109 imux->items[imux->num_items].index = idx;
3115 static int vt1708B_parse_auto_config(struct hda_codec *codec)
3117 struct via_spec *spec = codec->spec;
3120 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3123 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3126 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3127 return 0; /* can't find valid BIOS pin config */
3129 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3132 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3135 err = vt1708B_auto_create_analog_input_ctls(spec, &spec->autocfg);
3139 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3141 if (spec->autocfg.dig_outs)
3142 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3143 spec->dig_in_pin = VT1708B_DIGIN_PIN;
3144 if (spec->autocfg.dig_in_pin)
3145 spec->dig_in_nid = VT1708B_DIGIN_NID;
3147 if (spec->kctls.list)
3148 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3150 spec->input_mux = &spec->private_imux[0];
3153 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3155 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
3159 #ifdef CONFIG_SND_HDA_POWER_SAVE
3160 static struct hda_amp_list vt1708B_loopbacks[] = {
3161 { 0x16, HDA_INPUT, 1 },
3162 { 0x16, HDA_INPUT, 2 },
3163 { 0x16, HDA_INPUT, 3 },
3164 { 0x16, HDA_INPUT, 4 },
3168 static int patch_vt1708S(struct hda_codec *codec);
3169 static int patch_vt1708B_8ch(struct hda_codec *codec)
3171 struct via_spec *spec;
3174 if (get_codec_type(codec) == VT1708BCE)
3175 return patch_vt1708S(codec);
3176 /* create a codec specific record */
3177 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3183 /* automatic parse from the BIOS config */
3184 err = vt1708B_parse_auto_config(codec);
3189 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3190 "from BIOS. Using genenic mode...\n");
3193 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3194 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3196 spec->stream_name_analog = "VT1708B Analog";
3197 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3198 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3200 spec->stream_name_digital = "VT1708B Digital";
3201 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3202 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3204 if (!spec->adc_nids && spec->input_mux) {
3205 spec->adc_nids = vt1708B_adc_nids;
3206 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3207 get_mux_nids(codec);
3208 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3212 codec->patch_ops = via_patch_ops;
3214 codec->patch_ops.init = via_auto_init;
3215 codec->patch_ops.unsol_event = via_unsol_event;
3216 #ifdef CONFIG_SND_HDA_POWER_SAVE
3217 spec->loopback.amplist = vt1708B_loopbacks;
3223 static int patch_vt1708B_4ch(struct hda_codec *codec)
3225 struct via_spec *spec;
3228 /* create a codec specific record */
3229 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3235 /* automatic parse from the BIOS config */
3236 err = vt1708B_parse_auto_config(codec);
3241 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3242 "from BIOS. Using genenic mode...\n");
3245 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3246 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3248 spec->stream_name_analog = "VT1708B Analog";
3249 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3250 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3252 spec->stream_name_digital = "VT1708B Digital";
3253 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3254 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3256 if (!spec->adc_nids && spec->input_mux) {
3257 spec->adc_nids = vt1708B_adc_nids;
3258 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3259 get_mux_nids(codec);
3260 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3264 codec->patch_ops = via_patch_ops;
3266 codec->patch_ops.init = via_auto_init;
3267 codec->patch_ops.unsol_event = via_unsol_event;
3268 #ifdef CONFIG_SND_HDA_POWER_SAVE
3269 spec->loopback.amplist = vt1708B_loopbacks;
3275 /* Patch for VT1708S */
3277 /* capture mixer elements */
3278 static struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3279 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3280 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3281 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3282 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3283 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3284 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3288 /* The multiple "Capture Source" controls confuse alsamixer
3289 * So call somewhat different..
3291 /* .name = "Capture Source", */
3292 .name = "Input Source",
3294 .info = via_mux_enum_info,
3295 .get = via_mux_enum_get,
3296 .put = via_mux_enum_put,
3301 static struct hda_verb vt1708S_volume_init_verbs[] = {
3302 /* Unmute ADC0-1 and set the default input to mic-in */
3303 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3304 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3306 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3307 * analog-loopback mixer widget */
3308 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3309 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3310 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3312 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3313 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3315 /* Setup default input of PW4 to MW0 */
3316 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3317 /* PW9, PW10 Output enable */
3318 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3319 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3320 /* Enable Mic Boost Volume backdoor */
3322 /* don't bybass mixer */
3327 static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3328 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3329 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3330 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3331 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3332 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3333 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3334 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3335 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3336 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3340 static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3344 .nid = 0x10, /* NID to query formats and rates */
3346 .open = via_playback_pcm_open,
3347 .prepare = via_playback_multi_pcm_prepare,
3348 .cleanup = via_playback_multi_pcm_cleanup,
3349 .close = via_pcm_open_close
3353 static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3357 .nid = 0x13, /* NID to query formats and rates */
3359 .open = via_pcm_open_close,
3360 .prepare = via_capture_pcm_prepare,
3361 .cleanup = via_capture_pcm_cleanup,
3362 .close = via_pcm_open_close
3366 static struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3370 /* NID is set in via_build_pcms */
3372 .open = via_dig_playback_pcm_open,
3373 .close = via_dig_playback_pcm_close,
3374 .prepare = via_dig_playback_pcm_prepare,
3375 .cleanup = via_dig_playback_pcm_cleanup
3379 /* fill in the dac_nids table from the parsed pin configuration */
3380 static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3381 const struct auto_pin_cfg *cfg)
3386 spec->multiout.num_dacs = cfg->line_outs;
3388 spec->multiout.dac_nids = spec->private_dac_nids;
3390 for (i = 0; i < 4; i++) {
3391 nid = cfg->line_out_pins[i];
3393 /* config dac list */
3395 case AUTO_SEQ_FRONT:
3396 spec->multiout.dac_nids[i] = 0x10;
3398 case AUTO_SEQ_CENLFE:
3399 spec->multiout.dac_nids[i] = 0x24;
3401 case AUTO_SEQ_SURROUND:
3402 spec->multiout.dac_nids[i] = 0x11;
3405 spec->multiout.dac_nids[i] = 0x25;
3414 /* add playback controls from the parsed DAC table */
3415 static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3416 const struct auto_pin_cfg *cfg)
3419 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
3420 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3421 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3422 hda_nid_t nid, nid_vol, nid_mute;
3425 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3426 nid = cfg->line_out_pins[i];
3431 nid_vol = nid_vols[i];
3432 nid_mute = nid_mutes[i];
3434 if (i == AUTO_SEQ_CENLFE) {
3436 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3437 "Center Playback Volume",
3438 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3442 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3443 "LFE Playback Volume",
3444 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3448 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3449 "Center Playback Switch",
3450 HDA_COMPOSE_AMP_VAL(nid_mute,
3455 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3456 "LFE Playback Switch",
3457 HDA_COMPOSE_AMP_VAL(nid_mute,
3462 } else if (i == AUTO_SEQ_FRONT) {
3463 /* add control to mixer index 0 */
3464 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3465 "Master Front Playback Volume",
3466 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3470 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3471 "Master Front Playback Switch",
3472 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3478 sprintf(name, "%s Playback Volume", chname[i]);
3479 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3480 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3484 sprintf(name, "%s Playback Switch", chname[i]);
3485 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3486 HDA_COMPOSE_AMP_VAL(nid_mute,
3492 sprintf(name, "%s Playback Volume", chname[i]);
3493 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3494 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3498 sprintf(name, "%s Playback Switch", chname[i]);
3499 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3500 HDA_COMPOSE_AMP_VAL(nid_mute,
3511 static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3518 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3519 spec->hp_independent_mode_index = 1;
3521 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3522 "Headphone Playback Volume",
3523 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
3527 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3528 "Headphone Playback Switch",
3529 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3533 create_hp_imux(spec);
3538 /* create playback/capture controls for input pins */
3539 static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec,
3540 const struct auto_pin_cfg *cfg)
3542 static char *labels[] = {
3543 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3545 struct hda_input_mux *imux = &spec->private_imux[0];
3546 int i, err, idx = 0;
3548 /* for internal loopback recording select */
3549 imux->items[imux->num_items].label = "Stereo Mixer";
3550 imux->items[imux->num_items].index = 5;
3553 for (i = 0; i < AUTO_PIN_LAST; i++) {
3554 if (!cfg->input_pins[i])
3557 switch (cfg->input_pins[i]) {
3558 case 0x1a: /* Mic */
3562 case 0x1b: /* Line In */
3566 case 0x1e: /* Front Mic */
3574 err = via_new_analog_input(spec, labels[i], idx, 0x16);
3577 imux->items[imux->num_items].label = labels[i];
3578 imux->items[imux->num_items].index = idx-1;
3584 /* fill out digital output widgets; one for master and one for slave outputs */
3585 static void fill_dig_outs(struct hda_codec *codec)
3587 struct via_spec *spec = codec->spec;
3590 for (i = 0; i < spec->autocfg.dig_outs; i++) {
3594 nid = spec->autocfg.dig_out_pins[i];
3597 conn = snd_hda_get_connections(codec, nid, &nid, 1);
3600 if (!spec->multiout.dig_out_nid)
3601 spec->multiout.dig_out_nid = nid;
3603 spec->slave_dig_outs[0] = nid;
3604 break; /* at most two dig outs */
3609 static int vt1708S_parse_auto_config(struct hda_codec *codec)
3611 struct via_spec *spec = codec->spec;
3614 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3617 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
3620 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3621 return 0; /* can't find valid BIOS pin config */
3623 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg);
3626 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3629 err = vt1708S_auto_create_analog_input_ctls(spec, &spec->autocfg);
3633 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3635 fill_dig_outs(codec);
3637 if (spec->kctls.list)
3638 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3640 spec->input_mux = &spec->private_imux[0];
3643 spec->mixers[spec->num_mixers++] = via_hp_mixer;
3645 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
3649 #ifdef CONFIG_SND_HDA_POWER_SAVE
3650 static struct hda_amp_list vt1708S_loopbacks[] = {
3651 { 0x16, HDA_INPUT, 1 },
3652 { 0x16, HDA_INPUT, 2 },
3653 { 0x16, HDA_INPUT, 3 },
3654 { 0x16, HDA_INPUT, 4 },
3659 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
3660 int offset, int num_steps, int step_size)
3662 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
3663 (offset << AC_AMPCAP_OFFSET_SHIFT) |
3664 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
3665 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
3666 (0 << AC_AMPCAP_MUTE_SHIFT));
3669 static int patch_vt1708S(struct hda_codec *codec)
3671 struct via_spec *spec;
3674 /* create a codec specific record */
3675 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3681 /* automatic parse from the BIOS config */
3682 err = vt1708S_parse_auto_config(codec);
3687 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3688 "from BIOS. Using genenic mode...\n");
3691 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
3692 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs;
3694 spec->stream_name_analog = "VT1708S Analog";
3695 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
3696 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
3698 spec->stream_name_digital = "VT1708S Digital";
3699 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
3701 if (!spec->adc_nids && spec->input_mux) {
3702 spec->adc_nids = vt1708S_adc_nids;
3703 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
3704 get_mux_nids(codec);
3705 override_mic_boost(codec, 0x1a, 0, 3, 40);
3706 override_mic_boost(codec, 0x1e, 0, 3, 40);
3707 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
3711 codec->patch_ops = via_patch_ops;
3713 codec->patch_ops.init = via_auto_init;
3714 codec->patch_ops.unsol_event = via_unsol_event;
3715 #ifdef CONFIG_SND_HDA_POWER_SAVE
3716 spec->loopback.amplist = vt1708S_loopbacks;
3719 /* correct names for VT1708BCE */
3720 if (get_codec_type(codec) == VT1708BCE) {
3721 kfree(codec->chip_name);
3722 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
3723 snprintf(codec->bus->card->mixername,
3724 sizeof(codec->bus->card->mixername),
3725 "%s %s", codec->vendor_name, codec->chip_name);
3726 spec->stream_name_analog = "VT1708BCE Analog";
3727 spec->stream_name_digital = "VT1708BCE Digital";
3732 /* Patch for VT1702 */
3734 /* capture mixer elements */
3735 static struct snd_kcontrol_new vt1702_capture_mixer[] = {
3736 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
3737 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
3738 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
3739 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
3740 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
3741 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
3742 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
3745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3746 /* The multiple "Capture Source" controls confuse alsamixer
3747 * So call somewhat different..
3749 /* .name = "Capture Source", */
3750 .name = "Input Source",
3752 .info = via_mux_enum_info,
3753 .get = via_mux_enum_get,
3754 .put = via_mux_enum_put,
3759 static struct hda_verb vt1702_volume_init_verbs[] = {
3761 * Unmute ADC0-1 and set the default input to mic-in
3763 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3764 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3765 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3768 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3771 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
3772 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3773 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3774 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3775 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3776 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3778 /* Setup default input of PW4 to MW0 */
3779 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
3780 /* PW6 PW7 Output enable */
3781 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3782 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3790 static struct hda_verb vt1702_uniwill_init_verbs[] = {
3791 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
3792 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3793 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3794 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3795 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3800 static struct hda_pcm_stream vt1702_pcm_analog_playback = {
3804 .nid = 0x10, /* NID to query formats and rates */
3806 .open = via_playback_pcm_open,
3807 .prepare = via_playback_multi_pcm_prepare,
3808 .cleanup = via_playback_multi_pcm_cleanup,
3809 .close = via_pcm_open_close
3813 static struct hda_pcm_stream vt1702_pcm_analog_capture = {
3817 .nid = 0x12, /* NID to query formats and rates */
3819 .open = via_pcm_open_close,
3820 .prepare = via_capture_pcm_prepare,
3821 .cleanup = via_capture_pcm_cleanup,
3822 .close = via_pcm_open_close
3826 static struct hda_pcm_stream vt1702_pcm_digital_playback = {
3830 /* NID is set in via_build_pcms */
3832 .open = via_dig_playback_pcm_open,
3833 .close = via_dig_playback_pcm_close,
3834 .prepare = via_dig_playback_pcm_prepare,
3835 .cleanup = via_dig_playback_pcm_cleanup
3839 /* fill in the dac_nids table from the parsed pin configuration */
3840 static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
3841 const struct auto_pin_cfg *cfg)
3843 spec->multiout.num_dacs = 1;
3844 spec->multiout.dac_nids = spec->private_dac_nids;
3846 if (cfg->line_out_pins[0]) {
3847 /* config dac list */
3848 spec->multiout.dac_nids[0] = 0x10;
3854 /* add playback controls from the parsed DAC table */
3855 static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
3856 const struct auto_pin_cfg *cfg)
3860 if (!cfg->line_out_pins[0])
3863 /* add control to mixer index 0 */
3864 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3865 "Master Front Playback Volume",
3866 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3869 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3870 "Master Front Playback Switch",
3871 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
3876 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3877 "Front Playback Volume",
3878 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
3881 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3882 "Front Playback Switch",
3883 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
3890 static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3893 struct hda_input_mux *imux;
3894 static const char *texts[] = { "ON", "OFF", NULL};
3897 spec->multiout.hp_nid = 0x1D;
3898 spec->hp_independent_mode_index = 0;
3900 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3901 "Headphone Playback Volume",
3902 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
3906 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3907 "Headphone Playback Switch",
3908 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3912 imux = &spec->private_imux[1];
3914 /* for hp mode select */
3916 while (texts[i] != NULL) {
3917 imux->items[imux->num_items].label = texts[i];
3918 imux->items[imux->num_items].index = i;
3923 spec->hp_mux = &spec->private_imux[1];
3927 /* create playback/capture controls for input pins */
3928 static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec,
3929 const struct auto_pin_cfg *cfg)
3931 static char *labels[] = {
3932 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
3934 struct hda_input_mux *imux = &spec->private_imux[0];
3935 int i, err, idx = 0;
3937 /* for internal loopback recording select */
3938 imux->items[imux->num_items].label = "Stereo Mixer";
3939 imux->items[imux->num_items].index = 3;
3942 for (i = 0; i < AUTO_PIN_LAST; i++) {
3943 if (!cfg->input_pins[i])
3946 switch (cfg->input_pins[i]) {
3947 case 0x14: /* Mic */
3951 case 0x15: /* Line In */
3955 case 0x18: /* Front Mic */
3959 err = via_new_analog_input(spec, labels[i], idx, 0x1A);
3962 imux->items[imux->num_items].label = labels[i];
3963 imux->items[imux->num_items].index = idx-1;
3969 static int vt1702_parse_auto_config(struct hda_codec *codec)
3971 struct via_spec *spec = codec->spec;
3974 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3977 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
3980 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3981 return 0; /* can't find valid BIOS pin config */
3983 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
3986 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3989 /* limit AA path volume to 0 dB */
3990 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
3991 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3992 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3993 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3994 (1 << AC_AMPCAP_MUTE_SHIFT));
3995 err = vt1702_auto_create_analog_input_ctls(spec, &spec->autocfg);
3999 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4001 fill_dig_outs(codec);
4003 if (spec->kctls.list)
4004 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4006 spec->input_mux = &spec->private_imux[0];
4009 spec->mixers[spec->num_mixers++] = via_hp_mixer;
4014 #ifdef CONFIG_SND_HDA_POWER_SAVE
4015 static struct hda_amp_list vt1702_loopbacks[] = {
4016 { 0x1A, HDA_INPUT, 1 },
4017 { 0x1A, HDA_INPUT, 2 },
4018 { 0x1A, HDA_INPUT, 3 },
4019 { 0x1A, HDA_INPUT, 4 },
4024 static int patch_vt1702(struct hda_codec *codec)
4026 struct via_spec *spec;
4029 /* create a codec specific record */
4030 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4036 /* automatic parse from the BIOS config */
4037 err = vt1702_parse_auto_config(codec);
4042 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4043 "from BIOS. Using genenic mode...\n");
4046 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs;
4047 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4049 spec->stream_name_analog = "VT1702 Analog";
4050 spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4051 spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4053 spec->stream_name_digital = "VT1702 Digital";
4054 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4056 if (!spec->adc_nids && spec->input_mux) {
4057 spec->adc_nids = vt1702_adc_nids;
4058 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4059 get_mux_nids(codec);
4060 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4064 codec->patch_ops = via_patch_ops;
4066 codec->patch_ops.init = via_auto_init;
4067 codec->patch_ops.unsol_event = via_unsol_event;
4068 #ifdef CONFIG_SND_HDA_POWER_SAVE
4069 spec->loopback.amplist = vt1702_loopbacks;
4075 /* Patch for VT1718S */
4077 /* capture mixer elements */
4078 static struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4079 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4080 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4081 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4082 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4083 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4084 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4088 /* The multiple "Capture Source" controls confuse alsamixer
4089 * So call somewhat different..
4091 .name = "Input Source",
4093 .info = via_mux_enum_info,
4094 .get = via_mux_enum_get,
4095 .put = via_mux_enum_put,
4100 static struct hda_verb vt1718S_volume_init_verbs[] = {
4102 * Unmute ADC0-1 and set the default input to mic-in
4104 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4105 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4108 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4111 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4112 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4113 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4114 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4115 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4116 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4118 /* Setup default input of Front HP to MW9 */
4119 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4120 /* PW9 PW10 Output enable */
4121 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4122 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4123 /* PW11 Input enable */
4124 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4125 /* Enable Boost Volume backdoor */
4127 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4130 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4131 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4132 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4134 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4136 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4137 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4138 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4139 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4140 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4141 /* Unmute MW4's index 0 */
4142 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4147 static struct hda_verb vt1718S_uniwill_init_verbs[] = {
4148 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4149 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4150 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4151 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4152 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4153 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4154 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4155 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4156 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4160 static struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4164 .nid = 0x8, /* NID to query formats and rates */
4166 .open = via_playback_pcm_open,
4167 .prepare = via_playback_multi_pcm_prepare,
4168 .cleanup = via_playback_multi_pcm_cleanup,
4169 .close = via_pcm_open_close,
4173 static struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4177 .nid = 0x10, /* NID to query formats and rates */
4179 .open = via_pcm_open_close,
4180 .prepare = via_capture_pcm_prepare,
4181 .cleanup = via_capture_pcm_cleanup,
4182 .close = via_pcm_open_close,
4186 static struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4190 .rates = SNDRV_PCM_RATE_48000,
4191 /* NID is set in via_build_pcms */
4193 .open = via_dig_playback_pcm_open,
4194 .close = via_dig_playback_pcm_close,
4195 .prepare = via_dig_playback_pcm_prepare,
4196 .cleanup = via_dig_playback_pcm_cleanup
4200 static struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4206 /* fill in the dac_nids table from the parsed pin configuration */
4207 static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4208 const struct auto_pin_cfg *cfg)
4213 spec->multiout.num_dacs = cfg->line_outs;
4215 spec->multiout.dac_nids = spec->private_dac_nids;
4217 for (i = 0; i < 4; i++) {
4218 nid = cfg->line_out_pins[i];
4220 /* config dac list */
4222 case AUTO_SEQ_FRONT:
4223 spec->multiout.dac_nids[i] = 0x8;
4225 case AUTO_SEQ_CENLFE:
4226 spec->multiout.dac_nids[i] = 0xa;
4228 case AUTO_SEQ_SURROUND:
4229 spec->multiout.dac_nids[i] = 0x9;
4232 spec->multiout.dac_nids[i] = 0xb;
4241 /* add playback controls from the parsed DAC table */
4242 static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4243 const struct auto_pin_cfg *cfg)
4246 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
4247 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4248 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4249 hda_nid_t nid, nid_vol, nid_mute = 0;
4252 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4253 nid = cfg->line_out_pins[i];
4257 nid_vol = nid_vols[i];
4258 nid_mute = nid_mutes[i];
4260 if (i == AUTO_SEQ_CENLFE) {
4262 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4263 "Center Playback Volume",
4264 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4268 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4269 "LFE Playback Volume",
4270 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4274 err = via_add_control(
4275 spec, VIA_CTL_WIDGET_MUTE,
4276 "Center Playback Switch",
4277 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4281 err = via_add_control(
4282 spec, VIA_CTL_WIDGET_MUTE,
4283 "LFE Playback Switch",
4284 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4288 } else if (i == AUTO_SEQ_FRONT) {
4290 sprintf(name, "%s Playback Volume", chname[i]);
4291 err = via_add_control(
4292 spec, VIA_CTL_WIDGET_VOL, name,
4293 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4296 sprintf(name, "%s Playback Switch", chname[i]);
4297 err = via_add_control(
4298 spec, VIA_CTL_WIDGET_MUTE, name,
4299 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4304 sprintf(name, "%s Playback Volume", chname[i]);
4305 err = via_add_control(
4306 spec, VIA_CTL_WIDGET_VOL, name,
4307 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4310 sprintf(name, "%s Playback Switch", chname[i]);
4311 err = via_add_control(
4312 spec, VIA_CTL_WIDGET_MUTE, name,
4313 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4322 static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4329 spec->multiout.hp_nid = 0xc; /* AOW4 */
4330 spec->hp_independent_mode_index = 1;
4332 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4333 "Headphone Playback Volume",
4334 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4338 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4339 "Headphone Playback Switch",
4340 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4344 create_hp_imux(spec);
4348 /* create playback/capture controls for input pins */
4349 static int vt1718S_auto_create_analog_input_ctls(struct via_spec *spec,
4350 const struct auto_pin_cfg *cfg)
4352 static char *labels[] = {
4353 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4355 struct hda_input_mux *imux = &spec->private_imux[0];
4356 int i, err, idx = 0;
4358 /* for internal loopback recording select */
4359 imux->items[imux->num_items].label = "Stereo Mixer";
4360 imux->items[imux->num_items].index = 5;
4363 for (i = 0; i < AUTO_PIN_LAST; i++) {
4364 if (!cfg->input_pins[i])
4367 switch (cfg->input_pins[i]) {
4368 case 0x2b: /* Mic */
4372 case 0x2a: /* Line In */
4376 case 0x29: /* Front Mic */
4384 err = via_new_analog_input(spec, labels[i], idx, 0x21);
4387 imux->items[imux->num_items].label = labels[i];
4388 imux->items[imux->num_items].index = idx;
4394 static int vt1718S_parse_auto_config(struct hda_codec *codec)
4396 struct via_spec *spec = codec->spec;
4399 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4403 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4406 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4407 return 0; /* can't find valid BIOS pin config */
4409 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4412 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4415 err = vt1718S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4419 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4421 fill_dig_outs(codec);
4423 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4424 spec->dig_in_nid = 0x13;
4426 if (spec->kctls.list)
4427 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4429 spec->input_mux = &spec->private_imux[0];
4432 spec->mixers[spec->num_mixers++] = via_hp_mixer;
4434 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
4439 #ifdef CONFIG_SND_HDA_POWER_SAVE
4440 static struct hda_amp_list vt1718S_loopbacks[] = {
4441 { 0x21, HDA_INPUT, 1 },
4442 { 0x21, HDA_INPUT, 2 },
4443 { 0x21, HDA_INPUT, 3 },
4444 { 0x21, HDA_INPUT, 4 },
4449 static int patch_vt1718S(struct hda_codec *codec)
4451 struct via_spec *spec;
4454 /* create a codec specific record */
4455 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4461 /* automatic parse from the BIOS config */
4462 err = vt1718S_parse_auto_config(codec);
4467 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4468 "from BIOS. Using genenic mode...\n");
4471 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs;
4472 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4474 if (codec->vendor_id == 0x11060441)
4475 spec->stream_name_analog = "VT2020 Analog";
4476 else if (codec->vendor_id == 0x11064441)
4477 spec->stream_name_analog = "VT1828S Analog";
4479 spec->stream_name_analog = "VT1718S Analog";
4480 spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4481 spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4483 if (codec->vendor_id == 0x11060441)
4484 spec->stream_name_digital = "VT2020 Digital";
4485 else if (codec->vendor_id == 0x11064441)
4486 spec->stream_name_digital = "VT1828S Digital";
4488 spec->stream_name_digital = "VT1718S Digital";
4489 spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4490 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4491 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4493 if (!spec->adc_nids && spec->input_mux) {
4494 spec->adc_nids = vt1718S_adc_nids;
4495 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4496 get_mux_nids(codec);
4497 override_mic_boost(codec, 0x2b, 0, 3, 40);
4498 override_mic_boost(codec, 0x29, 0, 3, 40);
4499 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4503 codec->patch_ops = via_patch_ops;
4505 codec->patch_ops.init = via_auto_init;
4506 codec->patch_ops.unsol_event = via_unsol_event,
4508 #ifdef CONFIG_SND_HDA_POWER_SAVE
4509 spec->loopback.amplist = vt1718S_loopbacks;
4515 /* Patch for VT1716S */
4517 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
4518 struct snd_ctl_elem_info *uinfo)
4520 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
4522 uinfo->value.integer.min = 0;
4523 uinfo->value.integer.max = 1;
4527 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
4528 struct snd_ctl_elem_value *ucontrol)
4530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4533 index = snd_hda_codec_read(codec, 0x26, 0,
4534 AC_VERB_GET_CONNECT_SEL, 0);
4536 *ucontrol->value.integer.value = index;
4541 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4542 struct snd_ctl_elem_value *ucontrol)
4544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4545 struct via_spec *spec = codec->spec;
4546 int index = *ucontrol->value.integer.value;
4548 snd_hda_codec_write(codec, 0x26, 0,
4549 AC_VERB_SET_CONNECT_SEL, index);
4550 spec->dmic_enabled = index;
4551 set_jack_power_state(codec);
4556 /* capture mixer elements */
4557 static struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4558 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4559 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4560 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4561 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4562 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4563 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4566 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4567 .name = "Input Source",
4569 .info = via_mux_enum_info,
4570 .get = via_mux_enum_get,
4571 .put = via_mux_enum_put,
4576 static struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4577 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4580 .name = "Digital Mic Capture Switch",
4582 .info = vt1716s_dmic_info,
4583 .get = vt1716s_dmic_get,
4584 .put = vt1716s_dmic_put,
4590 /* mono-out mixer elements */
4591 static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4592 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
4596 static struct hda_verb vt1716S_volume_init_verbs[] = {
4598 * Unmute ADC0-1 and set the default input to mic-in
4600 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4601 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4604 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4607 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4609 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4611 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4614 /* MUX Indices: Stereo Mixer = 5 */
4615 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4617 /* Setup default input of PW4 to MW0 */
4618 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4620 /* Setup default input of SW1 as MW0 */
4621 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4623 /* Setup default input of SW4 as AOW0 */
4624 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4626 /* PW9 PW10 Output enable */
4627 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4628 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4630 /* Unmute SW1, PW12 */
4631 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4632 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4633 /* PW12 Output enable */
4634 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4635 /* Enable Boost Volume backdoor */
4637 /* don't bybass mixer */
4639 /* Enable mono output */
4645 static struct hda_verb vt1716S_uniwill_init_verbs[] = {
4646 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
4647 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4648 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4649 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4650 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4651 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
4652 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
4653 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4654 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4658 static struct hda_pcm_stream vt1716S_pcm_analog_playback = {
4662 .nid = 0x10, /* NID to query formats and rates */
4664 .open = via_playback_pcm_open,
4665 .prepare = via_playback_multi_pcm_prepare,
4666 .cleanup = via_playback_multi_pcm_cleanup,
4667 .close = via_pcm_open_close,
4671 static struct hda_pcm_stream vt1716S_pcm_analog_capture = {
4675 .nid = 0x13, /* NID to query formats and rates */
4677 .open = via_pcm_open_close,
4678 .prepare = via_capture_pcm_prepare,
4679 .cleanup = via_capture_pcm_cleanup,
4680 .close = via_pcm_open_close,
4684 static struct hda_pcm_stream vt1716S_pcm_digital_playback = {
4688 .rates = SNDRV_PCM_RATE_48000,
4689 /* NID is set in via_build_pcms */
4691 .open = via_dig_playback_pcm_open,
4692 .close = via_dig_playback_pcm_close,
4693 .prepare = via_dig_playback_pcm_prepare,
4694 .cleanup = via_dig_playback_pcm_cleanup
4698 /* fill in the dac_nids table from the parsed pin configuration */
4699 static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
4700 const struct auto_pin_cfg *cfg)
4704 spec->multiout.num_dacs = cfg->line_outs;
4706 spec->multiout.dac_nids = spec->private_dac_nids;
4708 for (i = 0; i < 3; i++) {
4709 nid = cfg->line_out_pins[i];
4711 /* config dac list */
4713 case AUTO_SEQ_FRONT:
4714 spec->multiout.dac_nids[i] = 0x10;
4716 case AUTO_SEQ_CENLFE:
4717 spec->multiout.dac_nids[i] = 0x25;
4719 case AUTO_SEQ_SURROUND:
4720 spec->multiout.dac_nids[i] = 0x11;
4729 /* add playback controls from the parsed DAC table */
4730 static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
4731 const struct auto_pin_cfg *cfg)
4734 static const char *chname[3] = { "Front", "Surround", "C/LFE" };
4735 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
4736 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
4737 hda_nid_t nid, nid_vol, nid_mute;
4740 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
4741 nid = cfg->line_out_pins[i];
4746 nid_vol = nid_vols[i];
4747 nid_mute = nid_mutes[i];
4749 if (i == AUTO_SEQ_CENLFE) {
4750 err = via_add_control(
4751 spec, VIA_CTL_WIDGET_VOL,
4752 "Center Playback Volume",
4753 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
4756 err = via_add_control(
4757 spec, VIA_CTL_WIDGET_VOL,
4758 "LFE Playback Volume",
4759 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
4762 err = via_add_control(
4763 spec, VIA_CTL_WIDGET_MUTE,
4764 "Center Playback Switch",
4765 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4769 err = via_add_control(
4770 spec, VIA_CTL_WIDGET_MUTE,
4771 "LFE Playback Switch",
4772 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4776 } else if (i == AUTO_SEQ_FRONT) {
4778 err = via_add_control(
4779 spec, VIA_CTL_WIDGET_VOL,
4780 "Master Front Playback Volume",
4781 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
4784 err = via_add_control(
4785 spec, VIA_CTL_WIDGET_MUTE,
4786 "Master Front Playback Switch",
4787 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
4791 sprintf(name, "%s Playback Volume", chname[i]);
4792 err = via_add_control(
4793 spec, VIA_CTL_WIDGET_VOL, name,
4794 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4797 sprintf(name, "%s Playback Switch", chname[i]);
4798 err = via_add_control(
4799 spec, VIA_CTL_WIDGET_MUTE, name,
4800 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4805 sprintf(name, "%s Playback Volume", chname[i]);
4806 err = via_add_control(
4807 spec, VIA_CTL_WIDGET_VOL, name,
4808 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4811 sprintf(name, "%s Playback Switch", chname[i]);
4812 err = via_add_control(
4813 spec, VIA_CTL_WIDGET_MUTE, name,
4814 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4823 static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4830 spec->multiout.hp_nid = 0x25; /* AOW3 */
4831 spec->hp_independent_mode_index = 1;
4833 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4834 "Headphone Playback Volume",
4835 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
4839 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4840 "Headphone Playback Switch",
4841 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4845 create_hp_imux(spec);
4849 /* create playback/capture controls for input pins */
4850 static int vt1716S_auto_create_analog_input_ctls(struct via_spec *spec,
4851 const struct auto_pin_cfg *cfg)
4853 static char *labels[] = {
4854 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
4856 struct hda_input_mux *imux = &spec->private_imux[0];
4857 int i, err, idx = 0;
4859 /* for internal loopback recording select */
4860 imux->items[imux->num_items].label = "Stereo Mixer";
4861 imux->items[imux->num_items].index = 5;
4864 for (i = 0; i < AUTO_PIN_LAST; i++) {
4865 if (!cfg->input_pins[i])
4868 switch (cfg->input_pins[i]) {
4869 case 0x1a: /* Mic */
4873 case 0x1b: /* Line In */
4877 case 0x1e: /* Front Mic */
4885 err = via_new_analog_input(spec, labels[i], idx, 0x16);
4888 imux->items[imux->num_items].label = labels[i];
4889 imux->items[imux->num_items].index = idx-1;
4895 static int vt1716S_parse_auto_config(struct hda_codec *codec)
4897 struct via_spec *spec = codec->spec;
4900 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4903 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
4906 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4907 return 0; /* can't find valid BIOS pin config */
4909 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4912 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4915 err = vt1716S_auto_create_analog_input_ctls(spec, &spec->autocfg);
4919 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4921 fill_dig_outs(codec);
4923 if (spec->kctls.list)
4924 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4926 spec->input_mux = &spec->private_imux[0];
4929 spec->mixers[spec->num_mixers++] = via_hp_mixer;
4931 spec->mixers[spec->num_mixers++] = via_smart51_mixer;
4936 #ifdef CONFIG_SND_HDA_POWER_SAVE
4937 static struct hda_amp_list vt1716S_loopbacks[] = {
4938 { 0x16, HDA_INPUT, 1 },
4939 { 0x16, HDA_INPUT, 2 },
4940 { 0x16, HDA_INPUT, 3 },
4941 { 0x16, HDA_INPUT, 4 },
4946 static int patch_vt1716S(struct hda_codec *codec)
4948 struct via_spec *spec;
4951 /* create a codec specific record */
4952 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4958 /* automatic parse from the BIOS config */
4959 err = vt1716S_parse_auto_config(codec);
4964 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4965 "from BIOS. Using genenic mode...\n");
4968 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs;
4969 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
4971 spec->stream_name_analog = "VT1716S Analog";
4972 spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
4973 spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
4975 spec->stream_name_digital = "VT1716S Digital";
4976 spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
4978 if (!spec->adc_nids && spec->input_mux) {
4979 spec->adc_nids = vt1716S_adc_nids;
4980 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
4981 get_mux_nids(codec);
4982 override_mic_boost(codec, 0x1a, 0, 3, 40);
4983 override_mic_boost(codec, 0x1e, 0, 3, 40);
4984 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
4988 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
4991 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
4993 codec->patch_ops = via_patch_ops;
4995 codec->patch_ops.init = via_auto_init;
4996 codec->patch_ops.unsol_event = via_unsol_event,
4998 #ifdef CONFIG_SND_HDA_POWER_SAVE
4999 spec->loopback.amplist = vt1716S_loopbacks;
5007 static struct hda_codec_preset snd_hda_preset_via[] = {
5008 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
5009 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
5010 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
5011 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
5012 { .id = 0x1106e710, .name = "VT1709 10-Ch",
5013 .patch = patch_vt1709_10ch},
5014 { .id = 0x1106e711, .name = "VT1709 10-Ch",
5015 .patch = patch_vt1709_10ch},
5016 { .id = 0x1106e712, .name = "VT1709 10-Ch",
5017 .patch = patch_vt1709_10ch},
5018 { .id = 0x1106e713, .name = "VT1709 10-Ch",
5019 .patch = patch_vt1709_10ch},
5020 { .id = 0x1106e714, .name = "VT1709 6-Ch",
5021 .patch = patch_vt1709_6ch},
5022 { .id = 0x1106e715, .name = "VT1709 6-Ch",
5023 .patch = patch_vt1709_6ch},
5024 { .id = 0x1106e716, .name = "VT1709 6-Ch",
5025 .patch = patch_vt1709_6ch},
5026 { .id = 0x1106e717, .name = "VT1709 6-Ch",
5027 .patch = patch_vt1709_6ch},
5028 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
5029 .patch = patch_vt1708B_8ch},
5030 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
5031 .patch = patch_vt1708B_8ch},
5032 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
5033 .patch = patch_vt1708B_8ch},
5034 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
5035 .patch = patch_vt1708B_8ch},
5036 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
5037 .patch = patch_vt1708B_4ch},
5038 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
5039 .patch = patch_vt1708B_4ch},
5040 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
5041 .patch = patch_vt1708B_4ch},
5042 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
5043 .patch = patch_vt1708B_4ch},
5044 { .id = 0x11060397, .name = "VT1708S",
5045 .patch = patch_vt1708S},
5046 { .id = 0x11061397, .name = "VT1708S",
5047 .patch = patch_vt1708S},
5048 { .id = 0x11062397, .name = "VT1708S",
5049 .patch = patch_vt1708S},
5050 { .id = 0x11063397, .name = "VT1708S",
5051 .patch = patch_vt1708S},
5052 { .id = 0x11064397, .name = "VT1708S",
5053 .patch = patch_vt1708S},
5054 { .id = 0x11065397, .name = "VT1708S",
5055 .patch = patch_vt1708S},
5056 { .id = 0x11066397, .name = "VT1708S",
5057 .patch = patch_vt1708S},
5058 { .id = 0x11067397, .name = "VT1708S",
5059 .patch = patch_vt1708S},
5060 { .id = 0x11060398, .name = "VT1702",
5061 .patch = patch_vt1702},
5062 { .id = 0x11061398, .name = "VT1702",
5063 .patch = patch_vt1702},
5064 { .id = 0x11062398, .name = "VT1702",
5065 .patch = patch_vt1702},
5066 { .id = 0x11063398, .name = "VT1702",
5067 .patch = patch_vt1702},
5068 { .id = 0x11064398, .name = "VT1702",
5069 .patch = patch_vt1702},
5070 { .id = 0x11065398, .name = "VT1702",
5071 .patch = patch_vt1702},
5072 { .id = 0x11066398, .name = "VT1702",
5073 .patch = patch_vt1702},
5074 { .id = 0x11067398, .name = "VT1702",
5075 .patch = patch_vt1702},
5076 { .id = 0x11060428, .name = "VT1718S",
5077 .patch = patch_vt1718S},
5078 { .id = 0x11064428, .name = "VT1718S",
5079 .patch = patch_vt1718S},
5080 { .id = 0x11060441, .name = "VT2020",
5081 .patch = patch_vt1718S},
5082 { .id = 0x11064441, .name = "VT1828S",
5083 .patch = patch_vt1718S},
5084 { .id = 0x11060433, .name = "VT1716S",
5085 .patch = patch_vt1716S},
5086 { .id = 0x1106a721, .name = "VT1716S",
5087 .patch = patch_vt1716S},
5091 MODULE_ALIAS("snd-hda-codec-id:1106*");
5093 static struct hda_codec_preset_list via_list = {
5094 .preset = snd_hda_preset_via,
5095 .owner = THIS_MODULE,
5098 MODULE_LICENSE("GPL");
5099 MODULE_DESCRIPTION("VIA HD-audio codec");
5101 static int __init patch_via_init(void)
5103 return snd_hda_add_codec_preset(&via_list);
5106 static void __exit patch_via_exit(void)
5108 snd_hda_delete_codec_preset(&via_list);
5111 module_init(patch_via_init)
5112 module_exit(patch_via_exit)