ALSA: hda - Implement dynamic loopback control for VIA codecs
[linux-2.6-block.git] / sound / pci / hda / patch_via.c
CommitLineData
c577b8a1
JC
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
8e86597f 4 * HD audio interface patch for VIA VT17xx/VT18xx/VT20xx codec
c577b8a1 5 *
8e86597f
LW
6 * (C) 2006-2009 VIA Technology, Inc.
7 * (C) 2006-2008 Takashi Iwai <tiwai@suse.de>
c577b8a1
JC
8 *
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.
13 *
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.
18 *
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
22 */
23
24/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
377ff31a 25/* */
c577b8a1 26/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
377ff31a
LW
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 */
c577b8a1 29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
377ff31a
LW
30/* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */
31/* 2007-09-17 Lydia Wang Add VT1708B codec support */
76d9b0dd 32/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */
fb4cb772 33/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */
377ff31a
LW
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 */
98aa34c0 37/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */
377ff31a 38/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */
8e86597f
LW
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 */
36dd5c4a 44/* 2009-09-19 Lydia Wang Add support for VT1818S */
377ff31a 45/* */
c577b8a1
JC
46/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47
48
c577b8a1
JC
49#include <linux/init.h>
50#include <linux/delay.h>
51#include <linux/slab.h>
c577b8a1 52#include <sound/core.h>
0aa62aef 53#include <sound/asoundef.h>
c577b8a1
JC
54#include "hda_codec.h"
55#include "hda_local.h"
c577b8a1 56
c577b8a1 57/* Pin Widget NID */
d949cac1
HW
58#define VT1708_HP_PIN_NID 0x20
59#define VT1708_CD_PIN_NID 0x24
c577b8a1 60
d7426329
HW
61enum VIA_HDA_CODEC {
62 UNKNOWN = -1,
63 VT1708,
64 VT1709_10CH,
65 VT1709_6CH,
66 VT1708B_8CH,
67 VT1708B_4CH,
68 VT1708S,
518bf3ba 69 VT1708BCE,
d7426329 70 VT1702,
eb7188ca 71 VT1718S,
f3db423d 72 VT1716S,
25eaba2f 73 VT2002P,
ab6734e7 74 VT1812,
11890956 75 VT1802,
d7426329
HW
76 CODEC_TYPES,
77};
78
11890956
LW
79#define VT2002P_COMPATIBLE(spec) \
80 ((spec)->codec_type == VT2002P ||\
81 (spec)->codec_type == VT1812 ||\
82 (spec)->codec_type == VT1802)
83
8e3679dc
TI
84#define MAX_NID_PATH_DEPTH 5
85
09a9ad69
TI
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
92 */
4a79616d
TI
93struct nid_path {
94 int depth;
8e3679dc 95 hda_nid_t path[MAX_NID_PATH_DEPTH];
09a9ad69
TI
96 unsigned char idx[MAX_NID_PATH_DEPTH];
97 unsigned char multi[MAX_NID_PATH_DEPTH];
98 unsigned int vol_ctl;
99 unsigned int mute_ctl;
4a79616d
TI
100};
101
a86a88ea
TI
102/* input-path */
103struct via_input {
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 */
108};
109
de6c74f3
TI
110#define VIA_MAX_ADCS 3
111
1f2e99fe
LW
112struct via_spec {
113 /* codec parameterization */
90dd48a1 114 const struct snd_kcontrol_new *mixers[6];
1f2e99fe
LW
115 unsigned int num_mixers;
116
90dd48a1 117 const struct hda_verb *init_verbs[5];
1f2e99fe
LW
118 unsigned int num_iverbs;
119
82673bc8 120 char stream_name_analog[32];
7eb56e84 121 char stream_name_hp[32];
90dd48a1
TI
122 const struct hda_pcm_stream *stream_analog_playback;
123 const struct hda_pcm_stream *stream_analog_capture;
1f2e99fe 124
82673bc8 125 char stream_name_digital[32];
90dd48a1
TI
126 const struct hda_pcm_stream *stream_digital_playback;
127 const struct hda_pcm_stream *stream_digital_capture;
1f2e99fe
LW
128
129 /* playback */
130 struct hda_multi_out multiout;
131 hda_nid_t slave_dig_outs[2];
ece8d043 132 hda_nid_t hp_dac_nid;
3214b966
TI
133 hda_nid_t speaker_dac_nid;
134 int hp_indep_shared; /* indep HP-DAC is shared with side ch */
ada509ec 135 int num_active_streams;
3214b966
TI
136 int aamix_mode; /* loopback is enabled for output-path? */
137
138 /* Output-paths:
139 * There are different output-paths depending on the setup.
140 * out_path, hp_path and speaker_path are primary paths. If both
141 * direct DAC and aa-loopback routes are available, these contain
142 * the former paths. Meanwhile *_mix_path contain the paths with
143 * loopback mixer. (Since the loopback is only for front channel,
144 * no out_mix_path for surround channels.)
145 * The HP output has another path, hp_indep_path, which is used in
146 * the independent-HP mode.
147 */
de6c74f3 148 struct nid_path out_path[HDA_SIDE + 1];
3214b966 149 struct nid_path out_mix_path;
4a79616d 150 struct nid_path hp_path;
3214b966
TI
151 struct nid_path hp_mix_path;
152 struct nid_path hp_indep_path;
4a918ffe 153 struct nid_path speaker_path;
3214b966 154 struct nid_path speaker_mix_path;
4a79616d 155
1f2e99fe
LW
156 /* capture */
157 unsigned int num_adc_nids;
de6c74f3
TI
158 hda_nid_t adc_nids[VIA_MAX_ADCS];
159 hda_nid_t mux_nids[VIA_MAX_ADCS];
620e2b28 160 hda_nid_t aa_mix_nid;
1f2e99fe 161 hda_nid_t dig_in_nid;
1f2e99fe
LW
162
163 /* capture source */
a86a88ea
TI
164 bool dyn_adc_switch;
165 int num_inputs;
166 struct via_input inputs[AUTO_CFG_MAX_INS + 1];
de6c74f3 167 unsigned int cur_mux[VIA_MAX_ADCS];
1f2e99fe 168
a86a88ea
TI
169 /* dynamic ADC switching */
170 hda_nid_t cur_adc;
171 unsigned int cur_adc_stream_tag;
172 unsigned int cur_adc_format;
173
1f2e99fe
LW
174 /* PCM information */
175 struct hda_pcm pcm_rec[3];
176
177 /* dynamic controls, init_verbs and input_mux */
178 struct auto_pin_cfg autocfg;
179 struct snd_array kctls;
1f2e99fe
LW
180 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
181
182 /* HP mode source */
1f2e99fe 183 unsigned int hp_independent_mode;
f3db423d 184 unsigned int dmic_enabled;
24088a58 185 unsigned int no_pin_power_ctl;
1f2e99fe
LW
186 enum VIA_HDA_CODEC codec_type;
187
e3d7a143
TI
188 /* smart51 setup */
189 unsigned int smart51_nums;
190 hda_nid_t smart51_pins[2];
191 int smart51_idxs[2];
192 const char *smart51_labels[2];
193 unsigned int smart51_enabled;
194
1f2e99fe
LW
195 /* work to check hp jack state */
196 struct hda_codec *codec;
197 struct delayed_work vt1708_hp_work;
e06e5a29 198 int vt1708_jack_detect;
1f2e99fe 199 int vt1708_hp_present;
3e95b9ab
LW
200
201 void (*set_widgets_power_state)(struct hda_codec *codec);
202
1f2e99fe 203 struct hda_loopback_check loopback;
13af8e77
TI
204 int num_loopbacks;
205 struct hda_amp_list loopback_list[8];
a86a88ea
TI
206
207 /* bind capture-volume */
208 struct hda_bind_ctls *bind_cap_vol;
209 struct hda_bind_ctls *bind_cap_sw;
1f2e99fe
LW
210};
211
0341ccd7 212static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
5b0cb1d8
JK
213static struct via_spec * via_new_spec(struct hda_codec *codec)
214{
215 struct via_spec *spec;
216
217 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
218 if (spec == NULL)
219 return NULL;
220
221 codec->spec = spec;
222 spec->codec = codec;
0341ccd7
LW
223 spec->codec_type = get_codec_type(codec);
224 /* VT1708BCE & VT1708S are almost same */
225 if (spec->codec_type == VT1708BCE)
226 spec->codec_type = VT1708S;
5b0cb1d8
JK
227 return spec;
228}
229
744ff5f4 230static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
d7426329 231{
744ff5f4 232 u32 vendor_id = codec->vendor_id;
d7426329
HW
233 u16 ven_id = vendor_id >> 16;
234 u16 dev_id = vendor_id & 0xffff;
235 enum VIA_HDA_CODEC codec_type;
236
237 /* get codec type */
238 if (ven_id != 0x1106)
239 codec_type = UNKNOWN;
240 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
241 codec_type = VT1708;
242 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
243 codec_type = VT1709_10CH;
244 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
245 codec_type = VT1709_6CH;
518bf3ba 246 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
d7426329 247 codec_type = VT1708B_8CH;
518bf3ba
LW
248 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
249 codec_type = VT1708BCE;
250 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
d7426329
HW
251 codec_type = VT1708B_4CH;
252 else if ((dev_id & 0xfff) == 0x397
253 && (dev_id >> 12) < 8)
254 codec_type = VT1708S;
255 else if ((dev_id & 0xfff) == 0x398
256 && (dev_id >> 12) < 8)
257 codec_type = VT1702;
eb7188ca
LW
258 else if ((dev_id & 0xfff) == 0x428
259 && (dev_id >> 12) < 8)
260 codec_type = VT1718S;
f3db423d
LW
261 else if (dev_id == 0x0433 || dev_id == 0xa721)
262 codec_type = VT1716S;
bb3c6bfc
LW
263 else if (dev_id == 0x0441 || dev_id == 0x4441)
264 codec_type = VT1718S;
25eaba2f
LW
265 else if (dev_id == 0x0438 || dev_id == 0x4438)
266 codec_type = VT2002P;
ab6734e7
LW
267 else if (dev_id == 0x0448)
268 codec_type = VT1812;
36dd5c4a
LW
269 else if (dev_id == 0x0440)
270 codec_type = VT1708S;
11890956
LW
271 else if ((dev_id & 0xfff) == 0x446)
272 codec_type = VT1802;
d7426329
HW
273 else
274 codec_type = UNKNOWN;
275 return codec_type;
276};
277
ec7e7e42 278#define VIA_JACK_EVENT 0x20
69e52a80
HW
279#define VIA_HP_EVENT 0x01
280#define VIA_GPIO_EVENT 0x02
4a918ffe 281#define VIA_LINE_EVENT 0x03
69e52a80 282
c577b8a1
JC
283enum {
284 VIA_CTL_WIDGET_VOL,
285 VIA_CTL_WIDGET_MUTE,
f5271101 286 VIA_CTL_WIDGET_ANALOG_MUTE,
c577b8a1
JC
287};
288
ada509ec
TI
289static void analog_low_current_mode(struct hda_codec *codec);
290static bool is_aa_path_mute(struct hda_codec *codec);
1f2e99fe
LW
291
292static void vt1708_start_hp_work(struct via_spec *spec)
293{
294 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
295 return;
296 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
e06e5a29 297 !spec->vt1708_jack_detect);
1f2e99fe
LW
298 if (!delayed_work_pending(&spec->vt1708_hp_work))
299 schedule_delayed_work(&spec->vt1708_hp_work,
300 msecs_to_jiffies(100));
301}
302
303static void vt1708_stop_hp_work(struct via_spec *spec)
304{
305 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
306 return;
307 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1
308 && !is_aa_path_mute(spec->codec))
309 return;
310 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
e06e5a29 311 !spec->vt1708_jack_detect);
5b84ba26 312 cancel_delayed_work_sync(&spec->vt1708_hp_work);
1f2e99fe 313}
f5271101 314
3e95b9ab
LW
315static void set_widgets_power_state(struct hda_codec *codec)
316{
317 struct via_spec *spec = codec->spec;
318 if (spec->set_widgets_power_state)
319 spec->set_widgets_power_state(codec);
320}
25eaba2f 321
f5271101
LW
322static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
324{
325 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
326 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
327
3e95b9ab 328 set_widgets_power_state(codec);
ada509ec 329 analog_low_current_mode(snd_kcontrol_chip(kcontrol));
1f2e99fe
LW
330 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
331 if (is_aa_path_mute(codec))
332 vt1708_start_hp_work(codec->spec);
333 else
334 vt1708_stop_hp_work(codec->spec);
335 }
f5271101
LW
336 return change;
337}
338
339/* modify .put = snd_hda_mixer_amp_switch_put */
340#define ANALOG_INPUT_MUTE \
341 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
342 .name = NULL, \
343 .index = 0, \
344 .info = snd_hda_mixer_amp_switch_info, \
345 .get = snd_hda_mixer_amp_switch_get, \
346 .put = analog_input_switch_put, \
347 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
348
90dd48a1 349static const struct snd_kcontrol_new via_control_templates[] = {
c577b8a1
JC
350 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
351 HDA_CODEC_MUTE(NULL, 0, 0, 0),
f5271101 352 ANALOG_INPUT_MUTE,
c577b8a1
JC
353};
354
ab6734e7 355
c577b8a1 356/* add dynamic controls */
291c9e33
TI
357static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
358 const struct snd_kcontrol_new *tmpl,
359 const char *name)
c577b8a1
JC
360{
361 struct snd_kcontrol_new *knew;
362
603c4019
TI
363 snd_array_init(&spec->kctls, sizeof(*knew), 32);
364 knew = snd_array_new(&spec->kctls);
365 if (!knew)
291c9e33
TI
366 return NULL;
367 *knew = *tmpl;
368 if (!name)
369 name = tmpl->name;
370 if (name) {
371 knew->name = kstrdup(name, GFP_KERNEL);
372 if (!knew->name)
373 return NULL;
374 }
375 return knew;
376}
377
378static int __via_add_control(struct via_spec *spec, int type, const char *name,
379 int idx, unsigned long val)
380{
381 struct snd_kcontrol_new *knew;
382
383 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
384 if (!knew)
c577b8a1 385 return -ENOMEM;
d7a99cce 386 knew->index = idx;
4d02d1b6 387 if (get_amp_nid_(val))
5e26dfd0 388 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
c577b8a1 389 knew->private_value = val;
c577b8a1
JC
390 return 0;
391}
392
7b315bb4
TI
393#define via_add_control(spec, type, name, val) \
394 __via_add_control(spec, type, name, 0, val)
395
291c9e33 396#define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
5b0cb1d8 397
603c4019
TI
398static void via_free_kctls(struct hda_codec *codec)
399{
400 struct via_spec *spec = codec->spec;
401
402 if (spec->kctls.list) {
403 struct snd_kcontrol_new *kctl = spec->kctls.list;
404 int i;
405 for (i = 0; i < spec->kctls.used; i++)
406 kfree(kctl[i].name);
407 }
408 snd_array_free(&spec->kctls);
409}
410
c577b8a1 411/* create input playback/capture controls for the given pin */
9510e8dd 412static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
7b315bb4 413 int type_idx, int idx, int mix_nid)
c577b8a1
JC
414{
415 char name[32];
416 int err;
417
418 sprintf(name, "%s Playback Volume", ctlname);
7b315bb4 419 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx,
c577b8a1
JC
420 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
421 if (err < 0)
422 return err;
423 sprintf(name, "%s Playback Switch", ctlname);
7b315bb4 424 err = __via_add_control(spec, VIA_CTL_WIDGET_ANALOG_MUTE, name, type_idx,
c577b8a1
JC
425 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
426 if (err < 0)
427 return err;
428 return 0;
429}
430
5d41762a 431#define get_connection_index(codec, mux, nid) \
8d087c76 432 snd_hda_get_conn_index(codec, mux, nid, 0)
5d41762a 433
8df2a312
TI
434static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
435 unsigned int mask)
436{
a934d5a9
TI
437 unsigned int caps;
438 if (!nid)
439 return false;
440 caps = get_wcaps(codec, nid);
8df2a312
TI
441 if (dir == HDA_INPUT)
442 caps &= AC_WCAP_IN_AMP;
443 else
444 caps &= AC_WCAP_OUT_AMP;
445 if (!caps)
446 return false;
447 if (query_amp_caps(codec, nid, dir) & mask)
448 return true;
449 return false;
450}
451
09a9ad69
TI
452#define have_mute(codec, nid, dir) \
453 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
8df2a312 454
d69607b3
LW
455/* enable/disable the output-route mixers */
456static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
3214b966 457 hda_nid_t mix_nid, int idx, bool enable)
d69607b3
LW
458{
459 int i, num, val;
d69607b3
LW
460
461 if (!path)
462 return;
463 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
d69607b3 464 for (i = 0; i < num; i++) {
3214b966
TI
465 if (i == idx)
466 val = AMP_IN_UNMUTE(i);
467 else
468 val = AMP_IN_MUTE(i);
d69607b3
LW
469 snd_hda_codec_write(codec, mix_nid, 0,
470 AC_VERB_SET_AMP_GAIN_MUTE, val);
471 }
472}
473
09a9ad69
TI
474/* enable/disable the output-route */
475static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
476 bool enable, bool force)
5d41762a 477{
d69607b3 478 struct via_spec *spec = codec->spec;
3214b966 479 int i;
09a9ad69
TI
480 for (i = 0; i < path->depth; i++) {
481 hda_nid_t src, dst;
482 int idx = path->idx[i];
483 src = path->path[i];
484 if (i < path->depth - 1)
485 dst = path->path[i + 1];
486 else
487 dst = 0;
488 if (enable && path->multi[i])
489 snd_hda_codec_write(codec, dst, 0,
490 AC_VERB_SET_CONNECT_SEL, idx);
3214b966 491 if (!force && (dst == spec->aa_mix_nid))
e5e14681 492 continue;
3214b966
TI
493 if (have_mute(codec, dst, HDA_INPUT))
494 activate_output_mix(codec, path, dst, idx, enable);
09a9ad69
TI
495 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
496 continue;
497 if (have_mute(codec, src, HDA_OUTPUT)) {
498 int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
499 snd_hda_codec_write(codec, src, 0,
500 AC_VERB_SET_AMP_GAIN_MUTE, val);
501 }
502 }
5d41762a
TI
503}
504
505/* set the given pin as output */
506static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
507 int pin_type)
508{
509 if (!pin)
510 return;
511 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
512 pin_type);
513 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
514 snd_hda_codec_write(codec, pin, 0,
d3a11e60 515 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
c577b8a1
JC
516}
517
09a9ad69
TI
518static void via_auto_init_output(struct hda_codec *codec,
519 struct nid_path *path, int pin_type,
3214b966 520 bool force)
5d41762a 521{
5d41762a 522 unsigned int caps;
d69607b3 523 hda_nid_t pin;
5d41762a 524
09a9ad69 525 if (!path->depth)
5d41762a 526 return;
09a9ad69 527 pin = path->path[path->depth - 1];
5d41762a
TI
528
529 init_output_pin(codec, pin, pin_type);
530 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
531 if (caps & AC_AMPCAP_MUTE) {
532 unsigned int val;
533 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
534 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
535 AMP_OUT_MUTE | val);
536 }
d69607b3 537 activate_output_path(codec, path, true, force);
5d41762a
TI
538}
539
c577b8a1
JC
540static void via_auto_init_multi_out(struct hda_codec *codec)
541{
542 struct via_spec *spec = codec->spec;
3214b966 543 struct nid_path *path;
c577b8a1
JC
544 int i;
545
3214b966
TI
546 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
547 path = &spec->out_path[i];
548 if (!i && spec->aamix_mode && spec->out_mix_path.depth)
549 path = &spec->out_mix_path;
550 via_auto_init_output(codec, path, PIN_OUT, true);
551 }
c577b8a1
JC
552}
553
554static void via_auto_init_hp_out(struct hda_codec *codec)
555{
556 struct via_spec *spec = codec->spec;
3214b966 557 int shared = spec->hp_indep_shared;
c577b8a1 558
3214b966
TI
559 if (!spec->hp_path.depth) {
560 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true);
09a9ad69
TI
561 return;
562 }
563 if (spec->hp_independent_mode) {
09a9ad69 564 activate_output_path(codec, &spec->hp_path, false, false);
3214b966
TI
565 activate_output_path(codec, &spec->hp_mix_path, false, false);
566 if (shared)
567 activate_output_path(codec, &spec->out_path[shared],
568 false, false);
569 via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP, true);
570 } else if (spec->aamix_mode) {
571 activate_output_path(codec, &spec->hp_path, false, false);
572 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP, true);
573 } else {
574 activate_output_path(codec, &spec->hp_mix_path, false, false);
575 via_auto_init_output(codec, &spec->hp_path, PIN_HP, true);
09a9ad69 576 }
c577b8a1
JC
577}
578
4a918ffe
TI
579static void via_auto_init_speaker_out(struct hda_codec *codec)
580{
581 struct via_spec *spec = codec->spec;
582
3214b966
TI
583 if (!spec->autocfg.speaker_outs)
584 return;
585 if (!spec->speaker_path.depth) {
586 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT,
587 true);
588 return;
589 }
590 if (!spec->aamix_mode) {
591 activate_output_path(codec, &spec->speaker_mix_path,
592 false, false);
bac4b92c 593 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT,
3214b966
TI
594 true);
595 } else {
596 activate_output_path(codec, &spec->speaker_path, false, false);
597 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT,
598 true);
599 }
4a918ffe
TI
600}
601
f4a7828b 602static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
6e969d91 603static void via_hp_automute(struct hda_codec *codec);
32e0191d 604
c577b8a1
JC
605static void via_auto_init_analog_input(struct hda_codec *codec)
606{
607 struct via_spec *spec = codec->spec;
7b315bb4 608 const struct auto_pin_cfg *cfg = &spec->autocfg;
096a8854 609 hda_nid_t conn[HDA_MAX_CONNECTIONS];
32e0191d 610 unsigned int ctl;
096a8854
TI
611 int i, num_conns;
612
613 /* init ADCs */
614 for (i = 0; i < spec->num_adc_nids; i++) {
615 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
616 AC_VERB_SET_AMP_GAIN_MUTE,
617 AMP_IN_UNMUTE(0));
618 }
c577b8a1 619
096a8854 620 /* init pins */
7b315bb4
TI
621 for (i = 0; i < cfg->num_inputs; i++) {
622 hda_nid_t nid = cfg->inputs[i].pin;
f4a7828b 623 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
32e0191d 624 ctl = PIN_OUT;
30649676 625 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
32e0191d
CL
626 ctl = PIN_VREF50;
627 else
628 ctl = PIN_IN;
c577b8a1 629 snd_hda_codec_write(codec, nid, 0,
32e0191d 630 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
c577b8a1 631 }
096a8854
TI
632
633 /* init input-src */
634 for (i = 0; i < spec->num_adc_nids; i++) {
a86a88ea
TI
635 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
636 if (spec->mux_nids[adc_idx]) {
637 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
638 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
639 AC_VERB_SET_CONNECT_SEL,
640 mux_idx);
641 }
642 if (spec->dyn_adc_switch)
643 break; /* only one input-src */
096a8854
TI
644 }
645
646 /* init aa-mixer */
647 if (!spec->aa_mix_nid)
648 return;
649 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
650 ARRAY_SIZE(conn));
651 for (i = 0; i < num_conns; i++) {
652 unsigned int caps = get_wcaps(codec, conn[i]);
653 if (get_wcaps_type(caps) == AC_WID_PIN)
654 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
655 AC_VERB_SET_AMP_GAIN_MUTE,
656 AMP_IN_MUTE(i));
657 }
c577b8a1 658}
f5271101
LW
659
660static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
661 unsigned int *affected_parm)
662{
663 unsigned parm;
664 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
665 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
666 >> AC_DEFCFG_MISC_SHIFT
667 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
1564b287 668 struct via_spec *spec = codec->spec;
24088a58
TI
669 unsigned present = 0;
670
671 no_presence |= spec->no_pin_power_ctl;
672 if (!no_presence)
673 present = snd_hda_jack_detect(codec, nid);
f4a7828b 674 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
1564b287
LW
675 || ((no_presence || present)
676 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
f5271101
LW
677 *affected_parm = AC_PWRST_D0; /* if it's connected */
678 parm = AC_PWRST_D0;
679 } else
680 parm = AC_PWRST_D3;
681
682 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
683}
684
24088a58
TI
685static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
686 struct snd_ctl_elem_info *uinfo)
687{
688 static const char * const texts[] = {
689 "Disabled", "Enabled"
690 };
691
692 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
693 uinfo->count = 1;
694 uinfo->value.enumerated.items = 2;
695 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
696 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
697 strcpy(uinfo->value.enumerated.name,
698 texts[uinfo->value.enumerated.item]);
699 return 0;
700}
701
702static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_value *ucontrol)
704{
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 struct via_spec *spec = codec->spec;
707 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
708 return 0;
709}
710
711static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
712 struct snd_ctl_elem_value *ucontrol)
713{
714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
715 struct via_spec *spec = codec->spec;
716 unsigned int val = !ucontrol->value.enumerated.item[0];
717
718 if (val == spec->no_pin_power_ctl)
719 return 0;
720 spec->no_pin_power_ctl = val;
721 set_widgets_power_state(codec);
722 return 1;
723}
724
725static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
726 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
727 .name = "Dynamic Power-Control",
728 .info = via_pin_power_ctl_info,
729 .get = via_pin_power_ctl_get,
730 .put = via_pin_power_ctl_put,
731};
732
733
0aa62aef
HW
734static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_info *uinfo)
736{
8df2a312
TI
737 static const char * const texts[] = { "OFF", "ON" };
738
739 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
740 uinfo->count = 1;
741 uinfo->value.enumerated.items = 2;
742 if (uinfo->value.enumerated.item >= 2)
743 uinfo->value.enumerated.item = 1;
744 strcpy(uinfo->value.enumerated.name,
745 texts[uinfo->value.enumerated.item]);
746 return 0;
0aa62aef
HW
747}
748
749static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
750 struct snd_ctl_elem_value *ucontrol)
751{
752 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
cdc1784d 753 struct via_spec *spec = codec->spec;
cdc1784d 754
ece8d043 755 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
cdc1784d
LW
756 return 0;
757}
758
0aa62aef
HW
759static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
760 struct snd_ctl_elem_value *ucontrol)
761{
762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
763 struct via_spec *spec = codec->spec;
3214b966 764 int cur, shared;
8df2a312 765
25250505
TI
766 /* no independent-hp status change during PCM playback is running */
767 if (spec->num_active_streams)
768 return -EBUSY;
769
770 cur = !!ucontrol->value.enumerated.item[0];
771 if (spec->hp_independent_mode == cur)
772 return 0;
773 spec->hp_independent_mode = cur;
3214b966 774 shared = spec->hp_indep_shared;
25250505 775 if (cur) {
3214b966
TI
776 activate_output_path(codec, &spec->hp_mix_path, false, false);
777 if (shared)
778 activate_output_path(codec, &spec->out_path[shared],
25250505 779 false, false);
3214b966 780 activate_output_path(codec, &spec->hp_path, true, false);
09a9ad69
TI
781 } else {
782 activate_output_path(codec, &spec->hp_path, false, false);
3214b966
TI
783 if (shared)
784 activate_output_path(codec, &spec->out_path[shared],
25250505 785 true, false);
3214b966 786 activate_output_path(codec, &spec->hp_mix_path, true, false);
8df2a312 787 }
ece8d043 788
ce0e5a9e 789 /* update jack power state */
3e95b9ab 790 set_widgets_power_state(codec);
6e969d91 791 via_hp_automute(codec);
25250505 792 return 1;
0aa62aef
HW
793}
794
ece8d043
TI
795static const struct snd_kcontrol_new via_hp_mixer = {
796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
797 .name = "Independent HP",
798 .info = via_independent_hp_info,
799 .get = via_independent_hp_get,
800 .put = via_independent_hp_put,
0aa62aef
HW
801};
802
3d83e577 803static int via_hp_build(struct hda_codec *codec)
5b0cb1d8 804{
3d83e577 805 struct via_spec *spec = codec->spec;
5b0cb1d8
JK
806 struct snd_kcontrol_new *knew;
807 hda_nid_t nid;
5b0cb1d8 808
ece8d043
TI
809 nid = spec->autocfg.hp_pins[0];
810 knew = via_clone_control(spec, &via_hp_mixer);
3d83e577
TI
811 if (knew == NULL)
812 return -ENOMEM;
813
5b0cb1d8 814 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
5b0cb1d8 815
5b0cb1d8
JK
816 return 0;
817}
818
1564b287
LW
819static void notify_aa_path_ctls(struct hda_codec *codec)
820{
e3d7a143 821 struct via_spec *spec = codec->spec;
1564b287 822 int i;
e3d7a143
TI
823
824 for (i = 0; i < spec->smart51_nums; i++) {
825 struct snd_kcontrol *ctl;
826 struct snd_ctl_elem_id id;
827 memset(&id, 0, sizeof(id));
828 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
829 sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]);
525566cb
LW
830 ctl = snd_hda_find_mixer_ctl(codec, id.name);
831 if (ctl)
832 snd_ctl_notify(codec->bus->card,
833 SNDRV_CTL_EVENT_MASK_VALUE,
834 &ctl->id);
1564b287
LW
835 }
836}
837
838static void mute_aa_path(struct hda_codec *codec, int mute)
839{
840 struct via_spec *spec = codec->spec;
e3d7a143 841 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
1564b287 842 int i;
e3d7a143 843
1564b287 844 /* check AA path's mute status */
e3d7a143
TI
845 for (i = 0; i < spec->smart51_nums; i++) {
846 if (spec->smart51_idxs[i] < 0)
847 continue;
848 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
849 HDA_INPUT, spec->smart51_idxs[i],
1564b287
LW
850 HDA_AMP_MUTE, val);
851 }
852}
f4a7828b 853
e3d7a143
TI
854static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
855{
856 struct via_spec *spec = codec->spec;
857 int i;
858
859 for (i = 0; i < spec->smart51_nums; i++)
860 if (spec->smart51_pins[i] == pin)
861 return true;
862 return false;
863}
864
1564b287
LW
865static int via_smart51_get(struct snd_kcontrol *kcontrol,
866 struct snd_ctl_elem_value *ucontrol)
867{
868 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
869 struct via_spec *spec = codec->spec;
1564b287 870
f2b1c9f0 871 *ucontrol->value.integer.value = spec->smart51_enabled;
1564b287
LW
872 return 0;
873}
874
875static int via_smart51_put(struct snd_kcontrol *kcontrol,
876 struct snd_ctl_elem_value *ucontrol)
877{
878 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
879 struct via_spec *spec = codec->spec;
880 int out_in = *ucontrol->value.integer.value
881 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
1564b287
LW
882 int i;
883
e3d7a143
TI
884 for (i = 0; i < spec->smart51_nums; i++) {
885 hda_nid_t nid = spec->smart51_pins[i];
7b315bb4
TI
886 unsigned int parm;
887
7b315bb4
TI
888 parm = snd_hda_codec_read(codec, nid, 0,
889 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
890 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
891 parm |= out_in;
892 snd_hda_codec_write(codec, nid, 0,
893 AC_VERB_SET_PIN_WIDGET_CONTROL,
894 parm);
895 if (out_in == AC_PINCTL_OUT_EN) {
896 mute_aa_path(codec, 1);
897 notify_aa_path_ctls(codec);
898 }
1564b287
LW
899 }
900 spec->smart51_enabled = *ucontrol->value.integer.value;
3e95b9ab 901 set_widgets_power_state(codec);
1564b287
LW
902 return 1;
903}
904
5f4b36d6
TI
905static const struct snd_kcontrol_new via_smart51_mixer = {
906 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
907 .name = "Smart 5.1",
908 .count = 1,
f2b1c9f0 909 .info = snd_ctl_boolean_mono_info,
5f4b36d6
TI
910 .get = via_smart51_get,
911 .put = via_smart51_put,
1564b287
LW
912};
913
f4a7828b 914static int via_smart51_build(struct hda_codec *codec)
5b0cb1d8 915{
f4a7828b 916 struct via_spec *spec = codec->spec;
5b0cb1d8 917
e3d7a143 918 if (!spec->smart51_nums)
cb34c207 919 return 0;
e3d7a143 920 if (!via_clone_control(spec, &via_smart51_mixer))
5b0cb1d8 921 return -ENOMEM;
5b0cb1d8
JK
922 return 0;
923}
924
ada509ec
TI
925/* check AA path's mute status */
926static bool is_aa_path_mute(struct hda_codec *codec)
f5271101 927{
f5271101 928 struct via_spec *spec = codec->spec;
ada509ec
TI
929 const struct hda_amp_list *p;
930 int i, ch, v;
931
932 for (i = 0; i < spec->num_loopbacks; i++) {
933 p = &spec->loopback_list[i];
934 for (ch = 0; ch < 2; ch++) {
935 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
936 p->idx);
937 if (!(v & HDA_AMP_MUTE) && v > 0)
938 return false;
f5271101
LW
939 }
940 }
ada509ec 941 return true;
f5271101
LW
942}
943
944/* enter/exit analog low-current mode */
ada509ec 945static void analog_low_current_mode(struct hda_codec *codec)
f5271101
LW
946{
947 struct via_spec *spec = codec->spec;
ada509ec
TI
948 bool enable;
949 unsigned int verb, parm;
950
951 enable = is_aa_path_mute(codec) && (spec->num_active_streams > 0);
f5271101
LW
952
953 /* decide low current mode's verb & parameter */
954 switch (spec->codec_type) {
955 case VT1708B_8CH:
956 case VT1708B_4CH:
957 verb = 0xf70;
958 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
959 break;
960 case VT1708S:
eb7188ca 961 case VT1718S:
f3db423d 962 case VT1716S:
f5271101
LW
963 verb = 0xf73;
964 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
965 break;
966 case VT1702:
967 verb = 0xf73;
968 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
969 break;
25eaba2f 970 case VT2002P:
ab6734e7 971 case VT1812:
11890956 972 case VT1802:
25eaba2f
LW
973 verb = 0xf93;
974 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
975 break;
f5271101
LW
976 default:
977 return; /* other codecs are not supported */
978 }
979 /* send verb */
980 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
981}
982
c577b8a1
JC
983/*
984 * generic initialization of ADC, input mixers and output mixers
985 */
096a8854 986static const struct hda_verb vt1708_init_verbs[] = {
aa266fcc
LW
987 /* power down jack detect function */
988 {0x1, 0xf81, 0x1},
f7278fd0 989 { }
c577b8a1
JC
990};
991
ada509ec 992static void set_stream_active(struct hda_codec *codec, bool active)
7eb56e84 993{
ada509ec
TI
994 struct via_spec *spec = codec->spec;
995
996 if (active)
997 spec->num_active_streams++;
998 else
999 spec->num_active_streams--;
1000 analog_low_current_mode(codec);
7eb56e84
TI
1001}
1002
ece8d043 1003static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
c577b8a1
JC
1004 struct hda_codec *codec,
1005 struct snd_pcm_substream *substream)
1006{
1007 struct via_spec *spec = codec->spec;
25250505 1008 const struct auto_pin_cfg *cfg = &spec->autocfg;
ada509ec 1009 int err;
ece8d043 1010
25250505
TI
1011 spec->multiout.hp_nid = 0;
1012 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
1013 if (!spec->hp_independent_mode) {
1014 if (!spec->hp_indep_shared)
1015 spec->multiout.hp_nid = spec->hp_dac_nid;
1016 } else {
1017 if (spec->hp_indep_shared)
1018 spec->multiout.num_dacs = cfg->line_outs - 1;
1019 }
1020 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
ada509ec
TI
1021 set_stream_active(codec, true);
1022 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1023 hinfo);
1024 if (err < 0) {
1025 spec->multiout.hp_nid = 0;
1026 set_stream_active(codec, false);
1027 return err;
1028 }
1029 return 0;
c577b8a1
JC
1030}
1031
ece8d043 1032static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
9af74210
TI
1033 struct hda_codec *codec,
1034 struct snd_pcm_substream *substream)
1035{
ece8d043
TI
1036 struct via_spec *spec = codec->spec;
1037
1038 spec->multiout.hp_nid = 0;
ada509ec 1039 set_stream_active(codec, false);
7eb56e84
TI
1040 return 0;
1041}
9af74210 1042
7eb56e84
TI
1043static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1044 struct hda_codec *codec,
1045 struct snd_pcm_substream *substream)
1046{
1047 struct via_spec *spec = codec->spec;
7eb56e84 1048
ece8d043 1049 if (snd_BUG_ON(!spec->hp_dac_nid))
7eb56e84 1050 return -EINVAL;
ece8d043
TI
1051 if (!spec->hp_independent_mode || spec->multiout.hp_nid)
1052 return -EBUSY;
ada509ec 1053 set_stream_active(codec, true);
ece8d043
TI
1054 return 0;
1055}
1056
1057static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1058 struct hda_codec *codec,
1059 struct snd_pcm_substream *substream)
1060{
ada509ec 1061 set_stream_active(codec, false);
9af74210
TI
1062 return 0;
1063}
1064
7eb56e84
TI
1065static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1066 struct hda_codec *codec,
1067 unsigned int stream_tag,
1068 unsigned int format,
1069 struct snd_pcm_substream *substream)
0aa62aef
HW
1070{
1071 struct via_spec *spec = codec->spec;
ece8d043
TI
1072
1073 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1074 format, substream);
7eb56e84
TI
1075 vt1708_start_hp_work(spec);
1076 return 0;
0aa62aef
HW
1077}
1078
7eb56e84
TI
1079static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1080 struct hda_codec *codec,
1081 unsigned int stream_tag,
1082 unsigned int format,
1083 struct snd_pcm_substream *substream)
0aa62aef
HW
1084{
1085 struct via_spec *spec = codec->spec;
0aa62aef 1086
ece8d043
TI
1087 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1088 stream_tag, 0, format);
1f2e99fe 1089 vt1708_start_hp_work(spec);
0aa62aef
HW
1090 return 0;
1091}
1092
1093static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1094 struct hda_codec *codec,
1095 struct snd_pcm_substream *substream)
1096{
1097 struct via_spec *spec = codec->spec;
0aa62aef 1098
ece8d043 1099 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
7eb56e84
TI
1100 vt1708_stop_hp_work(spec);
1101 return 0;
1102}
1103
1104static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1105 struct hda_codec *codec,
1106 struct snd_pcm_substream *substream)
1107{
1108 struct via_spec *spec = codec->spec;
7eb56e84 1109
ece8d043 1110 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1f2e99fe 1111 vt1708_stop_hp_work(spec);
0aa62aef
HW
1112 return 0;
1113}
1114
c577b8a1
JC
1115/*
1116 * Digital out
1117 */
1118static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1119 struct hda_codec *codec,
1120 struct snd_pcm_substream *substream)
1121{
1122 struct via_spec *spec = codec->spec;
1123 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1124}
1125
1126static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1127 struct hda_codec *codec,
1128 struct snd_pcm_substream *substream)
1129{
1130 struct via_spec *spec = codec->spec;
1131 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
1132}
1133
5691ec7f 1134static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
98aa34c0
HW
1135 struct hda_codec *codec,
1136 unsigned int stream_tag,
1137 unsigned int format,
1138 struct snd_pcm_substream *substream)
1139{
1140 struct via_spec *spec = codec->spec;
9da29271
TI
1141 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
1142 stream_tag, format, substream);
1143}
98aa34c0 1144
9da29271
TI
1145static int via_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1146 struct hda_codec *codec,
1147 struct snd_pcm_substream *substream)
1148{
1149 struct via_spec *spec = codec->spec;
1150 snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
98aa34c0
HW
1151 return 0;
1152}
1153
c577b8a1
JC
1154/*
1155 * Analog capture
1156 */
1157static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1158 struct hda_codec *codec,
1159 unsigned int stream_tag,
1160 unsigned int format,
1161 struct snd_pcm_substream *substream)
1162{
1163 struct via_spec *spec = codec->spec;
1164
1165 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
1166 stream_tag, 0, format);
1167 return 0;
1168}
1169
1170static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1171 struct hda_codec *codec,
1172 struct snd_pcm_substream *substream)
1173{
1174 struct via_spec *spec = codec->spec;
888afa15 1175 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
c577b8a1
JC
1176 return 0;
1177}
1178
a86a88ea
TI
1179/* analog capture with dynamic ADC switching */
1180static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1181 struct hda_codec *codec,
1182 unsigned int stream_tag,
1183 unsigned int format,
1184 struct snd_pcm_substream *substream)
1185{
1186 struct via_spec *spec = codec->spec;
1187 int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
1188
1189 spec->cur_adc = spec->adc_nids[adc_idx];
1190 spec->cur_adc_stream_tag = stream_tag;
1191 spec->cur_adc_format = format;
1192 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
1193 return 0;
1194}
1195
1196static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1197 struct hda_codec *codec,
1198 struct snd_pcm_substream *substream)
1199{
1200 struct via_spec *spec = codec->spec;
1201
1202 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1203 spec->cur_adc = 0;
1204 return 0;
1205}
1206
1207/* re-setup the stream if running; called from input-src put */
1208static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
1209{
1210 struct via_spec *spec = codec->spec;
1211 int adc_idx = spec->inputs[cur].adc_idx;
1212 hda_nid_t adc = spec->adc_nids[adc_idx];
1213
1214 if (spec->cur_adc && spec->cur_adc != adc) {
1215 /* stream is running, let's swap the current ADC */
1216 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1217 spec->cur_adc = adc;
1218 snd_hda_codec_setup_stream(codec, adc,
1219 spec->cur_adc_stream_tag, 0,
1220 spec->cur_adc_format);
1221 return true;
1222 }
1223 return false;
1224}
1225
9af74210 1226static const struct hda_pcm_stream via_pcm_analog_playback = {
7eb56e84 1227 .substreams = 1,
c577b8a1
JC
1228 .channels_min = 2,
1229 .channels_max = 8,
9af74210 1230 /* NID is set in via_build_pcms */
c577b8a1 1231 .ops = {
ece8d043
TI
1232 .open = via_playback_multi_pcm_open,
1233 .close = via_playback_multi_pcm_close,
0aa62aef
HW
1234 .prepare = via_playback_multi_pcm_prepare,
1235 .cleanup = via_playback_multi_pcm_cleanup
c577b8a1
JC
1236 },
1237};
1238
7eb56e84
TI
1239static const struct hda_pcm_stream via_pcm_hp_playback = {
1240 .substreams = 1,
1241 .channels_min = 2,
1242 .channels_max = 2,
1243 /* NID is set in via_build_pcms */
1244 .ops = {
1245 .open = via_playback_hp_pcm_open,
ece8d043 1246 .close = via_playback_hp_pcm_close,
7eb56e84
TI
1247 .prepare = via_playback_hp_pcm_prepare,
1248 .cleanup = via_playback_hp_pcm_cleanup
1249 },
1250};
1251
90dd48a1 1252static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
7eb56e84 1253 .substreams = 1,
bc9b5623
TI
1254 .channels_min = 2,
1255 .channels_max = 8,
9af74210 1256 /* NID is set in via_build_pcms */
bc9b5623
TI
1257 /* We got noisy outputs on the right channel on VT1708 when
1258 * 24bit samples are used. Until any workaround is found,
1259 * disable the 24bit format, so far.
1260 */
1261 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1262 .ops = {
ece8d043
TI
1263 .open = via_playback_multi_pcm_open,
1264 .close = via_playback_multi_pcm_close,
c873cc25
LW
1265 .prepare = via_playback_multi_pcm_prepare,
1266 .cleanup = via_playback_multi_pcm_cleanup
bc9b5623
TI
1267 },
1268};
1269
9af74210 1270static const struct hda_pcm_stream via_pcm_analog_capture = {
7eb56e84 1271 .substreams = 1, /* will be changed in via_build_pcms() */
c577b8a1
JC
1272 .channels_min = 2,
1273 .channels_max = 2,
9af74210 1274 /* NID is set in via_build_pcms */
c577b8a1
JC
1275 .ops = {
1276 .prepare = via_capture_pcm_prepare,
1277 .cleanup = via_capture_pcm_cleanup
1278 },
1279};
1280
a86a88ea
TI
1281static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
1282 .substreams = 1,
1283 .channels_min = 2,
1284 .channels_max = 2,
1285 /* NID is set in via_build_pcms */
1286 .ops = {
1287 .prepare = via_dyn_adc_capture_pcm_prepare,
1288 .cleanup = via_dyn_adc_capture_pcm_cleanup,
1289 },
1290};
1291
9af74210 1292static const struct hda_pcm_stream via_pcm_digital_playback = {
c577b8a1
JC
1293 .substreams = 1,
1294 .channels_min = 2,
1295 .channels_max = 2,
1296 /* NID is set in via_build_pcms */
1297 .ops = {
1298 .open = via_dig_playback_pcm_open,
6b97eb45 1299 .close = via_dig_playback_pcm_close,
9da29271
TI
1300 .prepare = via_dig_playback_pcm_prepare,
1301 .cleanup = via_dig_playback_pcm_cleanup
c577b8a1
JC
1302 },
1303};
1304
9af74210 1305static const struct hda_pcm_stream via_pcm_digital_capture = {
c577b8a1
JC
1306 .substreams = 1,
1307 .channels_min = 2,
1308 .channels_max = 2,
1309};
1310
370bafbd
TI
1311/*
1312 * slave controls for virtual master
1313 */
1314static 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",
1322 NULL,
1323};
1324
1325static 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",
1333 NULL,
1334};
1335
c577b8a1
JC
1336static int via_build_controls(struct hda_codec *codec)
1337{
1338 struct via_spec *spec = codec->spec;
5b0cb1d8 1339 struct snd_kcontrol *kctl;
5b0cb1d8 1340 int err, i;
c577b8a1 1341
24088a58
TI
1342 if (spec->set_widgets_power_state)
1343 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1344 return -ENOMEM;
1345
c577b8a1
JC
1346 for (i = 0; i < spec->num_mixers; i++) {
1347 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1348 if (err < 0)
1349 return err;
1350 }
1351
1352 if (spec->multiout.dig_out_nid) {
1353 err = snd_hda_create_spdif_out_ctls(codec,
74b654c9 1354 spec->multiout.dig_out_nid,
c577b8a1
JC
1355 spec->multiout.dig_out_nid);
1356 if (err < 0)
1357 return err;
9a08160b
TI
1358 err = snd_hda_create_spdif_share_sw(codec,
1359 &spec->multiout);
1360 if (err < 0)
1361 return err;
1362 spec->multiout.share_spdif = 1;
c577b8a1
JC
1363 }
1364 if (spec->dig_in_nid) {
1365 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1366 if (err < 0)
1367 return err;
1368 }
17314379 1369
370bafbd
TI
1370 /* if we have no master control, let's create it */
1371 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1372 unsigned int vmaster_tlv[4];
1373 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1374 HDA_OUTPUT, vmaster_tlv);
1375 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1376 vmaster_tlv, via_slave_vols);
1377 if (err < 0)
1378 return err;
1379 }
1380 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1381 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1382 NULL, via_slave_sws);
1383 if (err < 0)
1384 return err;
1385 }
1386
5b0cb1d8
JK
1387 /* assign Capture Source enums to NID */
1388 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1389 for (i = 0; kctl && i < kctl->count; i++) {
21949f00 1390 err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]);
5b0cb1d8
JK
1391 if (err < 0)
1392 return err;
1393 }
1394
17314379 1395 /* init power states */
3e95b9ab 1396 set_widgets_power_state(codec);
ada509ec 1397 analog_low_current_mode(codec);
17314379 1398
603c4019 1399 via_free_kctls(codec); /* no longer needed */
c577b8a1
JC
1400 return 0;
1401}
1402
1403static int via_build_pcms(struct hda_codec *codec)
1404{
1405 struct via_spec *spec = codec->spec;
1406 struct hda_pcm *info = spec->pcm_rec;
1407
1408 codec->num_pcms = 1;
1409 codec->pcm_info = info;
1410
82673bc8
TI
1411 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1412 "%s Analog", codec->chip_name);
c577b8a1 1413 info->name = spec->stream_name_analog;
9af74210
TI
1414
1415 if (!spec->stream_analog_playback)
1416 spec->stream_analog_playback = &via_pcm_analog_playback;
377ff31a 1417 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
9af74210 1418 *spec->stream_analog_playback;
377ff31a
LW
1419 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1420 spec->multiout.dac_nids[0];
9af74210
TI
1421 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1422 spec->multiout.max_channels;
c577b8a1 1423
a86a88ea
TI
1424 if (!spec->stream_analog_capture) {
1425 if (spec->dyn_adc_switch)
1426 spec->stream_analog_capture =
1427 &via_pcm_dyn_adc_analog_capture;
1428 else
1429 spec->stream_analog_capture = &via_pcm_analog_capture;
1430 }
9af74210
TI
1431 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1432 *spec->stream_analog_capture;
1433 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
a86a88ea
TI
1434 if (!spec->dyn_adc_switch)
1435 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1436 spec->num_adc_nids;
c577b8a1
JC
1437
1438 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1439 codec->num_pcms++;
1440 info++;
82673bc8
TI
1441 snprintf(spec->stream_name_digital,
1442 sizeof(spec->stream_name_digital),
1443 "%s Digital", codec->chip_name);
c577b8a1 1444 info->name = spec->stream_name_digital;
7ba72ba1 1445 info->pcm_type = HDA_PCM_TYPE_SPDIF;
c577b8a1 1446 if (spec->multiout.dig_out_nid) {
9af74210
TI
1447 if (!spec->stream_digital_playback)
1448 spec->stream_digital_playback =
1449 &via_pcm_digital_playback;
c577b8a1 1450 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
9af74210 1451 *spec->stream_digital_playback;
c577b8a1
JC
1452 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1453 spec->multiout.dig_out_nid;
1454 }
1455 if (spec->dig_in_nid) {
9af74210
TI
1456 if (!spec->stream_digital_capture)
1457 spec->stream_digital_capture =
1458 &via_pcm_digital_capture;
c577b8a1 1459 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
9af74210 1460 *spec->stream_digital_capture;
c577b8a1
JC
1461 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1462 spec->dig_in_nid;
1463 }
1464 }
1465
ece8d043 1466 if (spec->hp_dac_nid) {
7eb56e84
TI
1467 codec->num_pcms++;
1468 info++;
1469 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1470 "%s HP", codec->chip_name);
1471 info->name = spec->stream_name_hp;
1472 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1473 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
ece8d043 1474 spec->hp_dac_nid;
7eb56e84 1475 }
c577b8a1
JC
1476 return 0;
1477}
1478
1479static void via_free(struct hda_codec *codec)
1480{
1481 struct via_spec *spec = codec->spec;
c577b8a1
JC
1482
1483 if (!spec)
1484 return;
1485
603c4019 1486 via_free_kctls(codec);
1f2e99fe 1487 vt1708_stop_hp_work(spec);
a86a88ea
TI
1488 kfree(spec->bind_cap_vol);
1489 kfree(spec->bind_cap_sw);
1490 kfree(spec);
c577b8a1
JC
1491}
1492
64be285b
TI
1493/* mute/unmute outputs */
1494static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1495 hda_nid_t *pins, bool mute)
1496{
1497 int i;
94994734
TI
1498 for (i = 0; i < num_pins; i++) {
1499 unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
1500 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1501 if (parm & AC_PINCTL_IN_EN)
1502 continue;
1503 if (mute)
1504 parm &= ~AC_PINCTL_OUT_EN;
1505 else
1506 parm |= AC_PINCTL_OUT_EN;
64be285b 1507 snd_hda_codec_write(codec, pins[i], 0,
94994734
TI
1508 AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
1509 }
64be285b
TI
1510}
1511
4a918ffe
TI
1512/* mute internal speaker if line-out is plugged */
1513static void via_line_automute(struct hda_codec *codec, int present)
69e52a80 1514{
69e52a80
HW
1515 struct via_spec *spec = codec->spec;
1516
4a918ffe
TI
1517 if (!spec->autocfg.speaker_outs)
1518 return;
1519 if (!present)
1520 present = snd_hda_jack_detect(codec,
1521 spec->autocfg.line_out_pins[0]);
1522 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1523 spec->autocfg.speaker_pins,
1524 present);
69e52a80
HW
1525}
1526
4a918ffe
TI
1527/* mute internal speaker if HP is plugged */
1528static void via_hp_automute(struct hda_codec *codec)
f3db423d 1529{
4a918ffe 1530 int present = 0;
6e969d91 1531 int nums;
f3db423d
LW
1532 struct via_spec *spec = codec->spec;
1533
6e969d91 1534 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
4a918ffe 1535 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
6e969d91
TI
1536
1537 if (spec->smart51_enabled)
1538 nums = spec->autocfg.line_outs + spec->smart51_nums;
1539 else
1540 nums = spec->autocfg.line_outs;
1541 toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
1542
4a918ffe 1543 via_line_automute(codec, present);
f3db423d
LW
1544}
1545
69e52a80
HW
1546static void via_gpio_control(struct hda_codec *codec)
1547{
1548 unsigned int gpio_data;
1549 unsigned int vol_counter;
1550 unsigned int vol;
1551 unsigned int master_vol;
1552
1553 struct via_spec *spec = codec->spec;
1554
1555 gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
1556 AC_VERB_GET_GPIO_DATA, 0) & 0x03;
1557
1558 vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
1559 0xF84, 0) & 0x3F0000) >> 16;
1560
1561 vol = vol_counter & 0x1F;
1562 master_vol = snd_hda_codec_read(codec, 0x1A, 0,
1563 AC_VERB_GET_AMP_GAIN_MUTE,
1564 AC_AMP_GET_INPUT);
1565
1566 if (gpio_data == 0x02) {
1567 /* unmute line out */
3e0693e2
TI
1568 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1569 AC_VERB_SET_PIN_WIDGET_CONTROL,
1570 PIN_OUT);
69e52a80
HW
1571 if (vol_counter & 0x20) {
1572 /* decrease volume */
1573 if (vol > master_vol)
1574 vol = master_vol;
1575 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
1576 0, HDA_AMP_VOLMASK,
1577 master_vol-vol);
1578 } else {
1579 /* increase volume */
1580 snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
1581 HDA_AMP_VOLMASK,
1582 ((master_vol+vol) > 0x2A) ? 0x2A :
1583 (master_vol+vol));
1584 }
1585 } else if (!(gpio_data & 0x02)) {
1586 /* mute line out */
3e0693e2
TI
1587 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1588 AC_VERB_SET_PIN_WIDGET_CONTROL,
1589 0);
69e52a80
HW
1590 }
1591}
1592
1593/* unsolicited event for jack sensing */
1594static void via_unsol_event(struct hda_codec *codec,
1595 unsigned int res)
1596{
1597 res >>= 26;
ec7e7e42 1598
a34df19a 1599 if (res & VIA_JACK_EVENT)
3e95b9ab 1600 set_widgets_power_state(codec);
ec7e7e42
LW
1601
1602 res &= ~VIA_JACK_EVENT;
1603
21ce0b65 1604 if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
ec7e7e42
LW
1605 via_hp_automute(codec);
1606 else if (res == VIA_GPIO_EVENT)
1607 via_gpio_control(codec);
69e52a80
HW
1608}
1609
1f2e99fe
LW
1610#ifdef SND_HDA_NEEDS_RESUME
1611static int via_suspend(struct hda_codec *codec, pm_message_t state)
1612{
1613 struct via_spec *spec = codec->spec;
1614 vt1708_stop_hp_work(spec);
1615 return 0;
1616}
1617#endif
1618
cb53c626
TI
1619#ifdef CONFIG_SND_HDA_POWER_SAVE
1620static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1621{
1622 struct via_spec *spec = codec->spec;
1623 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
1624}
1625#endif
1626
c577b8a1
JC
1627/*
1628 */
5d41762a
TI
1629
1630static int via_init(struct hda_codec *codec);
1631
90dd48a1 1632static const struct hda_codec_ops via_patch_ops = {
c577b8a1
JC
1633 .build_controls = via_build_controls,
1634 .build_pcms = via_build_pcms,
1635 .init = via_init,
1636 .free = via_free,
4a918ffe 1637 .unsol_event = via_unsol_event,
1f2e99fe
LW
1638#ifdef SND_HDA_NEEDS_RESUME
1639 .suspend = via_suspend,
1640#endif
cb53c626
TI
1641#ifdef CONFIG_SND_HDA_POWER_SAVE
1642 .check_power_status = via_check_power_status,
1643#endif
c577b8a1
JC
1644};
1645
4a79616d
TI
1646static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1647{
1648 struct via_spec *spec = codec->spec;
1649 int i;
1650
1651 for (i = 0; i < spec->multiout.num_dacs; i++) {
1652 if (spec->multiout.dac_nids[i] == dac)
1653 return false;
1654 }
ece8d043 1655 if (spec->hp_dac_nid == dac)
4a79616d
TI
1656 return false;
1657 return true;
1658}
1659
8e3679dc 1660static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
3214b966
TI
1661 hda_nid_t target_dac, int with_aa_mix,
1662 struct nid_path *path, int depth)
4a79616d 1663{
3214b966 1664 struct via_spec *spec = codec->spec;
4a79616d
TI
1665 hda_nid_t conn[8];
1666 int i, nums;
1667
3214b966
TI
1668 if (nid == spec->aa_mix_nid) {
1669 if (!with_aa_mix)
1670 return false;
1671 with_aa_mix = 2; /* mark aa-mix is included */
1672 }
1673
4a79616d
TI
1674 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1675 for (i = 0; i < nums; i++) {
1676 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1677 continue;
3214b966
TI
1678 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1679 /* aa-mix is requested but not included? */
1680 if (!(spec->aa_mix_nid && with_aa_mix == 1))
1681 goto found;
1682 }
4a79616d 1683 }
8e3679dc 1684 if (depth >= MAX_NID_PATH_DEPTH)
4a79616d
TI
1685 return false;
1686 for (i = 0; i < nums; i++) {
1687 unsigned int type;
1688 type = get_wcaps_type(get_wcaps(codec, conn[i]));
3214b966 1689 if (type == AC_WID_AUD_OUT)
4a79616d 1690 continue;
8e3679dc 1691 if (__parse_output_path(codec, conn[i], target_dac,
3214b966 1692 with_aa_mix, path, depth + 1))
09a9ad69 1693 goto found;
4a79616d
TI
1694 }
1695 return false;
09a9ad69
TI
1696
1697 found:
1698 path->path[path->depth] = conn[i];
1699 path->idx[path->depth] = i;
1700 if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
1701 path->multi[path->depth] = 1;
1702 path->depth++;
1703 return true;
4a79616d
TI
1704}
1705
8e3679dc 1706static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
3214b966
TI
1707 hda_nid_t target_dac, int with_aa_mix,
1708 struct nid_path *path)
8e3679dc 1709{
3214b966 1710 if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
8e3679dc
TI
1711 path->path[path->depth] = nid;
1712 path->depth++;
3214b966
TI
1713 snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
1714 path->depth, path->path[0], path->path[1],
1715 path->path[2], path->path[3], path->path[4]);
8e3679dc
TI
1716 return true;
1717 }
1718 return false;
1719}
1720
4a79616d 1721static int via_auto_fill_dac_nids(struct hda_codec *codec)
c577b8a1 1722{
4a79616d
TI
1723 struct via_spec *spec = codec->spec;
1724 const struct auto_pin_cfg *cfg = &spec->autocfg;
5c9a5615 1725 int i, dac_num;
c577b8a1
JC
1726 hda_nid_t nid;
1727
4a79616d 1728 spec->multiout.dac_nids = spec->private_dac_nids;
5c9a5615 1729 dac_num = 0;
4a79616d 1730 for (i = 0; i < cfg->line_outs; i++) {
3214b966 1731 hda_nid_t dac = 0;
4a79616d
TI
1732 nid = cfg->line_out_pins[i];
1733 if (!nid)
1734 continue;
3214b966
TI
1735 if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
1736 dac = spec->out_path[i].path[0];
1737 if (!i && parse_output_path(codec, nid, dac, 1,
1738 &spec->out_mix_path))
1739 dac = spec->out_mix_path.path[0];
1740 if (dac) {
1741 spec->private_dac_nids[i] = dac;
5c9a5615
LW
1742 dac_num++;
1743 }
4a79616d 1744 }
3214b966
TI
1745 if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
1746 spec->out_path[0] = spec->out_mix_path;
1747 spec->out_mix_path.depth = 0;
1748 }
5c9a5615 1749 spec->multiout.num_dacs = dac_num;
4a79616d
TI
1750 return 0;
1751}
c577b8a1 1752
4a79616d 1753static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
09a9ad69 1754 int chs, bool check_dac, struct nid_path *path)
4a79616d
TI
1755{
1756 struct via_spec *spec = codec->spec;
1757 char name[32];
09a9ad69
TI
1758 hda_nid_t dac, pin, sel, nid;
1759 int err;
a934d5a9 1760
09a9ad69
TI
1761 dac = check_dac ? path->path[0] : 0;
1762 pin = path->path[path->depth - 1];
1763 sel = path->depth > 1 ? path->path[1] : 0;
377ff31a 1764
8df2a312 1765 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
4a79616d 1766 nid = dac;
8df2a312 1767 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
4a79616d 1768 nid = pin;
a934d5a9
TI
1769 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1770 nid = sel;
4a79616d
TI
1771 else
1772 nid = 0;
1773 if (nid) {
1774 sprintf(name, "%s Playback Volume", pfx);
1775 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
a00a5fad 1776 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
4a79616d
TI
1777 if (err < 0)
1778 return err;
09a9ad69 1779 path->vol_ctl = nid;
c577b8a1
JC
1780 }
1781
8df2a312 1782 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
4a79616d 1783 nid = dac;
8df2a312 1784 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
4a79616d 1785 nid = pin;
a934d5a9
TI
1786 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
1787 nid = sel;
4a79616d
TI
1788 else
1789 nid = 0;
1790 if (nid) {
1791 sprintf(name, "%s Playback Switch", pfx);
1792 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1793 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1794 if (err < 0)
1795 return err;
09a9ad69 1796 path->mute_ctl = nid;
4a79616d 1797 }
c577b8a1
JC
1798 return 0;
1799}
1800
f4a7828b
TI
1801static void mangle_smart51(struct hda_codec *codec)
1802{
1803 struct via_spec *spec = codec->spec;
1804 struct auto_pin_cfg *cfg = &spec->autocfg;
0f98c24b
TI
1805 struct auto_pin_cfg_item *ins = cfg->inputs;
1806 int i, j, nums, attr;
1807 int pins[AUTO_CFG_MAX_INS];
1808
1809 for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
1810 nums = 0;
1811 for (i = 0; i < cfg->num_inputs; i++) {
1812 unsigned int def;
1813 if (ins[i].type > AUTO_PIN_LINE_IN)
1814 continue;
1815 def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
1816 if (snd_hda_get_input_pin_attr(def) != attr)
1817 continue;
1818 for (j = 0; j < nums; j++)
1819 if (ins[pins[j]].type < ins[i].type) {
1820 memmove(pins + j + 1, pins + j,
21d45d2b 1821 (nums - j) * sizeof(int));
0f98c24b
TI
1822 break;
1823 }
1824 pins[j] = i;
e3d7a143 1825 nums++;
0f98c24b
TI
1826 }
1827 if (cfg->line_outs + nums < 3)
f4a7828b 1828 continue;
0f98c24b
TI
1829 for (i = 0; i < nums; i++) {
1830 hda_nid_t pin = ins[pins[i]].pin;
1831 spec->smart51_pins[spec->smart51_nums++] = pin;
1832 cfg->line_out_pins[cfg->line_outs++] = pin;
1833 if (cfg->line_outs == 3)
1834 break;
1835 }
1836 return;
f4a7828b
TI
1837 }
1838}
1839
c577b8a1 1840/* add playback controls from the parsed DAC table */
4a79616d 1841static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
c577b8a1 1842{
4a79616d 1843 struct via_spec *spec = codec->spec;
f4a7828b 1844 struct auto_pin_cfg *cfg = &spec->autocfg;
3214b966 1845 struct nid_path *path;
ea734963
TI
1846 static const char * const chname[4] = {
1847 "Front", "Surround", "C/LFE", "Side"
1848 };
4a79616d 1849 int i, idx, err;
f4a7828b
TI
1850 int old_line_outs;
1851
1852 /* check smart51 */
1853 old_line_outs = cfg->line_outs;
1854 if (cfg->line_outs == 1)
1855 mangle_smart51(codec);
c577b8a1 1856
e3d7a143
TI
1857 err = via_auto_fill_dac_nids(codec);
1858 if (err < 0)
1859 return err;
1860
5c9a5615
LW
1861 if (spec->multiout.num_dacs < 3) {
1862 spec->smart51_nums = 0;
1863 cfg->line_outs = old_line_outs;
1864 }
4a79616d
TI
1865 for (i = 0; i < cfg->line_outs; i++) {
1866 hda_nid_t pin, dac;
1867 pin = cfg->line_out_pins[i];
1868 dac = spec->multiout.dac_nids[i];
1869 if (!pin || !dac)
c577b8a1 1870 continue;
3214b966 1871 path = spec->out_path + i;
0fe0adf8 1872 if (i == HDA_CLFE) {
3214b966 1873 err = create_ch_ctls(codec, "Center", 1, true, path);
c577b8a1
JC
1874 if (err < 0)
1875 return err;
3214b966 1876 err = create_ch_ctls(codec, "LFE", 2, true, path);
c577b8a1
JC
1877 if (err < 0)
1878 return err;
1879 } else {
6aadf41d
TI
1880 const char *pfx = chname[i];
1881 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1882 cfg->line_outs == 1)
1883 pfx = "Speaker";
3214b966 1884 err = create_ch_ctls(codec, pfx, 3, true, path);
c577b8a1
JC
1885 if (err < 0)
1886 return err;
1887 }
3214b966
TI
1888 if (path != spec->out_path + i) {
1889 spec->out_path[i].vol_ctl = path->vol_ctl;
1890 spec->out_path[i].mute_ctl = path->mute_ctl;
1891 }
1892 if (path == spec->out_path && spec->out_mix_path.depth) {
1893 spec->out_mix_path.vol_ctl = path->vol_ctl;
1894 spec->out_mix_path.mute_ctl = path->mute_ctl;
1895 }
c577b8a1
JC
1896 }
1897
4a79616d
TI
1898 idx = get_connection_index(codec, spec->aa_mix_nid,
1899 spec->multiout.dac_nids[0]);
1900 if (idx >= 0) {
1901 /* add control to mixer */
3214b966
TI
1902 const char *name;
1903 name = spec->out_mix_path.depth ?
1904 "PCM Loopback Playback Volume" : "PCM Playback Volume";
1905 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
4a79616d
TI
1906 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1907 idx, HDA_INPUT));
1908 if (err < 0)
1909 return err;
3214b966
TI
1910 name = spec->out_mix_path.depth ?
1911 "PCM Loopback Playback Switch" : "PCM Playback Switch";
1912 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
4a79616d
TI
1913 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
1914 idx, HDA_INPUT));
1915 if (err < 0)
1916 return err;
1917 }
1918
f4a7828b
TI
1919 cfg->line_outs = old_line_outs;
1920
c577b8a1
JC
1921 return 0;
1922}
1923
4a79616d 1924static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
c577b8a1 1925{
4a79616d 1926 struct via_spec *spec = codec->spec;
09a9ad69 1927 struct nid_path *path;
18bd2c44 1928 bool check_dac;
3214b966 1929 int i, err;
c577b8a1
JC
1930
1931 if (!pin)
1932 return 0;
1933
3214b966
TI
1934 if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
1935 for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
1936 if (i < spec->multiout.num_dacs &&
1937 parse_output_path(codec, pin,
1938 spec->multiout.dac_nids[i], 0,
1939 &spec->hp_indep_path)) {
1940 spec->hp_indep_shared = i;
1941 break;
1942 }
1943 }
25250505 1944 }
3214b966
TI
1945 if (spec->hp_indep_path.depth) {
1946 spec->hp_dac_nid = spec->hp_indep_path.path[0];
1947 if (!spec->hp_indep_shared)
1948 spec->hp_path = spec->hp_indep_path;
1949 }
1950 /* optionally check front-path w/o AA-mix */
1951 if (!spec->hp_path.depth)
1952 parse_output_path(codec, pin,
1953 spec->multiout.dac_nids[HDA_FRONT], 0,
1954 &spec->hp_path);
c577b8a1 1955
ece8d043 1956 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
3214b966 1957 1, &spec->hp_mix_path) && !spec->hp_path.depth)
ece8d043
TI
1958 return 0;
1959
3214b966 1960 if (spec->hp_path.depth) {
09a9ad69 1961 path = &spec->hp_path;
18bd2c44
TI
1962 check_dac = true;
1963 } else {
3214b966 1964 path = &spec->hp_mix_path;
18bd2c44
TI
1965 check_dac = false;
1966 }
1967 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
c577b8a1
JC
1968 if (err < 0)
1969 return err;
3214b966
TI
1970 if (check_dac) {
1971 spec->hp_mix_path.vol_ctl = path->vol_ctl;
1972 spec->hp_mix_path.mute_ctl = path->mute_ctl;
1973 } else {
1974 spec->hp_path.vol_ctl = path->vol_ctl;
1975 spec->hp_path.mute_ctl = path->mute_ctl;
09a9ad69 1976 }
c577b8a1
JC
1977 return 0;
1978}
1979
4a918ffe
TI
1980static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1981{
1982 struct via_spec *spec = codec->spec;
3214b966
TI
1983 struct nid_path *path;
1984 bool check_dac;
4a918ffe 1985 hda_nid_t pin, dac;
3214b966 1986 int err;
4a918ffe
TI
1987
1988 pin = spec->autocfg.speaker_pins[0];
1989 if (!spec->autocfg.speaker_outs || !pin)
1990 return 0;
1991
3214b966 1992 if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
8e3679dc 1993 dac = spec->speaker_path.path[0];
3214b966
TI
1994 if (!dac)
1995 parse_output_path(codec, pin,
1996 spec->multiout.dac_nids[HDA_FRONT], 0,
1997 &spec->speaker_path);
1998 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1999 1, &spec->speaker_mix_path) && !dac)
2000 return 0;
2001
2002 /* no AA-path for front? */
2003 if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
2004 dac = 0;
2005
2006 spec->speaker_dac_nid = dac;
2007 spec->multiout.extra_out_nid[0] = dac;
2008 if (dac) {
2009 path = &spec->speaker_path;
2010 check_dac = true;
2011 } else {
2012 path = &spec->speaker_mix_path;
2013 check_dac = false;
2014 }
2015 err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
2016 if (err < 0)
2017 return err;
2018 if (check_dac) {
2019 spec->speaker_mix_path.vol_ctl = path->vol_ctl;
2020 spec->speaker_mix_path.mute_ctl = path->mute_ctl;
2021 } else {
2022 spec->speaker_path.vol_ctl = path->vol_ctl;
2023 spec->speaker_path.mute_ctl = path->mute_ctl;
4a918ffe 2024 }
3214b966
TI
2025 return 0;
2026}
2027
2028#define via_aamix_ctl_info via_pin_power_ctl_info
4a918ffe 2029
3214b966
TI
2030static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
2031 struct snd_ctl_elem_value *ucontrol)
2032{
2033 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2034 struct via_spec *spec = codec->spec;
2035 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2036 return 0;
2037}
2038
2039static void update_aamix_paths(struct hda_codec *codec, int do_mix,
2040 struct nid_path *nomix, struct nid_path *mix)
2041{
2042 if (do_mix) {
2043 activate_output_path(codec, nomix, false, false);
2044 activate_output_path(codec, mix, true, false);
2045 } else {
2046 activate_output_path(codec, mix, false, false);
2047 activate_output_path(codec, nomix, true, false);
2048 }
2049}
2050
2051static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
2052 struct snd_ctl_elem_value *ucontrol)
2053{
2054 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2055 struct via_spec *spec = codec->spec;
2056 unsigned int val = ucontrol->value.enumerated.item[0];
2057
2058 if (val == spec->aamix_mode)
2059 return 0;
2060 spec->aamix_mode = val;
2061 /* update front path */
2062 update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
2063 /* update HP path */
2064 if (!spec->hp_independent_mode) {
2065 update_aamix_paths(codec, val, &spec->hp_path,
2066 &spec->hp_mix_path);
2067 }
2068 /* update speaker path */
2069 update_aamix_paths(codec, val, &spec->speaker_path,
2070 &spec->speaker_mix_path);
2071 return 1;
2072}
2073
2074static const struct snd_kcontrol_new via_aamix_ctl_enum = {
2075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2076 .name = "Loopback Mixing",
2077 .info = via_aamix_ctl_info,
2078 .get = via_aamix_ctl_get,
2079 .put = via_aamix_ctl_put,
2080};
2081
2082static int via_auto_create_loopback_switch(struct hda_codec *codec)
2083{
2084 struct via_spec *spec = codec->spec;
2085
2086 if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
2087 return 0; /* no loopback switching available */
2088 if (!via_clone_control(spec, &via_aamix_ctl_enum))
2089 return -ENOMEM;
4a918ffe
TI
2090 return 0;
2091}
2092
a766d0d7
TI
2093/* look for ADCs */
2094static int via_fill_adcs(struct hda_codec *codec)
2095{
2096 struct via_spec *spec = codec->spec;
2097 hda_nid_t nid = codec->start_nid;
2098 int i;
2099
2100 for (i = 0; i < codec->num_nodes; i++, nid++) {
2101 unsigned int wcaps = get_wcaps(codec, nid);
2102 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2103 continue;
2104 if (wcaps & AC_WCAP_DIGITAL)
2105 continue;
2106 if (!(wcaps & AC_WCAP_CONN_LIST))
2107 continue;
2108 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
2109 return -ENOMEM;
2110 spec->adc_nids[spec->num_adc_nids++] = nid;
2111 }
2112 return 0;
2113}
2114
a86a88ea
TI
2115/* input-src control */
2116static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
2117 struct snd_ctl_elem_info *uinfo)
2118{
2119 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2120 struct via_spec *spec = codec->spec;
2121
2122 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2123 uinfo->count = 1;
2124 uinfo->value.enumerated.items = spec->num_inputs;
2125 if (uinfo->value.enumerated.item >= spec->num_inputs)
2126 uinfo->value.enumerated.item = spec->num_inputs - 1;
2127 strcpy(uinfo->value.enumerated.name,
2128 spec->inputs[uinfo->value.enumerated.item].label);
2129 return 0;
2130}
2131
2132static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
2133 struct snd_ctl_elem_value *ucontrol)
2134{
2135 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2136 struct via_spec *spec = codec->spec;
2137 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2138
2139 ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
2140 return 0;
2141}
2142
2143static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2144 struct snd_ctl_elem_value *ucontrol)
2145{
2146 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2147 struct via_spec *spec = codec->spec;
2148 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2149 hda_nid_t mux;
2150 int cur;
2151
2152 cur = ucontrol->value.enumerated.item[0];
2153 if (cur < 0 || cur >= spec->num_inputs)
2154 return -EINVAL;
2155 if (spec->cur_mux[idx] == cur)
2156 return 0;
2157 spec->cur_mux[idx] = cur;
2158 if (spec->dyn_adc_switch) {
2159 int adc_idx = spec->inputs[cur].adc_idx;
2160 mux = spec->mux_nids[adc_idx];
2161 via_dyn_adc_pcm_resetup(codec, cur);
2162 } else {
2163 mux = spec->mux_nids[idx];
2164 if (snd_BUG_ON(!mux))
2165 return -EINVAL;
2166 }
2167
2168 if (mux) {
2169 /* switch to D0 beofre change index */
2170 if (snd_hda_codec_read(codec, mux, 0,
2171 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2172 snd_hda_codec_write(codec, mux, 0,
2173 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2174 snd_hda_codec_write(codec, mux, 0,
2175 AC_VERB_SET_CONNECT_SEL,
2176 spec->inputs[cur].mux_idx);
2177 }
2178
2179 /* update jack power state */
2180 set_widgets_power_state(codec);
2181 return 0;
2182}
a766d0d7 2183
d7a99cce
TI
2184static const struct snd_kcontrol_new via_input_src_ctl = {
2185 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2186 /* The multiple "Capture Source" controls confuse alsamixer
2187 * So call somewhat different..
2188 */
2189 /* .name = "Capture Source", */
2190 .name = "Input Source",
2191 .info = via_mux_enum_info,
2192 .get = via_mux_enum_get,
2193 .put = via_mux_enum_put,
2194};
2195
a86a88ea
TI
2196static int create_input_src_ctls(struct hda_codec *codec, int count)
2197{
2198 struct via_spec *spec = codec->spec;
2199 struct snd_kcontrol_new *knew;
2200
2201 if (spec->num_inputs <= 1 || !count)
2202 return 0; /* no need for single src */
2203
2204 knew = via_clone_control(spec, &via_input_src_ctl);
2205 if (!knew)
2206 return -ENOMEM;
2207 knew->count = count;
2208 return 0;
2209}
2210
2211/* add the powersave loopback-list entry */
13af8e77
TI
2212static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2213{
2214 struct hda_amp_list *list;
2215
2216 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2217 return;
2218 list = spec->loopback_list + spec->num_loopbacks;
2219 list->nid = mix;
2220 list->dir = HDA_INPUT;
2221 list->idx = idx;
2222 spec->num_loopbacks++;
2223 spec->loopback.amplist = spec->loopback_list;
2224}
13af8e77 2225
a86a88ea 2226static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
8d087c76 2227 hda_nid_t dst)
a86a88ea 2228{
8d087c76 2229 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
a86a88ea
TI
2230}
2231
2232/* add the input-route to the given pin */
2233static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
c577b8a1 2234{
10a20af7 2235 struct via_spec *spec = codec->spec;
a86a88ea
TI
2236 int c, idx;
2237
2238 spec->inputs[spec->num_inputs].adc_idx = -1;
2239 spec->inputs[spec->num_inputs].pin = pin;
2240 for (c = 0; c < spec->num_adc_nids; c++) {
2241 if (spec->mux_nids[c]) {
2242 idx = get_connection_index(codec, spec->mux_nids[c],
2243 pin);
2244 if (idx < 0)
2245 continue;
2246 spec->inputs[spec->num_inputs].mux_idx = idx;
2247 } else {
8d087c76 2248 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
a86a88ea
TI
2249 continue;
2250 }
2251 spec->inputs[spec->num_inputs].adc_idx = c;
2252 /* Can primary ADC satisfy all inputs? */
2253 if (!spec->dyn_adc_switch &&
2254 spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
2255 snd_printd(KERN_INFO
2256 "via: dynamic ADC switching enabled\n");
2257 spec->dyn_adc_switch = 1;
2258 }
2259 return true;
2260 }
2261 return false;
2262}
2263
2264static int get_mux_nids(struct hda_codec *codec);
2265
2266/* parse input-routes; fill ADCs, MUXs and input-src entries */
2267static int parse_analog_inputs(struct hda_codec *codec)
2268{
2269 struct via_spec *spec = codec->spec;
2270 const struct auto_pin_cfg *cfg = &spec->autocfg;
2271 int i, err;
a766d0d7
TI
2272
2273 err = via_fill_adcs(codec);
2274 if (err < 0)
2275 return err;
2276 err = get_mux_nids(codec);
2277 if (err < 0)
2278 return err;
c577b8a1 2279
a86a88ea
TI
2280 /* fill all input-routes */
2281 for (i = 0; i < cfg->num_inputs; i++) {
2282 if (add_input_route(codec, cfg->inputs[i].pin))
2283 spec->inputs[spec->num_inputs++].label =
2284 hda_get_autocfg_input_label(codec, cfg, i);
f3268512 2285 }
c577b8a1 2286
a86a88ea
TI
2287 /* check for internal loopback recording */
2288 if (spec->aa_mix_nid &&
2289 add_input_route(codec, spec->aa_mix_nid))
2290 spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
2291
2292 return 0;
2293}
2294
2295/* create analog-loopback volume/switch controls */
2296static int create_loopback_ctls(struct hda_codec *codec)
2297{
2298 struct via_spec *spec = codec->spec;
2299 const struct auto_pin_cfg *cfg = &spec->autocfg;
2300 const char *prev_label = NULL;
2301 int type_idx = 0;
2302 int i, j, err, idx;
2303
2304 if (!spec->aa_mix_nid)
2305 return 0;
2306
7b315bb4 2307 for (i = 0; i < cfg->num_inputs; i++) {
a86a88ea
TI
2308 hda_nid_t pin = cfg->inputs[i].pin;
2309 const char *label = hda_get_autocfg_input_label(codec, cfg, i);
2310
1e11cae1 2311 if (prev_label && !strcmp(label, prev_label))
7b315bb4
TI
2312 type_idx++;
2313 else
2314 type_idx = 0;
1e11cae1 2315 prev_label = label;
a86a88ea
TI
2316 idx = get_connection_index(codec, spec->aa_mix_nid, pin);
2317 if (idx >= 0) {
16922281 2318 err = via_new_analog_input(spec, label, type_idx,
a86a88ea 2319 idx, spec->aa_mix_nid);
13af8e77
TI
2320 if (err < 0)
2321 return err;
a86a88ea 2322 add_loopback_list(spec, spec->aa_mix_nid, idx);
13af8e77 2323 }
e3d7a143
TI
2324
2325 /* remember the label for smart51 control */
2326 for (j = 0; j < spec->smart51_nums; j++) {
a86a88ea 2327 if (spec->smart51_pins[j] == pin) {
e3d7a143
TI
2328 spec->smart51_idxs[j] = idx;
2329 spec->smart51_labels[j] = label;
2330 break;
2331 }
2332 }
c577b8a1 2333 }
a86a88ea
TI
2334 return 0;
2335}
2336
2337/* create mic-boost controls (if present) */
2338static int create_mic_boost_ctls(struct hda_codec *codec)
2339{
2340 struct via_spec *spec = codec->spec;
2341 const struct auto_pin_cfg *cfg = &spec->autocfg;
2342 int i, err;
2343
2344 for (i = 0; i < cfg->num_inputs; i++) {
2345 hda_nid_t pin = cfg->inputs[i].pin;
2346 unsigned int caps;
2347 const char *label;
2348 char name[32];
2349
2350 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2351 continue;
2352 caps = query_amp_caps(codec, pin, HDA_INPUT);
2353 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2354 continue;
2355 label = hda_get_autocfg_input_label(codec, cfg, i);
2356 snprintf(name, sizeof(name), "%s Boost Volume", label);
2357 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2358 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2359 if (err < 0)
2360 return err;
2361 }
2362 return 0;
2363}
2364
2365/* create capture and input-src controls for multiple streams */
2366static int create_multi_adc_ctls(struct hda_codec *codec)
2367{
2368 struct via_spec *spec = codec->spec;
2369 int i, err;
d7a99cce
TI
2370
2371 /* create capture mixer elements */
2372 for (i = 0; i < spec->num_adc_nids; i++) {
2373 hda_nid_t adc = spec->adc_nids[i];
2374 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
2375 "Capture Volume", i,
2376 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2377 HDA_INPUT));
2378 if (err < 0)
2379 return err;
2380 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2381 "Capture Switch", i,
2382 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2383 HDA_INPUT));
2384 if (err < 0)
2385 return err;
2386 }
2387
2388 /* input-source control */
2389 for (i = 0; i < spec->num_adc_nids; i++)
2390 if (!spec->mux_nids[i])
2391 break;
a86a88ea
TI
2392 err = create_input_src_ctls(codec, i);
2393 if (err < 0)
2394 return err;
2395 return 0;
2396}
d7a99cce 2397
a86a88ea
TI
2398/* bind capture volume/switch */
2399static struct snd_kcontrol_new via_bind_cap_vol_ctl =
2400 HDA_BIND_VOL("Capture Volume", 0);
2401static struct snd_kcontrol_new via_bind_cap_sw_ctl =
2402 HDA_BIND_SW("Capture Switch", 0);
d7a99cce 2403
a86a88ea
TI
2404static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
2405 struct hda_ctl_ops *ops)
2406{
2407 struct hda_bind_ctls *ctl;
2408 int i;
d7a99cce 2409
a86a88ea
TI
2410 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
2411 if (!ctl)
2412 return -ENOMEM;
2413 ctl->ops = ops;
2414 for (i = 0; i < spec->num_adc_nids; i++)
2415 ctl->values[i] =
2416 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
2417 *ctl_ret = ctl;
2418 return 0;
2419}
2420
2421/* create capture and input-src controls for dynamic ADC-switch case */
2422static int create_dyn_adc_ctls(struct hda_codec *codec)
2423{
2424 struct via_spec *spec = codec->spec;
2425 struct snd_kcontrol_new *knew;
2426 int err;
2427
2428 /* set up the bind capture ctls */
2429 err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
2430 if (err < 0)
2431 return err;
2432 err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
2433 if (err < 0)
2434 return err;
2435
2436 /* create capture mixer elements */
2437 knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
2438 if (!knew)
2439 return -ENOMEM;
2440 knew->private_value = (long)spec->bind_cap_vol;
2441
2442 knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
2443 if (!knew)
2444 return -ENOMEM;
2445 knew->private_value = (long)spec->bind_cap_sw;
2446
2447 /* input-source control */
2448 err = create_input_src_ctls(codec, 1);
2449 if (err < 0)
2450 return err;
2451 return 0;
2452}
2453
2454/* parse and create capture-related stuff */
2455static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
2456{
2457 struct via_spec *spec = codec->spec;
2458 int err;
2459
2460 err = parse_analog_inputs(codec);
2461 if (err < 0)
2462 return err;
2463 if (spec->dyn_adc_switch)
2464 err = create_dyn_adc_ctls(codec);
2465 else
2466 err = create_multi_adc_ctls(codec);
2467 if (err < 0)
2468 return err;
2469 err = create_loopback_ctls(codec);
2470 if (err < 0)
2471 return err;
2472 err = create_mic_boost_ctls(codec);
2473 if (err < 0)
2474 return err;
c577b8a1
JC
2475 return 0;
2476}
2477
76d9b0dd
HW
2478static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2479{
2480 unsigned int def_conf;
2481 unsigned char seqassoc;
2482
2f334f92 2483 def_conf = snd_hda_codec_get_pincfg(codec, nid);
76d9b0dd
HW
2484 seqassoc = (unsigned char) get_defcfg_association(def_conf);
2485 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
82ef9e45
LW
2486 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
2487 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
2488 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
2489 snd_hda_codec_set_pincfg(codec, nid, def_conf);
76d9b0dd
HW
2490 }
2491
2492 return;
2493}
2494
e06e5a29 2495static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
2496 struct snd_ctl_elem_value *ucontrol)
2497{
2498 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2499 struct via_spec *spec = codec->spec;
2500
2501 if (spec->codec_type != VT1708)
2502 return 0;
e06e5a29 2503 spec->vt1708_jack_detect =
1f2e99fe 2504 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
e06e5a29 2505 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
1f2e99fe
LW
2506 return 0;
2507}
2508
e06e5a29 2509static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
2510 struct snd_ctl_elem_value *ucontrol)
2511{
2512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2513 struct via_spec *spec = codec->spec;
2514 int change;
2515
2516 if (spec->codec_type != VT1708)
2517 return 0;
e06e5a29 2518 spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
1f2e99fe 2519 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
e06e5a29
TI
2520 == !spec->vt1708_jack_detect;
2521 if (spec->vt1708_jack_detect) {
1f2e99fe
LW
2522 mute_aa_path(codec, 1);
2523 notify_aa_path_ctls(codec);
2524 }
2525 return change;
2526}
2527
e06e5a29
TI
2528static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2529 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2530 .name = "Jack Detect",
2531 .count = 1,
2532 .info = snd_ctl_boolean_mono_info,
2533 .get = vt1708_jack_detect_get,
2534 .put = vt1708_jack_detect_put,
1f2e99fe
LW
2535};
2536
12daef65
TI
2537static void fill_dig_outs(struct hda_codec *codec);
2538static void fill_dig_in(struct hda_codec *codec);
2539
2540static int via_parse_auto_config(struct hda_codec *codec)
c577b8a1
JC
2541{
2542 struct via_spec *spec = codec->spec;
2543 int err;
2544
2545 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
c577b8a1
JC
2546 if (err < 0)
2547 return err;
2548 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
7f0df88c 2549 return -EINVAL;
c577b8a1 2550
4a79616d 2551 err = via_auto_create_multi_out_ctls(codec);
c577b8a1
JC
2552 if (err < 0)
2553 return err;
4a79616d 2554 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
4a918ffe
TI
2555 if (err < 0)
2556 return err;
2557 err = via_auto_create_speaker_ctls(codec);
3214b966
TI
2558 if (err < 0)
2559 return err;
2560 err = via_auto_create_loopback_switch(codec);
c577b8a1
JC
2561 if (err < 0)
2562 return err;
a86a88ea 2563 err = via_auto_create_analog_input_ctls(codec);
1f2e99fe
LW
2564 if (err < 0)
2565 return err;
c577b8a1
JC
2566
2567 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2568
12daef65
TI
2569 fill_dig_outs(codec);
2570 fill_dig_in(codec);
c577b8a1 2571
603c4019
TI
2572 if (spec->kctls.list)
2573 spec->mixers[spec->num_mixers++] = spec->kctls.list;
c577b8a1 2574
c577b8a1 2575
3214b966 2576 if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
ece8d043
TI
2577 err = via_hp_build(codec);
2578 if (err < 0)
2579 return err;
2580 }
c577b8a1 2581
f4a7828b
TI
2582 err = via_smart51_build(codec);
2583 if (err < 0)
2584 return err;
2585
5d41762a
TI
2586 /* assign slave outs */
2587 if (spec->slave_dig_outs[0])
2588 codec->slave_dig_outs = spec->slave_dig_outs;
2589
c577b8a1
JC
2590 return 1;
2591}
2592
5d41762a
TI
2593static void via_auto_init_dig_outs(struct hda_codec *codec)
2594{
2595 struct via_spec *spec = codec->spec;
2596 if (spec->multiout.dig_out_nid)
2597 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2598 if (spec->slave_dig_outs[0])
2599 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2600}
2601
2602static void via_auto_init_dig_in(struct hda_codec *codec)
c577b8a1 2603{
25eaba2f 2604 struct via_spec *spec = codec->spec;
5d41762a
TI
2605 if (!spec->dig_in_nid)
2606 return;
2607 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2608 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2609}
2610
4a918ffe
TI
2611/* initialize the unsolicited events */
2612static void via_auto_init_unsol_event(struct hda_codec *codec)
2613{
2614 struct via_spec *spec = codec->spec;
2615 struct auto_pin_cfg *cfg = &spec->autocfg;
2616 unsigned int ev;
2617 int i;
2618
2619 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2620 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2621 AC_VERB_SET_UNSOLICITED_ENABLE,
2622 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2623
2624 if (cfg->speaker_pins[0])
2625 ev = VIA_LINE_EVENT;
2626 else
2627 ev = 0;
2628 for (i = 0; i < cfg->line_outs; i++) {
2629 if (cfg->line_out_pins[i] &&
2630 is_jack_detectable(codec, cfg->line_out_pins[i]))
63f10d2c 2631 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
4a918ffe
TI
2632 AC_VERB_SET_UNSOLICITED_ENABLE,
2633 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2634 }
2635
2636 for (i = 0; i < cfg->num_inputs; i++) {
2637 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2638 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2639 AC_VERB_SET_UNSOLICITED_ENABLE,
2640 AC_USRSP_EN | VIA_JACK_EVENT);
2641 }
2642}
2643
5d41762a
TI
2644static int via_init(struct hda_codec *codec)
2645{
2646 struct via_spec *spec = codec->spec;
2647 int i;
2648
2649 for (i = 0; i < spec->num_iverbs; i++)
2650 snd_hda_sequence_write(codec, spec->init_verbs[i]);
25eaba2f 2651
c577b8a1
JC
2652 via_auto_init_multi_out(codec);
2653 via_auto_init_hp_out(codec);
4a918ffe 2654 via_auto_init_speaker_out(codec);
c577b8a1 2655 via_auto_init_analog_input(codec);
5d41762a
TI
2656 via_auto_init_dig_outs(codec);
2657 via_auto_init_dig_in(codec);
11890956 2658
4a918ffe
TI
2659 via_auto_init_unsol_event(codec);
2660
2661 via_hp_automute(codec);
25eaba2f 2662
c577b8a1
JC
2663 return 0;
2664}
2665
1f2e99fe
LW
2666static void vt1708_update_hp_jack_state(struct work_struct *work)
2667{
2668 struct via_spec *spec = container_of(work, struct via_spec,
2669 vt1708_hp_work.work);
2670 if (spec->codec_type != VT1708)
2671 return;
2672 /* if jack state toggled */
2673 if (spec->vt1708_hp_present
d56757ab 2674 != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) {
1f2e99fe
LW
2675 spec->vt1708_hp_present ^= 1;
2676 via_hp_automute(spec->codec);
2677 }
2678 vt1708_start_hp_work(spec);
2679}
2680
337b9d02
TI
2681static int get_mux_nids(struct hda_codec *codec)
2682{
2683 struct via_spec *spec = codec->spec;
2684 hda_nid_t nid, conn[8];
2685 unsigned int type;
2686 int i, n;
2687
2688 for (i = 0; i < spec->num_adc_nids; i++) {
2689 nid = spec->adc_nids[i];
2690 while (nid) {
a22d543a 2691 type = get_wcaps_type(get_wcaps(codec, nid));
1c55d521
TI
2692 if (type == AC_WID_PIN)
2693 break;
337b9d02
TI
2694 n = snd_hda_get_connections(codec, nid, conn,
2695 ARRAY_SIZE(conn));
2696 if (n <= 0)
2697 break;
2698 if (n > 1) {
2699 spec->mux_nids[i] = nid;
2700 break;
2701 }
2702 nid = conn[0];
2703 }
2704 }
1c55d521 2705 return 0;
337b9d02
TI
2706}
2707
c577b8a1
JC
2708static int patch_vt1708(struct hda_codec *codec)
2709{
2710 struct via_spec *spec;
2711 int err;
2712
2713 /* create a codec specific record */
5b0cb1d8 2714 spec = via_new_spec(codec);
c577b8a1
JC
2715 if (spec == NULL)
2716 return -ENOMEM;
2717
620e2b28
TI
2718 spec->aa_mix_nid = 0x17;
2719
12daef65
TI
2720 /* Add HP and CD pin config connect bit re-config action */
2721 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2722 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2723
c577b8a1 2724 /* automatic parse from the BIOS config */
12daef65 2725 err = via_parse_auto_config(codec);
c577b8a1
JC
2726 if (err < 0) {
2727 via_free(codec);
2728 return err;
c577b8a1
JC
2729 }
2730
12daef65
TI
2731 /* add jack detect on/off control */
2732 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2733 return -ENOMEM;
2734
bc9b5623
TI
2735 /* disable 32bit format on VT1708 */
2736 if (codec->vendor_id == 0x11061708)
2737 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
c577b8a1 2738
e322a36d
LW
2739 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
2740
c577b8a1
JC
2741 codec->patch_ops = via_patch_ops;
2742
1f2e99fe 2743 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
c577b8a1
JC
2744 return 0;
2745}
2746
ddd304d8 2747static int patch_vt1709(struct hda_codec *codec)
c577b8a1
JC
2748{
2749 struct via_spec *spec;
2750 int err;
2751
2752 /* create a codec specific record */
5b0cb1d8 2753 spec = via_new_spec(codec);
c577b8a1
JC
2754 if (spec == NULL)
2755 return -ENOMEM;
2756
620e2b28
TI
2757 spec->aa_mix_nid = 0x18;
2758
12daef65 2759 err = via_parse_auto_config(codec);
c577b8a1
JC
2760 if (err < 0) {
2761 via_free(codec);
2762 return err;
c577b8a1
JC
2763 }
2764
c577b8a1
JC
2765 codec->patch_ops = via_patch_ops;
2766
f7278fd0
JC
2767 return 0;
2768}
2769
3e95b9ab
LW
2770static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
2771{
2772 struct via_spec *spec = codec->spec;
2773 int imux_is_smixer;
2774 unsigned int parm;
2775 int is_8ch = 0;
bc92df7f
LW
2776 if ((spec->codec_type != VT1708B_4CH) &&
2777 (codec->vendor_id != 0x11064397))
3e95b9ab
LW
2778 is_8ch = 1;
2779
2780 /* SW0 (17h) = stereo mixer */
2781 imux_is_smixer =
2782 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
2783 == ((spec->codec_type == VT1708S) ? 5 : 0));
2784 /* inputs */
2785 /* PW 1/2/5 (1ah/1bh/1eh) */
2786 parm = AC_PWRST_D3;
2787 set_pin_power_state(codec, 0x1a, &parm);
2788 set_pin_power_state(codec, 0x1b, &parm);
2789 set_pin_power_state(codec, 0x1e, &parm);
2790 if (imux_is_smixer)
2791 parm = AC_PWRST_D0;
2792 /* SW0 (17h), AIW 0/1 (13h/14h) */
2793 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
2794 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
2795 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
2796
2797 /* outputs */
2798 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
2799 parm = AC_PWRST_D3;
2800 set_pin_power_state(codec, 0x19, &parm);
2801 if (spec->smart51_enabled)
2802 set_pin_power_state(codec, 0x1b, &parm);
2803 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
2804 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
2805
2806 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
2807 if (is_8ch) {
2808 parm = AC_PWRST_D3;
2809 set_pin_power_state(codec, 0x22, &parm);
2810 if (spec->smart51_enabled)
2811 set_pin_power_state(codec, 0x1a, &parm);
2812 snd_hda_codec_write(codec, 0x26, 0,
2813 AC_VERB_SET_POWER_STATE, parm);
2814 snd_hda_codec_write(codec, 0x24, 0,
2815 AC_VERB_SET_POWER_STATE, parm);
bc92df7f
LW
2816 } else if (codec->vendor_id == 0x11064397) {
2817 /* PW7(23h), SW2(27h), AOW2(25h) */
2818 parm = AC_PWRST_D3;
2819 set_pin_power_state(codec, 0x23, &parm);
2820 if (spec->smart51_enabled)
2821 set_pin_power_state(codec, 0x1a, &parm);
2822 snd_hda_codec_write(codec, 0x27, 0,
2823 AC_VERB_SET_POWER_STATE, parm);
2824 snd_hda_codec_write(codec, 0x25, 0,
2825 AC_VERB_SET_POWER_STATE, parm);
3e95b9ab
LW
2826 }
2827
2828 /* PW 3/4/7 (1ch/1dh/23h) */
2829 parm = AC_PWRST_D3;
2830 /* force to D0 for internal Speaker */
2831 set_pin_power_state(codec, 0x1c, &parm);
2832 set_pin_power_state(codec, 0x1d, &parm);
2833 if (is_8ch)
2834 set_pin_power_state(codec, 0x23, &parm);
2835
2836 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
2837 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
2838 imux_is_smixer ? AC_PWRST_D0 : parm);
2839 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
2840 if (is_8ch) {
2841 snd_hda_codec_write(codec, 0x25, 0,
2842 AC_VERB_SET_POWER_STATE, parm);
2843 snd_hda_codec_write(codec, 0x27, 0,
2844 AC_VERB_SET_POWER_STATE, parm);
bc92df7f
LW
2845 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
2846 snd_hda_codec_write(codec, 0x25, 0,
2847 AC_VERB_SET_POWER_STATE, parm);
3e95b9ab
LW
2848}
2849
518bf3ba 2850static int patch_vt1708S(struct hda_codec *codec);
ddd304d8 2851static int patch_vt1708B(struct hda_codec *codec)
f7278fd0
JC
2852{
2853 struct via_spec *spec;
2854 int err;
2855
518bf3ba
LW
2856 if (get_codec_type(codec) == VT1708BCE)
2857 return patch_vt1708S(codec);
ddd304d8 2858
f7278fd0 2859 /* create a codec specific record */
5b0cb1d8 2860 spec = via_new_spec(codec);
f7278fd0
JC
2861 if (spec == NULL)
2862 return -ENOMEM;
2863
620e2b28
TI
2864 spec->aa_mix_nid = 0x16;
2865
f7278fd0 2866 /* automatic parse from the BIOS config */
12daef65 2867 err = via_parse_auto_config(codec);
f7278fd0
JC
2868 if (err < 0) {
2869 via_free(codec);
2870 return err;
f7278fd0
JC
2871 }
2872
f7278fd0
JC
2873 codec->patch_ops = via_patch_ops;
2874
3e95b9ab
LW
2875 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
2876
f7278fd0
JC
2877 return 0;
2878}
2879
d949cac1 2880/* Patch for VT1708S */
096a8854 2881static const struct hda_verb vt1708S_init_verbs[] = {
d7426329
HW
2882 /* Enable Mic Boost Volume backdoor */
2883 {0x1, 0xf98, 0x1},
bc7e7e5c
LW
2884 /* don't bybass mixer */
2885 {0x1, 0xf88, 0xc0},
d949cac1
HW
2886 { }
2887};
2888
4a79616d
TI
2889/* fill out digital output widgets; one for master and one for slave outputs */
2890static void fill_dig_outs(struct hda_codec *codec)
d949cac1 2891{
4a79616d 2892 struct via_spec *spec = codec->spec;
d949cac1 2893 int i;
d949cac1 2894
4a79616d
TI
2895 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2896 hda_nid_t nid;
2897 int conn;
9da29271
TI
2898
2899 nid = spec->autocfg.dig_out_pins[i];
2900 if (!nid)
2901 continue;
2902 conn = snd_hda_get_connections(codec, nid, &nid, 1);
2903 if (conn < 1)
2904 continue;
2905 if (!spec->multiout.dig_out_nid)
2906 spec->multiout.dig_out_nid = nid;
2907 else {
2908 spec->slave_dig_outs[0] = nid;
2909 break; /* at most two dig outs */
2910 }
2911 }
2912}
2913
12daef65 2914static void fill_dig_in(struct hda_codec *codec)
d949cac1
HW
2915{
2916 struct via_spec *spec = codec->spec;
12daef65
TI
2917 hda_nid_t dig_nid;
2918 int i, err;
d949cac1 2919
12daef65
TI
2920 if (!spec->autocfg.dig_in_pin)
2921 return;
f4a7828b 2922
12daef65
TI
2923 dig_nid = codec->start_nid;
2924 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2925 unsigned int wcaps = get_wcaps(codec, dig_nid);
2926 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2927 continue;
2928 if (!(wcaps & AC_WCAP_DIGITAL))
2929 continue;
2930 if (!(wcaps & AC_WCAP_CONN_LIST))
2931 continue;
2932 err = get_connection_index(codec, dig_nid,
2933 spec->autocfg.dig_in_pin);
2934 if (err >= 0) {
2935 spec->dig_in_nid = dig_nid;
2936 break;
2937 }
2938 }
d949cac1
HW
2939}
2940
6369bcfc
LW
2941static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
2942 int offset, int num_steps, int step_size)
2943{
2944 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
2945 (offset << AC_AMPCAP_OFFSET_SHIFT) |
2946 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
2947 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
2948 (0 << AC_AMPCAP_MUTE_SHIFT));
2949}
2950
d949cac1
HW
2951static int patch_vt1708S(struct hda_codec *codec)
2952{
2953 struct via_spec *spec;
2954 int err;
2955
2956 /* create a codec specific record */
5b0cb1d8 2957 spec = via_new_spec(codec);
d949cac1
HW
2958 if (spec == NULL)
2959 return -ENOMEM;
2960
620e2b28 2961 spec->aa_mix_nid = 0x16;
d7a99cce
TI
2962 override_mic_boost(codec, 0x1a, 0, 3, 40);
2963 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 2964
d949cac1 2965 /* automatic parse from the BIOS config */
12daef65 2966 err = via_parse_auto_config(codec);
d949cac1
HW
2967 if (err < 0) {
2968 via_free(codec);
2969 return err;
d949cac1
HW
2970 }
2971
096a8854 2972 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
d949cac1 2973
d949cac1
HW
2974 codec->patch_ops = via_patch_ops;
2975
518bf3ba
LW
2976 /* correct names for VT1708BCE */
2977 if (get_codec_type(codec) == VT1708BCE) {
2978 kfree(codec->chip_name);
2979 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
2980 snprintf(codec->bus->card->mixername,
2981 sizeof(codec->bus->card->mixername),
2982 "%s %s", codec->vendor_name, codec->chip_name);
970f630f 2983 }
bc92df7f
LW
2984 /* correct names for VT1705 */
2985 if (codec->vendor_id == 0x11064397) {
2986 kfree(codec->chip_name);
2987 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
2988 snprintf(codec->bus->card->mixername,
2989 sizeof(codec->bus->card->mixername),
2990 "%s %s", codec->vendor_name, codec->chip_name);
2991 }
3e95b9ab 2992 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
d949cac1
HW
2993 return 0;
2994}
2995
2996/* Patch for VT1702 */
2997
096a8854 2998static const struct hda_verb vt1702_init_verbs[] = {
bc7e7e5c
LW
2999 /* mixer enable */
3000 {0x1, 0xF88, 0x3},
3001 /* GPIO 0~2 */
3002 {0x1, 0xF82, 0x3F},
d949cac1
HW
3003 { }
3004};
3005
3e95b9ab
LW
3006static void set_widgets_power_state_vt1702(struct hda_codec *codec)
3007{
3008 int imux_is_smixer =
3009 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3010 unsigned int parm;
3011 /* inputs */
3012 /* PW 1/2/5 (14h/15h/18h) */
3013 parm = AC_PWRST_D3;
3014 set_pin_power_state(codec, 0x14, &parm);
3015 set_pin_power_state(codec, 0x15, &parm);
3016 set_pin_power_state(codec, 0x18, &parm);
3017 if (imux_is_smixer)
3018 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
3019 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
3020 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3021 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm);
3022 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3023 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm);
3024
3025 /* outputs */
3026 /* PW 3/4 (16h/17h) */
3027 parm = AC_PWRST_D3;
3028 set_pin_power_state(codec, 0x17, &parm);
3029 set_pin_power_state(codec, 0x16, &parm);
3030 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
3031 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE,
3032 imux_is_smixer ? AC_PWRST_D0 : parm);
3033 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3034 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
3035}
3036
d949cac1
HW
3037static int patch_vt1702(struct hda_codec *codec)
3038{
3039 struct via_spec *spec;
3040 int err;
d949cac1
HW
3041
3042 /* create a codec specific record */
5b0cb1d8 3043 spec = via_new_spec(codec);
d949cac1
HW
3044 if (spec == NULL)
3045 return -ENOMEM;
3046
620e2b28
TI
3047 spec->aa_mix_nid = 0x1a;
3048
12daef65
TI
3049 /* limit AA path volume to 0 dB */
3050 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
3051 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3052 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3053 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3054 (1 << AC_AMPCAP_MUTE_SHIFT));
3055
d949cac1 3056 /* automatic parse from the BIOS config */
12daef65 3057 err = via_parse_auto_config(codec);
d949cac1
HW
3058 if (err < 0) {
3059 via_free(codec);
3060 return err;
d949cac1
HW
3061 }
3062
096a8854 3063 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
d949cac1 3064
d949cac1
HW
3065 codec->patch_ops = via_patch_ops;
3066
3e95b9ab 3067 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
d949cac1
HW
3068 return 0;
3069}
3070
eb7188ca
LW
3071/* Patch for VT1718S */
3072
096a8854 3073static const struct hda_verb vt1718S_init_verbs[] = {
4ab2d53a
LW
3074 /* Enable MW0 adjust Gain 5 */
3075 {0x1, 0xfb2, 0x10},
eb7188ca
LW
3076 /* Enable Boost Volume backdoor */
3077 {0x1, 0xf88, 0x8},
5d41762a 3078
eb7188ca
LW
3079 { }
3080};
3081
3e95b9ab
LW
3082static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
3083{
3084 struct via_spec *spec = codec->spec;
3085 int imux_is_smixer;
3086 unsigned int parm;
3087 /* MUX6 (1eh) = stereo mixer */
3088 imux_is_smixer =
3089 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
3090 /* inputs */
3091 /* PW 5/6/7 (29h/2ah/2bh) */
3092 parm = AC_PWRST_D3;
3093 set_pin_power_state(codec, 0x29, &parm);
3094 set_pin_power_state(codec, 0x2a, &parm);
3095 set_pin_power_state(codec, 0x2b, &parm);
3096 if (imux_is_smixer)
3097 parm = AC_PWRST_D0;
3098 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
3099 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3100 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3101 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3102 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3103
3104 /* outputs */
3105 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
3106 parm = AC_PWRST_D3;
3107 set_pin_power_state(codec, 0x27, &parm);
3108 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm);
3109 snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm);
3110
3111 /* PW2 (26h), AOW2 (ah) */
3112 parm = AC_PWRST_D3;
3113 set_pin_power_state(codec, 0x26, &parm);
3114 if (spec->smart51_enabled)
3115 set_pin_power_state(codec, 0x2b, &parm);
3116 snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm);
3117
3118 /* PW0 (24h), AOW0 (8h) */
3119 parm = AC_PWRST_D3;
3120 set_pin_power_state(codec, 0x24, &parm);
3121 if (!spec->hp_independent_mode) /* check for redirected HP */
3122 set_pin_power_state(codec, 0x28, &parm);
3123 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
3124 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
3125 snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE,
3126 imux_is_smixer ? AC_PWRST_D0 : parm);
3127
3128 /* PW1 (25h), AOW1 (9h) */
3129 parm = AC_PWRST_D3;
3130 set_pin_power_state(codec, 0x25, &parm);
3131 if (spec->smart51_enabled)
3132 set_pin_power_state(codec, 0x2a, &parm);
3133 snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm);
3134
3135 if (spec->hp_independent_mode) {
3136 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
3137 parm = AC_PWRST_D3;
3138 set_pin_power_state(codec, 0x28, &parm);
3139 snd_hda_codec_write(codec, 0x1b, 0,
3140 AC_VERB_SET_POWER_STATE, parm);
3141 snd_hda_codec_write(codec, 0x34, 0,
3142 AC_VERB_SET_POWER_STATE, parm);
3143 snd_hda_codec_write(codec, 0xc, 0,
3144 AC_VERB_SET_POWER_STATE, parm);
3145 }
3146}
3147
30b45033
TI
3148/* Add a connection to the primary DAC from AA-mixer for some codecs
3149 * This isn't listed from the raw info, but the chip has a secret connection.
3150 */
3151static int add_secret_dac_path(struct hda_codec *codec)
3152{
3153 struct via_spec *spec = codec->spec;
3154 int i, nums;
3155 hda_nid_t conn[8];
3156 hda_nid_t nid;
3157
3158 if (!spec->aa_mix_nid)
3159 return 0;
3160 nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
3161 ARRAY_SIZE(conn) - 1);
3162 for (i = 0; i < nums; i++) {
3163 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
3164 return 0;
3165 }
3166
3167 /* find the primary DAC and add to the connection list */
3168 nid = codec->start_nid;
3169 for (i = 0; i < codec->num_nodes; i++, nid++) {
3170 unsigned int caps = get_wcaps(codec, nid);
3171 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
3172 !(caps & AC_WCAP_DIGITAL)) {
3173 conn[nums++] = nid;
3174 return snd_hda_override_conn_list(codec,
3175 spec->aa_mix_nid,
3176 nums, conn);
3177 }
3178 }
3179 return 0;
3180}
3181
3182
eb7188ca
LW
3183static int patch_vt1718S(struct hda_codec *codec)
3184{
3185 struct via_spec *spec;
3186 int err;
3187
3188 /* create a codec specific record */
5b0cb1d8 3189 spec = via_new_spec(codec);
eb7188ca
LW
3190 if (spec == NULL)
3191 return -ENOMEM;
3192
620e2b28 3193 spec->aa_mix_nid = 0x21;
d7a99cce
TI
3194 override_mic_boost(codec, 0x2b, 0, 3, 40);
3195 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 3196 add_secret_dac_path(codec);
620e2b28 3197
eb7188ca 3198 /* automatic parse from the BIOS config */
12daef65 3199 err = via_parse_auto_config(codec);
eb7188ca
LW
3200 if (err < 0) {
3201 via_free(codec);
3202 return err;
eb7188ca
LW
3203 }
3204
096a8854 3205 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
eb7188ca 3206
eb7188ca
LW
3207 codec->patch_ops = via_patch_ops;
3208
3e95b9ab
LW
3209 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
3210
eb7188ca
LW
3211 return 0;
3212}
f3db423d
LW
3213
3214/* Patch for VT1716S */
3215
3216static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
3217 struct snd_ctl_elem_info *uinfo)
3218{
3219 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
3220 uinfo->count = 1;
3221 uinfo->value.integer.min = 0;
3222 uinfo->value.integer.max = 1;
3223 return 0;
3224}
3225
3226static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
3227 struct snd_ctl_elem_value *ucontrol)
3228{
3229 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3230 int index = 0;
3231
3232 index = snd_hda_codec_read(codec, 0x26, 0,
3233 AC_VERB_GET_CONNECT_SEL, 0);
3234 if (index != -1)
3235 *ucontrol->value.integer.value = index;
3236
3237 return 0;
3238}
3239
3240static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
3241 struct snd_ctl_elem_value *ucontrol)
3242{
3243 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3244 struct via_spec *spec = codec->spec;
3245 int index = *ucontrol->value.integer.value;
3246
3247 snd_hda_codec_write(codec, 0x26, 0,
3248 AC_VERB_SET_CONNECT_SEL, index);
3249 spec->dmic_enabled = index;
3e95b9ab 3250 set_widgets_power_state(codec);
f3db423d
LW
3251 return 1;
3252}
3253
90dd48a1 3254static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
f3db423d
LW
3255 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
3256 {
3257 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3258 .name = "Digital Mic Capture Switch",
5b0cb1d8 3259 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
f3db423d
LW
3260 .count = 1,
3261 .info = vt1716s_dmic_info,
3262 .get = vt1716s_dmic_get,
3263 .put = vt1716s_dmic_put,
3264 },
3265 {} /* end */
3266};
3267
3268
3269/* mono-out mixer elements */
90dd48a1 3270static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
f3db423d
LW
3271 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
3272 { } /* end */
3273};
3274
096a8854 3275static const struct hda_verb vt1716S_init_verbs[] = {
f3db423d
LW
3276 /* Enable Boost Volume backdoor */
3277 {0x1, 0xf8a, 0x80},
3278 /* don't bybass mixer */
3279 {0x1, 0xf88, 0xc0},
3280 /* Enable mono output */
3281 {0x1, 0xf90, 0x08},
3282 { }
3283};
3284
3e95b9ab
LW
3285static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
3286{
3287 struct via_spec *spec = codec->spec;
3288 int imux_is_smixer;
3289 unsigned int parm;
3290 unsigned int mono_out, present;
3291 /* SW0 (17h) = stereo mixer */
3292 imux_is_smixer =
3293 (snd_hda_codec_read(codec, 0x17, 0,
3294 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
3295 /* inputs */
3296 /* PW 1/2/5 (1ah/1bh/1eh) */
3297 parm = AC_PWRST_D3;
3298 set_pin_power_state(codec, 0x1a, &parm);
3299 set_pin_power_state(codec, 0x1b, &parm);
3300 set_pin_power_state(codec, 0x1e, &parm);
3301 if (imux_is_smixer)
3302 parm = AC_PWRST_D0;
3303 /* SW0 (17h), AIW0(13h) */
3304 snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm);
3305 snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm);
3306
3307 parm = AC_PWRST_D3;
3308 set_pin_power_state(codec, 0x1e, &parm);
3309 /* PW11 (22h) */
3310 if (spec->dmic_enabled)
3311 set_pin_power_state(codec, 0x22, &parm);
3312 else
3313 snd_hda_codec_write(codec, 0x22, 0,
3314 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3315
3316 /* SW2(26h), AIW1(14h) */
3317 snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm);
3318 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm);
3319
3320 /* outputs */
3321 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
3322 parm = AC_PWRST_D3;
3323 set_pin_power_state(codec, 0x19, &parm);
3324 /* Smart 5.1 PW2(1bh) */
3325 if (spec->smart51_enabled)
3326 set_pin_power_state(codec, 0x1b, &parm);
3327 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3328 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3329
3330 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
3331 parm = AC_PWRST_D3;
3332 set_pin_power_state(codec, 0x23, &parm);
3333 /* Smart 5.1 PW1(1ah) */
3334 if (spec->smart51_enabled)
3335 set_pin_power_state(codec, 0x1a, &parm);
3336 snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm);
3337
3338 /* Smart 5.1 PW5(1eh) */
3339 if (spec->smart51_enabled)
3340 set_pin_power_state(codec, 0x1e, &parm);
3341 snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm);
3342
3343 /* Mono out */
3344 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
3345 present = snd_hda_jack_detect(codec, 0x1c);
3346
3347 if (present)
3348 mono_out = 0;
3349 else {
3350 present = snd_hda_jack_detect(codec, 0x1d);
3351 if (!spec->hp_independent_mode && present)
3352 mono_out = 0;
3353 else
3354 mono_out = 1;
3355 }
3356 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
3357 snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm);
3358 snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm);
3359 snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm);
3360
3361 /* PW 3/4 (1ch/1dh) */
3362 parm = AC_PWRST_D3;
3363 set_pin_power_state(codec, 0x1c, &parm);
3364 set_pin_power_state(codec, 0x1d, &parm);
3365 /* HP Independent Mode, power on AOW3 */
3366 if (spec->hp_independent_mode)
3367 snd_hda_codec_write(codec, 0x25, 0,
3368 AC_VERB_SET_POWER_STATE, parm);
3369
3370 /* force to D0 for internal Speaker */
3371 /* MW0 (16h), AOW0 (10h) */
3372 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE,
3373 imux_is_smixer ? AC_PWRST_D0 : parm);
3374 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE,
3375 mono_out ? AC_PWRST_D0 : parm);
3376}
3377
f3db423d
LW
3378static int patch_vt1716S(struct hda_codec *codec)
3379{
3380 struct via_spec *spec;
3381 int err;
3382
3383 /* create a codec specific record */
5b0cb1d8 3384 spec = via_new_spec(codec);
f3db423d
LW
3385 if (spec == NULL)
3386 return -ENOMEM;
3387
620e2b28 3388 spec->aa_mix_nid = 0x16;
d7a99cce
TI
3389 override_mic_boost(codec, 0x1a, 0, 3, 40);
3390 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 3391
f3db423d 3392 /* automatic parse from the BIOS config */
12daef65 3393 err = via_parse_auto_config(codec);
f3db423d
LW
3394 if (err < 0) {
3395 via_free(codec);
3396 return err;
f3db423d
LW
3397 }
3398
096a8854 3399 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
f3db423d 3400
f3db423d
LW
3401 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
3402 spec->num_mixers++;
3403
3404 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
3405
3406 codec->patch_ops = via_patch_ops;
3407
3e95b9ab 3408 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
f3db423d
LW
3409 return 0;
3410}
25eaba2f
LW
3411
3412/* for vt2002P */
3413
096a8854 3414static const struct hda_verb vt2002P_init_verbs[] = {
eadb9a80
LW
3415 /* Class-D speaker related verbs */
3416 {0x1, 0xfe0, 0x4},
3417 {0x1, 0xfe9, 0x80},
3418 {0x1, 0xfe2, 0x22},
25eaba2f
LW
3419 /* Enable Boost Volume backdoor */
3420 {0x1, 0xfb9, 0x24},
25eaba2f
LW
3421 /* Enable AOW0 to MW9 */
3422 {0x1, 0xfb8, 0x88},
3423 { }
3424};
4a918ffe 3425
096a8854 3426static const struct hda_verb vt1802_init_verbs[] = {
11890956
LW
3427 /* Enable Boost Volume backdoor */
3428 {0x1, 0xfb9, 0x24},
11890956
LW
3429 /* Enable AOW0 to MW9 */
3430 {0x1, 0xfb8, 0x88},
3431 { }
3432};
25eaba2f 3433
3e95b9ab
LW
3434static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
3435{
3436 struct via_spec *spec = codec->spec;
3437 int imux_is_smixer;
3438 unsigned int parm;
3439 unsigned int present;
3440 /* MUX9 (1eh) = stereo mixer */
3441 imux_is_smixer =
3442 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3443 /* inputs */
3444 /* PW 5/6/7 (29h/2ah/2bh) */
3445 parm = AC_PWRST_D3;
3446 set_pin_power_state(codec, 0x29, &parm);
3447 set_pin_power_state(codec, 0x2a, &parm);
3448 set_pin_power_state(codec, 0x2b, &parm);
3449 parm = AC_PWRST_D0;
3450 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
3451 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3452 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3453 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3454 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3455
3456 /* outputs */
3457 /* AOW0 (8h)*/
3458 snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm);
3459
11890956
LW
3460 if (spec->codec_type == VT1802) {
3461 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3462 parm = AC_PWRST_D3;
3463 set_pin_power_state(codec, 0x28, &parm);
3464 snd_hda_codec_write(codec, 0x18, 0,
3465 AC_VERB_SET_POWER_STATE, parm);
3466 snd_hda_codec_write(codec, 0x38, 0,
3467 AC_VERB_SET_POWER_STATE, parm);
3468 } else {
3469 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
3470 parm = AC_PWRST_D3;
3471 set_pin_power_state(codec, 0x26, &parm);
3472 snd_hda_codec_write(codec, 0x1c, 0,
3473 AC_VERB_SET_POWER_STATE, parm);
3474 snd_hda_codec_write(codec, 0x37, 0,
3475 AC_VERB_SET_POWER_STATE, parm);
3476 }
3e95b9ab 3477
11890956
LW
3478 if (spec->codec_type == VT1802) {
3479 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3480 parm = AC_PWRST_D3;
3481 set_pin_power_state(codec, 0x25, &parm);
3482 snd_hda_codec_write(codec, 0x15, 0,
3483 AC_VERB_SET_POWER_STATE, parm);
3484 snd_hda_codec_write(codec, 0x35, 0,
3485 AC_VERB_SET_POWER_STATE, parm);
3486 } else {
3487 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
3488 parm = AC_PWRST_D3;
3489 set_pin_power_state(codec, 0x25, &parm);
3490 snd_hda_codec_write(codec, 0x19, 0,
3491 AC_VERB_SET_POWER_STATE, parm);
3492 snd_hda_codec_write(codec, 0x35, 0,
3493 AC_VERB_SET_POWER_STATE, parm);
3494 }
3e95b9ab
LW
3495
3496 if (spec->hp_independent_mode)
3497 snd_hda_codec_write(codec, 0x9, 0,
3498 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3499
3500 /* Class-D */
3501 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
3502 present = snd_hda_jack_detect(codec, 0x25);
3503
3504 parm = AC_PWRST_D3;
3505 set_pin_power_state(codec, 0x24, &parm);
3506 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
11890956
LW
3507 if (spec->codec_type == VT1802)
3508 snd_hda_codec_write(codec, 0x14, 0,
3509 AC_VERB_SET_POWER_STATE, parm);
3510 else
3511 snd_hda_codec_write(codec, 0x18, 0,
3512 AC_VERB_SET_POWER_STATE, parm);
3e95b9ab
LW
3513 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm);
3514
3515 /* Mono Out */
3516 present = snd_hda_jack_detect(codec, 0x26);
3517
3518 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
11890956
LW
3519 if (spec->codec_type == VT1802) {
3520 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
3521 snd_hda_codec_write(codec, 0x33, 0,
3522 AC_VERB_SET_POWER_STATE, parm);
3523 snd_hda_codec_write(codec, 0x1c, 0,
3524 AC_VERB_SET_POWER_STATE, parm);
3525 snd_hda_codec_write(codec, 0x3c, 0,
3526 AC_VERB_SET_POWER_STATE, parm);
3527 } else {
3528 /* PW15 (31h), MW8(17h), MUX8(3bh) */
3529 snd_hda_codec_write(codec, 0x31, 0,
3530 AC_VERB_SET_POWER_STATE, parm);
3531 snd_hda_codec_write(codec, 0x17, 0,
3532 AC_VERB_SET_POWER_STATE, parm);
3533 snd_hda_codec_write(codec, 0x3b, 0,
3534 AC_VERB_SET_POWER_STATE, parm);
3535 }
3e95b9ab
LW
3536 /* MW9 (21h) */
3537 if (imux_is_smixer || !is_aa_path_mute(codec))
3538 snd_hda_codec_write(codec, 0x21, 0,
3539 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3540 else
3541 snd_hda_codec_write(codec, 0x21, 0,
3542 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3543}
25eaba2f
LW
3544
3545/* patch for vt2002P */
3546static int patch_vt2002P(struct hda_codec *codec)
3547{
3548 struct via_spec *spec;
3549 int err;
3550
3551 /* create a codec specific record */
5b0cb1d8 3552 spec = via_new_spec(codec);
25eaba2f
LW
3553 if (spec == NULL)
3554 return -ENOMEM;
3555
620e2b28 3556 spec->aa_mix_nid = 0x21;
d7a99cce
TI
3557 override_mic_boost(codec, 0x2b, 0, 3, 40);
3558 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 3559 add_secret_dac_path(codec);
620e2b28 3560
25eaba2f 3561 /* automatic parse from the BIOS config */
12daef65 3562 err = via_parse_auto_config(codec);
25eaba2f
LW
3563 if (err < 0) {
3564 via_free(codec);
3565 return err;
25eaba2f
LW
3566 }
3567
11890956 3568 if (spec->codec_type == VT1802)
4a918ffe 3569 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
11890956 3570 else
4a918ffe 3571 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
11890956 3572
25eaba2f
LW
3573 codec->patch_ops = via_patch_ops;
3574
3e95b9ab 3575 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
25eaba2f
LW
3576 return 0;
3577}
ab6734e7
LW
3578
3579/* for vt1812 */
3580
096a8854 3581static const struct hda_verb vt1812_init_verbs[] = {
ab6734e7
LW
3582 /* Enable Boost Volume backdoor */
3583 {0x1, 0xfb9, 0x24},
ab6734e7
LW
3584 /* Enable AOW0 to MW9 */
3585 {0x1, 0xfb8, 0xa8},
3586 { }
3587};
3588
3e95b9ab
LW
3589static void set_widgets_power_state_vt1812(struct hda_codec *codec)
3590{
3591 struct via_spec *spec = codec->spec;
3592 int imux_is_smixer =
3593 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
3594 unsigned int parm;
3595 unsigned int present;
3596 /* MUX10 (1eh) = stereo mixer */
3597 imux_is_smixer =
3598 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
3599 /* inputs */
3600 /* PW 5/6/7 (29h/2ah/2bh) */
3601 parm = AC_PWRST_D3;
3602 set_pin_power_state(codec, 0x29, &parm);
3603 set_pin_power_state(codec, 0x2a, &parm);
3604 set_pin_power_state(codec, 0x2b, &parm);
3605 parm = AC_PWRST_D0;
3606 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
3607 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm);
3608 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm);
3609 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm);
3610 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm);
3611
3612 /* outputs */
3613 /* AOW0 (8h)*/
3614 snd_hda_codec_write(codec, 0x8, 0,
3615 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3616
3617 /* PW4 (28h), MW4 (18h), MUX4(38h) */
3618 parm = AC_PWRST_D3;
3619 set_pin_power_state(codec, 0x28, &parm);
3620 snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm);
3621 snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm);
3622
3623 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
3624 parm = AC_PWRST_D3;
3625 set_pin_power_state(codec, 0x25, &parm);
3626 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm);
3627 snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm);
3628 if (spec->hp_independent_mode)
3629 snd_hda_codec_write(codec, 0x9, 0,
3630 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3631
3632 /* Internal Speaker */
3633 /* PW0 (24h), MW0(14h), MUX0(34h) */
3634 present = snd_hda_jack_detect(codec, 0x25);
3635
3636 parm = AC_PWRST_D3;
3637 set_pin_power_state(codec, 0x24, &parm);
3638 if (present) {
3639 snd_hda_codec_write(codec, 0x14, 0,
3640 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3641 snd_hda_codec_write(codec, 0x34, 0,
3642 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3643 } else {
3644 snd_hda_codec_write(codec, 0x14, 0,
3645 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3646 snd_hda_codec_write(codec, 0x34, 0,
3647 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3648 }
3649
3650
3651 /* Mono Out */
3652 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
3653 present = snd_hda_jack_detect(codec, 0x28);
3654
3655 parm = AC_PWRST_D3;
3656 set_pin_power_state(codec, 0x31, &parm);
3657 if (present) {
3658 snd_hda_codec_write(codec, 0x1c, 0,
3659 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3660 snd_hda_codec_write(codec, 0x3c, 0,
3661 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3662 snd_hda_codec_write(codec, 0x3e, 0,
3663 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3664 } else {
3665 snd_hda_codec_write(codec, 0x1c, 0,
3666 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3667 snd_hda_codec_write(codec, 0x3c, 0,
3668 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3669 snd_hda_codec_write(codec, 0x3e, 0,
3670 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
3671 }
3672
3673 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
3674 parm = AC_PWRST_D3;
3675 set_pin_power_state(codec, 0x33, &parm);
3676 snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm);
3677 snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm);
3678
3679}
ab6734e7
LW
3680
3681/* patch for vt1812 */
3682static int patch_vt1812(struct hda_codec *codec)
3683{
3684 struct via_spec *spec;
3685 int err;
3686
3687 /* create a codec specific record */
5b0cb1d8 3688 spec = via_new_spec(codec);
ab6734e7
LW
3689 if (spec == NULL)
3690 return -ENOMEM;
3691
620e2b28 3692 spec->aa_mix_nid = 0x21;
d7a99cce
TI
3693 override_mic_boost(codec, 0x2b, 0, 3, 40);
3694 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 3695 add_secret_dac_path(codec);
620e2b28 3696
ab6734e7 3697 /* automatic parse from the BIOS config */
12daef65 3698 err = via_parse_auto_config(codec);
ab6734e7
LW
3699 if (err < 0) {
3700 via_free(codec);
3701 return err;
ab6734e7
LW
3702 }
3703
096a8854 3704 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
ab6734e7 3705
ab6734e7
LW
3706 codec->patch_ops = via_patch_ops;
3707
3e95b9ab 3708 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
ab6734e7
LW
3709 return 0;
3710}
3711
c577b8a1
JC
3712/*
3713 * patch entries
3714 */
90dd48a1 3715static const struct hda_codec_preset snd_hda_preset_via[] = {
3218c178
TI
3716 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3717 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3718 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3719 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3720 { .id = 0x1106e710, .name = "VT1709 10-Ch",
ddd304d8 3721 .patch = patch_vt1709},
3218c178 3722 { .id = 0x1106e711, .name = "VT1709 10-Ch",
ddd304d8 3723 .patch = patch_vt1709},
3218c178 3724 { .id = 0x1106e712, .name = "VT1709 10-Ch",
ddd304d8 3725 .patch = patch_vt1709},
3218c178 3726 { .id = 0x1106e713, .name = "VT1709 10-Ch",
ddd304d8 3727 .patch = patch_vt1709},
3218c178 3728 { .id = 0x1106e714, .name = "VT1709 6-Ch",
ddd304d8 3729 .patch = patch_vt1709},
3218c178 3730 { .id = 0x1106e715, .name = "VT1709 6-Ch",
ddd304d8 3731 .patch = patch_vt1709},
3218c178 3732 { .id = 0x1106e716, .name = "VT1709 6-Ch",
ddd304d8 3733 .patch = patch_vt1709},
3218c178 3734 { .id = 0x1106e717, .name = "VT1709 6-Ch",
ddd304d8 3735 .patch = patch_vt1709},
3218c178 3736 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
ddd304d8 3737 .patch = patch_vt1708B},
3218c178 3738 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
ddd304d8 3739 .patch = patch_vt1708B},
3218c178 3740 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
ddd304d8 3741 .patch = patch_vt1708B},
3218c178 3742 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
ddd304d8 3743 .patch = patch_vt1708B},
3218c178 3744 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
ddd304d8 3745 .patch = patch_vt1708B},
3218c178 3746 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
ddd304d8 3747 .patch = patch_vt1708B},
3218c178 3748 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
ddd304d8 3749 .patch = patch_vt1708B},
3218c178 3750 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
ddd304d8 3751 .patch = patch_vt1708B},
3218c178 3752 { .id = 0x11060397, .name = "VT1708S",
d949cac1 3753 .patch = patch_vt1708S},
3218c178 3754 { .id = 0x11061397, .name = "VT1708S",
d949cac1 3755 .patch = patch_vt1708S},
3218c178 3756 { .id = 0x11062397, .name = "VT1708S",
d949cac1 3757 .patch = patch_vt1708S},
3218c178 3758 { .id = 0x11063397, .name = "VT1708S",
d949cac1 3759 .patch = patch_vt1708S},
bc92df7f 3760 { .id = 0x11064397, .name = "VT1705",
d949cac1 3761 .patch = patch_vt1708S},
3218c178 3762 { .id = 0x11065397, .name = "VT1708S",
d949cac1 3763 .patch = patch_vt1708S},
3218c178 3764 { .id = 0x11066397, .name = "VT1708S",
d949cac1 3765 .patch = patch_vt1708S},
3218c178 3766 { .id = 0x11067397, .name = "VT1708S",
d949cac1 3767 .patch = patch_vt1708S},
3218c178 3768 { .id = 0x11060398, .name = "VT1702",
d949cac1 3769 .patch = patch_vt1702},
3218c178 3770 { .id = 0x11061398, .name = "VT1702",
d949cac1 3771 .patch = patch_vt1702},
3218c178 3772 { .id = 0x11062398, .name = "VT1702",
d949cac1 3773 .patch = patch_vt1702},
3218c178 3774 { .id = 0x11063398, .name = "VT1702",
d949cac1 3775 .patch = patch_vt1702},
3218c178 3776 { .id = 0x11064398, .name = "VT1702",
d949cac1 3777 .patch = patch_vt1702},
3218c178 3778 { .id = 0x11065398, .name = "VT1702",
d949cac1 3779 .patch = patch_vt1702},
3218c178 3780 { .id = 0x11066398, .name = "VT1702",
d949cac1 3781 .patch = patch_vt1702},
3218c178 3782 { .id = 0x11067398, .name = "VT1702",
d949cac1 3783 .patch = patch_vt1702},
eb7188ca
LW
3784 { .id = 0x11060428, .name = "VT1718S",
3785 .patch = patch_vt1718S},
3786 { .id = 0x11064428, .name = "VT1718S",
3787 .patch = patch_vt1718S},
bb3c6bfc
LW
3788 { .id = 0x11060441, .name = "VT2020",
3789 .patch = patch_vt1718S},
3790 { .id = 0x11064441, .name = "VT1828S",
3791 .patch = patch_vt1718S},
f3db423d
LW
3792 { .id = 0x11060433, .name = "VT1716S",
3793 .patch = patch_vt1716S},
3794 { .id = 0x1106a721, .name = "VT1716S",
3795 .patch = patch_vt1716S},
25eaba2f
LW
3796 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
3797 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
ab6734e7 3798 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
36dd5c4a
LW
3799 { .id = 0x11060440, .name = "VT1818S",
3800 .patch = patch_vt1708S},
11890956
LW
3801 { .id = 0x11060446, .name = "VT1802",
3802 .patch = patch_vt2002P},
3803 { .id = 0x11068446, .name = "VT1802",
3804 .patch = patch_vt2002P},
c577b8a1
JC
3805 {} /* terminator */
3806};
1289e9e8
TI
3807
3808MODULE_ALIAS("snd-hda-codec-id:1106*");
3809
3810static struct hda_codec_preset_list via_list = {
3811 .preset = snd_hda_preset_via,
3812 .owner = THIS_MODULE,
3813};
3814
3815MODULE_LICENSE("GPL");
3816MODULE_DESCRIPTION("VIA HD-audio codec");
3817
3818static int __init patch_via_init(void)
3819{
3820 return snd_hda_add_codec_preset(&via_list);
3821}
3822
3823static void __exit patch_via_exit(void)
3824{
3825 snd_hda_delete_codec_preset(&via_list);
3826}
3827
3828module_init(patch_via_init)
3829module_exit(patch_via_exit)