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