2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
6 * (C) 2006-2009 VIA Technology, Inc.
7 * (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
26 /* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
27 /* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
28 /* 2006-08-02 Lydia Wang Add support to VT1709 codec */
29 /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
30 /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
31 /* 2007-09-17 Lydia Wang Add VT1708B codec support */
32 /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
33 /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
34 /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */
35 /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */
36 /* 2008-04-09 Lydia Wang Add Independent HP feature */
37 /* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
38 /* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
39 /* 2009-02-16 Logan Li Add support for VT1718S */
40 /* 2009-03-13 Logan Li Add support for VT1716S */
41 /* 2009-04-14 Lydai Wang Add support for VT1828S and VT2020 */
42 /* 2009-07-08 Lydia Wang Add support for VT2002P */
43 /* 2009-07-21 Lydia Wang Add support for VT1812 */
44 /* 2009-09-19 Lydia Wang Add support for VT1818S */
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49 #include <linux/init.h>
50 #include <linux/delay.h>
51 #include <linux/slab.h>
52 #include <sound/core.h>
53 #include <sound/asoundef.h>
54 #include "hda_codec.h"
55 #include "hda_local.h"
57 #define NID_MAPPING (-1)
60 #define AMP_VAL_IDX_SHIFT 19
61 #define AMP_VAL_IDX_MASK (0x0f<<19)
64 #define VT1708_HP_NID 0x13
65 #define VT1708_DIGOUT_NID 0x14
66 #define VT1708_DIGIN_NID 0x16
67 #define VT1708_DIGIN_PIN 0x26
68 #define VT1708_HP_PIN_NID 0x20
69 #define VT1708_CD_PIN_NID 0x24
71 #define VT1709_HP_DAC_NID 0x28
72 #define VT1709_DIGOUT_NID 0x13
73 #define VT1709_DIGIN_NID 0x17
74 #define VT1709_DIGIN_PIN 0x25
76 #define VT1708B_HP_NID 0x25
77 #define VT1708B_DIGOUT_NID 0x12
78 #define VT1708B_DIGIN_NID 0x15
79 #define VT1708B_DIGIN_PIN 0x21
81 #define VT1708S_HP_NID 0x25
82 #define VT1708S_DIGOUT_NID 0x12
84 #define VT1702_HP_NID 0x17
85 #define VT1702_DIGOUT_NID 0x11
105 #define VT2002P_COMPATIBLE(spec) \
106 ((spec)->codec_type == VT2002P ||\
107 (spec)->codec_type == VT1812 ||\
108 (spec)->codec_type == VT1802)
117 /* codec parameterization */
118 const struct snd_kcontrol_new *mixers[6];
119 unsigned int num_mixers;
121 const struct hda_verb *init_verbs[5];
122 unsigned int num_iverbs;
124 char stream_name_analog[32];
125 char stream_name_hp[32];
126 const struct hda_pcm_stream *stream_analog_playback;
127 const struct hda_pcm_stream *stream_analog_capture;
129 char stream_name_digital[32];
130 const struct hda_pcm_stream *stream_digital_playback;
131 const struct hda_pcm_stream *stream_digital_capture;
134 struct hda_multi_out multiout;
135 hda_nid_t slave_dig_outs[2];
136 hda_nid_t hp_dac_nid;
138 struct nid_path out_path[4];
139 struct nid_path hp_path;
140 struct nid_path hp_dep_path;
141 struct nid_path speaker_path;
144 unsigned int num_adc_nids;
145 hda_nid_t adc_nids[3];
146 hda_nid_t mux_nids[3];
147 hda_nid_t aa_mix_nid;
148 hda_nid_t dig_in_nid;
149 hda_nid_t dig_in_pin;
152 const struct hda_input_mux *input_mux;
153 unsigned int cur_mux[3];
155 /* PCM information */
156 struct hda_pcm pcm_rec[3];
158 /* dynamic controls, init_verbs and input_mux */
159 struct auto_pin_cfg autocfg;
160 struct snd_array kctls;
161 struct hda_input_mux private_imux[2];
162 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
165 const struct hda_input_mux *hp_mux;
166 unsigned int hp_independent_mode;
167 unsigned int hp_independent_mode_index;
168 unsigned int can_smart51;
169 unsigned int smart51_enabled;
170 unsigned int dmic_enabled;
171 unsigned int no_pin_power_ctl;
172 enum VIA_HDA_CODEC codec_type;
174 /* work to check hp jack state */
175 struct hda_codec *codec;
176 struct delayed_work vt1708_hp_work;
177 int vt1708_jack_detect;
178 int vt1708_hp_present;
180 void (*set_widgets_power_state)(struct hda_codec *codec);
182 #ifdef CONFIG_SND_HDA_POWER_SAVE
183 struct hda_loopback_check loopback;
187 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
188 static struct via_spec * via_new_spec(struct hda_codec *codec)
190 struct via_spec *spec;
192 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
198 spec->codec_type = get_codec_type(codec);
199 /* VT1708BCE & VT1708S are almost same */
200 if (spec->codec_type == VT1708BCE)
201 spec->codec_type = VT1708S;
205 static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
207 u32 vendor_id = codec->vendor_id;
208 u16 ven_id = vendor_id >> 16;
209 u16 dev_id = vendor_id & 0xffff;
210 enum VIA_HDA_CODEC codec_type;
213 if (ven_id != 0x1106)
214 codec_type = UNKNOWN;
215 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
217 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
218 codec_type = VT1709_10CH;
219 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
220 codec_type = VT1709_6CH;
221 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
222 codec_type = VT1708B_8CH;
223 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
224 codec_type = VT1708BCE;
225 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
226 codec_type = VT1708B_4CH;
227 else if ((dev_id & 0xfff) == 0x397
228 && (dev_id >> 12) < 8)
229 codec_type = VT1708S;
230 else if ((dev_id & 0xfff) == 0x398
231 && (dev_id >> 12) < 8)
233 else if ((dev_id & 0xfff) == 0x428
234 && (dev_id >> 12) < 8)
235 codec_type = VT1718S;
236 else if (dev_id == 0x0433 || dev_id == 0xa721)
237 codec_type = VT1716S;
238 else if (dev_id == 0x0441 || dev_id == 0x4441)
239 codec_type = VT1718S;
240 else if (dev_id == 0x0438 || dev_id == 0x4438)
241 codec_type = VT2002P;
242 else if (dev_id == 0x0448)
244 else if (dev_id == 0x0440)
245 codec_type = VT1708S;
246 else if ((dev_id & 0xfff) == 0x446)
249 codec_type = UNKNOWN;
253 #define VIA_JACK_EVENT 0x20
254 #define VIA_HP_EVENT 0x01
255 #define VIA_GPIO_EVENT 0x02
256 #define VIA_LINE_EVENT 0x03
261 VIA_CTL_WIDGET_ANALOG_MUTE,
264 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
265 static int is_aa_path_mute(struct hda_codec *codec);
267 static void vt1708_start_hp_work(struct via_spec *spec)
269 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
271 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
272 !spec->vt1708_jack_detect);
273 if (!delayed_work_pending(&spec->vt1708_hp_work))
274 schedule_delayed_work(&spec->vt1708_hp_work,
275 msecs_to_jiffies(100));
278 static void vt1708_stop_hp_work(struct via_spec *spec)
280 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
282 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
283 && !is_aa_path_mute(spec->codec))
285 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
286 !spec->vt1708_jack_detect);
287 cancel_delayed_work_sync(&spec->vt1708_hp_work);
290 static void set_widgets_power_state(struct hda_codec *codec)
292 struct via_spec *spec = codec->spec;
293 if (spec->set_widgets_power_state)
294 spec->set_widgets_power_state(codec);
297 static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_value *ucontrol)
300 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
301 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
303 set_widgets_power_state(codec);
304 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1);
305 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
306 if (is_aa_path_mute(codec))
307 vt1708_start_hp_work(codec->spec);
309 vt1708_stop_hp_work(codec->spec);
314 /* modify .put = snd_hda_mixer_amp_switch_put */
315 #define ANALOG_INPUT_MUTE \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
319 .info = snd_hda_mixer_amp_switch_info, \
320 .get = snd_hda_mixer_amp_switch_get, \
321 .put = analog_input_switch_put, \
322 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
324 static const struct snd_kcontrol_new via_control_templates[] = {
325 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
326 HDA_CODEC_MUTE(NULL, 0, 0, 0),
331 /* add dynamic controls */
332 static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
333 const struct snd_kcontrol_new *tmpl,
336 struct snd_kcontrol_new *knew;
338 snd_array_init(&spec->kctls, sizeof(*knew), 32);
339 knew = snd_array_new(&spec->kctls);
346 knew->name = kstrdup(name, GFP_KERNEL);
353 static int __via_add_control(struct via_spec *spec, int type, const char *name,
354 int idx, unsigned long val)
356 struct snd_kcontrol_new *knew;
358 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
362 if (get_amp_nid_(val))
363 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
364 knew->private_value = val;
368 #define via_add_control(spec, type, name, val) \
369 __via_add_control(spec, type, name, 0, val)
371 #define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
373 static void via_free_kctls(struct hda_codec *codec)
375 struct via_spec *spec = codec->spec;
377 if (spec->kctls.list) {
378 struct snd_kcontrol_new *kctl = spec->kctls.list;
380 for (i = 0; i < spec->kctls.used; i++)
383 snd_array_free(&spec->kctls);
386 /* create input playback/capture controls for the given pin */
387 static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
388 int type_idx, int idx, int mix_nid)
393 sprintf(name, "%s Playback Volume", ctlname);
394 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
395 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
398 sprintf(name, "%s Playback Switch", ctlname);
399 err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
400 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
406 /* return the index of the given widget nid as the source of mux;
407 * return -1 if not found;
408 * if num_conns is non-NULL, set the total number of connections
410 static int __get_connection_index(struct hda_codec *codec, hda_nid_t mux,
411 hda_nid_t nid, int *num_conns)
413 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
416 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
419 for (i = 0; i < nums; i++)
425 #define get_connection_index(codec, mux, nid) \
426 __get_connection_index(codec, mux, nid, NULL)
428 /* unmute input amp and select the specificed source */
429 static void unmute_and_select(struct hda_codec *codec, hda_nid_t nid,
430 hda_nid_t src, hda_nid_t mix)
434 idx = __get_connection_index(codec, nid, src, &num_conns);
438 /* select the route explicitly when multiple connections exist */
440 snd_hda_codec_write(codec, nid, 0,
441 AC_VERB_SET_CONNECT_SEL, idx);
442 /* unmute if the input amp is present */
443 if (!(query_amp_caps(codec, nid, HDA_INPUT) &
444 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE)))
446 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
449 /* unmute AA-path if present */
452 idx = __get_connection_index(codec, nid, mix, NULL);
454 snd_hda_codec_write(codec, nid, 0,
455 AC_VERB_SET_AMP_GAIN_MUTE,
459 /* set the given pin as output */
460 static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
465 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
467 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
468 snd_hda_codec_write(codec, pin, 0,
469 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
472 static void via_auto_init_output(struct hda_codec *codec, hda_nid_t pin,
473 int pin_type, struct nid_path *path)
475 struct via_spec *spec = codec->spec;
483 init_output_pin(codec, pin, pin_type);
484 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
485 if (caps & AC_AMPCAP_MUTE) {
487 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
488 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
492 /* initialize the output path */
494 for (i = 0; i < path->depth; i++) {
495 unmute_and_select(codec, nid, path->idx[i], spec->aa_mix_nid);
497 if (query_amp_caps(codec, nid, HDA_OUTPUT) &
498 (AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE))
499 snd_hda_codec_write(codec, nid, 0,
500 AC_VERB_SET_AMP_GAIN_MUTE,
506 static void via_auto_init_multi_out(struct hda_codec *codec)
508 struct via_spec *spec = codec->spec;
511 for (i = 0; i < spec->autocfg.line_outs; i++)
512 via_auto_init_output(codec, spec->autocfg.line_out_pins[i],
513 PIN_OUT, &spec->out_path[i]);
516 static void via_auto_init_hp_out(struct hda_codec *codec)
518 struct via_spec *spec = codec->spec;
520 if (spec->hp_dac_nid)
521 via_auto_init_output(codec, spec->autocfg.hp_pins[0], PIN_HP,
524 via_auto_init_output(codec, spec->autocfg.hp_pins[0], PIN_HP,
528 static void via_auto_init_speaker_out(struct hda_codec *codec)
530 struct via_spec *spec = codec->spec;
532 if (spec->autocfg.speaker_outs)
533 via_auto_init_output(codec, spec->autocfg.speaker_pins[0],
534 PIN_OUT, &spec->speaker_path);
537 static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
539 static void via_auto_init_analog_input(struct hda_codec *codec)
541 struct via_spec *spec = codec->spec;
542 const struct auto_pin_cfg *cfg = &spec->autocfg;
543 hda_nid_t conn[HDA_MAX_CONNECTIONS];
548 for (i = 0; i < spec->num_adc_nids; i++) {
549 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
550 AC_VERB_SET_AMP_GAIN_MUTE,
555 for (i = 0; i < cfg->num_inputs; i++) {
556 hda_nid_t nid = cfg->inputs[i].pin;
557 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
559 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
563 snd_hda_codec_write(codec, nid, 0,
564 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
568 for (i = 0; i < spec->num_adc_nids; i++) {
569 const struct hda_input_mux *imux = spec->input_mux;
570 if (!imux || !spec->mux_nids[i])
572 snd_hda_codec_write(codec, spec->mux_nids[i], 0,
573 AC_VERB_SET_CONNECT_SEL,
574 imux->items[spec->cur_mux[i]].index);
578 if (!spec->aa_mix_nid)
580 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
582 for (i = 0; i < num_conns; i++) {
583 unsigned int caps = get_wcaps(codec, conn[i]);
584 if (get_wcaps_type(caps) == AC_WID_PIN)
585 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
586 AC_VERB_SET_AMP_GAIN_MUTE,
591 static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
592 unsigned int *affected_parm)
595 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
596 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
597 >> AC_DEFCFG_MISC_SHIFT
598 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
599 struct via_spec *spec = codec->spec;
600 unsigned present = 0;
602 no_presence |= spec->no_pin_power_ctl;
604 present = snd_hda_jack_detect(codec, nid);
605 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
606 || ((no_presence || present)
607 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
608 *affected_parm = AC_PWRST_D0; /* if it's connected */
613 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
616 static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
617 struct snd_ctl_elem_info *uinfo)
619 static const char * const texts[] = {
620 "Disabled", "Enabled"
623 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
625 uinfo->value.enumerated.items = 2;
626 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
627 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
628 strcpy(uinfo->value.enumerated.name,
629 texts[uinfo->value.enumerated.item]);
633 static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
634 struct snd_ctl_elem_value *ucontrol)
636 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
637 struct via_spec *spec = codec->spec;
638 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
642 static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 struct via_spec *spec = codec->spec;
647 unsigned int val = !ucontrol->value.enumerated.item[0];
649 if (val == spec->no_pin_power_ctl)
651 spec->no_pin_power_ctl = val;
652 set_widgets_power_state(codec);
656 static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
658 .name = "Dynamic Power-Control",
659 .info = via_pin_power_ctl_info,
660 .get = via_pin_power_ctl_get,
661 .put = via_pin_power_ctl_put,
668 static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_info *uinfo)
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672 struct via_spec *spec = codec->spec;
673 return snd_hda_input_mux_info(spec->input_mux, uinfo);
676 static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *ucontrol)
679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
680 struct via_spec *spec = codec->spec;
681 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
683 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
687 static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
688 struct snd_ctl_elem_value *ucontrol)
690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
691 struct via_spec *spec = codec->spec;
692 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
695 if (!spec->mux_nids[adc_idx])
697 /* switch to D0 beofre change index */
698 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
699 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
700 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
701 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
703 ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
704 spec->mux_nids[adc_idx],
705 &spec->cur_mux[adc_idx]);
706 /* update jack power state */
707 set_widgets_power_state(codec);
712 static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
713 struct snd_ctl_elem_info *uinfo)
715 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716 struct via_spec *spec = codec->spec;
717 return snd_hda_input_mux_info(spec->hp_mux, uinfo);
720 static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *ucontrol)
723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
724 struct via_spec *spec = codec->spec;
726 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
730 static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
731 struct snd_ctl_elem_value *ucontrol)
733 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
734 struct via_spec *spec = codec->spec;
735 hda_nid_t nid = kcontrol->private_value;
736 unsigned int pinsel = ucontrol->value.enumerated.item[0];
737 /* Get Independent Mode index of headphone pin widget */
738 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
740 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, pinsel);
742 /* update jack power state */
743 set_widgets_power_state(codec);
747 static const struct snd_kcontrol_new via_hp_mixer = {
748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
749 .name = "Independent HP",
750 .info = via_independent_hp_info,
751 .get = via_independent_hp_get,
752 .put = via_independent_hp_put,
755 static int via_hp_build(struct hda_codec *codec)
757 struct via_spec *spec = codec->spec;
758 struct snd_kcontrol_new *knew;
761 nid = spec->autocfg.hp_pins[0];
762 knew = via_clone_control(spec, &via_hp_mixer);
766 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
767 knew->private_value = nid;
772 static void notify_aa_path_ctls(struct hda_codec *codec)
775 struct snd_ctl_elem_id id;
776 const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"};
777 struct snd_kcontrol *ctl;
779 memset(&id, 0, sizeof(id));
780 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
781 for (i = 0; i < ARRAY_SIZE(labels); i++) {
782 sprintf(id.name, "%s Playback Volume", labels[i]);
783 ctl = snd_hda_find_mixer_ctl(codec, id.name);
785 snd_ctl_notify(codec->bus->card,
786 SNDRV_CTL_EVENT_MASK_VALUE,
791 static void mute_aa_path(struct hda_codec *codec, int mute)
793 struct via_spec *spec = codec->spec;
797 /* get nid of MW0 and start & end index */
798 switch (spec->codec_type) {
822 /* check AA path's mute status */
823 for (i = start_idx; i <= end_idx; i++) {
824 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
825 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid, HDA_INPUT, i,
830 static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
832 struct via_spec *spec = codec->spec;
833 const struct auto_pin_cfg *cfg = &spec->autocfg;
836 for (i = 0; i < cfg->num_inputs; i++) {
838 if (pin != cfg->inputs[i].pin)
840 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
842 defcfg = snd_hda_codec_get_pincfg(codec, pin);
843 if (snd_hda_get_input_pin_attr(defcfg) < INPUT_PIN_ATTR_NORMAL)
850 static int via_smart51_info(struct snd_kcontrol *kcontrol,
851 struct snd_ctl_elem_info *uinfo)
853 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
855 uinfo->value.integer.min = 0;
856 uinfo->value.integer.max = 1;
860 static int via_smart51_get(struct snd_kcontrol *kcontrol,
861 struct snd_ctl_elem_value *ucontrol)
863 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
864 struct via_spec *spec = codec->spec;
865 const struct auto_pin_cfg *cfg = &spec->autocfg;
869 for (i = 0; i < cfg->num_inputs; i++) {
870 hda_nid_t nid = cfg->inputs[i].pin;
872 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
873 spec->hp_independent_mode && spec->codec_type != VT1718S)
874 continue; /* ignore FMic for independent HP */
875 if (!is_smart51_pins(codec, nid))
877 ctl = snd_hda_codec_read(codec, nid, 0,
878 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
879 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
882 *ucontrol->value.integer.value = on;
886 static int via_smart51_put(struct snd_kcontrol *kcontrol,
887 struct snd_ctl_elem_value *ucontrol)
889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
890 struct via_spec *spec = codec->spec;
891 const struct auto_pin_cfg *cfg = &spec->autocfg;
892 int out_in = *ucontrol->value.integer.value
893 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
896 for (i = 0; i < cfg->num_inputs; i++) {
897 hda_nid_t nid = cfg->inputs[i].pin;
900 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
901 spec->hp_independent_mode && spec->codec_type != VT1718S)
902 continue; /* don't retask FMic for independent HP */
903 if (!is_smart51_pins(codec, nid))
906 parm = snd_hda_codec_read(codec, nid, 0,
907 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
908 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
910 snd_hda_codec_write(codec, nid, 0,
911 AC_VERB_SET_PIN_WIDGET_CONTROL,
913 if (out_in == AC_PINCTL_OUT_EN) {
914 mute_aa_path(codec, 1);
915 notify_aa_path_ctls(codec);
918 spec->smart51_enabled = *ucontrol->value.integer.value;
919 set_widgets_power_state(codec);
923 static const struct snd_kcontrol_new via_smart51_mixer = {
924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
927 .info = via_smart51_info,
928 .get = via_smart51_get,
929 .put = via_smart51_put,
932 static int via_smart51_build(struct hda_codec *codec)
934 struct via_spec *spec = codec->spec;
935 struct snd_kcontrol_new *knew;
936 const struct auto_pin_cfg *cfg = &spec->autocfg;
940 if (!spec->can_smart51)
943 knew = via_clone_control(spec, &via_smart51_mixer);
947 for (i = 0; i < cfg->num_inputs; i++) {
948 nid = cfg->inputs[i].pin;
949 if (is_smart51_pins(codec, nid)) {
950 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
958 /* check AA path's mute statue */
959 static int is_aa_path_mute(struct hda_codec *codec)
965 struct via_spec *spec = codec->spec;
966 /* get nid of MW0 and start & end index */
967 switch (spec->codec_type) {
992 /* check AA path's mute status */
993 for (i = start_idx; i <= end_idx; i++) {
994 unsigned int con_list = snd_hda_codec_read(
995 codec, spec->aa_mix_nid, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
996 int shift = 8 * (i % 4);
997 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
998 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
999 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1000 /* check mute status while the pin is connected */
1001 int mute_l = snd_hda_codec_amp_read(codec, spec->aa_mix_nid, 0,
1003 int mute_r = snd_hda_codec_amp_read(codec, spec->aa_mix_nid, 1,
1005 if (!mute_l || !mute_r) {
1014 /* enter/exit analog low-current mode */
1015 static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1017 struct via_spec *spec = codec->spec;
1018 static int saved_stream_idle = 1; /* saved stream idle status */
1019 int enable = is_aa_path_mute(codec);
1020 unsigned int verb = 0;
1021 unsigned int parm = 0;
1023 if (stream_idle == -1) /* stream status did not change */
1024 enable = enable && saved_stream_idle;
1026 enable = enable && stream_idle;
1027 saved_stream_idle = stream_idle;
1030 /* decide low current mode's verb & parameter */
1031 switch (spec->codec_type) {
1035 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
1041 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
1045 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
1051 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
1054 return; /* other codecs are not supported */
1057 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
1061 * generic initialization of ADC, input mixers and output mixers
1063 static const struct hda_verb vt1708_init_verbs[] = {
1064 /* power down jack detect function */
1069 static void substream_set_idle(struct hda_codec *codec,
1070 struct snd_pcm_substream *substream)
1072 int idle = substream->pstr->substream_opened == 1
1073 && substream->ref_count == 0;
1074 analog_low_current_mode(codec, idle);
1077 static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
1078 struct hda_codec *codec,
1079 struct snd_pcm_substream *substream)
1081 struct via_spec *spec = codec->spec;
1083 if (!spec->hp_independent_mode)
1084 spec->multiout.hp_nid = spec->hp_dac_nid;
1085 substream_set_idle(codec, substream);
1086 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1090 static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
1091 struct hda_codec *codec,
1092 struct snd_pcm_substream *substream)
1094 struct via_spec *spec = codec->spec;
1096 spec->multiout.hp_nid = 0;
1097 substream_set_idle(codec, substream);
1101 static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1102 struct hda_codec *codec,
1103 struct snd_pcm_substream *substream)
1105 struct via_spec *spec = codec->spec;
1107 if (snd_BUG_ON(!spec->hp_dac_nid))
1109 if (!spec->hp_independent_mode || spec->multiout.hp_nid)
1111 substream_set_idle(codec, substream);
1115 static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1116 struct hda_codec *codec,
1117 struct snd_pcm_substream *substream)
1119 substream_set_idle(codec, substream);
1123 static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1124 struct hda_codec *codec,
1125 unsigned int stream_tag,
1126 unsigned int format,
1127 struct snd_pcm_substream *substream)
1129 struct via_spec *spec = codec->spec;
1131 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1133 vt1708_start_hp_work(spec);
1137 static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1138 struct hda_codec *codec,
1139 unsigned int stream_tag,
1140 unsigned int format,
1141 struct snd_pcm_substream *substream)
1143 struct via_spec *spec = codec->spec;
1145 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1146 stream_tag, 0, format);
1147 vt1708_start_hp_work(spec);
1151 static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1152 struct hda_codec *codec,
1153 struct snd_pcm_substream *substream)
1155 struct via_spec *spec = codec->spec;
1157 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1158 vt1708_stop_hp_work(spec);
1162 static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1163 struct hda_codec *codec,
1164 struct snd_pcm_substream *substream)
1166 struct via_spec *spec = codec->spec;
1168 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1169 vt1708_stop_hp_work(spec);
1176 static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1177 struct hda_codec *codec,
1178 struct snd_pcm_substream *substream)
1180 struct via_spec *spec = codec->spec;
1181 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1184 static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1185 struct hda_codec *codec,
1186 struct snd_pcm_substream *substream)
1188 struct via_spec *spec = codec->spec;
1189 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1192 static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1193 struct hda_codec *codec,
1194 unsigned int stream_tag,
1195 unsigned int format,
1196 struct snd_pcm_substream *substream)
1198 struct via_spec *spec = codec->spec;
1199 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1200 stream_tag, format, substream);
1203 static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1204 struct hda_codec *codec,
1205 struct snd_pcm_substream *substream)
1207 struct via_spec *spec = codec->spec;
1208 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
1215 static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1216 struct hda_codec *codec,
1217 unsigned int stream_tag,
1218 unsigned int format,
1219 struct snd_pcm_substream *substream)
1221 struct via_spec *spec = codec->spec;
1223 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1224 stream_tag, 0, format);
1228 static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1229 struct hda_codec *codec,
1230 struct snd_pcm_substream *substream)
1232 struct via_spec *spec = codec->spec;
1233 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
1237 static const struct hda_pcm_stream via_pcm_analog_playback = {
1241 /* NID is set in via_build_pcms */
1243 .open = via_playback_multi_pcm_open,
1244 .close = via_playback_multi_pcm_close,
1245 .prepare = via_playback_multi_pcm_prepare,
1246 .cleanup = via_playback_multi_pcm_cleanup
1250 static const struct hda_pcm_stream via_pcm_hp_playback = {
1254 /* NID is set in via_build_pcms */
1256 .open = via_playback_hp_pcm_open,
1257 .close = via_playback_hp_pcm_close,
1258 .prepare = via_playback_hp_pcm_prepare,
1259 .cleanup = via_playback_hp_pcm_cleanup
1263 static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1267 /* NID is set in via_build_pcms */
1268 /* We got noisy outputs on the right channel on VT1708 when
1269 * 24bit samples are used. Until any workaround is found,
1270 * disable the 24bit format, so far.
1272 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1274 .open = via_playback_multi_pcm_open,
1275 .close = via_playback_multi_pcm_close,
1276 .prepare = via_playback_multi_pcm_prepare,
1277 .cleanup = via_playback_multi_pcm_cleanup
1281 static const struct hda_pcm_stream via_pcm_analog_capture = {
1282 .substreams = 1, /* will be changed in via_build_pcms() */
1285 /* NID is set in via_build_pcms */
1287 .prepare = via_capture_pcm_prepare,
1288 .cleanup = via_capture_pcm_cleanup
1292 static const struct hda_pcm_stream via_pcm_digital_playback = {
1296 /* NID is set in via_build_pcms */
1298 .open = via_dig_playback_pcm_open,
1299 .close = via_dig_playback_pcm_close,
1300 .prepare = via_dig_playback_pcm_prepare,
1301 .cleanup = via_dig_playback_pcm_cleanup
1305 static const struct hda_pcm_stream via_pcm_digital_capture = {
1312 * slave controls for virtual master
1314 static const char * const via_slave_vols[] = {
1315 "Front Playback Volume",
1316 "Surround Playback Volume",
1317 "Center Playback Volume",
1318 "LFE Playback Volume",
1319 "Side Playback Volume",
1320 "Headphone Playback Volume",
1321 "Speaker Playback Volume",
1325 static const char * const via_slave_sws[] = {
1326 "Front Playback Switch",
1327 "Surround Playback Switch",
1328 "Center Playback Switch",
1329 "LFE Playback Switch",
1330 "Side Playback Switch",
1331 "Headphone Playback Switch",
1332 "Speaker Playback Switch",
1336 static int via_build_controls(struct hda_codec *codec)
1338 struct via_spec *spec = codec->spec;
1339 struct snd_kcontrol *kctl;
1340 const struct snd_kcontrol_new *knew;
1343 if (spec->set_widgets_power_state)
1344 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1347 for (i = 0; i < spec->num_mixers; i++) {
1348 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1353 if (spec->multiout.dig_out_nid) {
1354 err = snd_hda_create_spdif_out_ctls(codec,
1355 spec->multiout.dig_out_nid,
1356 spec->multiout.dig_out_nid);
1359 err = snd_hda_create_spdif_share_sw(codec,
1363 spec->multiout.share_spdif = 1;
1365 if (spec->dig_in_nid) {
1366 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1371 /* if we have no master control, let's create it */
1372 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1373 unsigned int vmaster_tlv[4];
1374 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1375 HDA_OUTPUT, vmaster_tlv);
1376 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1377 vmaster_tlv, via_slave_vols);
1381 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1382 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1383 NULL, via_slave_sws);
1388 /* assign Capture Source enums to NID */
1389 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1390 for (i = 0; kctl && i < kctl->count; i++) {
1391 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
1396 /* other nid->control mapping */
1397 for (i = 0; i < spec->num_mixers; i++) {
1398 for (knew = spec->mixers[i]; knew->name; knew++) {
1399 if (knew->iface != NID_MAPPING)
1401 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1404 err = snd_hda_add_nid(codec, kctl, 0,
1409 /* init power states */
1410 set_widgets_power_state(codec);
1411 analog_low_current_mode(codec, 1);
1413 via_free_kctls(codec); /* no longer needed */
1417 static int via_build_pcms(struct hda_codec *codec)
1419 struct via_spec *spec = codec->spec;
1420 struct hda_pcm *info = spec->pcm_rec;
1422 codec->num_pcms = 1;
1423 codec->pcm_info = info;
1425 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1426 "%s Analog", codec->chip_name);
1427 info->name = spec->stream_name_analog;
1429 if (!spec->stream_analog_playback)
1430 spec->stream_analog_playback = &via_pcm_analog_playback;
1431 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1432 *spec->stream_analog_playback;
1433 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1434 spec->multiout.dac_nids[0];
1435 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1436 spec->multiout.max_channels;
1438 if (!spec->stream_analog_capture)
1439 spec->stream_analog_capture = &via_pcm_analog_capture;
1440 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1441 *spec->stream_analog_capture;
1442 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1443 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1446 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1449 snprintf(spec->stream_name_digital,
1450 sizeof(spec->stream_name_digital),
1451 "%s Digital", codec->chip_name);
1452 info->name = spec->stream_name_digital;
1453 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1454 if (spec->multiout.dig_out_nid) {
1455 if (!spec->stream_digital_playback)
1456 spec->stream_digital_playback =
1457 &via_pcm_digital_playback;
1458 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1459 *spec->stream_digital_playback;
1460 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1461 spec->multiout.dig_out_nid;
1463 if (spec->dig_in_nid) {
1464 if (!spec->stream_digital_capture)
1465 spec->stream_digital_capture =
1466 &via_pcm_digital_capture;
1467 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1468 *spec->stream_digital_capture;
1469 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1474 if (spec->hp_dac_nid) {
1477 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1478 "%s HP", codec->chip_name);
1479 info->name = spec->stream_name_hp;
1480 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1481 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1487 static void via_free(struct hda_codec *codec)
1489 struct via_spec *spec = codec->spec;
1494 via_free_kctls(codec);
1495 vt1708_stop_hp_work(spec);
1499 /* mute/unmute outputs */
1500 static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1501 hda_nid_t *pins, bool mute)
1504 for (i = 0; i < num_pins; i++)
1505 snd_hda_codec_write(codec, pins[i], 0,
1506 AC_VERB_SET_PIN_WIDGET_CONTROL,
1507 mute ? 0 : PIN_OUT);
1510 /* mute internal speaker if line-out is plugged */
1511 static void via_line_automute(struct hda_codec *codec, int present)
1513 struct via_spec *spec = codec->spec;
1515 if (!spec->autocfg.speaker_outs)
1518 present = snd_hda_jack_detect(codec,
1519 spec->autocfg.line_out_pins[0]);
1520 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1521 spec->autocfg.speaker_pins,
1525 /* mute internal speaker if HP is plugged */
1526 static void via_hp_automute(struct hda_codec *codec)
1529 struct via_spec *spec = codec->spec;
1531 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0]) {
1532 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1533 toggle_output_mutes(codec, spec->autocfg.line_outs,
1534 spec->autocfg.line_out_pins,
1537 via_line_automute(codec, present);
1540 static void via_gpio_control(struct hda_codec *codec)
1542 unsigned int gpio_data;
1543 unsigned int vol_counter;
1545 unsigned int master_vol;
1547 struct via_spec *spec = codec->spec;
1549 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
1550 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
1552 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
1553 0xF84, 0) & 0x3F0000) >> 16;
1555 vol = vol_counter & 0x1F;
1556 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
1557 AC_VERB_GET_AMP_GAIN_MUTE,
1560 if (gpio_data == 0x02) {
1561 /* unmute line out */
1562 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1563 AC_VERB_SET_PIN_WIDGET_CONTROL,
1565 if (vol_counter & 0x20) {
1566 /* decrease volume */
1567 if (vol > master_vol)
1569 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1573 /* increase volume */
1574 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1576 ((master_vol+vol) > 0x2A) ? 0x2A :
1579 } else if (!(gpio_data & 0x02)) {
1581 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1582 AC_VERB_SET_PIN_WIDGET_CONTROL,
1587 /* unsolicited event for jack sensing */
1588 static void via_unsol_event(struct hda_codec *codec,
1593 if (res & VIA_JACK_EVENT)
1594 set_widgets_power_state(codec);
1596 res &= ~VIA_JACK_EVENT;
1598 if (res == VIA_HP_EVENT)
1599 via_hp_automute(codec);
1600 else if (res == VIA_GPIO_EVENT)
1601 via_gpio_control(codec);
1602 else if (res == VIA_LINE_EVENT)
1603 via_line_automute(codec, false);
1606 #ifdef SND_HDA_NEEDS_RESUME
1607 static int via_suspend(struct hda_codec *codec, pm_message_t state)
1609 struct via_spec *spec = codec->spec;
1610 vt1708_stop_hp_work(spec);
1615 #ifdef CONFIG_SND_HDA_POWER_SAVE
1616 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1618 struct via_spec *spec = codec->spec;
1619 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1626 static int via_init(struct hda_codec *codec);
1628 static const struct hda_codec_ops via_patch_ops = {
1629 .build_controls = via_build_controls,
1630 .build_pcms = via_build_pcms,
1633 .unsol_event = via_unsol_event,
1634 #ifdef SND_HDA_NEEDS_RESUME
1635 .suspend = via_suspend,
1637 #ifdef CONFIG_SND_HDA_POWER_SAVE
1638 .check_power_status = via_check_power_status,
1642 static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1644 struct via_spec *spec = codec->spec;
1647 for (i = 0; i < spec->multiout.num_dacs; i++) {
1648 if (spec->multiout.dac_nids[i] == dac)
1651 if (spec->hp_dac_nid == dac)
1656 static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1657 hda_nid_t target_dac, struct nid_path *path,
1658 int depth, int wid_type)
1663 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1664 for (i = 0; i < nums; i++) {
1665 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1667 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1668 path->path[depth] = conn[i];
1669 path->idx[depth] = i;
1670 path->depth = ++depth;
1676 for (i = 0; i < nums; i++) {
1678 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1679 if (type == AC_WID_AUD_OUT ||
1680 (wid_type != -1 && type != wid_type))
1682 if (parse_output_path(codec, conn[i], target_dac,
1683 path, depth + 1, AC_WID_AUD_SEL)) {
1684 path->path[depth] = conn[i];
1685 path->idx[depth] = i;
1692 static int via_auto_fill_dac_nids(struct hda_codec *codec)
1694 struct via_spec *spec = codec->spec;
1695 const struct auto_pin_cfg *cfg = &spec->autocfg;
1699 spec->multiout.dac_nids = spec->private_dac_nids;
1700 spec->multiout.num_dacs = cfg->line_outs;
1701 for (i = 0; i < cfg->line_outs; i++) {
1702 nid = cfg->line_out_pins[i];
1705 if (parse_output_path(codec, nid, 0, &spec->out_path[i], 0, -1))
1706 spec->private_dac_nids[i] =
1707 spec->out_path[i].path[spec->out_path[i].depth - 1];
1712 static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
1713 hda_nid_t pin, hda_nid_t dac, int chs)
1715 struct via_spec *spec = codec->spec;
1720 if (dac && query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
1722 else if (query_amp_caps(codec, pin, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
1727 sprintf(name, "%s Playback Volume", pfx);
1728 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1729 HDA_COMPOSE_AMP_VAL(dac, chs, 0, HDA_OUTPUT));
1734 if (dac && query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_MUTE)
1736 else if (query_amp_caps(codec, pin, HDA_OUTPUT) & AC_AMPCAP_MUTE)
1741 sprintf(name, "%s Playback Switch", pfx);
1742 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1743 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1750 static void mangle_smart51(struct hda_codec *codec)
1752 struct via_spec *spec = codec->spec;
1753 struct auto_pin_cfg *cfg = &spec->autocfg;
1756 for (i = 0; i < cfg->num_inputs; i++) {
1757 if (!is_smart51_pins(codec, cfg->inputs[i].pin))
1759 spec->can_smart51 = 1;
1760 cfg->line_out_pins[cfg->line_outs++] = cfg->inputs[i].pin;
1761 if (cfg->line_outs == 3)
1766 /* add playback controls from the parsed DAC table */
1767 static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1769 struct via_spec *spec = codec->spec;
1770 struct auto_pin_cfg *cfg = &spec->autocfg;
1771 static const char * const chname[4] = {
1772 "Front", "Surround", "C/LFE", "Side"
1778 old_line_outs = cfg->line_outs;
1779 if (cfg->line_outs == 1)
1780 mangle_smart51(codec);
1782 for (i = 0; i < cfg->line_outs; i++) {
1784 pin = cfg->line_out_pins[i];
1785 dac = spec->multiout.dac_nids[i];
1788 if (i == HDA_CLFE) {
1789 err = create_ch_ctls(codec, "Center", pin, dac, 1);
1792 err = create_ch_ctls(codec, "LFE", pin, dac, 2);
1796 err = create_ch_ctls(codec, chname[i], pin, dac, 3);
1802 idx = get_connection_index(codec, spec->aa_mix_nid,
1803 spec->multiout.dac_nids[0]);
1805 /* add control to mixer */
1806 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1807 "PCM Playback Volume",
1808 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1812 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1813 "PCM Playback Switch",
1814 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1820 cfg->line_outs = old_line_outs;
1825 static void create_hp_imux(struct via_spec *spec)
1828 struct hda_input_mux *imux = &spec->private_imux[1];
1829 static const char * const texts[] = { "OFF", "ON", NULL};
1831 /* for hp mode select */
1832 for (i = 0; texts[i]; i++)
1833 snd_hda_add_imux_item(imux, texts[i], i, NULL);
1835 spec->hp_mux = &spec->private_imux[1];
1838 static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1840 struct via_spec *spec = codec->spec;
1846 if (parse_output_path(codec, pin, 0, &spec->hp_path, 0, -1)) {
1847 spec->hp_dac_nid = spec->hp_path.path[spec->hp_path.depth - 1];
1848 spec->hp_independent_mode_index =
1849 spec->hp_path.idx[spec->hp_path.depth - 1];
1850 create_hp_imux(spec);
1853 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1854 &spec->hp_dep_path, 0, -1) &&
1859 err = create_ch_ctls(codec, "Headphone", pin, spec->hp_dac_nid, 3);
1866 static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1868 struct via_spec *spec = codec->spec;
1871 pin = spec->autocfg.speaker_pins[0];
1872 if (!spec->autocfg.speaker_outs || !pin)
1875 if (parse_output_path(codec, pin, 0, &spec->speaker_path, 0, -1)) {
1876 dac = spec->speaker_path.path[spec->speaker_path.depth - 1];
1877 spec->multiout.extra_out_nid[0] = dac;
1878 return create_ch_ctls(codec, "Speaker", pin, dac, 3);
1880 if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1881 &spec->speaker_path, 0, -1))
1882 return create_ch_ctls(codec, "Headphone", pin, 0, 3);
1888 static int via_fill_adcs(struct hda_codec *codec)
1890 struct via_spec *spec = codec->spec;
1891 hda_nid_t nid = codec->start_nid;
1894 for (i = 0; i < codec->num_nodes; i++, nid++) {
1895 unsigned int wcaps = get_wcaps(codec, nid);
1896 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1898 if (wcaps & AC_WCAP_DIGITAL)
1900 if (!(wcaps & AC_WCAP_CONN_LIST))
1902 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
1904 spec->adc_nids[spec->num_adc_nids++] = nid;
1909 static int get_mux_nids(struct hda_codec *codec);
1911 static const struct snd_kcontrol_new via_input_src_ctl = {
1912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1913 /* The multiple "Capture Source" controls confuse alsamixer
1914 * So call somewhat different..
1916 /* .name = "Capture Source", */
1917 .name = "Input Source",
1918 .info = via_mux_enum_info,
1919 .get = via_mux_enum_get,
1920 .put = via_mux_enum_put,
1923 /* create playback/capture controls for input pins */
1924 static int via_auto_create_analog_input_ctls(struct hda_codec *codec,
1925 const struct auto_pin_cfg *cfg)
1927 struct via_spec *spec = codec->spec;
1928 struct hda_input_mux *imux = &spec->private_imux[0];
1929 int i, err, idx, idx2, type, type_idx = 0;
1931 hda_nid_t pin_idxs[8];
1934 err = via_fill_adcs(codec);
1937 err = get_mux_nids(codec);
1940 cap_nid = spec->mux_nids[0];
1942 num_idxs = snd_hda_get_connections(codec, cap_nid, pin_idxs,
1943 ARRAY_SIZE(pin_idxs));
1947 /* for internal loopback recording select */
1948 for (idx = 0; idx < num_idxs; idx++) {
1949 if (pin_idxs[idx] == spec->aa_mix_nid) {
1950 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL);
1955 for (i = 0; i < cfg->num_inputs; i++) {
1957 type = cfg->inputs[i].type;
1958 for (idx = 0; idx < num_idxs; idx++)
1959 if (pin_idxs[idx] == cfg->inputs[i].pin)
1961 if (idx >= num_idxs)
1963 if (i > 0 && type == cfg->inputs[i - 1].type)
1967 label = hda_get_autocfg_input_label(codec, cfg, i);
1968 idx2 = get_connection_index(codec, spec->aa_mix_nid,
1971 err = via_new_analog_input(spec, label, type_idx,
1972 idx2, spec->aa_mix_nid);
1975 snd_hda_add_imux_item(imux, label, idx, NULL);
1978 /* create capture mixer elements */
1979 for (i = 0; i < spec->num_adc_nids; i++) {
1980 hda_nid_t adc = spec->adc_nids[i];
1981 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
1982 "Capture Volume", i,
1983 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
1987 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1988 "Capture Switch", i,
1989 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
1995 /* input-source control */
1996 for (i = 0; i < spec->num_adc_nids; i++)
1997 if (!spec->mux_nids[i])
2000 struct snd_kcontrol_new *knew;
2001 knew = via_clone_control(spec, &via_input_src_ctl);
2008 for (i = 0; i < cfg->num_inputs; i++) {
2009 hda_nid_t pin = cfg->inputs[i].pin;
2014 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2016 caps = query_amp_caps(codec, pin, HDA_INPUT);
2017 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2019 label = hda_get_autocfg_input_label(codec, cfg, i);
2020 snprintf(name, sizeof(name), "%s Boost Capture Volume", label);
2021 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2022 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2030 #ifdef CONFIG_SND_HDA_POWER_SAVE
2031 static const struct hda_amp_list vt1708_loopbacks[] = {
2032 { 0x17, HDA_INPUT, 1 },
2033 { 0x17, HDA_INPUT, 2 },
2034 { 0x17, HDA_INPUT, 3 },
2035 { 0x17, HDA_INPUT, 4 },
2040 static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2042 unsigned int def_conf;
2043 unsigned char seqassoc;
2045 def_conf = snd_hda_codec_get_pincfg(codec, nid);
2046 seqassoc = (unsigned char) get_defcfg_association(def_conf);
2047 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
2048 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2049 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2050 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2051 snd_hda_codec_set_pincfg(codec, nid, def_conf);
2057 static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
2058 struct snd_ctl_elem_value *ucontrol)
2060 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2061 struct via_spec *spec = codec->spec;
2063 if (spec->codec_type != VT1708)
2065 spec->vt1708_jack_detect =
2066 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2067 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
2071 static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
2072 struct snd_ctl_elem_value *ucontrol)
2074 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2075 struct via_spec *spec = codec->spec;
2078 if (spec->codec_type != VT1708)
2080 spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
2081 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2082 == !spec->vt1708_jack_detect;
2083 if (spec->vt1708_jack_detect) {
2084 mute_aa_path(codec, 1);
2085 notify_aa_path_ctls(codec);
2090 static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2091 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2092 .name = "Jack Detect",
2094 .info = snd_ctl_boolean_mono_info,
2095 .get = vt1708_jack_detect_get,
2096 .put = vt1708_jack_detect_put,
2099 static void fill_dig_outs(struct hda_codec *codec);
2100 static void fill_dig_in(struct hda_codec *codec);
2102 static int via_parse_auto_config(struct hda_codec *codec)
2104 struct via_spec *spec = codec->spec;
2107 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2110 err = via_auto_fill_dac_nids(codec);
2113 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2116 err = via_auto_create_multi_out_ctls(codec);
2119 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
2122 err = via_auto_create_speaker_ctls(codec);
2125 err = via_auto_create_analog_input_ctls(codec, &spec->autocfg);
2129 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2131 fill_dig_outs(codec);
2134 if (spec->kctls.list)
2135 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2137 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
2139 spec->input_mux = &spec->private_imux[0];
2142 err = via_hp_build(codec);
2147 err = via_smart51_build(codec);
2151 /* assign slave outs */
2152 if (spec->slave_dig_outs[0])
2153 codec->slave_dig_outs = spec->slave_dig_outs;
2158 static void via_auto_init_dig_outs(struct hda_codec *codec)
2160 struct via_spec *spec = codec->spec;
2161 if (spec->multiout.dig_out_nid)
2162 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2163 if (spec->slave_dig_outs[0])
2164 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2167 static void via_auto_init_dig_in(struct hda_codec *codec)
2169 struct via_spec *spec = codec->spec;
2170 if (!spec->dig_in_nid)
2172 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2173 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2176 /* initialize the unsolicited events */
2177 static void via_auto_init_unsol_event(struct hda_codec *codec)
2179 struct via_spec *spec = codec->spec;
2180 struct auto_pin_cfg *cfg = &spec->autocfg;
2184 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2185 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2186 AC_VERB_SET_UNSOLICITED_ENABLE,
2187 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2189 if (cfg->speaker_pins[0])
2190 ev = VIA_LINE_EVENT;
2193 for (i = 0; i < cfg->line_outs; i++) {
2194 if (cfg->line_out_pins[i] &&
2195 is_jack_detectable(codec, cfg->line_out_pins[i]))
2196 snd_hda_codec_write(codec, cfg->line_out_pins[0], 0,
2197 AC_VERB_SET_UNSOLICITED_ENABLE,
2198 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2201 for (i = 0; i < cfg->num_inputs; i++) {
2202 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2203 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2204 AC_VERB_SET_UNSOLICITED_ENABLE,
2205 AC_USRSP_EN | VIA_JACK_EVENT);
2209 static int via_init(struct hda_codec *codec)
2211 struct via_spec *spec = codec->spec;
2214 for (i = 0; i < spec->num_iverbs; i++)
2215 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2217 via_auto_init_multi_out(codec);
2218 via_auto_init_hp_out(codec);
2219 via_auto_init_speaker_out(codec);
2220 via_auto_init_analog_input(codec);
2221 via_auto_init_dig_outs(codec);
2222 via_auto_init_dig_in(codec);
2224 via_auto_init_unsol_event(codec);
2226 via_hp_automute(codec);
2227 via_line_automute(codec, false);
2232 static void vt1708_update_hp_jack_state(struct work_struct *work)
2234 struct via_spec *spec = container_of(work, struct via_spec,
2235 vt1708_hp_work.work);
2236 if (spec->codec_type != VT1708)
2238 /* if jack state toggled */
2239 if (spec->vt1708_hp_present
2240 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
2241 spec->vt1708_hp_present ^= 1;
2242 via_hp_automute(spec->codec);
2244 vt1708_start_hp_work(spec);
2247 static int get_mux_nids(struct hda_codec *codec)
2249 struct via_spec *spec = codec->spec;
2250 hda_nid_t nid, conn[8];
2254 for (i = 0; i < spec->num_adc_nids; i++) {
2255 nid = spec->adc_nids[i];
2257 type = get_wcaps_type(get_wcaps(codec, nid));
2258 if (type == AC_WID_PIN)
2260 n = snd_hda_get_connections(codec, nid, conn,
2265 spec->mux_nids[i] = nid;
2274 static int patch_vt1708(struct hda_codec *codec)
2276 struct via_spec *spec;
2279 /* create a codec specific record */
2280 spec = via_new_spec(codec);
2284 spec->aa_mix_nid = 0x17;
2286 /* Add HP and CD pin config connect bit re-config action */
2287 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2288 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2290 /* automatic parse from the BIOS config */
2291 err = via_parse_auto_config(codec);
2297 /* add jack detect on/off control */
2298 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2301 /* disable 32bit format on VT1708 */
2302 if (codec->vendor_id == 0x11061708)
2303 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2305 codec->patch_ops = via_patch_ops;
2307 #ifdef CONFIG_SND_HDA_POWER_SAVE
2308 spec->loopback.amplist = vt1708_loopbacks;
2310 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2315 * generic initialization of ADC, input mixers and output mixers
2317 #ifdef CONFIG_SND_HDA_POWER_SAVE
2318 static const struct hda_amp_list vt1709_loopbacks[] = {
2319 { 0x18, HDA_INPUT, 1 },
2320 { 0x18, HDA_INPUT, 2 },
2321 { 0x18, HDA_INPUT, 3 },
2322 { 0x18, HDA_INPUT, 4 },
2327 static int patch_vt1709_10ch(struct hda_codec *codec)
2329 struct via_spec *spec;
2332 /* create a codec specific record */
2333 spec = via_new_spec(codec);
2337 spec->aa_mix_nid = 0x18;
2339 err = via_parse_auto_config(codec);
2345 codec->patch_ops = via_patch_ops;
2347 #ifdef CONFIG_SND_HDA_POWER_SAVE
2348 spec->loopback.amplist = vt1709_loopbacks;
2354 * generic initialization of ADC, input mixers and output mixers
2356 static int patch_vt1709_6ch(struct hda_codec *codec)
2358 struct via_spec *spec;
2361 /* create a codec specific record */
2362 spec = via_new_spec(codec);
2366 spec->aa_mix_nid = 0x18;
2368 err = via_parse_auto_config(codec);
2374 codec->patch_ops = via_patch_ops;
2376 #ifdef CONFIG_SND_HDA_POWER_SAVE
2377 spec->loopback.amplist = vt1709_loopbacks;
2383 * generic initialization of ADC, input mixers and output mixers
2385 #ifdef CONFIG_SND_HDA_POWER_SAVE
2386 static const struct hda_amp_list vt1708B_loopbacks[] = {
2387 { 0x16, HDA_INPUT, 1 },
2388 { 0x16, HDA_INPUT, 2 },
2389 { 0x16, HDA_INPUT, 3 },
2390 { 0x16, HDA_INPUT, 4 },
2395 static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2397 struct via_spec *spec = codec->spec;
2401 if ((spec->codec_type != VT1708B_4CH) &&
2402 (codec->vendor_id != 0x11064397))
2405 /* SW0 (17h) = stereo mixer */
2407 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
2408 == ((spec->codec_type == VT1708S) ? 5 : 0));
2410 /* PW 1/2/5 (1ah/1bh/1eh) */
2412 set_pin_power_state(codec, 0x1a, &parm);
2413 set_pin_power_state(codec, 0x1b, &parm);
2414 set_pin_power_state(codec, 0x1e, &parm);
2417 /* SW0 (17h), AIW 0/1 (13h/14h) */
2418 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
2419 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2420 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
2423 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
2425 set_pin_power_state(codec, 0x19, &parm);
2426 if (spec->smart51_enabled)
2427 set_pin_power_state(codec, 0x1b, &parm);
2428 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
2429 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
2431 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
2434 set_pin_power_state(codec, 0x22, &parm);
2435 if (spec->smart51_enabled)
2436 set_pin_power_state(codec, 0x1a, &parm);
2437 snd_hda_codec_write(codec, 0x26, 0,
2438 AC_VERB_SET_POWER_STATE, parm);
2439 snd_hda_codec_write(codec, 0x24, 0,
2440 AC_VERB_SET_POWER_STATE, parm);
2441 } else if (codec->vendor_id == 0x11064397) {
2442 /* PW7(23h), SW2(27h), AOW2(25h) */
2444 set_pin_power_state(codec, 0x23, &parm);
2445 if (spec->smart51_enabled)
2446 set_pin_power_state(codec, 0x1a, &parm);
2447 snd_hda_codec_write(codec, 0x27, 0,
2448 AC_VERB_SET_POWER_STATE, parm);
2449 snd_hda_codec_write(codec, 0x25, 0,
2450 AC_VERB_SET_POWER_STATE, parm);
2453 /* PW 3/4/7 (1ch/1dh/23h) */
2455 /* force to D0 for internal Speaker */
2456 set_pin_power_state(codec, 0x1c, &parm);
2457 set_pin_power_state(codec, 0x1d, &parm);
2459 set_pin_power_state(codec, 0x23, &parm);
2461 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
2462 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
2463 imux_is_smixer ? AC_PWRST_D0 : parm);
2464 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2466 snd_hda_codec_write(codec, 0x25, 0,
2467 AC_VERB_SET_POWER_STATE, parm);
2468 snd_hda_codec_write(codec, 0x27, 0,
2469 AC_VERB_SET_POWER_STATE, parm);
2470 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
2471 snd_hda_codec_write(codec, 0x25, 0,
2472 AC_VERB_SET_POWER_STATE, parm);
2475 static int patch_vt1708S(struct hda_codec *codec);
2476 static int patch_vt1708B_8ch(struct hda_codec *codec)
2478 struct via_spec *spec;
2481 if (get_codec_type(codec) == VT1708BCE)
2482 return patch_vt1708S(codec);
2483 /* create a codec specific record */
2484 spec = via_new_spec(codec);
2488 spec->aa_mix_nid = 0x16;
2490 /* automatic parse from the BIOS config */
2491 err = via_parse_auto_config(codec);
2497 codec->patch_ops = via_patch_ops;
2499 #ifdef CONFIG_SND_HDA_POWER_SAVE
2500 spec->loopback.amplist = vt1708B_loopbacks;
2503 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2508 static int patch_vt1708B_4ch(struct hda_codec *codec)
2510 struct via_spec *spec;
2513 /* create a codec specific record */
2514 spec = via_new_spec(codec);
2518 /* automatic parse from the BIOS config */
2519 err = via_parse_auto_config(codec);
2525 codec->patch_ops = via_patch_ops;
2527 #ifdef CONFIG_SND_HDA_POWER_SAVE
2528 spec->loopback.amplist = vt1708B_loopbacks;
2531 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2536 /* Patch for VT1708S */
2537 static const struct hda_verb vt1708S_init_verbs[] = {
2538 /* Enable Mic Boost Volume backdoor */
2540 /* don't bybass mixer */
2545 /* fill out digital output widgets; one for master and one for slave outputs */
2546 static void fill_dig_outs(struct hda_codec *codec)
2548 struct via_spec *spec = codec->spec;
2551 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2555 nid = spec->autocfg.dig_out_pins[i];
2558 conn = snd_hda_get_connections(codec, nid, &nid, 1);
2561 if (!spec->multiout.dig_out_nid)
2562 spec->multiout.dig_out_nid = nid;
2564 spec->slave_dig_outs[0] = nid;
2565 break; /* at most two dig outs */
2570 static void fill_dig_in(struct hda_codec *codec)
2572 struct via_spec *spec = codec->spec;
2576 if (!spec->autocfg.dig_in_pin)
2579 dig_nid = codec->start_nid;
2580 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2581 unsigned int wcaps = get_wcaps(codec, dig_nid);
2582 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2584 if (!(wcaps & AC_WCAP_DIGITAL))
2586 if (!(wcaps & AC_WCAP_CONN_LIST))
2588 err = get_connection_index(codec, dig_nid,
2589 spec->autocfg.dig_in_pin);
2591 spec->dig_in_nid = dig_nid;
2597 #ifdef CONFIG_SND_HDA_POWER_SAVE
2598 static const struct hda_amp_list vt1708S_loopbacks[] = {
2599 { 0x16, HDA_INPUT, 1 },
2600 { 0x16, HDA_INPUT, 2 },
2601 { 0x16, HDA_INPUT, 3 },
2602 { 0x16, HDA_INPUT, 4 },
2607 static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
2608 int offset, int num_steps, int step_size)
2610 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
2611 (offset << AC_AMPCAP_OFFSET_SHIFT) |
2612 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
2613 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
2614 (0 << AC_AMPCAP_MUTE_SHIFT));
2617 static int patch_vt1708S(struct hda_codec *codec)
2619 struct via_spec *spec;
2622 /* create a codec specific record */
2623 spec = via_new_spec(codec);
2627 spec->aa_mix_nid = 0x16;
2628 override_mic_boost(codec, 0x1a, 0, 3, 40);
2629 override_mic_boost(codec, 0x1e, 0, 3, 40);
2631 /* automatic parse from the BIOS config */
2632 err = via_parse_auto_config(codec);
2638 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
2640 codec->patch_ops = via_patch_ops;
2642 #ifdef CONFIG_SND_HDA_POWER_SAVE
2643 spec->loopback.amplist = vt1708S_loopbacks;
2646 /* correct names for VT1708BCE */
2647 if (get_codec_type(codec) == VT1708BCE) {
2648 kfree(codec->chip_name);
2649 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
2650 snprintf(codec->bus->card->mixername,
2651 sizeof(codec->bus->card->mixername),
2652 "%s %s", codec->vendor_name, codec->chip_name);
2654 /* correct names for VT1705 */
2655 if (codec->vendor_id == 0x11064397) {
2656 kfree(codec->chip_name);
2657 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
2658 snprintf(codec->bus->card->mixername,
2659 sizeof(codec->bus->card->mixername),
2660 "%s %s", codec->vendor_name, codec->chip_name);
2662 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2666 /* Patch for VT1702 */
2668 static const struct hda_verb vt1702_init_verbs[] = {
2676 #ifdef CONFIG_SND_HDA_POWER_SAVE
2677 static const struct hda_amp_list vt1702_loopbacks[] = {
2678 { 0x1A, HDA_INPUT, 1 },
2679 { 0x1A, HDA_INPUT, 2 },
2680 { 0x1A, HDA_INPUT, 3 },
2681 { 0x1A, HDA_INPUT, 4 },
2686 static void set_widgets_power_state_vt1702(struct hda_codec *codec)
2688 int imux_is_smixer =
2689 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
2692 /* PW 1/2/5 (14h/15h/18h) */
2694 set_pin_power_state(codec, 0x14, &parm);
2695 set_pin_power_state(codec, 0x15, &parm);
2696 set_pin_power_state(codec, 0x18, &parm);
2698 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
2699 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
2700 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2701 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
2702 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
2703 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
2706 /* PW 3/4 (16h/17h) */
2708 set_pin_power_state(codec, 0x17, &parm);
2709 set_pin_power_state(codec, 0x16, &parm);
2710 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
2711 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
2712 imux_is_smixer ? AC_PWRST_D0 : parm);
2713 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2714 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
2717 static int patch_vt1702(struct hda_codec *codec)
2719 struct via_spec *spec;
2722 /* create a codec specific record */
2723 spec = via_new_spec(codec);
2727 spec->aa_mix_nid = 0x1a;
2729 /* limit AA path volume to 0 dB */
2730 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
2731 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2732 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2733 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2734 (1 << AC_AMPCAP_MUTE_SHIFT));
2736 /* automatic parse from the BIOS config */
2737 err = via_parse_auto_config(codec);
2743 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
2745 codec->patch_ops = via_patch_ops;
2747 #ifdef CONFIG_SND_HDA_POWER_SAVE
2748 spec->loopback.amplist = vt1702_loopbacks;
2751 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
2755 /* Patch for VT1718S */
2757 static const struct hda_verb vt1718S_init_verbs[] = {
2758 /* Enable MW0 adjust Gain 5 */
2760 /* Enable Boost Volume backdoor */
2766 #ifdef CONFIG_SND_HDA_POWER_SAVE
2767 static const struct hda_amp_list vt1718S_loopbacks[] = {
2768 { 0x21, HDA_INPUT, 1 },
2769 { 0x21, HDA_INPUT, 2 },
2770 { 0x21, HDA_INPUT, 3 },
2771 { 0x21, HDA_INPUT, 4 },
2776 static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
2778 struct via_spec *spec = codec->spec;
2781 /* MUX6 (1eh) = stereo mixer */
2783 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
2785 /* PW 5/6/7 (29h/2ah/2bh) */
2787 set_pin_power_state(codec, 0x29, &parm);
2788 set_pin_power_state(codec, 0x2a, &parm);
2789 set_pin_power_state(codec, 0x2b, &parm);
2792 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
2793 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
2794 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
2795 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2796 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
2799 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
2801 set_pin_power_state(codec, 0x27, &parm);
2802 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
2803 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
2805 /* PW2 (26h), AOW2 (ah) */
2807 set_pin_power_state(codec, 0x26, &parm);
2808 if (spec->smart51_enabled)
2809 set_pin_power_state(codec, 0x2b, &parm);
2810 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
2812 /* PW0 (24h), AOW0 (8h) */
2814 set_pin_power_state(codec, 0x24, &parm);
2815 if (!spec->hp_independent_mode) /* check for redirected HP */
2816 set_pin_power_state(codec, 0x28, &parm);
2817 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
2818 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
2819 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
2820 imux_is_smixer ? AC_PWRST_D0 : parm);
2822 /* PW1 (25h), AOW1 (9h) */
2824 set_pin_power_state(codec, 0x25, &parm);
2825 if (spec->smart51_enabled)
2826 set_pin_power_state(codec, 0x2a, &parm);
2827 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
2829 if (spec->hp_independent_mode) {
2830 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
2832 set_pin_power_state(codec, 0x28, &parm);
2833 snd_hda_codec_write(codec, 0x1b, 0,
2834 AC_VERB_SET_POWER_STATE, parm);
2835 snd_hda_codec_write(codec, 0x34, 0,
2836 AC_VERB_SET_POWER_STATE, parm);
2837 snd_hda_codec_write(codec, 0xc, 0,
2838 AC_VERB_SET_POWER_STATE, parm);
2842 static int patch_vt1718S(struct hda_codec *codec)
2844 struct via_spec *spec;
2847 /* create a codec specific record */
2848 spec = via_new_spec(codec);
2852 spec->aa_mix_nid = 0x21;
2853 override_mic_boost(codec, 0x2b, 0, 3, 40);
2854 override_mic_boost(codec, 0x29, 0, 3, 40);
2856 /* automatic parse from the BIOS config */
2857 err = via_parse_auto_config(codec);
2863 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
2865 codec->patch_ops = via_patch_ops;
2867 #ifdef CONFIG_SND_HDA_POWER_SAVE
2868 spec->loopback.amplist = vt1718S_loopbacks;
2871 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
2876 /* Patch for VT1716S */
2878 static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
2879 struct snd_ctl_elem_info *uinfo)
2881 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2883 uinfo->value.integer.min = 0;
2884 uinfo->value.integer.max = 1;
2888 static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
2889 struct snd_ctl_elem_value *ucontrol)
2891 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2894 index = snd_hda_codec_read(codec, 0x26, 0,
2895 AC_VERB_GET_CONNECT_SEL, 0);
2897 *ucontrol->value.integer.value = index;
2902 static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
2903 struct snd_ctl_elem_value *ucontrol)
2905 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2906 struct via_spec *spec = codec->spec;
2907 int index = *ucontrol->value.integer.value;
2909 snd_hda_codec_write(codec, 0x26, 0,
2910 AC_VERB_SET_CONNECT_SEL, index);
2911 spec->dmic_enabled = index;
2912 set_widgets_power_state(codec);
2916 static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
2917 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
2919 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2920 .name = "Digital Mic Capture Switch",
2921 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
2923 .info = vt1716s_dmic_info,
2924 .get = vt1716s_dmic_get,
2925 .put = vt1716s_dmic_put,
2931 /* mono-out mixer elements */
2932 static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
2933 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
2937 static const struct hda_verb vt1716S_init_verbs[] = {
2938 /* Enable Boost Volume backdoor */
2940 /* don't bybass mixer */
2942 /* Enable mono output */
2947 #ifdef CONFIG_SND_HDA_POWER_SAVE
2948 static const struct hda_amp_list vt1716S_loopbacks[] = {
2949 { 0x16, HDA_INPUT, 1 },
2950 { 0x16, HDA_INPUT, 2 },
2951 { 0x16, HDA_INPUT, 3 },
2952 { 0x16, HDA_INPUT, 4 },
2957 static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
2959 struct via_spec *spec = codec->spec;
2962 unsigned int mono_out, present;
2963 /* SW0 (17h) = stereo mixer */
2965 (snd_hda_codec_read(codec, 0x17, 0,
2966 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
2968 /* PW 1/2/5 (1ah/1bh/1eh) */
2970 set_pin_power_state(codec, 0x1a, &parm);
2971 set_pin_power_state(codec, 0x1b, &parm);
2972 set_pin_power_state(codec, 0x1e, &parm);
2975 /* SW0 (17h), AIW0(13h) */
2976 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
2977 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2980 set_pin_power_state(codec, 0x1e, &parm);
2982 if (spec->dmic_enabled)
2983 set_pin_power_state(codec, 0x22, &parm);
2985 snd_hda_codec_write(codec, 0x22, 0,
2986 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2988 /* SW2(26h), AIW1(14h) */
2989 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
2990 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
2993 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
2995 set_pin_power_state(codec, 0x19, &parm);
2996 /* Smart 5.1 PW2(1bh) */
2997 if (spec->smart51_enabled)
2998 set_pin_power_state(codec, 0x1b, &parm);
2999 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3000 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3002 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
3004 set_pin_power_state(codec, 0x23, &parm);
3005 /* Smart 5.1 PW1(1ah) */
3006 if (spec->smart51_enabled)
3007 set_pin_power_state(codec, 0x1a, &parm);
3008 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
3010 /* Smart 5.1 PW5(1eh) */
3011 if (spec->smart51_enabled)
3012 set_pin_power_state(codec, 0x1e, &parm);
3013 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
3016 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
3017 present = snd_hda_jack_detect(codec, 0x1c);
3022 present = snd_hda_jack_detect(codec, 0x1d);
3023 if (!spec->hp_independent_mode && present)
3028 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
3029 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
3030 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
3031 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
3033 /* PW 3/4 (1ch/1dh) */
3035 set_pin_power_state(codec, 0x1c, &parm);
3036 set_pin_power_state(codec, 0x1d, &parm);
3037 /* HP Independent Mode, power on AOW3 */
3038 if (spec->hp_independent_mode)
3039 snd_hda_codec_write(codec, 0x25, 0,
3040 AC_VERB_SET_POWER_STATE, parm);
3042 /* force to D0 for internal Speaker */
3043 /* MW0 (16h), AOW0 (10h) */
3044 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3045 imux_is_smixer ? AC_PWRST_D0 : parm);
3046 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
3047 mono_out ? AC_PWRST_D0 : parm);
3050 static int patch_vt1716S(struct hda_codec *codec)
3052 struct via_spec *spec;
3055 /* create a codec specific record */
3056 spec = via_new_spec(codec);
3060 spec->aa_mix_nid = 0x16;
3061 override_mic_boost(codec, 0x1a, 0, 3, 40);
3062 override_mic_boost(codec, 0x1e, 0, 3, 40);
3064 /* automatic parse from the BIOS config */
3065 err = via_parse_auto_config(codec);
3071 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
3073 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
3076 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
3078 codec->patch_ops = via_patch_ops;
3080 #ifdef CONFIG_SND_HDA_POWER_SAVE
3081 spec->loopback.amplist = vt1716S_loopbacks;
3084 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
3090 static const struct hda_verb vt2002P_init_verbs[] = {
3091 /* Class-D speaker related verbs */
3095 /* Enable Boost Volume backdoor */
3097 /* Enable AOW0 to MW9 */
3102 static const struct hda_verb vt1802_init_verbs[] = {
3103 /* Enable Boost Volume backdoor */
3105 /* Enable AOW0 to MW9 */
3110 #ifdef CONFIG_SND_HDA_POWER_SAVE
3111 static const struct hda_amp_list vt2002P_loopbacks[] = {
3112 { 0x21, HDA_INPUT, 0 },
3113 { 0x21, HDA_INPUT, 1 },
3114 { 0x21, HDA_INPUT, 2 },
3119 static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3121 struct via_spec *spec = codec->spec;
3124 unsigned int present;
3125 /* MUX9 (1eh) = stereo mixer */
3127 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3129 /* PW 5/6/7 (29h/2ah/2bh) */
3131 set_pin_power_state(codec, 0x29, &parm);
3132 set_pin_power_state(codec, 0x2a, &parm);
3133 set_pin_power_state(codec, 0x2b, &parm);
3135 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
3136 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3137 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3138 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3139 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3143 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
3145 if (spec->codec_type == VT1802) {
3146 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3148 set_pin_power_state(codec, 0x28, &parm);
3149 snd_hda_codec_write(codec, 0x18, 0,
3150 AC_VERB_SET_POWER_STATE, parm);
3151 snd_hda_codec_write(codec, 0x38, 0,
3152 AC_VERB_SET_POWER_STATE, parm);
3154 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
3156 set_pin_power_state(codec, 0x26, &parm);
3157 snd_hda_codec_write(codec, 0x1c, 0,
3158 AC_VERB_SET_POWER_STATE, parm);
3159 snd_hda_codec_write(codec, 0x37, 0,
3160 AC_VERB_SET_POWER_STATE, parm);
3163 if (spec->codec_type == VT1802) {
3164 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3166 set_pin_power_state(codec, 0x25, &parm);
3167 snd_hda_codec_write(codec, 0x15, 0,
3168 AC_VERB_SET_POWER_STATE, parm);
3169 snd_hda_codec_write(codec, 0x35, 0,
3170 AC_VERB_SET_POWER_STATE, parm);
3172 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
3174 set_pin_power_state(codec, 0x25, &parm);
3175 snd_hda_codec_write(codec, 0x19, 0,
3176 AC_VERB_SET_POWER_STATE, parm);
3177 snd_hda_codec_write(codec, 0x35, 0,
3178 AC_VERB_SET_POWER_STATE, parm);
3181 if (spec->hp_independent_mode)
3182 snd_hda_codec_write(codec, 0x9, 0,
3183 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3186 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
3187 present = snd_hda_jack_detect(codec, 0x25);
3190 set_pin_power_state(codec, 0x24, &parm);
3191 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3192 if (spec->codec_type == VT1802)
3193 snd_hda_codec_write(codec, 0x14, 0,
3194 AC_VERB_SET_POWER_STATE, parm);
3196 snd_hda_codec_write(codec, 0x18, 0,
3197 AC_VERB_SET_POWER_STATE, parm);
3198 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
3201 present = snd_hda_jack_detect(codec, 0x26);
3203 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
3204 if (spec->codec_type == VT1802) {
3205 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
3206 snd_hda_codec_write(codec, 0x33, 0,
3207 AC_VERB_SET_POWER_STATE, parm);
3208 snd_hda_codec_write(codec, 0x1c, 0,
3209 AC_VERB_SET_POWER_STATE, parm);
3210 snd_hda_codec_write(codec, 0x3c, 0,
3211 AC_VERB_SET_POWER_STATE, parm);
3213 /* PW15 (31h), MW8(17h), MUX8(3bh) */
3214 snd_hda_codec_write(codec, 0x31, 0,
3215 AC_VERB_SET_POWER_STATE, parm);
3216 snd_hda_codec_write(codec, 0x17, 0,
3217 AC_VERB_SET_POWER_STATE, parm);
3218 snd_hda_codec_write(codec, 0x3b, 0,
3219 AC_VERB_SET_POWER_STATE, parm);
3222 if (imux_is_smixer || !is_aa_path_mute(codec))
3223 snd_hda_codec_write(codec, 0x21, 0,
3224 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3226 snd_hda_codec_write(codec, 0x21, 0,
3227 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3230 /* patch for vt2002P */
3231 static int patch_vt2002P(struct hda_codec *codec)
3233 struct via_spec *spec;
3236 /* create a codec specific record */
3237 spec = via_new_spec(codec);
3241 spec->aa_mix_nid = 0x21;
3242 override_mic_boost(codec, 0x2b, 0, 3, 40);
3243 override_mic_boost(codec, 0x29, 0, 3, 40);
3245 /* automatic parse from the BIOS config */
3246 err = via_parse_auto_config(codec);
3252 if (spec->codec_type == VT1802)
3253 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
3255 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
3257 codec->patch_ops = via_patch_ops;
3259 #ifdef CONFIG_SND_HDA_POWER_SAVE
3260 spec->loopback.amplist = vt2002P_loopbacks;
3263 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
3269 static const struct hda_verb vt1812_init_verbs[] = {
3270 /* Enable Boost Volume backdoor */
3272 /* Enable AOW0 to MW9 */
3277 #ifdef CONFIG_SND_HDA_POWER_SAVE
3278 static const struct hda_amp_list vt1812_loopbacks[] = {
3279 { 0x21, HDA_INPUT, 0 },
3280 { 0x21, HDA_INPUT, 1 },
3281 { 0x21, HDA_INPUT, 2 },
3286 static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3288 struct via_spec *spec = codec->spec;
3289 int imux_is_smixer =
3290 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3292 unsigned int present;
3293 /* MUX10 (1eh) = stereo mixer */
3295 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
3297 /* PW 5/6/7 (29h/2ah/2bh) */
3299 set_pin_power_state(codec, 0x29, &parm);
3300 set_pin_power_state(codec, 0x2a, &parm);
3301 set_pin_power_state(codec, 0x2b, &parm);
3303 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
3304 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3305 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3306 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3307 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3311 snd_hda_codec_write(codec, 0x8, 0,
3312 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3314 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3316 set_pin_power_state(codec, 0x28, &parm);
3317 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3318 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
3320 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3322 set_pin_power_state(codec, 0x25, &parm);
3323 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
3324 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
3325 if (spec->hp_independent_mode)
3326 snd_hda_codec_write(codec, 0x9, 0,
3327 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3329 /* Internal Speaker */
3330 /* PW0 (24h), MW0(14h), MUX0(34h) */
3331 present = snd_hda_jack_detect(codec, 0x25);
3334 set_pin_power_state(codec, 0x24, &parm);
3336 snd_hda_codec_write(codec, 0x14, 0,
3337 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3338 snd_hda_codec_write(codec, 0x34, 0,
3339 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3341 snd_hda_codec_write(codec, 0x14, 0,
3342 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3343 snd_hda_codec_write(codec, 0x34, 0,
3344 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3349 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
3350 present = snd_hda_jack_detect(codec, 0x28);
3353 set_pin_power_state(codec, 0x31, &parm);
3355 snd_hda_codec_write(codec, 0x1c, 0,
3356 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3357 snd_hda_codec_write(codec, 0x3c, 0,
3358 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3359 snd_hda_codec_write(codec, 0x3e, 0,
3360 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3362 snd_hda_codec_write(codec, 0x1c, 0,
3363 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3364 snd_hda_codec_write(codec, 0x3c, 0,
3365 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3366 snd_hda_codec_write(codec, 0x3e, 0,
3367 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3370 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
3372 set_pin_power_state(codec, 0x33, &parm);
3373 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
3374 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
3378 /* patch for vt1812 */
3379 static int patch_vt1812(struct hda_codec *codec)
3381 struct via_spec *spec;
3384 /* create a codec specific record */
3385 spec = via_new_spec(codec);
3389 spec->aa_mix_nid = 0x21;
3390 override_mic_boost(codec, 0x2b, 0, 3, 40);
3391 override_mic_boost(codec, 0x29, 0, 3, 40);
3393 /* automatic parse from the BIOS config */
3394 err = via_parse_auto_config(codec);
3400 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
3402 codec->patch_ops = via_patch_ops;
3404 #ifdef CONFIG_SND_HDA_POWER_SAVE
3405 spec->loopback.amplist = vt1812_loopbacks;
3408 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
3415 static const struct hda_codec_preset snd_hda_preset_via[] = {
3416 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3417 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3418 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3419 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3420 { .id = 0x1106e710, .name = "VT1709 10-Ch",
3421 .patch = patch_vt1709_10ch},
3422 { .id = 0x1106e711, .name = "VT1709 10-Ch",
3423 .patch = patch_vt1709_10ch},
3424 { .id = 0x1106e712, .name = "VT1709 10-Ch",
3425 .patch = patch_vt1709_10ch},
3426 { .id = 0x1106e713, .name = "VT1709 10-Ch",
3427 .patch = patch_vt1709_10ch},
3428 { .id = 0x1106e714, .name = "VT1709 6-Ch",
3429 .patch = patch_vt1709_6ch},
3430 { .id = 0x1106e715, .name = "VT1709 6-Ch",
3431 .patch = patch_vt1709_6ch},
3432 { .id = 0x1106e716, .name = "VT1709 6-Ch",
3433 .patch = patch_vt1709_6ch},
3434 { .id = 0x1106e717, .name = "VT1709 6-Ch",
3435 .patch = patch_vt1709_6ch},
3436 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3437 .patch = patch_vt1708B_8ch},
3438 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3439 .patch = patch_vt1708B_8ch},
3440 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3441 .patch = patch_vt1708B_8ch},
3442 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3443 .patch = patch_vt1708B_8ch},
3444 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3445 .patch = patch_vt1708B_4ch},
3446 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3447 .patch = patch_vt1708B_4ch},
3448 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3449 .patch = patch_vt1708B_4ch},
3450 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3451 .patch = patch_vt1708B_4ch},
3452 { .id = 0x11060397, .name = "VT1708S",
3453 .patch = patch_vt1708S},
3454 { .id = 0x11061397, .name = "VT1708S",
3455 .patch = patch_vt1708S},
3456 { .id = 0x11062397, .name = "VT1708S",
3457 .patch = patch_vt1708S},
3458 { .id = 0x11063397, .name = "VT1708S",
3459 .patch = patch_vt1708S},
3460 { .id = 0x11064397, .name = "VT1705",
3461 .patch = patch_vt1708S},
3462 { .id = 0x11065397, .name = "VT1708S",
3463 .patch = patch_vt1708S},
3464 { .id = 0x11066397, .name = "VT1708S",
3465 .patch = patch_vt1708S},
3466 { .id = 0x11067397, .name = "VT1708S",
3467 .patch = patch_vt1708S},
3468 { .id = 0x11060398, .name = "VT1702",
3469 .patch = patch_vt1702},
3470 { .id = 0x11061398, .name = "VT1702",
3471 .patch = patch_vt1702},
3472 { .id = 0x11062398, .name = "VT1702",
3473 .patch = patch_vt1702},
3474 { .id = 0x11063398, .name = "VT1702",
3475 .patch = patch_vt1702},
3476 { .id = 0x11064398, .name = "VT1702",
3477 .patch = patch_vt1702},
3478 { .id = 0x11065398, .name = "VT1702",
3479 .patch = patch_vt1702},
3480 { .id = 0x11066398, .name = "VT1702",
3481 .patch = patch_vt1702},
3482 { .id = 0x11067398, .name = "VT1702",
3483 .patch = patch_vt1702},
3484 { .id = 0x11060428, .name = "VT1718S",
3485 .patch = patch_vt1718S},
3486 { .id = 0x11064428, .name = "VT1718S",
3487 .patch = patch_vt1718S},
3488 { .id = 0x11060441, .name = "VT2020",
3489 .patch = patch_vt1718S},
3490 { .id = 0x11064441, .name = "VT1828S",
3491 .patch = patch_vt1718S},
3492 { .id = 0x11060433, .name = "VT1716S",
3493 .patch = patch_vt1716S},
3494 { .id = 0x1106a721, .name = "VT1716S",
3495 .patch = patch_vt1716S},
3496 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
3497 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
3498 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
3499 { .id = 0x11060440, .name = "VT1818S",
3500 .patch = patch_vt1708S},
3501 { .id = 0x11060446, .name = "VT1802",
3502 .patch = patch_vt2002P},
3503 { .id = 0x11068446, .name = "VT1802",
3504 .patch = patch_vt2002P},
3508 MODULE_ALIAS("snd-hda-codec-id:1106*");
3510 static struct hda_codec_preset_list via_list = {
3511 .preset = snd_hda_preset_via,
3512 .owner = THIS_MODULE,
3515 MODULE_LICENSE("GPL");
3516 MODULE_DESCRIPTION("VIA HD-audio codec");
3518 static int __init patch_via_init(void)
3520 return snd_hda_add_codec_preset(&via_list);
3523 static void __exit patch_via_exit(void)
3525 snd_hda_delete_codec_preset(&via_list);
3528 module_init(patch_via_init)
3529 module_exit(patch_via_exit)