2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
6 * (C) 2006-2009 VIA Technology, Inc.
7 * (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
26 /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
27 /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
28 /* 2006-08-02 Lydia Wang Add support to VT1709 codec */
29 /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
30 /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
31 /* 2007-09-17 Lydia Wang Add VT1708B codec support */
32 /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
33 /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
34 /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
35 /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36 /* 2008-04-09 Lydia Wang Add Independent HP feature */
37 /* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38 /* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
39 /* 2009-02-16 Logan Li Add support for VT1718S */
40 /* 2009-03-13 Logan Li Add support for VT1716S */
41 /* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */
42 /* 2009-07-08 Lydia Wang Add support for VT2002P */
43 /* 2009-07-21 Lydia Wang Add support for VT1812 */
44 /* 2009-09-19 Lydia Wang Add support for VT1818S */
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49 #include <linux/init.h>
50 #include <linux/delay.h>
51 #include <linux/slab.h>
52 #include <sound/core.h>
53 #include <sound/asoundef.h>
54 #include "hda_codec.h"
55 #include "hda_local.h"
58 #define VT1708_HP_PIN_NID 0x20
59 #define VT1708_CD_PIN_NID 0x24
79 #define VT2002P_COMPATIBLE(spec) \
80 ((spec)->codec_type == VT2002P ||\
81 (spec)->codec_type == VT1812 ||\
82 (spec)->codec_type == VT1802)
84 #define MAX_NID_PATH_DEPTH 5
86 /* output-path: DAC -> ... -> pin
87 * idx[] contains the source index number of the next widget;
88 * e.g. idx[0] is the index of the DAC selected by path[1] widget
89 * multi[] indicates whether it's a selector widget with multi-connectors
90 * (i.e. the connection selection is mandatory)
91 * vol_ctl and mute_ctl contains the NIDs for the assigned mixers
95 hda_nid_t path[MAX_NID_PATH_DEPTH];
96 unsigned char idx[MAX_NID_PATH_DEPTH];
97 unsigned char multi[MAX_NID_PATH_DEPTH];
99 unsigned int mute_ctl;
104 hda_nid_t pin; /* input-pin or aa-mix */
105 int adc_idx; /* ADC index to be used */
106 int mux_idx; /* MUX index (if any) */
107 const char *label; /* input-source label */
110 #define VIA_MAX_ADCS 3
113 /* codec parameterization */
114 const struct snd_kcontrol_new *mixers[6];
115 unsigned int num_mixers;
117 const struct hda_verb *init_verbs[5];
118 unsigned int num_iverbs;
120 char stream_name_analog[32];
121 char stream_name_hp[32];
122 const struct hda_pcm_stream *stream_analog_playback;
123 const struct hda_pcm_stream *stream_analog_capture;
125 char stream_name_digital[32];
126 const struct hda_pcm_stream *stream_digital_playback;
127 const struct hda_pcm_stream *stream_digital_capture;
130 struct hda_multi_out multiout;
131 hda_nid_t slave_dig_outs[2];
132 hda_nid_t hp_dac_nid;
133 bool hp_indep_shared; /* indep HP-DAC is shared with side ch */
134 int num_active_streams;
136 struct nid_path out_path[HDA_SIDE + 1];
137 struct nid_path hp_path;
138 struct nid_path hp_dep_path;
139 struct nid_path speaker_path;
142 unsigned int num_adc_nids;
143 hda_nid_t adc_nids[VIA_MAX_ADCS];
144 hda_nid_t mux_nids[VIA_MAX_ADCS];
145 hda_nid_t aa_mix_nid;
146 hda_nid_t dig_in_nid;
151 struct via_input inputs[AUTO_CFG_MAX_INS + 1];
152 unsigned int cur_mux[VIA_MAX_ADCS];
154 /* dynamic ADC switching */
156 unsigned int cur_adc_stream_tag;
157 unsigned int cur_adc_format;
159 /* PCM information */
160 struct hda_pcm pcm_rec[3];
162 /* dynamic controls, init_verbs and input_mux */
163 struct auto_pin_cfg autocfg;
164 struct snd_array kctls;
165 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
168 unsigned int hp_independent_mode;
169 unsigned int dmic_enabled;
170 unsigned int no_pin_power_ctl;
171 enum VIA_HDA_CODEC codec_type;
174 unsigned int smart51_nums;
175 hda_nid_t smart51_pins[2];
177 const char *smart51_labels[2];
178 unsigned int smart51_enabled;
180 /* work to check hp jack state */
181 struct hda_codec *codec;
182 struct delayed_work vt1708_hp_work;
183 int vt1708_jack_detect;
184 int vt1708_hp_present;
186 void (*set_widgets_power_state)(struct hda_codec *codec);
188 struct hda_loopback_check loopback;
190 struct hda_amp_list loopback_list[8];
192 /* bind capture-volume */
193 struct hda_bind_ctls *bind_cap_vol;
194 struct hda_bind_ctls *bind_cap_sw;
197 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
198 static struct via_spec * via_new_spec(struct hda_codec *codec)
200 struct via_spec *spec;
202 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
208 spec->codec_type = get_codec_type(codec);
209 /* VT1708BCE & VT1708S are almost same */
210 if (spec->codec_type == VT1708BCE)
211 spec->codec_type = VT1708S;
215 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
217 u32 vendor_id = codec->vendor_id;
218 u16 ven_id = vendor_id >> 16;
219 u16 dev_id = vendor_id & 0xffff;
220 enum VIA_HDA_CODEC codec_type;
223 if (ven_id != 0x1106)
224 codec_type = UNKNOWN;
225 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
227 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
228 codec_type = VT1709_10CH;
229 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
230 codec_type = VT1709_6CH;
231 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
232 codec_type = VT1708B_8CH;
233 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
234 codec_type = VT1708BCE;
235 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
236 codec_type = VT1708B_4CH;
237 else if ((dev_id & 0xfff) == 0x397
238 && (dev_id >> 12) < 8)
239 codec_type = VT1708S;
240 else if ((dev_id & 0xfff) == 0x398
241 && (dev_id >> 12) < 8)
243 else if ((dev_id & 0xfff) == 0x428
244 && (dev_id >> 12) < 8)
245 codec_type = VT1718S;
246 else if (dev_id == 0x0433 || dev_id == 0xa721)
247 codec_type = VT1716S;
248 else if (dev_id == 0x0441 || dev_id == 0x4441)
249 codec_type = VT1718S;
250 else if (dev_id == 0x0438 || dev_id == 0x4438)
251 codec_type = VT2002P;
252 else if (dev_id == 0x0448)
254 else if (dev_id == 0x0440)
255 codec_type = VT1708S;
256 else if ((dev_id & 0xfff) == 0x446)
259 codec_type = UNKNOWN;
263 #define VIA_JACK_EVENT 0x20
264 #define VIA_HP_EVENT 0x01
265 #define VIA_GPIO_EVENT 0x02
266 #define VIA_LINE_EVENT 0x03
271 VIA_CTL_WIDGET_ANALOG_MUTE,
274 static void analog_low_current_mode(struct hda_codec *codec);
275 static bool is_aa_path_mute(struct hda_codec *codec);
277 static void vt1708_start_hp_work(struct via_spec *spec)
279 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
281 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
282 !spec->vt1708_jack_detect);
283 if (!delayed_work_pending(&spec->vt1708_hp_work))
284 schedule_delayed_work(&spec->vt1708_hp_work,
285 msecs_to_jiffies(100));
288 static void vt1708_stop_hp_work(struct via_spec *spec)
290 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
292 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
293 && !is_aa_path_mute(spec->codec))
295 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
296 !spec->vt1708_jack_detect);
297 cancel_delayed_work_sync(&spec->vt1708_hp_work);
300 static void set_widgets_power_state(struct hda_codec *codec)
302 struct via_spec *spec = codec->spec;
303 if (spec->set_widgets_power_state)
304 spec->set_widgets_power_state(codec);
307 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
308 struct snd_ctl_elem_value *ucontrol)
310 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
311 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
313 set_widgets_power_state(codec);
314 analog_low_current_mode(snd_kcontrol_chip(kcontrol));
315 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
316 if (is_aa_path_mute(codec))
317 vt1708_start_hp_work(codec->spec);
319 vt1708_stop_hp_work(codec->spec);
324 /* modify .put = snd_hda_mixer_amp_switch_put */
325 #define ANALOG_INPUT_MUTE \
326 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
329 .info = snd_hda_mixer_amp_switch_info, \
330 .get = snd_hda_mixer_amp_switch_get, \
331 .put = analog_input_switch_put, \
332 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
334 static const struct snd_kcontrol_new via_control_templates[] = {
335 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
336 HDA_CODEC_MUTE(NULL, 0, 0, 0),
341 /* add dynamic controls */
342 static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
343 const struct snd_kcontrol_new *tmpl,
346 struct snd_kcontrol_new *knew;
348 snd_array_init(&spec->kctls, sizeof(*knew), 32);
349 knew = snd_array_new(&spec->kctls);
356 knew->name = kstrdup(name, GFP_KERNEL);
363 static int __via_add_control(struct via_spec *spec, int type, const char *name,
364 int idx, unsigned long val)
366 struct snd_kcontrol_new *knew;
368 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
372 if (get_amp_nid_(val))
373 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
374 knew->private_value = val;
378 #define via_add_control(spec, type, name, val) \
379 __via_add_control(spec, type, name, 0, val)
381 #define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
383 static void via_free_kctls(struct hda_codec *codec)
385 struct via_spec *spec = codec->spec;
387 if (spec->kctls.list) {
388 struct snd_kcontrol_new *kctl = spec->kctls.list;
390 for (i = 0; i < spec->kctls.used; i++)
393 snd_array_free(&spec->kctls);
396 /* create input playback/capture controls for the given pin */
397 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
398 int type_idx, int idx, int mix_nid)
403 sprintf(name, "%s Playback Volume", ctlname);
404 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
405 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
408 sprintf(name, "%s Playback Switch", ctlname);
409 err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
410 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
416 #define get_connection_index(codec, mux, nid) \
417 snd_hda_get_conn_index(codec, mux, nid, 0)
419 static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
425 caps = get_wcaps(codec, nid);
426 if (dir == HDA_INPUT)
427 caps &= AC_WCAP_IN_AMP;
429 caps &= AC_WCAP_OUT_AMP;
432 if (query_amp_caps(codec, nid, dir) & mask)
437 #define have_mute(codec, nid, dir) \
438 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
440 static bool is_node_in_path(struct nid_path *path, hda_nid_t nid)
445 for (i = 0; i < path->depth; i++) {
446 if (path->path[i] == nid)
452 /* enable/disable the output-route mixers */
453 static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
454 hda_nid_t mix_nid, int aa_mix_idx, bool enable)
457 bool hp_path, front_path;
458 struct via_spec *spec = codec->spec;
462 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
463 hp_path = is_node_in_path(path, spec->hp_dac_nid);
464 front_path = is_node_in_path(path, spec->multiout.dac_nids[0]);
466 for (i = 0; i < num; i++) {
467 if (i == aa_mix_idx) {
469 val = enable ? AMP_IN_MUTE(i) :
472 val = AMP_IN_UNMUTE(i);
474 val = AMP_IN_MUTE(i);
477 val = enable ? AMP_IN_UNMUTE(i) :
480 val = AMP_IN_MUTE(i);
482 val = AMP_IN_UNMUTE(i);
484 snd_hda_codec_write(codec, mix_nid, 0,
485 AC_VERB_SET_AMP_GAIN_MUTE, val);
489 /* enable/disable the output-route */
490 static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
491 bool enable, bool force)
494 struct via_spec *spec = codec->spec;
495 hda_nid_t aa_mix_nid = spec->aa_mix_nid;
496 for (i = 0; i < path->depth; i++) {
498 int idx = path->idx[i];
500 if (i < path->depth - 1)
501 dst = path->path[i + 1];
504 if (enable && path->multi[i])
505 snd_hda_codec_write(codec, dst, 0,
506 AC_VERB_SET_CONNECT_SEL, idx);
508 && get_wcaps_type(get_wcaps(codec, src)) == AC_WID_AUD_OUT
509 && get_wcaps_type(get_wcaps(codec, dst)) == AC_WID_AUD_MIX)
511 if (have_mute(codec, dst, HDA_INPUT)) {
512 if (dst == aa_mix_nid) {
513 val = enable ? AMP_IN_UNMUTE(idx) :
515 snd_hda_codec_write(codec, dst, 0,
516 AC_VERB_SET_AMP_GAIN_MUTE, val);
518 idx = get_connection_index(codec, dst,
521 activate_output_mix(codec, path,
526 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
528 if (have_mute(codec, src, HDA_OUTPUT)) {
529 int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
530 snd_hda_codec_write(codec, src, 0,
531 AC_VERB_SET_AMP_GAIN_MUTE, val);
536 /* set the given pin as output */
537 static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
542 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
544 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
545 snd_hda_codec_write(codec, pin, 0,
546 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
549 static void via_auto_init_output(struct hda_codec *codec,
550 struct nid_path *path, int pin_type,
551 bool with_aa_mix, bool force)
553 struct via_spec *spec = codec->spec;
559 pin = path->path[path->depth - 1];
561 init_output_pin(codec, pin, pin_type);
562 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
563 if (caps & AC_AMPCAP_MUTE) {
565 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
566 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
570 /* initialize the AA-path */
571 if (!spec->aa_mix_nid)
573 activate_output_path(codec, path, true, force);
576 static void via_auto_init_multi_out(struct hda_codec *codec)
578 struct via_spec *spec = codec->spec;
581 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++)
582 /* enable aa-mute only for the front channel */
583 via_auto_init_output(codec, &spec->out_path[i], PIN_OUT,
587 static void via_auto_init_hp_out(struct hda_codec *codec)
589 struct via_spec *spec = codec->spec;
591 if (!spec->hp_dac_nid) {
592 via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP,
596 if (spec->hp_independent_mode) {
597 activate_output_path(codec, &spec->hp_dep_path, false, false);
598 via_auto_init_output(codec, &spec->hp_path, PIN_HP,
601 activate_output_path(codec, &spec->hp_path, false, false);
602 via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP,
607 static void via_auto_init_speaker_out(struct hda_codec *codec)
609 struct via_spec *spec = codec->spec;
611 if (spec->autocfg.speaker_outs)
612 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT,
616 static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
617 static void via_hp_automute(struct hda_codec *codec);
619 static void via_auto_init_analog_input(struct hda_codec *codec)
621 struct via_spec *spec = codec->spec;
622 const struct auto_pin_cfg *cfg = &spec->autocfg;
623 hda_nid_t conn[HDA_MAX_CONNECTIONS];
628 for (i = 0; i < spec->num_adc_nids; i++) {
629 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
630 AC_VERB_SET_AMP_GAIN_MUTE,
635 for (i = 0; i < cfg->num_inputs; i++) {
636 hda_nid_t nid = cfg->inputs[i].pin;
637 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
639 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
643 snd_hda_codec_write(codec, nid, 0,
644 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
648 for (i = 0; i < spec->num_adc_nids; i++) {
649 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
650 if (spec->mux_nids[adc_idx]) {
651 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
652 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
653 AC_VERB_SET_CONNECT_SEL,
656 if (spec->dyn_adc_switch)
657 break; /* only one input-src */
661 if (!spec->aa_mix_nid)
663 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
665 for (i = 0; i < num_conns; i++) {
666 unsigned int caps = get_wcaps(codec, conn[i]);
667 if (get_wcaps_type(caps) == AC_WID_PIN)
668 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
669 AC_VERB_SET_AMP_GAIN_MUTE,
674 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
675 unsigned int *affected_parm)
678 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
679 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
680 >> AC_DEFCFG_MISC_SHIFT
681 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
682 struct via_spec *spec = codec->spec;
683 unsigned present = 0;
685 no_presence |= spec->no_pin_power_ctl;
687 present = snd_hda_jack_detect(codec, nid);
688 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
689 || ((no_presence || present)
690 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
691 *affected_parm = AC_PWRST_D0; /* if it's connected */
696 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
699 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_info *uinfo)
702 static const char * const texts[] = {
703 "Disabled", "Enabled"
706 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
708 uinfo->value.enumerated.items = 2;
709 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
710 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
711 strcpy(uinfo->value.enumerated.name,
712 texts[uinfo->value.enumerated.item]);
716 static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
717 struct snd_ctl_elem_value *ucontrol)
719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
720 struct via_spec *spec = codec->spec;
721 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
725 static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
729 struct via_spec *spec = codec->spec;
730 unsigned int val = !ucontrol->value.enumerated.item[0];
732 if (val == spec->no_pin_power_ctl)
734 spec->no_pin_power_ctl = val;
735 set_widgets_power_state(codec);
739 static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
741 .name = "Dynamic Power-Control",
742 .info = via_pin_power_ctl_info,
743 .get = via_pin_power_ctl_get,
744 .put = via_pin_power_ctl_put,
748 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
749 struct snd_ctl_elem_info *uinfo)
751 static const char * const texts[] = { "OFF", "ON" };
753 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
755 uinfo->value.enumerated.items = 2;
756 if (uinfo->value.enumerated.item >= 2)
757 uinfo->value.enumerated.item = 1;
758 strcpy(uinfo->value.enumerated.name,
759 texts[uinfo->value.enumerated.item]);
763 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
764 struct snd_ctl_elem_value *ucontrol)
766 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
767 struct via_spec *spec = codec->spec;
769 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
773 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
774 struct snd_ctl_elem_value *ucontrol)
776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
777 struct via_spec *spec = codec->spec;
780 /* no independent-hp status change during PCM playback is running */
781 if (spec->num_active_streams)
784 cur = !!ucontrol->value.enumerated.item[0];
785 if (spec->hp_independent_mode == cur)
787 spec->hp_independent_mode = cur;
789 activate_output_path(codec, &spec->hp_dep_path, false, false);
790 activate_output_path(codec, &spec->hp_path, true, false);
791 if (spec->hp_indep_shared)
792 activate_output_path(codec, &spec->out_path[HDA_SIDE],
795 activate_output_path(codec, &spec->hp_path, false, false);
796 activate_output_path(codec, &spec->hp_dep_path, true, false);
797 if (spec->hp_indep_shared)
798 activate_output_path(codec, &spec->out_path[HDA_SIDE],
802 /* update jack power state */
803 set_widgets_power_state(codec);
804 via_hp_automute(codec);
808 static const struct snd_kcontrol_new via_hp_mixer = {
809 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
810 .name = "Independent HP",
811 .info = via_independent_hp_info,
812 .get = via_independent_hp_get,
813 .put = via_independent_hp_put,
816 static int via_hp_build(struct hda_codec *codec)
818 struct via_spec *spec = codec->spec;
819 struct snd_kcontrol_new *knew;
822 nid = spec->autocfg.hp_pins[0];
823 knew = via_clone_control(spec, &via_hp_mixer);
827 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
832 static void notify_aa_path_ctls(struct hda_codec *codec)
834 struct via_spec *spec = codec->spec;
837 for (i = 0; i < spec->smart51_nums; i++) {
838 struct snd_kcontrol *ctl;
839 struct snd_ctl_elem_id id;
840 memset(&id, 0, sizeof(id));
841 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
842 sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]);
843 ctl = snd_hda_find_mixer_ctl(codec, id.name);
845 snd_ctl_notify(codec->bus->card,
846 SNDRV_CTL_EVENT_MASK_VALUE,
851 static void mute_aa_path(struct hda_codec *codec, int mute)
853 struct via_spec *spec = codec->spec;
854 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
857 /* check AA path's mute status */
858 for (i = 0; i < spec->smart51_nums; i++) {
859 if (spec->smart51_idxs[i] < 0)
861 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
862 HDA_INPUT, spec->smart51_idxs[i],
867 static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
869 struct via_spec *spec = codec->spec;
872 for (i = 0; i < spec->smart51_nums; i++)
873 if (spec->smart51_pins[i] == pin)
878 static int via_smart51_get(struct snd_kcontrol *kcontrol,
879 struct snd_ctl_elem_value *ucontrol)
881 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
882 struct via_spec *spec = codec->spec;
884 *ucontrol->value.integer.value = spec->smart51_enabled;
888 static int via_smart51_put(struct snd_kcontrol *kcontrol,
889 struct snd_ctl_elem_value *ucontrol)
891 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
892 struct via_spec *spec = codec->spec;
893 int out_in = *ucontrol->value.integer.value
894 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
897 for (i = 0; i < spec->smart51_nums; i++) {
898 hda_nid_t nid = spec->smart51_pins[i];
901 parm = snd_hda_codec_read(codec, nid, 0,
902 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
903 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
905 snd_hda_codec_write(codec, nid, 0,
906 AC_VERB_SET_PIN_WIDGET_CONTROL,
908 if (out_in == AC_PINCTL_OUT_EN) {
909 mute_aa_path(codec, 1);
910 notify_aa_path_ctls(codec);
913 spec->smart51_enabled = *ucontrol->value.integer.value;
914 set_widgets_power_state(codec);
918 static const struct snd_kcontrol_new via_smart51_mixer = {
919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
922 .info = snd_ctl_boolean_mono_info,
923 .get = via_smart51_get,
924 .put = via_smart51_put,
927 static int via_smart51_build(struct hda_codec *codec)
929 struct via_spec *spec = codec->spec;
931 if (!spec->smart51_nums)
933 if (!via_clone_control(spec, &via_smart51_mixer))
938 /* check AA path's mute status */
939 static bool is_aa_path_mute(struct hda_codec *codec)
941 struct via_spec *spec = codec->spec;
942 const struct hda_amp_list *p;
945 for (i = 0; i < spec->num_loopbacks; i++) {
946 p = &spec->loopback_list[i];
947 for (ch = 0; ch < 2; ch++) {
948 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
950 if (!(v & HDA_AMP_MUTE) && v > 0)
957 /* enter/exit analog low-current mode */
958 static void analog_low_current_mode(struct hda_codec *codec)
960 struct via_spec *spec = codec->spec;
962 unsigned int verb, parm;
964 enable = is_aa_path_mute(codec) && (spec->num_active_streams > 0);
966 /* decide low current mode's verb & parameter */
967 switch (spec->codec_type) {
971 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
977 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
981 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
987 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
990 return; /* other codecs are not supported */
993 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
997 * generic initialization of ADC, input mixers and output mixers
999 static const struct hda_verb vt1708_init_verbs[] = {
1000 /* power down jack detect function */
1005 static void set_stream_active(struct hda_codec *codec, bool active)
1007 struct via_spec *spec = codec->spec;
1010 spec->num_active_streams++;
1012 spec->num_active_streams--;
1013 analog_low_current_mode(codec);
1016 static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
1017 struct hda_codec *codec,
1018 struct snd_pcm_substream *substream)
1020 struct via_spec *spec = codec->spec;
1021 const struct auto_pin_cfg *cfg = &spec->autocfg;
1024 spec->multiout.hp_nid = 0;
1025 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
1026 if (!spec->hp_independent_mode) {
1027 if (!spec->hp_indep_shared)
1028 spec->multiout.hp_nid = spec->hp_dac_nid;
1030 if (spec->hp_indep_shared)
1031 spec->multiout.num_dacs = cfg->line_outs - 1;
1033 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1034 set_stream_active(codec, true);
1035 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1038 spec->multiout.hp_nid = 0;
1039 set_stream_active(codec, false);
1045 static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
1046 struct hda_codec *codec,
1047 struct snd_pcm_substream *substream)
1049 struct via_spec *spec = codec->spec;
1051 spec->multiout.hp_nid = 0;
1052 set_stream_active(codec, false);
1056 static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1057 struct hda_codec *codec,
1058 struct snd_pcm_substream *substream)
1060 struct via_spec *spec = codec->spec;
1062 if (snd_BUG_ON(!spec->hp_dac_nid))
1064 if (!spec->hp_independent_mode || spec->multiout.hp_nid)
1066 set_stream_active(codec, true);
1070 static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1071 struct hda_codec *codec,
1072 struct snd_pcm_substream *substream)
1074 set_stream_active(codec, false);
1078 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1079 struct hda_codec *codec,
1080 unsigned int stream_tag,
1081 unsigned int format,
1082 struct snd_pcm_substream *substream)
1084 struct via_spec *spec = codec->spec;
1086 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1088 vt1708_start_hp_work(spec);
1092 static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1093 struct hda_codec *codec,
1094 unsigned int stream_tag,
1095 unsigned int format,
1096 struct snd_pcm_substream *substream)
1098 struct via_spec *spec = codec->spec;
1100 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1101 stream_tag, 0, format);
1102 vt1708_start_hp_work(spec);
1106 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1107 struct hda_codec *codec,
1108 struct snd_pcm_substream *substream)
1110 struct via_spec *spec = codec->spec;
1112 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1113 vt1708_stop_hp_work(spec);
1117 static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1118 struct hda_codec *codec,
1119 struct snd_pcm_substream *substream)
1121 struct via_spec *spec = codec->spec;
1123 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1124 vt1708_stop_hp_work(spec);
1131 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1132 struct hda_codec *codec,
1133 struct snd_pcm_substream *substream)
1135 struct via_spec *spec = codec->spec;
1136 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1139 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1140 struct hda_codec *codec,
1141 struct snd_pcm_substream *substream)
1143 struct via_spec *spec = codec->spec;
1144 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1147 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1148 struct hda_codec *codec,
1149 unsigned int stream_tag,
1150 unsigned int format,
1151 struct snd_pcm_substream *substream)
1153 struct via_spec *spec = codec->spec;
1154 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1155 stream_tag, format, substream);
1158 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1159 struct hda_codec *codec,
1160 struct snd_pcm_substream *substream)
1162 struct via_spec *spec = codec->spec;
1163 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1170 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1171 struct hda_codec *codec,
1172 unsigned int stream_tag,
1173 unsigned int format,
1174 struct snd_pcm_substream *substream)
1176 struct via_spec *spec = codec->spec;
1178 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1179 stream_tag, 0, format);
1183 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1184 struct hda_codec *codec,
1185 struct snd_pcm_substream *substream)
1187 struct via_spec *spec = codec->spec;
1188 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1192 /* analog capture with dynamic ADC switching */
1193 static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1194 struct hda_codec *codec,
1195 unsigned int stream_tag,
1196 unsigned int format,
1197 struct snd_pcm_substream *substream)
1199 struct via_spec *spec = codec->spec;
1200 int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
1202 spec->cur_adc = spec->adc_nids[adc_idx];
1203 spec->cur_adc_stream_tag = stream_tag;
1204 spec->cur_adc_format = format;
1205 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
1209 static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1210 struct hda_codec *codec,
1211 struct snd_pcm_substream *substream)
1213 struct via_spec *spec = codec->spec;
1215 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1220 /* re-setup the stream if running; called from input-src put */
1221 static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
1223 struct via_spec *spec = codec->spec;
1224 int adc_idx = spec->inputs[cur].adc_idx;
1225 hda_nid_t adc = spec->adc_nids[adc_idx];
1227 if (spec->cur_adc && spec->cur_adc != adc) {
1228 /* stream is running, let's swap the current ADC */
1229 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1230 spec->cur_adc = adc;
1231 snd_hda_codec_setup_stream(codec, adc,
1232 spec->cur_adc_stream_tag, 0,
1233 spec->cur_adc_format);
1239 static const struct hda_pcm_stream via_pcm_analog_playback = {
1243 /* NID is set in via_build_pcms */
1245 .open = via_playback_multi_pcm_open,
1246 .close = via_playback_multi_pcm_close,
1247 .prepare = via_playback_multi_pcm_prepare,
1248 .cleanup = via_playback_multi_pcm_cleanup
1252 static const struct hda_pcm_stream via_pcm_hp_playback = {
1256 /* NID is set in via_build_pcms */
1258 .open = via_playback_hp_pcm_open,
1259 .close = via_playback_hp_pcm_close,
1260 .prepare = via_playback_hp_pcm_prepare,
1261 .cleanup = via_playback_hp_pcm_cleanup
1265 static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1269 /* NID is set in via_build_pcms */
1270 /* We got noisy outputs on the right channel on VT1708 when
1271 * 24bit samples are used. Until any workaround is found,
1272 * disable the 24bit format, so far.
1274 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1276 .open = via_playback_multi_pcm_open,
1277 .close = via_playback_multi_pcm_close,
1278 .prepare = via_playback_multi_pcm_prepare,
1279 .cleanup = via_playback_multi_pcm_cleanup
1283 static const struct hda_pcm_stream via_pcm_analog_capture = {
1284 .substreams = 1, /* will be changed in via_build_pcms() */
1287 /* NID is set in via_build_pcms */
1289 .prepare = via_capture_pcm_prepare,
1290 .cleanup = via_capture_pcm_cleanup
1294 static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
1298 /* NID is set in via_build_pcms */
1300 .prepare = via_dyn_adc_capture_pcm_prepare,
1301 .cleanup = via_dyn_adc_capture_pcm_cleanup,
1305 static const struct hda_pcm_stream via_pcm_digital_playback = {
1309 /* NID is set in via_build_pcms */
1311 .open = via_dig_playback_pcm_open,
1312 .close = via_dig_playback_pcm_close,
1313 .prepare = via_dig_playback_pcm_prepare,
1314 .cleanup = via_dig_playback_pcm_cleanup
1318 static const struct hda_pcm_stream via_pcm_digital_capture = {
1325 * slave controls for virtual master
1327 static const char * const via_slave_vols[] = {
1328 "Front Playback Volume",
1329 "Surround Playback Volume",
1330 "Center Playback Volume",
1331 "LFE Playback Volume",
1332 "Side Playback Volume",
1333 "Headphone Playback Volume",
1334 "Speaker Playback Volume",
1338 static const char * const via_slave_sws[] = {
1339 "Front Playback Switch",
1340 "Surround Playback Switch",
1341 "Center Playback Switch",
1342 "LFE Playback Switch",
1343 "Side Playback Switch",
1344 "Headphone Playback Switch",
1345 "Speaker Playback Switch",
1349 static int via_build_controls(struct hda_codec *codec)
1351 struct via_spec *spec = codec->spec;
1352 struct snd_kcontrol *kctl;
1355 if (spec->set_widgets_power_state)
1356 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1359 for (i = 0; i < spec->num_mixers; i++) {
1360 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1365 if (spec->multiout.dig_out_nid) {
1366 err = snd_hda_create_spdif_out_ctls(codec,
1367 spec->multiout.dig_out_nid,
1368 spec->multiout.dig_out_nid);
1371 err = snd_hda_create_spdif_share_sw(codec,
1375 spec->multiout.share_spdif = 1;
1377 if (spec->dig_in_nid) {
1378 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1383 /* if we have no master control, let's create it */
1384 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1385 unsigned int vmaster_tlv[4];
1386 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1387 HDA_OUTPUT, vmaster_tlv);
1388 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1389 vmaster_tlv, via_slave_vols);
1393 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1394 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1395 NULL, via_slave_sws);
1400 /* assign Capture Source enums to NID */
1401 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1402 for (i = 0; kctl && i < kctl->count; i++) {
1403 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1408 /* init power states */
1409 set_widgets_power_state(codec);
1410 analog_low_current_mode(codec);
1412 via_free_kctls(codec); /* no longer needed */
1416 static int via_build_pcms(struct hda_codec *codec)
1418 struct via_spec *spec = codec->spec;
1419 struct hda_pcm *info = spec->pcm_rec;
1421 codec->num_pcms = 1;
1422 codec->pcm_info = info;
1424 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1425 "%s Analog", codec->chip_name);
1426 info->name = spec->stream_name_analog;
1428 if (!spec->stream_analog_playback)
1429 spec->stream_analog_playback = &via_pcm_analog_playback;
1430 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1431 *spec->stream_analog_playback;
1432 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1433 spec->multiout.dac_nids[0];
1434 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1435 spec->multiout.max_channels;
1437 if (!spec->stream_analog_capture) {
1438 if (spec->dyn_adc_switch)
1439 spec->stream_analog_capture =
1440 &via_pcm_dyn_adc_analog_capture;
1442 spec->stream_analog_capture = &via_pcm_analog_capture;
1444 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1445 *spec->stream_analog_capture;
1446 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1447 if (!spec->dyn_adc_switch)
1448 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1451 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1454 snprintf(spec->stream_name_digital,
1455 sizeof(spec->stream_name_digital),
1456 "%s Digital", codec->chip_name);
1457 info->name = spec->stream_name_digital;
1458 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1459 if (spec->multiout.dig_out_nid) {
1460 if (!spec->stream_digital_playback)
1461 spec->stream_digital_playback =
1462 &via_pcm_digital_playback;
1463 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1464 *spec->stream_digital_playback;
1465 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1466 spec->multiout.dig_out_nid;
1468 if (spec->dig_in_nid) {
1469 if (!spec->stream_digital_capture)
1470 spec->stream_digital_capture =
1471 &via_pcm_digital_capture;
1472 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1473 *spec->stream_digital_capture;
1474 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1479 if (spec->hp_dac_nid) {
1482 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1483 "%s HP", codec->chip_name);
1484 info->name = spec->stream_name_hp;
1485 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1486 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1492 static void via_free(struct hda_codec *codec)
1494 struct via_spec *spec = codec->spec;
1499 via_free_kctls(codec);
1500 vt1708_stop_hp_work(spec);
1501 kfree(spec->bind_cap_vol);
1502 kfree(spec->bind_cap_sw);
1506 /* mute/unmute outputs */
1507 static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1508 hda_nid_t *pins, bool mute)
1511 for (i = 0; i < num_pins; i++) {
1512 unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
1513 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1514 if (parm & AC_PINCTL_IN_EN)
1517 parm &= ~AC_PINCTL_OUT_EN;
1519 parm |= AC_PINCTL_OUT_EN;
1520 snd_hda_codec_write(codec, pins[i], 0,
1521 AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
1525 /* mute internal speaker if line-out is plugged */
1526 static void via_line_automute(struct hda_codec *codec, int present)
1528 struct via_spec *spec = codec->spec;
1530 if (!spec->autocfg.speaker_outs)
1533 present = snd_hda_jack_detect(codec,
1534 spec->autocfg.line_out_pins[0]);
1535 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1536 spec->autocfg.speaker_pins,
1540 /* mute internal speaker if HP is plugged */
1541 static void via_hp_automute(struct hda_codec *codec)
1545 struct via_spec *spec = codec->spec;
1547 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
1548 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1550 if (spec->smart51_enabled)
1551 nums = spec->autocfg.line_outs + spec->smart51_nums;
1553 nums = spec->autocfg.line_outs;
1554 toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
1556 via_line_automute(codec, present);
1559 static void via_gpio_control(struct hda_codec *codec)
1561 unsigned int gpio_data;
1562 unsigned int vol_counter;
1564 unsigned int master_vol;
1566 struct via_spec *spec = codec->spec;
1568 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
1569 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
1571 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
1572 0xF84, 0) & 0x3F0000) >> 16;
1574 vol = vol_counter & 0x1F;
1575 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
1576 AC_VERB_GET_AMP_GAIN_MUTE,
1579 if (gpio_data == 0x02) {
1580 /* unmute line out */
1581 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1582 AC_VERB_SET_PIN_WIDGET_CONTROL,
1584 if (vol_counter & 0x20) {
1585 /* decrease volume */
1586 if (vol > master_vol)
1588 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1592 /* increase volume */
1593 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1595 ((master_vol+vol) > 0x2A) ? 0x2A :
1598 } else if (!(gpio_data & 0x02)) {
1600 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1601 AC_VERB_SET_PIN_WIDGET_CONTROL,
1606 /* unsolicited event for jack sensing */
1607 static void via_unsol_event(struct hda_codec *codec,
1612 if (res & VIA_JACK_EVENT)
1613 set_widgets_power_state(codec);
1615 res &= ~VIA_JACK_EVENT;
1617 if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
1618 via_hp_automute(codec);
1619 else if (res == VIA_GPIO_EVENT)
1620 via_gpio_control(codec);
1623 #ifdef SND_HDA_NEEDS_RESUME
1624 static int via_suspend(struct hda_codec *codec, pm_message_t state)
1626 struct via_spec *spec = codec->spec;
1627 vt1708_stop_hp_work(spec);
1632 #ifdef CONFIG_SND_HDA_POWER_SAVE
1633 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1635 struct via_spec *spec = codec->spec;
1636 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1643 static int via_init(struct hda_codec *codec);
1645 static const struct hda_codec_ops via_patch_ops = {
1646 .build_controls = via_build_controls,
1647 .build_pcms = via_build_pcms,
1650 .unsol_event = via_unsol_event,
1651 #ifdef SND_HDA_NEEDS_RESUME
1652 .suspend = via_suspend,
1654 #ifdef CONFIG_SND_HDA_POWER_SAVE
1655 .check_power_status = via_check_power_status,
1659 static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1661 struct via_spec *spec = codec->spec;
1664 for (i = 0; i < spec->multiout.num_dacs; i++) {
1665 if (spec->multiout.dac_nids[i] == dac)
1668 if (spec->hp_dac_nid == dac)
1673 static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1674 hda_nid_t target_dac, struct nid_path *path,
1675 int depth, int wid_type)
1680 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1681 for (i = 0; i < nums; i++) {
1682 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1684 if (conn[i] == target_dac || is_empty_dac(codec, conn[i]))
1687 if (depth >= MAX_NID_PATH_DEPTH)
1689 for (i = 0; i < nums; i++) {
1691 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1692 if (type == AC_WID_AUD_OUT ||
1693 (wid_type != -1 && type != wid_type))
1695 if (__parse_output_path(codec, conn[i], target_dac,
1696 path, depth + 1, AC_WID_AUD_SEL))
1702 path->path[path->depth] = conn[i];
1703 path->idx[path->depth] = i;
1704 if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
1705 path->multi[path->depth] = 1;
1710 static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1711 hda_nid_t target_dac, struct nid_path *path)
1713 if (__parse_output_path(codec, nid, target_dac, path, 1, -1)) {
1714 path->path[path->depth] = nid;
1721 static int via_auto_fill_dac_nids(struct hda_codec *codec)
1723 struct via_spec *spec = codec->spec;
1724 const struct auto_pin_cfg *cfg = &spec->autocfg;
1728 spec->multiout.dac_nids = spec->private_dac_nids;
1730 for (i = 0; i < cfg->line_outs; i++) {
1731 nid = cfg->line_out_pins[i];
1734 if (parse_output_path(codec, nid, 0, &spec->out_path[i])) {
1735 spec->private_dac_nids[i] = spec->out_path[i].path[0];
1739 spec->multiout.num_dacs = dac_num;
1743 static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
1744 int chs, bool check_dac, struct nid_path *path)
1746 struct via_spec *spec = codec->spec;
1748 hda_nid_t dac, pin, sel, nid;
1751 dac = check_dac ? path->path[0] : 0;
1752 pin = path->path[path->depth - 1];
1753 sel = path->depth > 1 ? path->path[1] : 0;
1755 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1757 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1759 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1764 sprintf(name, "%s Playback Volume", pfx);
1765 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1766 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1769 path->vol_ctl = nid;
1772 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
1774 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
1776 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
1781 sprintf(name, "%s Playback Switch", pfx);
1782 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1783 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1786 path->mute_ctl = nid;
1791 static void mangle_smart51(struct hda_codec *codec)
1793 struct via_spec *spec = codec->spec;
1794 struct auto_pin_cfg *cfg = &spec->autocfg;
1795 struct auto_pin_cfg_item *ins = cfg->inputs;
1796 int i, j, nums, attr;
1797 int pins[AUTO_CFG_MAX_INS];
1799 for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
1801 for (i = 0; i < cfg->num_inputs; i++) {
1803 if (ins[i].type > AUTO_PIN_LINE_IN)
1805 def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
1806 if (snd_hda_get_input_pin_attr(def) != attr)
1808 for (j = 0; j < nums; j++)
1809 if (ins[pins[j]].type < ins[i].type) {
1810 memmove(pins + j + 1, pins + j,
1811 (nums - j) * sizeof(int));
1817 if (cfg->line_outs + nums < 3)
1819 for (i = 0; i < nums; i++) {
1820 hda_nid_t pin = ins[pins[i]].pin;
1821 spec->smart51_pins[spec->smart51_nums++] = pin;
1822 cfg->line_out_pins[cfg->line_outs++] = pin;
1823 if (cfg->line_outs == 3)
1830 /* add playback controls from the parsed DAC table */
1831 static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1833 struct via_spec *spec = codec->spec;
1834 struct auto_pin_cfg *cfg = &spec->autocfg;
1835 static const char * const chname[4] = {
1836 "Front", "Surround", "C/LFE", "Side"
1842 old_line_outs = cfg->line_outs;
1843 if (cfg->line_outs == 1)
1844 mangle_smart51(codec);
1846 err = via_auto_fill_dac_nids(codec);
1850 if (spec->multiout.num_dacs < 3) {
1851 spec->smart51_nums = 0;
1852 cfg->line_outs = old_line_outs;
1854 for (i = 0; i < cfg->line_outs; i++) {
1856 pin = cfg->line_out_pins[i];
1857 dac = spec->multiout.dac_nids[i];
1860 if (i == HDA_CLFE) {
1861 err = create_ch_ctls(codec, "Center", 1, true,
1862 &spec->out_path[i]);
1865 err = create_ch_ctls(codec, "LFE", 2, true,
1866 &spec->out_path[i]);
1870 const char *pfx = chname[i];
1871 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1872 cfg->line_outs == 1)
1874 err = create_ch_ctls(codec, pfx, 3, true,
1875 &spec->out_path[i]);
1881 idx = get_connection_index(codec, spec->aa_mix_nid,
1882 spec->multiout.dac_nids[0]);
1884 /* add control to mixer */
1885 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1886 "PCM Playback Volume",
1887 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1891 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1892 "PCM Playback Switch",
1893 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1899 cfg->line_outs = old_line_outs;
1904 static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1906 struct via_spec *spec = codec->spec;
1907 struct nid_path *path;
1914 if (parse_output_path(codec, pin, 0, &spec->hp_path))
1915 spec->hp_dac_nid = spec->hp_path.path[0];
1916 else if (spec->multiout.dac_nids[HDA_SIDE] &&
1917 parse_output_path(codec, pin,
1918 spec->multiout.dac_nids[HDA_SIDE],
1920 spec->hp_dac_nid = spec->hp_path.path[0];
1921 spec->hp_indep_shared = true;
1922 } else if (spec->multiout.dac_nids[HDA_CLFE] &&
1923 parse_output_path(codec, pin,
1924 spec->multiout.dac_nids[HDA_CLFE],
1926 spec->hp_dac_nid = spec->hp_path.path[0];
1927 spec->hp_indep_shared = true;
1930 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1931 &spec->hp_dep_path) &&
1935 if (spec->hp_dac_nid && !spec->hp_indep_shared) {
1936 path = &spec->hp_path;
1939 path = &spec->hp_dep_path;
1942 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
1945 if (spec->hp_dac_nid) {
1946 spec->hp_dep_path.vol_ctl = spec->hp_path.vol_ctl;
1947 spec->hp_dep_path.mute_ctl = spec->hp_path.mute_ctl;
1953 static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1955 struct via_spec *spec = codec->spec;
1958 pin = spec->autocfg.speaker_pins[0];
1959 if (!spec->autocfg.speaker_outs || !pin)
1962 if (parse_output_path(codec, pin, 0, &spec->speaker_path)) {
1963 dac = spec->speaker_path.path[0];
1964 spec->multiout.extra_out_nid[0] = dac;
1965 return create_ch_ctls(codec, "Speaker", 3, true,
1966 &spec->speaker_path);
1968 if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1969 &spec->speaker_path))
1970 return create_ch_ctls(codec, "Speaker", 3, false,
1971 &spec->speaker_path);
1977 static int via_fill_adcs(struct hda_codec *codec)
1979 struct via_spec *spec = codec->spec;
1980 hda_nid_t nid = codec->start_nid;
1983 for (i = 0; i < codec->num_nodes; i++, nid++) {
1984 unsigned int wcaps = get_wcaps(codec, nid);
1985 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1987 if (wcaps & AC_WCAP_DIGITAL)
1989 if (!(wcaps & AC_WCAP_CONN_LIST))
1991 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
1993 spec->adc_nids[spec->num_adc_nids++] = nid;
1998 /* input-src control */
1999 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
2000 struct snd_ctl_elem_info *uinfo)
2002 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2003 struct via_spec *spec = codec->spec;
2005 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2007 uinfo->value.enumerated.items = spec->num_inputs;
2008 if (uinfo->value.enumerated.item >= spec->num_inputs)
2009 uinfo->value.enumerated.item = spec->num_inputs - 1;
2010 strcpy(uinfo->value.enumerated.name,
2011 spec->inputs[uinfo->value.enumerated.item].label);
2015 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
2016 struct snd_ctl_elem_value *ucontrol)
2018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2019 struct via_spec *spec = codec->spec;
2020 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2022 ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
2026 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2027 struct snd_ctl_elem_value *ucontrol)
2029 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2030 struct via_spec *spec = codec->spec;
2031 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2035 cur = ucontrol->value.enumerated.item[0];
2036 if (cur < 0 || cur >= spec->num_inputs)
2038 if (spec->cur_mux[idx] == cur)
2040 spec->cur_mux[idx] = cur;
2041 if (spec->dyn_adc_switch) {
2042 int adc_idx = spec->inputs[cur].adc_idx;
2043 mux = spec->mux_nids[adc_idx];
2044 via_dyn_adc_pcm_resetup(codec, cur);
2046 mux = spec->mux_nids[idx];
2047 if (snd_BUG_ON(!mux))
2052 /* switch to D0 beofre change index */
2053 if (snd_hda_codec_read(codec, mux, 0,
2054 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2055 snd_hda_codec_write(codec, mux, 0,
2056 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2057 snd_hda_codec_write(codec, mux, 0,
2058 AC_VERB_SET_CONNECT_SEL,
2059 spec->inputs[cur].mux_idx);
2062 /* update jack power state */
2063 set_widgets_power_state(codec);
2067 static const struct snd_kcontrol_new via_input_src_ctl = {
2068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2069 /* The multiple "Capture Source" controls confuse alsamixer
2070 * So call somewhat different..
2072 /* .name = "Capture Source", */
2073 .name = "Input Source",
2074 .info = via_mux_enum_info,
2075 .get = via_mux_enum_get,
2076 .put = via_mux_enum_put,
2079 static int create_input_src_ctls(struct hda_codec *codec, int count)
2081 struct via_spec *spec = codec->spec;
2082 struct snd_kcontrol_new *knew;
2084 if (spec->num_inputs <= 1 || !count)
2085 return 0; /* no need for single src */
2087 knew = via_clone_control(spec, &via_input_src_ctl);
2090 knew->count = count;
2094 /* add the powersave loopback-list entry */
2095 static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2097 struct hda_amp_list *list;
2099 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2101 list = spec->loopback_list + spec->num_loopbacks;
2103 list->dir = HDA_INPUT;
2105 spec->num_loopbacks++;
2106 spec->loopback.amplist = spec->loopback_list;
2109 static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
2112 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
2115 /* add the input-route to the given pin */
2116 static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
2118 struct via_spec *spec = codec->spec;
2121 spec->inputs[spec->num_inputs].adc_idx = -1;
2122 spec->inputs[spec->num_inputs].pin = pin;
2123 for (c = 0; c < spec->num_adc_nids; c++) {
2124 if (spec->mux_nids[c]) {
2125 idx = get_connection_index(codec, spec->mux_nids[c],
2129 spec->inputs[spec->num_inputs].mux_idx = idx;
2131 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
2134 spec->inputs[spec->num_inputs].adc_idx = c;
2135 /* Can primary ADC satisfy all inputs? */
2136 if (!spec->dyn_adc_switch &&
2137 spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
2138 snd_printd(KERN_INFO
2139 "via: dynamic ADC switching enabled\n");
2140 spec->dyn_adc_switch = 1;
2147 static int get_mux_nids(struct hda_codec *codec);
2149 /* parse input-routes; fill ADCs, MUXs and input-src entries */
2150 static int parse_analog_inputs(struct hda_codec *codec)
2152 struct via_spec *spec = codec->spec;
2153 const struct auto_pin_cfg *cfg = &spec->autocfg;
2156 err = via_fill_adcs(codec);
2159 err = get_mux_nids(codec);
2163 /* fill all input-routes */
2164 for (i = 0; i < cfg->num_inputs; i++) {
2165 if (add_input_route(codec, cfg->inputs[i].pin))
2166 spec->inputs[spec->num_inputs++].label =
2167 hda_get_autocfg_input_label(codec, cfg, i);
2170 /* check for internal loopback recording */
2171 if (spec->aa_mix_nid &&
2172 add_input_route(codec, spec->aa_mix_nid))
2173 spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
2178 /* create analog-loopback volume/switch controls */
2179 static int create_loopback_ctls(struct hda_codec *codec)
2181 struct via_spec *spec = codec->spec;
2182 const struct auto_pin_cfg *cfg = &spec->autocfg;
2183 const char *prev_label = NULL;
2187 if (!spec->aa_mix_nid)
2190 for (i = 0; i < cfg->num_inputs; i++) {
2191 hda_nid_t pin = cfg->inputs[i].pin;
2192 const char *label = hda_get_autocfg_input_label(codec, cfg, i);
2194 if (prev_label && !strcmp(label, prev_label))
2199 idx = get_connection_index(codec, spec->aa_mix_nid, pin);
2201 err = via_new_analog_input(spec, label, type_idx,
2202 idx, spec->aa_mix_nid);
2205 add_loopback_list(spec, spec->aa_mix_nid, idx);
2208 /* remember the label for smart51 control */
2209 for (j = 0; j < spec->smart51_nums; j++) {
2210 if (spec->smart51_pins[j] == pin) {
2211 spec->smart51_idxs[j] = idx;
2212 spec->smart51_labels[j] = label;
2220 /* create mic-boost controls (if present) */
2221 static int create_mic_boost_ctls(struct hda_codec *codec)
2223 struct via_spec *spec = codec->spec;
2224 const struct auto_pin_cfg *cfg = &spec->autocfg;
2227 for (i = 0; i < cfg->num_inputs; i++) {
2228 hda_nid_t pin = cfg->inputs[i].pin;
2233 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2235 caps = query_amp_caps(codec, pin, HDA_INPUT);
2236 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2238 label = hda_get_autocfg_input_label(codec, cfg, i);
2239 snprintf(name, sizeof(name), "%s Boost Volume", label);
2240 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2241 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2248 /* create capture and input-src controls for multiple streams */
2249 static int create_multi_adc_ctls(struct hda_codec *codec)
2251 struct via_spec *spec = codec->spec;
2254 /* create capture mixer elements */
2255 for (i = 0; i < spec->num_adc_nids; i++) {
2256 hda_nid_t adc = spec->adc_nids[i];
2257 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
2258 "Capture Volume", i,
2259 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2263 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2264 "Capture Switch", i,
2265 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2271 /* input-source control */
2272 for (i = 0; i < spec->num_adc_nids; i++)
2273 if (!spec->mux_nids[i])
2275 err = create_input_src_ctls(codec, i);
2281 /* bind capture volume/switch */
2282 static struct snd_kcontrol_new via_bind_cap_vol_ctl =
2283 HDA_BIND_VOL("Capture Volume", 0);
2284 static struct snd_kcontrol_new via_bind_cap_sw_ctl =
2285 HDA_BIND_SW("Capture Switch", 0);
2287 static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
2288 struct hda_ctl_ops *ops)
2290 struct hda_bind_ctls *ctl;
2293 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
2297 for (i = 0; i < spec->num_adc_nids; i++)
2299 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
2304 /* create capture and input-src controls for dynamic ADC-switch case */
2305 static int create_dyn_adc_ctls(struct hda_codec *codec)
2307 struct via_spec *spec = codec->spec;
2308 struct snd_kcontrol_new *knew;
2311 /* set up the bind capture ctls */
2312 err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
2315 err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
2319 /* create capture mixer elements */
2320 knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
2323 knew->private_value = (long)spec->bind_cap_vol;
2325 knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
2328 knew->private_value = (long)spec->bind_cap_sw;
2330 /* input-source control */
2331 err = create_input_src_ctls(codec, 1);
2337 /* parse and create capture-related stuff */
2338 static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
2340 struct via_spec *spec = codec->spec;
2343 err = parse_analog_inputs(codec);
2346 if (spec->dyn_adc_switch)
2347 err = create_dyn_adc_ctls(codec);
2349 err = create_multi_adc_ctls(codec);
2352 err = create_loopback_ctls(codec);
2355 err = create_mic_boost_ctls(codec);
2361 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2363 unsigned int def_conf;
2364 unsigned char seqassoc;
2366 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2367 seqassoc = (unsigned char) get_defcfg_association(def_conf);
2368 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2369 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2370 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2371 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2372 snd_hda_codec_set_pincfg(codec, nid, def_conf);
2378 static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
2379 struct snd_ctl_elem_value *ucontrol)
2381 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2382 struct via_spec *spec = codec->spec;
2384 if (spec->codec_type != VT1708)
2386 spec->vt1708_jack_detect =
2387 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2388 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
2392 static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
2393 struct snd_ctl_elem_value *ucontrol)
2395 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2396 struct via_spec *spec = codec->spec;
2399 if (spec->codec_type != VT1708)
2401 spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
2402 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2403 == !spec->vt1708_jack_detect;
2404 if (spec->vt1708_jack_detect) {
2405 mute_aa_path(codec, 1);
2406 notify_aa_path_ctls(codec);
2411 static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2413 .name = "Jack Detect",
2415 .info = snd_ctl_boolean_mono_info,
2416 .get = vt1708_jack_detect_get,
2417 .put = vt1708_jack_detect_put,
2420 static void fill_dig_outs(struct hda_codec *codec);
2421 static void fill_dig_in(struct hda_codec *codec);
2423 static int via_parse_auto_config(struct hda_codec *codec)
2425 struct via_spec *spec = codec->spec;
2428 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2431 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2434 err = via_auto_create_multi_out_ctls(codec);
2437 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
2440 err = via_auto_create_speaker_ctls(codec);
2443 err = via_auto_create_analog_input_ctls(codec);
2447 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2449 fill_dig_outs(codec);
2452 if (spec->kctls.list)
2453 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2456 if (spec->hp_dac_nid && spec->hp_dep_path.depth) {
2457 err = via_hp_build(codec);
2462 err = via_smart51_build(codec);
2466 /* assign slave outs */
2467 if (spec->slave_dig_outs[0])
2468 codec->slave_dig_outs = spec->slave_dig_outs;
2473 static void via_auto_init_dig_outs(struct hda_codec *codec)
2475 struct via_spec *spec = codec->spec;
2476 if (spec->multiout.dig_out_nid)
2477 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2478 if (spec->slave_dig_outs[0])
2479 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2482 static void via_auto_init_dig_in(struct hda_codec *codec)
2484 struct via_spec *spec = codec->spec;
2485 if (!spec->dig_in_nid)
2487 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2488 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2491 /* initialize the unsolicited events */
2492 static void via_auto_init_unsol_event(struct hda_codec *codec)
2494 struct via_spec *spec = codec->spec;
2495 struct auto_pin_cfg *cfg = &spec->autocfg;
2499 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2500 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2501 AC_VERB_SET_UNSOLICITED_ENABLE,
2502 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2504 if (cfg->speaker_pins[0])
2505 ev = VIA_LINE_EVENT;
2508 for (i = 0; i < cfg->line_outs; i++) {
2509 if (cfg->line_out_pins[i] &&
2510 is_jack_detectable(codec, cfg->line_out_pins[i]))
2511 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
2512 AC_VERB_SET_UNSOLICITED_ENABLE,
2513 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2516 for (i = 0; i < cfg->num_inputs; i++) {
2517 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2518 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2519 AC_VERB_SET_UNSOLICITED_ENABLE,
2520 AC_USRSP_EN | VIA_JACK_EVENT);
2524 static int via_init(struct hda_codec *codec)
2526 struct via_spec *spec = codec->spec;
2529 for (i = 0; i < spec->num_iverbs; i++)
2530 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2532 via_auto_init_multi_out(codec);
2533 via_auto_init_hp_out(codec);
2534 via_auto_init_speaker_out(codec);
2535 via_auto_init_analog_input(codec);
2536 via_auto_init_dig_outs(codec);
2537 via_auto_init_dig_in(codec);
2539 via_auto_init_unsol_event(codec);
2541 via_hp_automute(codec);
2546 static void vt1708_update_hp_jack_state(struct work_struct *work)
2548 struct via_spec *spec = container_of(work, struct via_spec,
2549 vt1708_hp_work.work);
2550 if (spec->codec_type != VT1708)
2552 /* if jack state toggled */
2553 if (spec->vt1708_hp_present
2554 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2555 spec->vt1708_hp_present ^= 1;
2556 via_hp_automute(spec->codec);
2558 vt1708_start_hp_work(spec);
2561 static int get_mux_nids(struct hda_codec *codec)
2563 struct via_spec *spec = codec->spec;
2564 hda_nid_t nid, conn[8];
2568 for (i = 0; i < spec->num_adc_nids; i++) {
2569 nid = spec->adc_nids[i];
2571 type = get_wcaps_type(get_wcaps(codec, nid));
2572 if (type == AC_WID_PIN)
2574 n = snd_hda_get_connections(codec, nid, conn,
2579 spec->mux_nids[i] = nid;
2588 static int patch_vt1708(struct hda_codec *codec)
2590 struct via_spec *spec;
2593 /* create a codec specific record */
2594 spec = via_new_spec(codec);
2598 spec->aa_mix_nid = 0x17;
2600 /* Add HP and CD pin config connect bit re-config action */
2601 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2602 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2604 /* automatic parse from the BIOS config */
2605 err = via_parse_auto_config(codec);
2611 /* add jack detect on/off control */
2612 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2615 /* disable 32bit format on VT1708 */
2616 if (codec->vendor_id == 0x11061708)
2617 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2619 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
2621 codec->patch_ops = via_patch_ops;
2623 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2627 static int patch_vt1709(struct hda_codec *codec)
2629 struct via_spec *spec;
2632 /* create a codec specific record */
2633 spec = via_new_spec(codec);
2637 spec->aa_mix_nid = 0x18;
2639 err = via_parse_auto_config(codec);
2645 codec->patch_ops = via_patch_ops;
2650 static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2652 struct via_spec *spec = codec->spec;
2656 if ((spec->codec_type != VT1708B_4CH) &&
2657 (codec->vendor_id != 0x11064397))
2660 /* SW0 (17h) = stereo mixer */
2662 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
2663 == ((spec->codec_type == VT1708S) ? 5 : 0));
2665 /* PW 1/2/5 (1ah/1bh/1eh) */
2667 set_pin_power_state(codec, 0x1a, &parm);
2668 set_pin_power_state(codec, 0x1b, &parm);
2669 set_pin_power_state(codec, 0x1e, &parm);
2672 /* SW0 (17h), AIW 0/1 (13h/14h) */
2673 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
2674 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2675 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
2678 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
2680 set_pin_power_state(codec, 0x19, &parm);
2681 if (spec->smart51_enabled)
2682 set_pin_power_state(codec, 0x1b, &parm);
2683 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
2684 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
2686 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
2689 set_pin_power_state(codec, 0x22, &parm);
2690 if (spec->smart51_enabled)
2691 set_pin_power_state(codec, 0x1a, &parm);
2692 snd_hda_codec_write(codec, 0x26, 0,
2693 AC_VERB_SET_POWER_STATE, parm);
2694 snd_hda_codec_write(codec, 0x24, 0,
2695 AC_VERB_SET_POWER_STATE, parm);
2696 } else if (codec->vendor_id == 0x11064397) {
2697 /* PW7(23h), SW2(27h), AOW2(25h) */
2699 set_pin_power_state(codec, 0x23, &parm);
2700 if (spec->smart51_enabled)
2701 set_pin_power_state(codec, 0x1a, &parm);
2702 snd_hda_codec_write(codec, 0x27, 0,
2703 AC_VERB_SET_POWER_STATE, parm);
2704 snd_hda_codec_write(codec, 0x25, 0,
2705 AC_VERB_SET_POWER_STATE, parm);
2708 /* PW 3/4/7 (1ch/1dh/23h) */
2710 /* force to D0 for internal Speaker */
2711 set_pin_power_state(codec, 0x1c, &parm);
2712 set_pin_power_state(codec, 0x1d, &parm);
2714 set_pin_power_state(codec, 0x23, &parm);
2716 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
2717 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
2718 imux_is_smixer ? AC_PWRST_D0 : parm);
2719 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2721 snd_hda_codec_write(codec, 0x25, 0,
2722 AC_VERB_SET_POWER_STATE, parm);
2723 snd_hda_codec_write(codec, 0x27, 0,
2724 AC_VERB_SET_POWER_STATE, parm);
2725 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
2726 snd_hda_codec_write(codec, 0x25, 0,
2727 AC_VERB_SET_POWER_STATE, parm);
2730 static int patch_vt1708S(struct hda_codec *codec);
2731 static int patch_vt1708B(struct hda_codec *codec)
2733 struct via_spec *spec;
2736 if (get_codec_type(codec) == VT1708BCE)
2737 return patch_vt1708S(codec);
2739 /* create a codec specific record */
2740 spec = via_new_spec(codec);
2744 spec->aa_mix_nid = 0x16;
2746 /* automatic parse from the BIOS config */
2747 err = via_parse_auto_config(codec);
2753 codec->patch_ops = via_patch_ops;
2755 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2760 /* Patch for VT1708S */
2761 static const struct hda_verb vt1708S_init_verbs[] = {
2762 /* Enable Mic Boost Volume backdoor */
2764 /* don't bybass mixer */
2769 /* fill out digital output widgets; one for master and one for slave outputs */
2770 static void fill_dig_outs(struct hda_codec *codec)
2772 struct via_spec *spec = codec->spec;
2775 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2779 nid = spec->autocfg.dig_out_pins[i];
2782 conn = snd_hda_get_connections(codec, nid, &nid, 1);
2785 if (!spec->multiout.dig_out_nid)
2786 spec->multiout.dig_out_nid = nid;
2788 spec->slave_dig_outs[0] = nid;
2789 break; /* at most two dig outs */
2794 static void fill_dig_in(struct hda_codec *codec)
2796 struct via_spec *spec = codec->spec;
2800 if (!spec->autocfg.dig_in_pin)
2803 dig_nid = codec->start_nid;
2804 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2805 unsigned int wcaps = get_wcaps(codec, dig_nid);
2806 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2808 if (!(wcaps & AC_WCAP_DIGITAL))
2810 if (!(wcaps & AC_WCAP_CONN_LIST))
2812 err = get_connection_index(codec, dig_nid,
2813 spec->autocfg.dig_in_pin);
2815 spec->dig_in_nid = dig_nid;
2821 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
2822 int offset, int num_steps, int step_size)
2824 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
2825 (offset << AC_AMPCAP_OFFSET_SHIFT) |
2826 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
2827 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
2828 (0 << AC_AMPCAP_MUTE_SHIFT));
2831 static int patch_vt1708S(struct hda_codec *codec)
2833 struct via_spec *spec;
2836 /* create a codec specific record */
2837 spec = via_new_spec(codec);
2841 spec->aa_mix_nid = 0x16;
2842 override_mic_boost(codec, 0x1a, 0, 3, 40);
2843 override_mic_boost(codec, 0x1e, 0, 3, 40);
2845 /* automatic parse from the BIOS config */
2846 err = via_parse_auto_config(codec);
2852 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
2854 codec->patch_ops = via_patch_ops;
2856 /* correct names for VT1708BCE */
2857 if (get_codec_type(codec) == VT1708BCE) {
2858 kfree(codec->chip_name);
2859 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
2860 snprintf(codec->bus->card->mixername,
2861 sizeof(codec->bus->card->mixername),
2862 "%s %s", codec->vendor_name, codec->chip_name);
2864 /* correct names for VT1705 */
2865 if (codec->vendor_id == 0x11064397) {
2866 kfree(codec->chip_name);
2867 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
2868 snprintf(codec->bus->card->mixername,
2869 sizeof(codec->bus->card->mixername),
2870 "%s %s", codec->vendor_name, codec->chip_name);
2872 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2876 /* Patch for VT1702 */
2878 static const struct hda_verb vt1702_init_verbs[] = {
2886 static void set_widgets_power_state_vt1702(struct hda_codec *codec)
2888 int imux_is_smixer =
2889 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
2892 /* PW 1/2/5 (14h/15h/18h) */
2894 set_pin_power_state(codec, 0x14, &parm);
2895 set_pin_power_state(codec, 0x15, &parm);
2896 set_pin_power_state(codec, 0x18, &parm);
2898 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
2899 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
2900 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2901 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
2902 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
2903 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
2906 /* PW 3/4 (16h/17h) */
2908 set_pin_power_state(codec, 0x17, &parm);
2909 set_pin_power_state(codec, 0x16, &parm);
2910 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
2911 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
2912 imux_is_smixer ? AC_PWRST_D0 : parm);
2913 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2914 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
2917 static int patch_vt1702(struct hda_codec *codec)
2919 struct via_spec *spec;
2922 /* create a codec specific record */
2923 spec = via_new_spec(codec);
2927 spec->aa_mix_nid = 0x1a;
2929 /* limit AA path volume to 0 dB */
2930 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
2931 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2932 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2933 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2934 (1 << AC_AMPCAP_MUTE_SHIFT));
2936 /* automatic parse from the BIOS config */
2937 err = via_parse_auto_config(codec);
2943 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
2945 codec->patch_ops = via_patch_ops;
2947 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
2951 /* Patch for VT1718S */
2953 static const struct hda_verb vt1718S_init_verbs[] = {
2954 /* Enable MW0 adjust Gain 5 */
2956 /* Enable Boost Volume backdoor */
2962 static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
2964 struct via_spec *spec = codec->spec;
2967 /* MUX6 (1eh) = stereo mixer */
2969 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
2971 /* PW 5/6/7 (29h/2ah/2bh) */
2973 set_pin_power_state(codec, 0x29, &parm);
2974 set_pin_power_state(codec, 0x2a, &parm);
2975 set_pin_power_state(codec, 0x2b, &parm);
2978 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
2979 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
2980 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
2981 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2982 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
2985 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
2987 set_pin_power_state(codec, 0x27, &parm);
2988 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
2989 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
2991 /* PW2 (26h), AOW2 (ah) */
2993 set_pin_power_state(codec, 0x26, &parm);
2994 if (spec->smart51_enabled)
2995 set_pin_power_state(codec, 0x2b, &parm);
2996 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
2998 /* PW0 (24h), AOW0 (8h) */
3000 set_pin_power_state(codec, 0x24, &parm);
3001 if (!spec->hp_independent_mode) /* check for redirected HP */
3002 set_pin_power_state(codec, 0x28, &parm);
3003 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
3004 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
3005 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
3006 imux_is_smixer ? AC_PWRST_D0 : parm);
3008 /* PW1 (25h), AOW1 (9h) */
3010 set_pin_power_state(codec, 0x25, &parm);
3011 if (spec->smart51_enabled)
3012 set_pin_power_state(codec, 0x2a, &parm);
3013 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
3015 if (spec->hp_independent_mode) {
3016 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
3018 set_pin_power_state(codec, 0x28, &parm);
3019 snd_hda_codec_write(codec, 0x1b, 0,
3020 AC_VERB_SET_POWER_STATE, parm);
3021 snd_hda_codec_write(codec, 0x34, 0,
3022 AC_VERB_SET_POWER_STATE, parm);
3023 snd_hda_codec_write(codec, 0xc, 0,
3024 AC_VERB_SET_POWER_STATE, parm);
3028 /* Add a connection to the primary DAC from AA-mixer for some codecs
3029 * This isn't listed from the raw info, but the chip has a secret connection.
3031 static int add_secret_dac_path(struct hda_codec *codec)
3033 struct via_spec *spec = codec->spec;
3038 if (!spec->aa_mix_nid)
3040 nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
3041 ARRAY_SIZE(conn) - 1);
3042 for (i = 0; i < nums; i++) {
3043 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
3047 /* find the primary DAC and add to the connection list */
3048 nid = codec->start_nid;
3049 for (i = 0; i < codec->num_nodes; i++, nid++) {
3050 unsigned int caps = get_wcaps(codec, nid);
3051 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
3052 !(caps & AC_WCAP_DIGITAL)) {
3054 return snd_hda_override_conn_list(codec,
3063 static int patch_vt1718S(struct hda_codec *codec)
3065 struct via_spec *spec;
3068 /* create a codec specific record */
3069 spec = via_new_spec(codec);
3073 spec->aa_mix_nid = 0x21;
3074 override_mic_boost(codec, 0x2b, 0, 3, 40);
3075 override_mic_boost(codec, 0x29, 0, 3, 40);
3076 add_secret_dac_path(codec);
3078 /* automatic parse from the BIOS config */
3079 err = via_parse_auto_config(codec);
3085 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
3087 codec->patch_ops = via_patch_ops;
3089 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
3094 /* Patch for VT1716S */
3096 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
3097 struct snd_ctl_elem_info *uinfo)
3099 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
3101 uinfo->value.integer.min = 0;
3102 uinfo->value.integer.max = 1;
3106 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
3107 struct snd_ctl_elem_value *ucontrol)
3109 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3112 index = snd_hda_codec_read(codec, 0x26, 0,
3113 AC_VERB_GET_CONNECT_SEL, 0);
3115 *ucontrol->value.integer.value = index;
3120 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
3121 struct snd_ctl_elem_value *ucontrol)
3123 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3124 struct via_spec *spec = codec->spec;
3125 int index = *ucontrol->value.integer.value;
3127 snd_hda_codec_write(codec, 0x26, 0,
3128 AC_VERB_SET_CONNECT_SEL, index);
3129 spec->dmic_enabled = index;
3130 set_widgets_power_state(codec);
3134 static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
3135 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
3137 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3138 .name = "Digital Mic Capture Switch",
3139 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
3141 .info = vt1716s_dmic_info,
3142 .get = vt1716s_dmic_get,
3143 .put = vt1716s_dmic_put,
3149 /* mono-out mixer elements */
3150 static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
3151 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
3155 static const struct hda_verb vt1716S_init_verbs[] = {
3156 /* Enable Boost Volume backdoor */
3158 /* don't bybass mixer */
3160 /* Enable mono output */
3165 static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3167 struct via_spec *spec = codec->spec;
3170 unsigned int mono_out, present;
3171 /* SW0 (17h) = stereo mixer */
3173 (snd_hda_codec_read(codec, 0x17, 0,
3174 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
3176 /* PW 1/2/5 (1ah/1bh/1eh) */
3178 set_pin_power_state(codec, 0x1a, &parm);
3179 set_pin_power_state(codec, 0x1b, &parm);
3180 set_pin_power_state(codec, 0x1e, &parm);
3183 /* SW0 (17h), AIW0(13h) */
3184 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
3185 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3188 set_pin_power_state(codec, 0x1e, &parm);
3190 if (spec->dmic_enabled)
3191 set_pin_power_state(codec, 0x22, &parm);
3193 snd_hda_codec_write(codec, 0x22, 0,
3194 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3196 /* SW2(26h), AIW1(14h) */
3197 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
3198 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
3201 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
3203 set_pin_power_state(codec, 0x19, &parm);
3204 /* Smart 5.1 PW2(1bh) */
3205 if (spec->smart51_enabled)
3206 set_pin_power_state(codec, 0x1b, &parm);
3207 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3208 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3210 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
3212 set_pin_power_state(codec, 0x23, &parm);
3213 /* Smart 5.1 PW1(1ah) */
3214 if (spec->smart51_enabled)
3215 set_pin_power_state(codec, 0x1a, &parm);
3216 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
3218 /* Smart 5.1 PW5(1eh) */
3219 if (spec->smart51_enabled)
3220 set_pin_power_state(codec, 0x1e, &parm);
3221 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
3224 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
3225 present = snd_hda_jack_detect(codec, 0x1c);
3230 present = snd_hda_jack_detect(codec, 0x1d);
3231 if (!spec->hp_independent_mode && present)
3236 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
3237 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
3238 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
3239 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
3241 /* PW 3/4 (1ch/1dh) */
3243 set_pin_power_state(codec, 0x1c, &parm);
3244 set_pin_power_state(codec, 0x1d, &parm);
3245 /* HP Independent Mode, power on AOW3 */
3246 if (spec->hp_independent_mode)
3247 snd_hda_codec_write(codec, 0x25, 0,
3248 AC_VERB_SET_POWER_STATE, parm);
3250 /* force to D0 for internal Speaker */
3251 /* MW0 (16h), AOW0 (10h) */
3252 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3253 imux_is_smixer ? AC_PWRST_D0 : parm);
3254 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
3255 mono_out ? AC_PWRST_D0 : parm);
3258 static int patch_vt1716S(struct hda_codec *codec)
3260 struct via_spec *spec;
3263 /* create a codec specific record */
3264 spec = via_new_spec(codec);
3268 spec->aa_mix_nid = 0x16;
3269 override_mic_boost(codec, 0x1a, 0, 3, 40);
3270 override_mic_boost(codec, 0x1e, 0, 3, 40);
3272 /* automatic parse from the BIOS config */
3273 err = via_parse_auto_config(codec);
3279 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
3281 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
3284 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
3286 codec->patch_ops = via_patch_ops;
3288 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
3294 static const struct hda_verb vt2002P_init_verbs[] = {
3295 /* Class-D speaker related verbs */
3299 /* Enable Boost Volume backdoor */
3301 /* Enable AOW0 to MW9 */
3306 static const struct hda_verb vt1802_init_verbs[] = {
3307 /* Enable Boost Volume backdoor */
3309 /* Enable AOW0 to MW9 */
3314 static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3316 struct via_spec *spec = codec->spec;
3319 unsigned int present;
3320 /* MUX9 (1eh) = stereo mixer */
3322 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3324 /* PW 5/6/7 (29h/2ah/2bh) */
3326 set_pin_power_state(codec, 0x29, &parm);
3327 set_pin_power_state(codec, 0x2a, &parm);
3328 set_pin_power_state(codec, 0x2b, &parm);
3330 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
3331 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3332 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3333 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3334 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3338 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
3340 if (spec->codec_type == VT1802) {
3341 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3343 set_pin_power_state(codec, 0x28, &parm);
3344 snd_hda_codec_write(codec, 0x18, 0,
3345 AC_VERB_SET_POWER_STATE, parm);
3346 snd_hda_codec_write(codec, 0x38, 0,
3347 AC_VERB_SET_POWER_STATE, parm);
3349 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
3351 set_pin_power_state(codec, 0x26, &parm);
3352 snd_hda_codec_write(codec, 0x1c, 0,
3353 AC_VERB_SET_POWER_STATE, parm);
3354 snd_hda_codec_write(codec, 0x37, 0,
3355 AC_VERB_SET_POWER_STATE, parm);
3358 if (spec->codec_type == VT1802) {
3359 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3361 set_pin_power_state(codec, 0x25, &parm);
3362 snd_hda_codec_write(codec, 0x15, 0,
3363 AC_VERB_SET_POWER_STATE, parm);
3364 snd_hda_codec_write(codec, 0x35, 0,
3365 AC_VERB_SET_POWER_STATE, parm);
3367 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
3369 set_pin_power_state(codec, 0x25, &parm);
3370 snd_hda_codec_write(codec, 0x19, 0,
3371 AC_VERB_SET_POWER_STATE, parm);
3372 snd_hda_codec_write(codec, 0x35, 0,
3373 AC_VERB_SET_POWER_STATE, parm);
3376 if (spec->hp_independent_mode)
3377 snd_hda_codec_write(codec, 0x9, 0,
3378 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3381 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
3382 present = snd_hda_jack_detect(codec, 0x25);
3385 set_pin_power_state(codec, 0x24, &parm);
3386 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3387 if (spec->codec_type == VT1802)
3388 snd_hda_codec_write(codec, 0x14, 0,
3389 AC_VERB_SET_POWER_STATE, parm);
3391 snd_hda_codec_write(codec, 0x18, 0,
3392 AC_VERB_SET_POWER_STATE, parm);
3393 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
3396 present = snd_hda_jack_detect(codec, 0x26);
3398 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3399 if (spec->codec_type == VT1802) {
3400 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
3401 snd_hda_codec_write(codec, 0x33, 0,
3402 AC_VERB_SET_POWER_STATE, parm);
3403 snd_hda_codec_write(codec, 0x1c, 0,
3404 AC_VERB_SET_POWER_STATE, parm);
3405 snd_hda_codec_write(codec, 0x3c, 0,
3406 AC_VERB_SET_POWER_STATE, parm);
3408 /* PW15 (31h), MW8(17h), MUX8(3bh) */
3409 snd_hda_codec_write(codec, 0x31, 0,
3410 AC_VERB_SET_POWER_STATE, parm);
3411 snd_hda_codec_write(codec, 0x17, 0,
3412 AC_VERB_SET_POWER_STATE, parm);
3413 snd_hda_codec_write(codec, 0x3b, 0,
3414 AC_VERB_SET_POWER_STATE, parm);
3417 if (imux_is_smixer || !is_aa_path_mute(codec))
3418 snd_hda_codec_write(codec, 0x21, 0,
3419 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3421 snd_hda_codec_write(codec, 0x21, 0,
3422 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3425 /* patch for vt2002P */
3426 static int patch_vt2002P(struct hda_codec *codec)
3428 struct via_spec *spec;
3431 /* create a codec specific record */
3432 spec = via_new_spec(codec);
3436 spec->aa_mix_nid = 0x21;
3437 override_mic_boost(codec, 0x2b, 0, 3, 40);
3438 override_mic_boost(codec, 0x29, 0, 3, 40);
3439 add_secret_dac_path(codec);
3441 /* automatic parse from the BIOS config */
3442 err = via_parse_auto_config(codec);
3448 if (spec->codec_type == VT1802)
3449 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
3451 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
3453 codec->patch_ops = via_patch_ops;
3455 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
3461 static const struct hda_verb vt1812_init_verbs[] = {
3462 /* Enable Boost Volume backdoor */
3464 /* Enable AOW0 to MW9 */
3469 static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3471 struct via_spec *spec = codec->spec;
3472 int imux_is_smixer =
3473 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3475 unsigned int present;
3476 /* MUX10 (1eh) = stereo mixer */
3478 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
3480 /* PW 5/6/7 (29h/2ah/2bh) */
3482 set_pin_power_state(codec, 0x29, &parm);
3483 set_pin_power_state(codec, 0x2a, &parm);
3484 set_pin_power_state(codec, 0x2b, &parm);
3486 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
3487 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3488 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3489 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3490 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3494 snd_hda_codec_write(codec, 0x8, 0,
3495 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3497 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3499 set_pin_power_state(codec, 0x28, &parm);
3500 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3501 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
3503 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3505 set_pin_power_state(codec, 0x25, &parm);
3506 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
3507 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
3508 if (spec->hp_independent_mode)
3509 snd_hda_codec_write(codec, 0x9, 0,
3510 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3512 /* Internal Speaker */
3513 /* PW0 (24h), MW0(14h), MUX0(34h) */
3514 present = snd_hda_jack_detect(codec, 0x25);
3517 set_pin_power_state(codec, 0x24, &parm);
3519 snd_hda_codec_write(codec, 0x14, 0,
3520 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3521 snd_hda_codec_write(codec, 0x34, 0,
3522 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3524 snd_hda_codec_write(codec, 0x14, 0,
3525 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3526 snd_hda_codec_write(codec, 0x34, 0,
3527 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3532 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
3533 present = snd_hda_jack_detect(codec, 0x28);
3536 set_pin_power_state(codec, 0x31, &parm);
3538 snd_hda_codec_write(codec, 0x1c, 0,
3539 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3540 snd_hda_codec_write(codec, 0x3c, 0,
3541 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3542 snd_hda_codec_write(codec, 0x3e, 0,
3543 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3545 snd_hda_codec_write(codec, 0x1c, 0,
3546 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3547 snd_hda_codec_write(codec, 0x3c, 0,
3548 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3549 snd_hda_codec_write(codec, 0x3e, 0,
3550 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3553 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
3555 set_pin_power_state(codec, 0x33, &parm);
3556 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
3557 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
3561 /* patch for vt1812 */
3562 static int patch_vt1812(struct hda_codec *codec)
3564 struct via_spec *spec;
3567 /* create a codec specific record */
3568 spec = via_new_spec(codec);
3572 spec->aa_mix_nid = 0x21;
3573 override_mic_boost(codec, 0x2b, 0, 3, 40);
3574 override_mic_boost(codec, 0x29, 0, 3, 40);
3575 add_secret_dac_path(codec);
3577 /* automatic parse from the BIOS config */
3578 err = via_parse_auto_config(codec);
3584 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
3586 codec->patch_ops = via_patch_ops;
3588 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
3595 static const struct hda_codec_preset snd_hda_preset_via[] = {
3596 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3597 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3598 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3599 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3600 { .id = 0x1106e710, .name = "VT1709 10-Ch",
3601 .patch = patch_vt1709},
3602 { .id = 0x1106e711, .name = "VT1709 10-Ch",
3603 .patch = patch_vt1709},
3604 { .id = 0x1106e712, .name = "VT1709 10-Ch",
3605 .patch = patch_vt1709},
3606 { .id = 0x1106e713, .name = "VT1709 10-Ch",
3607 .patch = patch_vt1709},
3608 { .id = 0x1106e714, .name = "VT1709 6-Ch",
3609 .patch = patch_vt1709},
3610 { .id = 0x1106e715, .name = "VT1709 6-Ch",
3611 .patch = patch_vt1709},
3612 { .id = 0x1106e716, .name = "VT1709 6-Ch",
3613 .patch = patch_vt1709},
3614 { .id = 0x1106e717, .name = "VT1709 6-Ch",
3615 .patch = patch_vt1709},
3616 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3617 .patch = patch_vt1708B},
3618 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3619 .patch = patch_vt1708B},
3620 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3621 .patch = patch_vt1708B},
3622 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3623 .patch = patch_vt1708B},
3624 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3625 .patch = patch_vt1708B},
3626 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3627 .patch = patch_vt1708B},
3628 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3629 .patch = patch_vt1708B},
3630 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3631 .patch = patch_vt1708B},
3632 { .id = 0x11060397, .name = "VT1708S",
3633 .patch = patch_vt1708S},
3634 { .id = 0x11061397, .name = "VT1708S",
3635 .patch = patch_vt1708S},
3636 { .id = 0x11062397, .name = "VT1708S",
3637 .patch = patch_vt1708S},
3638 { .id = 0x11063397, .name = "VT1708S",
3639 .patch = patch_vt1708S},
3640 { .id = 0x11064397, .name = "VT1705",
3641 .patch = patch_vt1708S},
3642 { .id = 0x11065397, .name = "VT1708S",
3643 .patch = patch_vt1708S},
3644 { .id = 0x11066397, .name = "VT1708S",
3645 .patch = patch_vt1708S},
3646 { .id = 0x11067397, .name = "VT1708S",
3647 .patch = patch_vt1708S},
3648 { .id = 0x11060398, .name = "VT1702",
3649 .patch = patch_vt1702},
3650 { .id = 0x11061398, .name = "VT1702",
3651 .patch = patch_vt1702},
3652 { .id = 0x11062398, .name = "VT1702",
3653 .patch = patch_vt1702},
3654 { .id = 0x11063398, .name = "VT1702",
3655 .patch = patch_vt1702},
3656 { .id = 0x11064398, .name = "VT1702",
3657 .patch = patch_vt1702},
3658 { .id = 0x11065398, .name = "VT1702",
3659 .patch = patch_vt1702},
3660 { .id = 0x11066398, .name = "VT1702",
3661 .patch = patch_vt1702},
3662 { .id = 0x11067398, .name = "VT1702",
3663 .patch = patch_vt1702},
3664 { .id = 0x11060428, .name = "VT1718S",
3665 .patch = patch_vt1718S},
3666 { .id = 0x11064428, .name = "VT1718S",
3667 .patch = patch_vt1718S},
3668 { .id = 0x11060441, .name = "VT2020",
3669 .patch = patch_vt1718S},
3670 { .id = 0x11064441, .name = "VT1828S",
3671 .patch = patch_vt1718S},
3672 { .id = 0x11060433, .name = "VT1716S",
3673 .patch = patch_vt1716S},
3674 { .id = 0x1106a721, .name = "VT1716S",
3675 .patch = patch_vt1716S},
3676 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
3677 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
3678 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
3679 { .id = 0x11060440, .name = "VT1818S",
3680 .patch = patch_vt1708S},
3681 { .id = 0x11060446, .name = "VT1802",
3682 .patch = patch_vt2002P},
3683 { .id = 0x11068446, .name = "VT1802",
3684 .patch = patch_vt2002P},
3688 MODULE_ALIAS("snd-hda-codec-id:1106*");
3690 static struct hda_codec_preset_list via_list = {
3691 .preset = snd_hda_preset_via,
3692 .owner = THIS_MODULE,
3695 MODULE_LICENSE("GPL");
3696 MODULE_DESCRIPTION("VIA HD-audio codec");
3698 static int __init patch_via_init(void)
3700 return snd_hda_add_codec_preset(&via_list);
3703 static void __exit patch_via_exit(void)
3705 snd_hda_delete_codec_preset(&via_list);
3708 module_init(patch_via_init)
3709 module_exit(patch_via_exit)