Merge branch 'compat' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[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>
da155d5b 52#include <linux/module.h>
c577b8a1 53#include <sound/core.h>
0aa62aef 54#include <sound/asoundef.h>
c577b8a1
JC
55#include "hda_codec.h"
56#include "hda_local.h"
128bc4ba 57#include "hda_auto_parser.h"
1835a0f9 58#include "hda_jack.h"
b3f6008f 59#include "hda_generic.h"
c577b8a1 60
c577b8a1 61/* Pin Widget NID */
d949cac1
HW
62#define VT1708_HP_PIN_NID 0x20
63#define VT1708_CD_PIN_NID 0x24
c577b8a1 64
d7426329
HW
65enum VIA_HDA_CODEC {
66 UNKNOWN = -1,
67 VT1708,
68 VT1709_10CH,
69 VT1709_6CH,
70 VT1708B_8CH,
71 VT1708B_4CH,
72 VT1708S,
518bf3ba 73 VT1708BCE,
d7426329 74 VT1702,
eb7188ca 75 VT1718S,
f3db423d 76 VT1716S,
25eaba2f 77 VT2002P,
ab6734e7 78 VT1812,
11890956 79 VT1802,
43737e0a 80 VT1705CF,
6121b84a 81 VT1808,
d7426329
HW
82 CODEC_TYPES,
83};
84
11890956
LW
85#define VT2002P_COMPATIBLE(spec) \
86 ((spec)->codec_type == VT2002P ||\
87 (spec)->codec_type == VT1812 ||\
88 (spec)->codec_type == VT1802)
89
1f2e99fe 90struct via_spec {
b3f6008f
TI
91 struct hda_gen_spec gen;
92
1f2e99fe 93 /* codec parameterization */
90dd48a1 94 const struct snd_kcontrol_new *mixers[6];
1f2e99fe
LW
95 unsigned int num_mixers;
96
90dd48a1 97 const struct hda_verb *init_verbs[5];
1f2e99fe
LW
98 unsigned int num_iverbs;
99
1f2e99fe 100 /* HP mode source */
f3db423d 101 unsigned int dmic_enabled;
24088a58 102 unsigned int no_pin_power_ctl;
1f2e99fe
LW
103 enum VIA_HDA_CODEC codec_type;
104
e9d010c2
TI
105 /* analog low-power control */
106 bool alc_mode;
107
1f2e99fe 108 /* work to check hp jack state */
187d333e 109 int hp_work_active;
e06e5a29 110 int vt1708_jack_detect;
3e95b9ab
LW
111
112 void (*set_widgets_power_state)(struct hda_codec *codec);
43737e0a 113 unsigned int dac_stream_tag[4];
1f2e99fe
LW
114};
115
0341ccd7 116static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
b3f6008f
TI
117static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
118 struct hda_codec *codec,
119 struct snd_pcm_substream *substream,
120 int action);
121static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl);
122
123static struct via_spec *via_new_spec(struct hda_codec *codec)
5b0cb1d8
JK
124{
125 struct via_spec *spec;
126
127 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
128 if (spec == NULL)
129 return NULL;
130
131 codec->spec = spec;
b3f6008f 132 snd_hda_gen_spec_init(&spec->gen);
0341ccd7
LW
133 spec->codec_type = get_codec_type(codec);
134 /* VT1708BCE & VT1708S are almost same */
135 if (spec->codec_type == VT1708BCE)
136 spec->codec_type = VT1708S;
b3f6008f 137 spec->no_pin_power_ctl = 1;
13961170 138 spec->gen.indep_hp = 1;
05909d5c 139 spec->gen.keep_eapd_on = 1;
b3f6008f 140 spec->gen.pcm_playback_hook = via_playback_pcm_hook;
f1e762dd 141 spec->gen.add_stereo_mix_input = 1;
5b0cb1d8
JK
142 return spec;
143}
144
744ff5f4 145static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
d7426329 146{
744ff5f4 147 u32 vendor_id = codec->vendor_id;
d7426329
HW
148 u16 ven_id = vendor_id >> 16;
149 u16 dev_id = vendor_id & 0xffff;
150 enum VIA_HDA_CODEC codec_type;
151
152 /* get codec type */
153 if (ven_id != 0x1106)
154 codec_type = UNKNOWN;
155 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
156 codec_type = VT1708;
157 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
158 codec_type = VT1709_10CH;
159 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
160 codec_type = VT1709_6CH;
518bf3ba 161 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
d7426329 162 codec_type = VT1708B_8CH;
518bf3ba
LW
163 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
164 codec_type = VT1708BCE;
165 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
d7426329
HW
166 codec_type = VT1708B_4CH;
167 else if ((dev_id & 0xfff) == 0x397
168 && (dev_id >> 12) < 8)
169 codec_type = VT1708S;
170 else if ((dev_id & 0xfff) == 0x398
171 && (dev_id >> 12) < 8)
172 codec_type = VT1702;
eb7188ca
LW
173 else if ((dev_id & 0xfff) == 0x428
174 && (dev_id >> 12) < 8)
175 codec_type = VT1718S;
f3db423d
LW
176 else if (dev_id == 0x0433 || dev_id == 0xa721)
177 codec_type = VT1716S;
bb3c6bfc
LW
178 else if (dev_id == 0x0441 || dev_id == 0x4441)
179 codec_type = VT1718S;
25eaba2f
LW
180 else if (dev_id == 0x0438 || dev_id == 0x4438)
181 codec_type = VT2002P;
ab6734e7
LW
182 else if (dev_id == 0x0448)
183 codec_type = VT1812;
36dd5c4a
LW
184 else if (dev_id == 0x0440)
185 codec_type = VT1708S;
11890956
LW
186 else if ((dev_id & 0xfff) == 0x446)
187 codec_type = VT1802;
43737e0a
LW
188 else if (dev_id == 0x4760)
189 codec_type = VT1705CF;
6121b84a
LW
190 else if (dev_id == 0x4761 || dev_id == 0x4762)
191 codec_type = VT1808;
d7426329
HW
192 else
193 codec_type = UNKNOWN;
194 return codec_type;
195};
196
ada509ec
TI
197static void analog_low_current_mode(struct hda_codec *codec);
198static bool is_aa_path_mute(struct hda_codec *codec);
1f2e99fe 199
187d333e
TI
200#define hp_detect_with_aa(codec) \
201 (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
202 !is_aa_path_mute(codec))
203
b3f6008f 204static void vt1708_stop_hp_work(struct hda_codec *codec)
1f2e99fe 205{
b3f6008f
TI
206 struct via_spec *spec = codec->spec;
207 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs)
1f2e99fe 208 return;
187d333e 209 if (spec->hp_work_active) {
b3f6008f 210 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1);
7eaa9161 211 codec->jackpoll_interval = 0;
b3f6008f
TI
212 cancel_delayed_work_sync(&codec->jackpoll_work);
213 spec->hp_work_active = false;
187d333e 214 }
1f2e99fe
LW
215}
216
b3f6008f 217static void vt1708_update_hp_work(struct hda_codec *codec)
1f2e99fe 218{
b3f6008f
TI
219 struct via_spec *spec = codec->spec;
220 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs)
1f2e99fe 221 return;
05dc0fc9 222 if (spec->vt1708_jack_detect) {
187d333e 223 if (!spec->hp_work_active) {
b3f6008f
TI
224 codec->jackpoll_interval = msecs_to_jiffies(100);
225 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0);
226 queue_delayed_work(codec->bus->workq,
227 &codec->jackpoll_work, 0);
228 spec->hp_work_active = true;
187d333e 229 }
b3f6008f
TI
230 } else if (!hp_detect_with_aa(codec))
231 vt1708_stop_hp_work(codec);
1f2e99fe 232}
f5271101 233
3e95b9ab
LW
234static void set_widgets_power_state(struct hda_codec *codec)
235{
087c2e3b
TI
236#if 0 /* FIXME: the assumed connections don't match always with the
237 * actual routes by the generic parser, so better to disable
238 * the control for safety.
239 */
3e95b9ab
LW
240 struct via_spec *spec = codec->spec;
241 if (spec->set_widgets_power_state)
242 spec->set_widgets_power_state(codec);
087c2e3b 243#endif
3e95b9ab 244}
25eaba2f 245
054d867e
TI
246static void update_power_state(struct hda_codec *codec, hda_nid_t nid,
247 unsigned int parm)
248{
9040d102 249 if (snd_hda_check_power_state(codec, nid, parm))
054d867e
TI
250 return;
251 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
252}
253
43737e0a
LW
254static void update_conv_power_state(struct hda_codec *codec, hda_nid_t nid,
255 unsigned int parm, unsigned int index)
256{
257 struct via_spec *spec = codec->spec;
258 unsigned int format;
9040d102
TI
259
260 if (snd_hda_check_power_state(codec, nid, parm))
43737e0a
LW
261 return;
262 format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
263 if (format && (spec->dac_stream_tag[index] != format))
264 spec->dac_stream_tag[index] = format;
265
266 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
267 if (parm == AC_PWRST_D0) {
268 format = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
269 if (!format && (spec->dac_stream_tag[index] != format))
270 snd_hda_codec_write(codec, nid, 0,
271 AC_VERB_SET_CHANNEL_STREAMID,
272 spec->dac_stream_tag[index]);
273 }
274}
275
b3f6008f
TI
276static bool smart51_enabled(struct hda_codec *codec)
277{
278 struct via_spec *spec = codec->spec;
279 return spec->gen.ext_channel_count > 2;
280}
281
282static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
283{
284 struct via_spec *spec = codec->spec;
285 int i;
286
287 for (i = 0; i < spec->gen.multi_ios; i++)
288 if (spec->gen.multi_io[i].pin == pin)
289 return true;
290 return false;
291}
292
f5271101
LW
293static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
294 unsigned int *affected_parm)
295{
296 unsigned parm;
297 unsigned def_conf = snd_hda_codec_get_pincfg(codec, nid);
298 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
299 >> AC_DEFCFG_MISC_SHIFT
300 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
1564b287 301 struct via_spec *spec = codec->spec;
24088a58
TI
302 unsigned present = 0;
303
304 no_presence |= spec->no_pin_power_ctl;
305 if (!no_presence)
306 present = snd_hda_jack_detect(codec, nid);
b3f6008f 307 if ((smart51_enabled(codec) && is_smart51_pins(codec, nid))
1564b287
LW
308 || ((no_presence || present)
309 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
f5271101
LW
310 *affected_parm = AC_PWRST_D0; /* if it's connected */
311 parm = AC_PWRST_D0;
312 } else
313 parm = AC_PWRST_D3;
314
054d867e 315 update_power_state(codec, nid, parm);
f5271101
LW
316}
317
24088a58
TI
318static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
319 struct snd_ctl_elem_info *uinfo)
320{
dda415d4 321 return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
24088a58
TI
322}
323
324static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
326{
327 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
328 struct via_spec *spec = codec->spec;
329 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
330 return 0;
331}
332
333static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_value *ucontrol)
335{
336 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
337 struct via_spec *spec = codec->spec;
338 unsigned int val = !ucontrol->value.enumerated.item[0];
339
340 if (val == spec->no_pin_power_ctl)
341 return 0;
342 spec->no_pin_power_ctl = val;
343 set_widgets_power_state(codec);
e9d010c2 344 analog_low_current_mode(codec);
24088a58
TI
345 return 1;
346}
347
b3f6008f
TI
348static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = {
349 {
24088a58
TI
350 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
351 .name = "Dynamic Power-Control",
352 .info = via_pin_power_ctl_info,
353 .get = via_pin_power_ctl_get,
354 .put = via_pin_power_ctl_put,
b3f6008f
TI
355 },
356 {} /* terminator */
24088a58
TI
357};
358
359
b3f6008f
TI
360/* check AA path's mute status */
361static bool is_aa_path_mute(struct hda_codec *codec)
0aa62aef 362{
cdc1784d 363 struct via_spec *spec = codec->spec;
b3f6008f 364 const struct hda_amp_list *p;
0186f4f4 365 int ch, v;
cdc1784d 366
0186f4f4
TI
367 p = spec->gen.loopback.amplist;
368 if (!p)
369 return true;
370 for (; p->nid; p++) {
b3f6008f
TI
371 for (ch = 0; ch < 2; ch++) {
372 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
373 p->idx);
374 if (!(v & HDA_AMP_MUTE) && v > 0)
375 return false;
376 }
3b607e3d 377 }
b3f6008f 378 return true;
3b607e3d
TI
379}
380
b3f6008f
TI
381/* enter/exit analog low-current mode */
382static void __analog_low_current_mode(struct hda_codec *codec, bool force)
3b607e3d
TI
383{
384 struct via_spec *spec = codec->spec;
b3f6008f
TI
385 bool enable;
386 unsigned int verb, parm;
3b607e3d 387
b3f6008f
TI
388 if (spec->no_pin_power_ctl)
389 enable = false;
390 else
391 enable = is_aa_path_mute(codec) && !spec->gen.active_streams;
392 if (enable == spec->alc_mode && !force)
3b607e3d 393 return;
b3f6008f 394 spec->alc_mode = enable;
3b607e3d 395
b3f6008f
TI
396 /* decide low current mode's verb & parameter */
397 switch (spec->codec_type) {
398 case VT1708B_8CH:
399 case VT1708B_4CH:
400 verb = 0xf70;
401 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
402 break;
403 case VT1708S:
404 case VT1718S:
405 case VT1716S:
406 verb = 0xf73;
407 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
408 break;
409 case VT1702:
410 verb = 0xf73;
411 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
412 break;
413 case VT2002P:
414 case VT1812:
415 case VT1802:
416 verb = 0xf93;
417 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
418 break;
419 case VT1705CF:
420 case VT1808:
421 verb = 0xf82;
422 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
423 break;
424 default:
425 return; /* other codecs are not supported */
f5271101
LW
426 }
427 /* send verb */
b3f6008f 428 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
a86a88ea
TI
429}
430
b3f6008f
TI
431static void analog_low_current_mode(struct hda_codec *codec)
432{
433 return __analog_low_current_mode(codec, false);
434}
a86a88ea 435
b3f6008f 436static int via_build_controls(struct hda_codec *codec)
a86a88ea
TI
437{
438 struct via_spec *spec = codec->spec;
b3f6008f 439 int err, i;
a766d0d7 440
b3f6008f 441 err = snd_hda_gen_build_controls(codec);
a766d0d7
TI
442 if (err < 0)
443 return err;
c577b8a1 444
b3f6008f
TI
445 if (spec->set_widgets_power_state)
446 spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
c577b8a1 447
b3f6008f
TI
448 for (i = 0; i < spec->num_mixers; i++) {
449 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
450 if (err < 0)
451 return err;
452 }
a86a88ea
TI
453
454 return 0;
455}
456
b3f6008f
TI
457static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
458 struct hda_codec *codec,
459 struct snd_pcm_substream *substream,
460 int action)
a86a88ea 461{
b3f6008f
TI
462 analog_low_current_mode(codec);
463 vt1708_update_hp_work(codec);
a86a88ea
TI
464}
465
b3f6008f 466static void via_free(struct hda_codec *codec)
a86a88ea
TI
467{
468 struct via_spec *spec = codec->spec;
a86a88ea 469
b3f6008f
TI
470 if (!spec)
471 return;
a86a88ea 472
b3f6008f
TI
473 vt1708_stop_hp_work(codec);
474 snd_hda_gen_spec_free(&spec->gen);
475 kfree(spec);
a86a88ea
TI
476}
477
b3f6008f
TI
478#ifdef CONFIG_PM
479static int via_suspend(struct hda_codec *codec)
a86a88ea
TI
480{
481 struct via_spec *spec = codec->spec;
b3f6008f 482 vt1708_stop_hp_work(codec);
d7a99cce 483
2c38d990
TI
484 /* Fix pop noise on headphones */
485 if (spec->codec_type == VT1802)
486 snd_hda_shutup_pins(codec);
d7a99cce 487
a86a88ea
TI
488 return 0;
489}
b3f6008f 490#endif
a86a88ea 491
b3f6008f
TI
492#ifdef CONFIG_PM
493static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
a86a88ea
TI
494{
495 struct via_spec *spec = codec->spec;
b3f6008f
TI
496 set_widgets_power_state(codec);
497 analog_low_current_mode(codec);
498 vt1708_update_hp_work(codec);
499 return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid);
500}
501#endif
a86a88ea 502
b3f6008f
TI
503/*
504 */
a86a88ea 505
b3f6008f 506static int via_init(struct hda_codec *codec);
a86a88ea 507
b3f6008f
TI
508static const struct hda_codec_ops via_patch_ops = {
509 .build_controls = via_build_controls,
510 .build_pcms = snd_hda_gen_build_pcms,
511 .init = via_init,
512 .free = via_free,
513 .unsol_event = snd_hda_jack_unsol_event,
514#ifdef CONFIG_PM
515 .suspend = via_suspend,
516 .check_power_status = via_check_power_status,
517#endif
518};
a86a88ea 519
c577b8a1 520
b3f6008f
TI
521static const struct hda_verb vt1708_init_verbs[] = {
522 /* power down jack detect function */
523 {0x1, 0xf81, 0x1},
524 { }
525};
76d9b0dd
HW
526static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
527{
528 unsigned int def_conf;
529 unsigned char seqassoc;
530
2f334f92 531 def_conf = snd_hda_codec_get_pincfg(codec, nid);
76d9b0dd
HW
532 seqassoc = (unsigned char) get_defcfg_association(def_conf);
533 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
82ef9e45
LW
534 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
535 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
536 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
537 snd_hda_codec_set_pincfg(codec, nid, def_conf);
76d9b0dd
HW
538 }
539
540 return;
541}
542
e06e5a29 543static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
544 struct snd_ctl_elem_value *ucontrol)
545{
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct via_spec *spec = codec->spec;
548
549 if (spec->codec_type != VT1708)
550 return 0;
e06e5a29 551 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
1f2e99fe
LW
552 return 0;
553}
554
e06e5a29 555static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
556 struct snd_ctl_elem_value *ucontrol)
557{
558 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
559 struct via_spec *spec = codec->spec;
187d333e 560 int val;
1f2e99fe
LW
561
562 if (spec->codec_type != VT1708)
563 return 0;
187d333e
TI
564 val = !!ucontrol->value.integer.value[0];
565 if (spec->vt1708_jack_detect == val)
566 return 0;
567 spec->vt1708_jack_detect = val;
b3f6008f 568 vt1708_update_hp_work(codec);
187d333e 569 return 1;
1f2e99fe
LW
570}
571
b3f6008f
TI
572static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
573 {
e06e5a29
TI
574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
575 .name = "Jack Detect",
576 .count = 1,
577 .info = snd_ctl_boolean_mono_info,
578 .get = vt1708_jack_detect_get,
579 .put = vt1708_jack_detect_put,
b3f6008f
TI
580 },
581 {} /* terminator */
1f2e99fe
LW
582};
583
b3f6008f 584static void via_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
c577b8a1 585{
b3f6008f
TI
586 set_widgets_power_state(codec);
587 snd_hda_gen_hp_automute(codec, tbl);
5d41762a
TI
588}
589
b3f6008f 590static void via_line_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
4e2d16d3
DH
591{
592 set_widgets_power_state(codec);
b3f6008f 593 snd_hda_gen_line_automute(codec, tbl);
4e2d16d3
DH
594}
595
596static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
597{
598 set_widgets_power_state(codec);
599}
600
b3f6008f
TI
601#define VIA_JACK_EVENT (HDA_GEN_LAST_EVENT + 1)
602
603static void via_set_jack_unsol_events(struct hda_codec *codec)
4a918ffe
TI
604{
605 struct via_spec *spec = codec->spec;
b3f6008f
TI
606 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
607 hda_nid_t pin;
4a918ffe 608 int i;
4a918ffe 609
b3f6008f 610 spec->gen.hp_automute_hook = via_hp_automute;
4a918ffe 611 if (cfg->speaker_pins[0])
b3f6008f 612 spec->gen.line_automute_hook = via_line_automute;
4e2d16d3 613
4a918ffe 614 for (i = 0; i < cfg->line_outs; i++) {
b3f6008f
TI
615 pin = cfg->line_out_pins[i];
616 if (pin && !snd_hda_jack_tbl_get(codec, pin) &&
617 is_jack_detectable(codec, pin))
618 snd_hda_jack_detect_enable_callback(codec, pin,
619 VIA_JACK_EVENT,
620 via_jack_powerstate_event);
4a918ffe
TI
621 }
622
623 for (i = 0; i < cfg->num_inputs; i++) {
b3f6008f
TI
624 pin = cfg->line_out_pins[i];
625 if (pin && !snd_hda_jack_tbl_get(codec, pin) &&
626 is_jack_detectable(codec, pin))
627 snd_hda_jack_detect_enable_callback(codec, pin,
4e2d16d3
DH
628 VIA_JACK_EVENT,
629 via_jack_powerstate_event);
4a918ffe
TI
630 }
631}
632
4abdbd1c
TI
633static const struct badness_table via_main_out_badness = {
634 .no_primary_dac = 0x10000,
635 .no_dac = 0x4000,
636 .shared_primary = 0x10000,
637 .shared_surr = 0x20,
638 .shared_clfe = 0x20,
639 .shared_surr_main = 0x20,
640};
641static const struct badness_table via_extra_out_badness = {
642 .no_primary_dac = 0x4000,
643 .no_dac = 0x4000,
644 .shared_primary = 0x12,
645 .shared_surr = 0x20,
646 .shared_clfe = 0x20,
647 .shared_surr_main = 0x10,
648};
649
b3f6008f
TI
650static int via_parse_auto_config(struct hda_codec *codec)
651{
652 struct via_spec *spec = codec->spec;
653 int err;
654
4abdbd1c
TI
655 spec->gen.main_out_badness = &via_main_out_badness;
656 spec->gen.extra_out_badness = &via_extra_out_badness;
657
b3f6008f
TI
658 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
659 if (err < 0)
660 return err;
661
662 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
663 if (err < 0)
664 return err;
665
666 via_set_jack_unsol_events(codec);
667 return 0;
668}
669
5d41762a
TI
670static int via_init(struct hda_codec *codec)
671{
672 struct via_spec *spec = codec->spec;
673 int i;
674
675 for (i = 0; i < spec->num_iverbs; i++)
676 snd_hda_sequence_write(codec, spec->init_verbs[i]);
25eaba2f 677
e9d010c2
TI
678 /* init power states */
679 set_widgets_power_state(codec);
680 __analog_low_current_mode(codec, true);
681
b3f6008f 682 snd_hda_gen_init(codec);
4a918ffe 683
b3f6008f 684 vt1708_update_hp_work(codec);
25eaba2f 685
c577b8a1
JC
686 return 0;
687}
688
f672f65a
DH
689static int vt1708_build_controls(struct hda_codec *codec)
690{
691 /* In order not to create "Phantom Jack" controls,
692 temporary enable jackpoll */
693 int err;
694 int old_interval = codec->jackpoll_interval;
695 codec->jackpoll_interval = msecs_to_jiffies(100);
696 err = via_build_controls(codec);
697 codec->jackpoll_interval = old_interval;
698 return err;
699}
700
b3f6008f 701static int vt1708_build_pcms(struct hda_codec *codec)
337b9d02
TI
702{
703 struct via_spec *spec = codec->spec;
b3f6008f
TI
704 int i, err;
705
706 err = snd_hda_gen_build_pcms(codec);
707 if (err < 0 || codec->vendor_id != 0x11061708)
708 return err;
709
710 /* We got noisy outputs on the right channel on VT1708 when
711 * 24bit samples are used. Until any workaround is found,
712 * disable the 24bit format, so far.
713 */
714 for (i = 0; i < codec->num_pcms; i++) {
715 struct hda_pcm *info = &spec->gen.pcm_rec[i];
716 if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams ||
717 info->pcm_type != HDA_PCM_TYPE_AUDIO)
718 continue;
719 info->stream[SNDRV_PCM_STREAM_PLAYBACK].formats =
720 SNDRV_PCM_FMTBIT_S16_LE;
337b9d02 721 }
b3f6008f 722
1c55d521 723 return 0;
337b9d02
TI
724}
725
c577b8a1
JC
726static int patch_vt1708(struct hda_codec *codec)
727{
728 struct via_spec *spec;
729 int err;
730
731 /* create a codec specific record */
5b0cb1d8 732 spec = via_new_spec(codec);
c577b8a1
JC
733 if (spec == NULL)
734 return -ENOMEM;
735
b3f6008f
TI
736 spec->gen.mixer_nid = 0x17;
737
738 /* set jackpoll_interval while parsing the codec */
739 codec->jackpoll_interval = msecs_to_jiffies(100);
740 spec->vt1708_jack_detect = 1;
741
742 /* don't support the input jack switching due to lack of unsol event */
743 /* (it may work with polling, though, but it needs testing) */
744 spec->gen.suppress_auto_mic = 1;
eb33ccf7
TI
745 /* Some machines show the broken speaker mute */
746 spec->gen.auto_mute_via_amp = 1;
620e2b28 747
12daef65
TI
748 /* Add HP and CD pin config connect bit re-config action */
749 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
750 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
751
c577b8a1 752 /* automatic parse from the BIOS config */
12daef65 753 err = via_parse_auto_config(codec);
c577b8a1
JC
754 if (err < 0) {
755 via_free(codec);
756 return err;
c577b8a1
JC
757 }
758
12daef65 759 /* add jack detect on/off control */
b3f6008f 760 spec->mixers[spec->num_mixers++] = vt1708_jack_detect_ctl;
c577b8a1 761
e322a36d
LW
762 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
763
c577b8a1 764 codec->patch_ops = via_patch_ops;
f672f65a 765 codec->patch_ops.build_controls = vt1708_build_controls;
b3f6008f
TI
766 codec->patch_ops.build_pcms = vt1708_build_pcms;
767
768 /* clear jackpoll_interval again; it's set dynamically */
769 codec->jackpoll_interval = 0;
c577b8a1 770
c577b8a1
JC
771 return 0;
772}
773
ddd304d8 774static int patch_vt1709(struct hda_codec *codec)
c577b8a1
JC
775{
776 struct via_spec *spec;
777 int err;
778
779 /* create a codec specific record */
5b0cb1d8 780 spec = via_new_spec(codec);
c577b8a1
JC
781 if (spec == NULL)
782 return -ENOMEM;
783
b3f6008f 784 spec->gen.mixer_nid = 0x18;
620e2b28 785
12daef65 786 err = via_parse_auto_config(codec);
c577b8a1
JC
787 if (err < 0) {
788 via_free(codec);
789 return err;
c577b8a1
JC
790 }
791
c577b8a1
JC
792 codec->patch_ops = via_patch_ops;
793
f7278fd0
JC
794 return 0;
795}
796
3e95b9ab
LW
797static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
798{
799 struct via_spec *spec = codec->spec;
800 int imux_is_smixer;
801 unsigned int parm;
802 int is_8ch = 0;
bc92df7f
LW
803 if ((spec->codec_type != VT1708B_4CH) &&
804 (codec->vendor_id != 0x11064397))
3e95b9ab
LW
805 is_8ch = 1;
806
807 /* SW0 (17h) = stereo mixer */
808 imux_is_smixer =
809 (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00)
810 == ((spec->codec_type == VT1708S) ? 5 : 0));
811 /* inputs */
812 /* PW 1/2/5 (1ah/1bh/1eh) */
813 parm = AC_PWRST_D3;
814 set_pin_power_state(codec, 0x1a, &parm);
815 set_pin_power_state(codec, 0x1b, &parm);
816 set_pin_power_state(codec, 0x1e, &parm);
817 if (imux_is_smixer)
818 parm = AC_PWRST_D0;
819 /* SW0 (17h), AIW 0/1 (13h/14h) */
054d867e
TI
820 update_power_state(codec, 0x17, parm);
821 update_power_state(codec, 0x13, parm);
822 update_power_state(codec, 0x14, parm);
3e95b9ab
LW
823
824 /* outputs */
825 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
826 parm = AC_PWRST_D3;
827 set_pin_power_state(codec, 0x19, &parm);
b3f6008f 828 if (smart51_enabled(codec))
3e95b9ab 829 set_pin_power_state(codec, 0x1b, &parm);
054d867e
TI
830 update_power_state(codec, 0x18, parm);
831 update_power_state(codec, 0x11, parm);
3e95b9ab
LW
832
833 /* PW6 (22h), SW2 (26h), AOW2 (24h) */
834 if (is_8ch) {
835 parm = AC_PWRST_D3;
836 set_pin_power_state(codec, 0x22, &parm);
b3f6008f 837 if (smart51_enabled(codec))
3e95b9ab 838 set_pin_power_state(codec, 0x1a, &parm);
054d867e
TI
839 update_power_state(codec, 0x26, parm);
840 update_power_state(codec, 0x24, parm);
bc92df7f
LW
841 } else if (codec->vendor_id == 0x11064397) {
842 /* PW7(23h), SW2(27h), AOW2(25h) */
843 parm = AC_PWRST_D3;
844 set_pin_power_state(codec, 0x23, &parm);
b3f6008f 845 if (smart51_enabled(codec))
bc92df7f 846 set_pin_power_state(codec, 0x1a, &parm);
054d867e
TI
847 update_power_state(codec, 0x27, parm);
848 update_power_state(codec, 0x25, parm);
3e95b9ab
LW
849 }
850
851 /* PW 3/4/7 (1ch/1dh/23h) */
852 parm = AC_PWRST_D3;
853 /* force to D0 for internal Speaker */
854 set_pin_power_state(codec, 0x1c, &parm);
855 set_pin_power_state(codec, 0x1d, &parm);
856 if (is_8ch)
857 set_pin_power_state(codec, 0x23, &parm);
858
859 /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */
054d867e
TI
860 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
861 update_power_state(codec, 0x10, parm);
3e95b9ab 862 if (is_8ch) {
054d867e
TI
863 update_power_state(codec, 0x25, parm);
864 update_power_state(codec, 0x27, parm);
b3f6008f 865 } else if (codec->vendor_id == 0x11064397 && spec->gen.indep_hp_enabled)
054d867e 866 update_power_state(codec, 0x25, parm);
3e95b9ab
LW
867}
868
518bf3ba 869static int patch_vt1708S(struct hda_codec *codec);
ddd304d8 870static int patch_vt1708B(struct hda_codec *codec)
f7278fd0
JC
871{
872 struct via_spec *spec;
873 int err;
874
518bf3ba
LW
875 if (get_codec_type(codec) == VT1708BCE)
876 return patch_vt1708S(codec);
ddd304d8 877
f7278fd0 878 /* create a codec specific record */
5b0cb1d8 879 spec = via_new_spec(codec);
f7278fd0
JC
880 if (spec == NULL)
881 return -ENOMEM;
882
b3f6008f 883 spec->gen.mixer_nid = 0x16;
620e2b28 884
f7278fd0 885 /* automatic parse from the BIOS config */
12daef65 886 err = via_parse_auto_config(codec);
f7278fd0
JC
887 if (err < 0) {
888 via_free(codec);
889 return err;
f7278fd0
JC
890 }
891
f7278fd0
JC
892 codec->patch_ops = via_patch_ops;
893
3e95b9ab
LW
894 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
895
f7278fd0
JC
896 return 0;
897}
898
d949cac1 899/* Patch for VT1708S */
096a8854 900static const struct hda_verb vt1708S_init_verbs[] = {
d7426329
HW
901 /* Enable Mic Boost Volume backdoor */
902 {0x1, 0xf98, 0x1},
bc7e7e5c
LW
903 /* don't bybass mixer */
904 {0x1, 0xf88, 0xc0},
d949cac1
HW
905 { }
906};
907
6369bcfc
LW
908static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
909 int offset, int num_steps, int step_size)
910{
d045c5dc
TI
911 snd_hda_override_wcaps(codec, pin,
912 get_wcaps(codec, pin) | AC_WCAP_IN_AMP);
6369bcfc
LW
913 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
914 (offset << AC_AMPCAP_OFFSET_SHIFT) |
915 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
916 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
917 (0 << AC_AMPCAP_MUTE_SHIFT));
918}
919
d949cac1
HW
920static int patch_vt1708S(struct hda_codec *codec)
921{
922 struct via_spec *spec;
923 int err;
924
925 /* create a codec specific record */
5b0cb1d8 926 spec = via_new_spec(codec);
d949cac1
HW
927 if (spec == NULL)
928 return -ENOMEM;
929
b3f6008f 930 spec->gen.mixer_nid = 0x16;
d7a99cce
TI
931 override_mic_boost(codec, 0x1a, 0, 3, 40);
932 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 933
518bf3ba
LW
934 /* correct names for VT1708BCE */
935 if (get_codec_type(codec) == VT1708BCE) {
936 kfree(codec->chip_name);
937 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
938 snprintf(codec->bus->card->mixername,
939 sizeof(codec->bus->card->mixername),
940 "%s %s", codec->vendor_name, codec->chip_name);
970f630f 941 }
bc92df7f
LW
942 /* correct names for VT1705 */
943 if (codec->vendor_id == 0x11064397) {
944 kfree(codec->chip_name);
945 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
946 snprintf(codec->bus->card->mixername,
947 sizeof(codec->bus->card->mixername),
948 "%s %s", codec->vendor_name, codec->chip_name);
949 }
b3f6008f
TI
950
951 /* automatic parse from the BIOS config */
952 err = via_parse_auto_config(codec);
953 if (err < 0) {
954 via_free(codec);
955 return err;
956 }
957
958 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
959
960 codec->patch_ops = via_patch_ops;
961
3e95b9ab 962 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
d949cac1
HW
963 return 0;
964}
965
966/* Patch for VT1702 */
967
096a8854 968static const struct hda_verb vt1702_init_verbs[] = {
bc7e7e5c
LW
969 /* mixer enable */
970 {0x1, 0xF88, 0x3},
971 /* GPIO 0~2 */
972 {0x1, 0xF82, 0x3F},
d949cac1
HW
973 { }
974};
975
3e95b9ab
LW
976static void set_widgets_power_state_vt1702(struct hda_codec *codec)
977{
978 int imux_is_smixer =
979 snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
980 unsigned int parm;
981 /* inputs */
982 /* PW 1/2/5 (14h/15h/18h) */
983 parm = AC_PWRST_D3;
984 set_pin_power_state(codec, 0x14, &parm);
985 set_pin_power_state(codec, 0x15, &parm);
986 set_pin_power_state(codec, 0x18, &parm);
987 if (imux_is_smixer)
988 parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */
989 /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */
054d867e
TI
990 update_power_state(codec, 0x13, parm);
991 update_power_state(codec, 0x12, parm);
992 update_power_state(codec, 0x1f, parm);
993 update_power_state(codec, 0x20, parm);
3e95b9ab
LW
994
995 /* outputs */
996 /* PW 3/4 (16h/17h) */
997 parm = AC_PWRST_D3;
998 set_pin_power_state(codec, 0x17, &parm);
999 set_pin_power_state(codec, 0x16, &parm);
1000 /* MW0 (1ah), AOW 0/1 (10h/1dh) */
054d867e
TI
1001 update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm);
1002 update_power_state(codec, 0x10, parm);
1003 update_power_state(codec, 0x1d, parm);
3e95b9ab
LW
1004}
1005
d949cac1
HW
1006static int patch_vt1702(struct hda_codec *codec)
1007{
1008 struct via_spec *spec;
1009 int err;
d949cac1
HW
1010
1011 /* create a codec specific record */
5b0cb1d8 1012 spec = via_new_spec(codec);
d949cac1
HW
1013 if (spec == NULL)
1014 return -ENOMEM;
1015
b3f6008f 1016 spec->gen.mixer_nid = 0x1a;
620e2b28 1017
12daef65
TI
1018 /* limit AA path volume to 0 dB */
1019 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
1020 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1021 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1022 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1023 (1 << AC_AMPCAP_MUTE_SHIFT));
1024
d949cac1 1025 /* automatic parse from the BIOS config */
12daef65 1026 err = via_parse_auto_config(codec);
d949cac1
HW
1027 if (err < 0) {
1028 via_free(codec);
1029 return err;
d949cac1
HW
1030 }
1031
096a8854 1032 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
d949cac1 1033
d949cac1
HW
1034 codec->patch_ops = via_patch_ops;
1035
3e95b9ab 1036 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
d949cac1
HW
1037 return 0;
1038}
1039
eb7188ca
LW
1040/* Patch for VT1718S */
1041
096a8854 1042static const struct hda_verb vt1718S_init_verbs[] = {
4ab2d53a
LW
1043 /* Enable MW0 adjust Gain 5 */
1044 {0x1, 0xfb2, 0x10},
eb7188ca
LW
1045 /* Enable Boost Volume backdoor */
1046 {0x1, 0xf88, 0x8},
5d41762a 1047
eb7188ca
LW
1048 { }
1049};
1050
3e95b9ab
LW
1051static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
1052{
1053 struct via_spec *spec = codec->spec;
1054 int imux_is_smixer;
6162552b 1055 unsigned int parm, parm2;
3e95b9ab
LW
1056 /* MUX6 (1eh) = stereo mixer */
1057 imux_is_smixer =
1058 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5;
1059 /* inputs */
1060 /* PW 5/6/7 (29h/2ah/2bh) */
1061 parm = AC_PWRST_D3;
1062 set_pin_power_state(codec, 0x29, &parm);
1063 set_pin_power_state(codec, 0x2a, &parm);
1064 set_pin_power_state(codec, 0x2b, &parm);
1065 if (imux_is_smixer)
1066 parm = AC_PWRST_D0;
1067 /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */
054d867e
TI
1068 update_power_state(codec, 0x1e, parm);
1069 update_power_state(codec, 0x1f, parm);
1070 update_power_state(codec, 0x10, parm);
1071 update_power_state(codec, 0x11, parm);
3e95b9ab
LW
1072
1073 /* outputs */
1074 /* PW3 (27h), MW2 (1ah), AOW3 (bh) */
1075 parm = AC_PWRST_D3;
1076 set_pin_power_state(codec, 0x27, &parm);
054d867e 1077 update_power_state(codec, 0x1a, parm);
6162552b 1078 parm2 = parm; /* for pin 0x0b */
3e95b9ab
LW
1079
1080 /* PW2 (26h), AOW2 (ah) */
1081 parm = AC_PWRST_D3;
1082 set_pin_power_state(codec, 0x26, &parm);
b3f6008f 1083 if (smart51_enabled(codec))
3e95b9ab 1084 set_pin_power_state(codec, 0x2b, &parm);
054d867e 1085 update_power_state(codec, 0xa, parm);
3e95b9ab
LW
1086
1087 /* PW0 (24h), AOW0 (8h) */
1088 parm = AC_PWRST_D3;
1089 set_pin_power_state(codec, 0x24, &parm);
b3f6008f 1090 if (!spec->gen.indep_hp_enabled) /* check for redirected HP */
3e95b9ab 1091 set_pin_power_state(codec, 0x28, &parm);
054d867e 1092 update_power_state(codec, 0x8, parm);
b3f6008f 1093 if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
6162552b
TI
1094 parm = parm2;
1095 update_power_state(codec, 0xb, parm);
3e95b9ab 1096 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
054d867e 1097 update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm);
3e95b9ab
LW
1098
1099 /* PW1 (25h), AOW1 (9h) */
1100 parm = AC_PWRST_D3;
1101 set_pin_power_state(codec, 0x25, &parm);
b3f6008f 1102 if (smart51_enabled(codec))
3e95b9ab 1103 set_pin_power_state(codec, 0x2a, &parm);
054d867e 1104 update_power_state(codec, 0x9, parm);
3e95b9ab 1105
b3f6008f 1106 if (spec->gen.indep_hp_enabled) {
3e95b9ab
LW
1107 /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */
1108 parm = AC_PWRST_D3;
1109 set_pin_power_state(codec, 0x28, &parm);
054d867e
TI
1110 update_power_state(codec, 0x1b, parm);
1111 update_power_state(codec, 0x34, parm);
1112 update_power_state(codec, 0xc, parm);
3e95b9ab
LW
1113 }
1114}
1115
30b45033
TI
1116/* Add a connection to the primary DAC from AA-mixer for some codecs
1117 * This isn't listed from the raw info, but the chip has a secret connection.
1118 */
1119static int add_secret_dac_path(struct hda_codec *codec)
1120{
1121 struct via_spec *spec = codec->spec;
1122 int i, nums;
1123 hda_nid_t conn[8];
1124 hda_nid_t nid;
1125
b3f6008f 1126 if (!spec->gen.mixer_nid)
30b45033 1127 return 0;
b3f6008f 1128 nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn,
30b45033
TI
1129 ARRAY_SIZE(conn) - 1);
1130 for (i = 0; i < nums; i++) {
1131 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
1132 return 0;
1133 }
1134
1135 /* find the primary DAC and add to the connection list */
1136 nid = codec->start_nid;
1137 for (i = 0; i < codec->num_nodes; i++, nid++) {
1138 unsigned int caps = get_wcaps(codec, nid);
1139 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
1140 !(caps & AC_WCAP_DIGITAL)) {
1141 conn[nums++] = nid;
1142 return snd_hda_override_conn_list(codec,
b3f6008f 1143 spec->gen.mixer_nid,
30b45033
TI
1144 nums, conn);
1145 }
1146 }
1147 return 0;
1148}
1149
1150
eb7188ca
LW
1151static int patch_vt1718S(struct hda_codec *codec)
1152{
1153 struct via_spec *spec;
1154 int err;
1155
1156 /* create a codec specific record */
5b0cb1d8 1157 spec = via_new_spec(codec);
eb7188ca
LW
1158 if (spec == NULL)
1159 return -ENOMEM;
1160
b3f6008f 1161 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
1162 override_mic_boost(codec, 0x2b, 0, 3, 40);
1163 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 1164 add_secret_dac_path(codec);
620e2b28 1165
eb7188ca 1166 /* automatic parse from the BIOS config */
12daef65 1167 err = via_parse_auto_config(codec);
eb7188ca
LW
1168 if (err < 0) {
1169 via_free(codec);
1170 return err;
eb7188ca
LW
1171 }
1172
096a8854 1173 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
eb7188ca 1174
eb7188ca
LW
1175 codec->patch_ops = via_patch_ops;
1176
3e95b9ab
LW
1177 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
1178
eb7188ca
LW
1179 return 0;
1180}
f3db423d
LW
1181
1182/* Patch for VT1716S */
1183
1184static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
1185 struct snd_ctl_elem_info *uinfo)
1186{
1187 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1188 uinfo->count = 1;
1189 uinfo->value.integer.min = 0;
1190 uinfo->value.integer.max = 1;
1191 return 0;
1192}
1193
1194static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
1195 struct snd_ctl_elem_value *ucontrol)
1196{
1197 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1198 int index = 0;
1199
1200 index = snd_hda_codec_read(codec, 0x26, 0,
1201 AC_VERB_GET_CONNECT_SEL, 0);
1202 if (index != -1)
1203 *ucontrol->value.integer.value = index;
1204
1205 return 0;
1206}
1207
1208static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
1209 struct snd_ctl_elem_value *ucontrol)
1210{
1211 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1212 struct via_spec *spec = codec->spec;
1213 int index = *ucontrol->value.integer.value;
1214
1215 snd_hda_codec_write(codec, 0x26, 0,
1216 AC_VERB_SET_CONNECT_SEL, index);
1217 spec->dmic_enabled = index;
3e95b9ab 1218 set_widgets_power_state(codec);
f3db423d
LW
1219 return 1;
1220}
1221
90dd48a1 1222static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
f3db423d
LW
1223 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
1224 {
1225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1226 .name = "Digital Mic Capture Switch",
5b0cb1d8 1227 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
f3db423d
LW
1228 .count = 1,
1229 .info = vt1716s_dmic_info,
1230 .get = vt1716s_dmic_get,
1231 .put = vt1716s_dmic_put,
1232 },
1233 {} /* end */
1234};
1235
1236
1237/* mono-out mixer elements */
90dd48a1 1238static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
f3db423d
LW
1239 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
1240 { } /* end */
1241};
1242
096a8854 1243static const struct hda_verb vt1716S_init_verbs[] = {
f3db423d
LW
1244 /* Enable Boost Volume backdoor */
1245 {0x1, 0xf8a, 0x80},
1246 /* don't bybass mixer */
1247 {0x1, 0xf88, 0xc0},
1248 /* Enable mono output */
1249 {0x1, 0xf90, 0x08},
1250 { }
1251};
1252
3e95b9ab
LW
1253static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
1254{
1255 struct via_spec *spec = codec->spec;
1256 int imux_is_smixer;
1257 unsigned int parm;
1258 unsigned int mono_out, present;
1259 /* SW0 (17h) = stereo mixer */
1260 imux_is_smixer =
1261 (snd_hda_codec_read(codec, 0x17, 0,
1262 AC_VERB_GET_CONNECT_SEL, 0x00) == 5);
1263 /* inputs */
1264 /* PW 1/2/5 (1ah/1bh/1eh) */
1265 parm = AC_PWRST_D3;
1266 set_pin_power_state(codec, 0x1a, &parm);
1267 set_pin_power_state(codec, 0x1b, &parm);
1268 set_pin_power_state(codec, 0x1e, &parm);
1269 if (imux_is_smixer)
1270 parm = AC_PWRST_D0;
1271 /* SW0 (17h), AIW0(13h) */
054d867e
TI
1272 update_power_state(codec, 0x17, parm);
1273 update_power_state(codec, 0x13, parm);
3e95b9ab
LW
1274
1275 parm = AC_PWRST_D3;
1276 set_pin_power_state(codec, 0x1e, &parm);
1277 /* PW11 (22h) */
1278 if (spec->dmic_enabled)
1279 set_pin_power_state(codec, 0x22, &parm);
1280 else
054d867e 1281 update_power_state(codec, 0x22, AC_PWRST_D3);
3e95b9ab
LW
1282
1283 /* SW2(26h), AIW1(14h) */
054d867e
TI
1284 update_power_state(codec, 0x26, parm);
1285 update_power_state(codec, 0x14, parm);
3e95b9ab
LW
1286
1287 /* outputs */
1288 /* PW0 (19h), SW1 (18h), AOW1 (11h) */
1289 parm = AC_PWRST_D3;
1290 set_pin_power_state(codec, 0x19, &parm);
1291 /* Smart 5.1 PW2(1bh) */
b3f6008f 1292 if (smart51_enabled(codec))
3e95b9ab 1293 set_pin_power_state(codec, 0x1b, &parm);
054d867e
TI
1294 update_power_state(codec, 0x18, parm);
1295 update_power_state(codec, 0x11, parm);
3e95b9ab
LW
1296
1297 /* PW7 (23h), SW3 (27h), AOW3 (25h) */
1298 parm = AC_PWRST_D3;
1299 set_pin_power_state(codec, 0x23, &parm);
1300 /* Smart 5.1 PW1(1ah) */
b3f6008f 1301 if (smart51_enabled(codec))
3e95b9ab 1302 set_pin_power_state(codec, 0x1a, &parm);
054d867e 1303 update_power_state(codec, 0x27, parm);
3e95b9ab
LW
1304
1305 /* Smart 5.1 PW5(1eh) */
b3f6008f 1306 if (smart51_enabled(codec))
3e95b9ab 1307 set_pin_power_state(codec, 0x1e, &parm);
054d867e 1308 update_power_state(codec, 0x25, parm);
3e95b9ab
LW
1309
1310 /* Mono out */
1311 /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/
1312 present = snd_hda_jack_detect(codec, 0x1c);
1313
1314 if (present)
1315 mono_out = 0;
1316 else {
1317 present = snd_hda_jack_detect(codec, 0x1d);
b3f6008f 1318 if (!spec->gen.indep_hp_enabled && present)
3e95b9ab
LW
1319 mono_out = 0;
1320 else
1321 mono_out = 1;
1322 }
1323 parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3;
054d867e
TI
1324 update_power_state(codec, 0x28, parm);
1325 update_power_state(codec, 0x29, parm);
1326 update_power_state(codec, 0x2a, parm);
3e95b9ab
LW
1327
1328 /* PW 3/4 (1ch/1dh) */
1329 parm = AC_PWRST_D3;
1330 set_pin_power_state(codec, 0x1c, &parm);
1331 set_pin_power_state(codec, 0x1d, &parm);
1332 /* HP Independent Mode, power on AOW3 */
b3f6008f 1333 if (spec->gen.indep_hp_enabled)
054d867e 1334 update_power_state(codec, 0x25, parm);
3e95b9ab
LW
1335
1336 /* force to D0 for internal Speaker */
1337 /* MW0 (16h), AOW0 (10h) */
054d867e
TI
1338 update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm);
1339 update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm);
3e95b9ab
LW
1340}
1341
f3db423d
LW
1342static int patch_vt1716S(struct hda_codec *codec)
1343{
1344 struct via_spec *spec;
1345 int err;
1346
1347 /* create a codec specific record */
5b0cb1d8 1348 spec = via_new_spec(codec);
f3db423d
LW
1349 if (spec == NULL)
1350 return -ENOMEM;
1351
b3f6008f 1352 spec->gen.mixer_nid = 0x16;
d7a99cce
TI
1353 override_mic_boost(codec, 0x1a, 0, 3, 40);
1354 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 1355
f3db423d 1356 /* automatic parse from the BIOS config */
12daef65 1357 err = via_parse_auto_config(codec);
f3db423d
LW
1358 if (err < 0) {
1359 via_free(codec);
1360 return err;
f3db423d
LW
1361 }
1362
096a8854 1363 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
f3db423d 1364
b3f6008f 1365 spec->mixers[spec->num_mixers++] = vt1716s_dmic_mixer;
f3db423d
LW
1366 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
1367
1368 codec->patch_ops = via_patch_ops;
1369
3e95b9ab 1370 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
f3db423d
LW
1371 return 0;
1372}
25eaba2f
LW
1373
1374/* for vt2002P */
1375
096a8854 1376static const struct hda_verb vt2002P_init_verbs[] = {
eadb9a80
LW
1377 /* Class-D speaker related verbs */
1378 {0x1, 0xfe0, 0x4},
1379 {0x1, 0xfe9, 0x80},
1380 {0x1, 0xfe2, 0x22},
25eaba2f
LW
1381 /* Enable Boost Volume backdoor */
1382 {0x1, 0xfb9, 0x24},
25eaba2f
LW
1383 /* Enable AOW0 to MW9 */
1384 {0x1, 0xfb8, 0x88},
1385 { }
1386};
4a918ffe 1387
096a8854 1388static const struct hda_verb vt1802_init_verbs[] = {
11890956
LW
1389 /* Enable Boost Volume backdoor */
1390 {0x1, 0xfb9, 0x24},
11890956
LW
1391 /* Enable AOW0 to MW9 */
1392 {0x1, 0xfb8, 0x88},
1393 { }
1394};
25eaba2f 1395
3e95b9ab
LW
1396static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
1397{
1398 struct via_spec *spec = codec->spec;
1399 int imux_is_smixer;
1400 unsigned int parm;
1401 unsigned int present;
1402 /* MUX9 (1eh) = stereo mixer */
1403 imux_is_smixer =
1404 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3;
1405 /* inputs */
1406 /* PW 5/6/7 (29h/2ah/2bh) */
1407 parm = AC_PWRST_D3;
1408 set_pin_power_state(codec, 0x29, &parm);
1409 set_pin_power_state(codec, 0x2a, &parm);
1410 set_pin_power_state(codec, 0x2b, &parm);
1411 parm = AC_PWRST_D0;
1412 /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */
054d867e
TI
1413 update_power_state(codec, 0x1e, parm);
1414 update_power_state(codec, 0x1f, parm);
1415 update_power_state(codec, 0x10, parm);
1416 update_power_state(codec, 0x11, parm);
3e95b9ab
LW
1417
1418 /* outputs */
1419 /* AOW0 (8h)*/
054d867e 1420 update_power_state(codec, 0x8, parm);
3e95b9ab 1421
11890956
LW
1422 if (spec->codec_type == VT1802) {
1423 /* PW4 (28h), MW4 (18h), MUX4(38h) */
1424 parm = AC_PWRST_D3;
1425 set_pin_power_state(codec, 0x28, &parm);
054d867e
TI
1426 update_power_state(codec, 0x18, parm);
1427 update_power_state(codec, 0x38, parm);
11890956
LW
1428 } else {
1429 /* PW4 (26h), MW4 (1ch), MUX4(37h) */
1430 parm = AC_PWRST_D3;
1431 set_pin_power_state(codec, 0x26, &parm);
054d867e
TI
1432 update_power_state(codec, 0x1c, parm);
1433 update_power_state(codec, 0x37, parm);
11890956 1434 }
3e95b9ab 1435
11890956
LW
1436 if (spec->codec_type == VT1802) {
1437 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1438 parm = AC_PWRST_D3;
1439 set_pin_power_state(codec, 0x25, &parm);
054d867e
TI
1440 update_power_state(codec, 0x15, parm);
1441 update_power_state(codec, 0x35, parm);
11890956
LW
1442 } else {
1443 /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */
1444 parm = AC_PWRST_D3;
1445 set_pin_power_state(codec, 0x25, &parm);
054d867e
TI
1446 update_power_state(codec, 0x19, parm);
1447 update_power_state(codec, 0x35, parm);
11890956 1448 }
3e95b9ab 1449
b3f6008f 1450 if (spec->gen.indep_hp_enabled)
054d867e 1451 update_power_state(codec, 0x9, AC_PWRST_D0);
3e95b9ab
LW
1452
1453 /* Class-D */
1454 /* PW0 (24h), MW0(18h/14h), MUX0(34h) */
1455 present = snd_hda_jack_detect(codec, 0x25);
1456
1457 parm = AC_PWRST_D3;
1458 set_pin_power_state(codec, 0x24, &parm);
1459 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
11890956 1460 if (spec->codec_type == VT1802)
054d867e 1461 update_power_state(codec, 0x14, parm);
11890956 1462 else
054d867e
TI
1463 update_power_state(codec, 0x18, parm);
1464 update_power_state(codec, 0x34, parm);
3e95b9ab
LW
1465
1466 /* Mono Out */
1467 present = snd_hda_jack_detect(codec, 0x26);
1468
1469 parm = present ? AC_PWRST_D3 : AC_PWRST_D0;
11890956
LW
1470 if (spec->codec_type == VT1802) {
1471 /* PW15 (33h), MW8(1ch), MUX8(3ch) */
054d867e
TI
1472 update_power_state(codec, 0x33, parm);
1473 update_power_state(codec, 0x1c, parm);
1474 update_power_state(codec, 0x3c, parm);
11890956
LW
1475 } else {
1476 /* PW15 (31h), MW8(17h), MUX8(3bh) */
054d867e
TI
1477 update_power_state(codec, 0x31, parm);
1478 update_power_state(codec, 0x17, parm);
1479 update_power_state(codec, 0x3b, parm);
11890956 1480 }
3e95b9ab
LW
1481 /* MW9 (21h) */
1482 if (imux_is_smixer || !is_aa_path_mute(codec))
054d867e 1483 update_power_state(codec, 0x21, AC_PWRST_D0);
3e95b9ab 1484 else
054d867e 1485 update_power_state(codec, 0x21, AC_PWRST_D3);
3e95b9ab 1486}
25eaba2f 1487
4b527b65
DH
1488/*
1489 * pin fix-up
1490 */
1491enum {
1492 VIA_FIXUP_INTMIC_BOOST,
d5266125 1493 VIA_FIXUP_ASUS_G75,
4b527b65
DH
1494};
1495
1496static void via_fixup_intmic_boost(struct hda_codec *codec,
1497 const struct hda_fixup *fix, int action)
1498{
1499 if (action == HDA_FIXUP_ACT_PRE_PROBE)
1500 override_mic_boost(codec, 0x30, 0, 2, 40);
1501}
1502
1503static const struct hda_fixup via_fixups[] = {
1504 [VIA_FIXUP_INTMIC_BOOST] = {
1505 .type = HDA_FIXUP_FUNC,
1506 .v.func = via_fixup_intmic_boost,
1507 },
d5266125
TI
1508 [VIA_FIXUP_ASUS_G75] = {
1509 .type = HDA_FIXUP_PINS,
1510 .v.pins = (const struct hda_pintbl[]) {
1511 /* set 0x24 and 0x33 as speakers */
1512 { 0x24, 0x991301f0 },
1513 { 0x33, 0x991301f1 }, /* subwoofer */
1514 { }
1515 }
1516 },
4b527b65
DH
1517};
1518
1519static const struct snd_pci_quirk vt2002p_fixups[] = {
d5266125 1520 SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
4b527b65
DH
1521 SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
1522 {}
1523};
1524
ef4da458
TI
1525/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e
1526 * Replace this with mixer NID 0x1c
1527 */
1528static void fix_vt1802_connections(struct hda_codec *codec)
1529{
1530 static hda_nid_t conn_24[] = { 0x14, 0x1c };
1531 static hda_nid_t conn_33[] = { 0x1c };
1532
1533 snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24);
1534 snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33);
1535}
1536
25eaba2f
LW
1537/* patch for vt2002P */
1538static int patch_vt2002P(struct hda_codec *codec)
1539{
1540 struct via_spec *spec;
1541 int err;
1542
1543 /* create a codec specific record */
5b0cb1d8 1544 spec = via_new_spec(codec);
25eaba2f
LW
1545 if (spec == NULL)
1546 return -ENOMEM;
1547
b3f6008f 1548 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
1549 override_mic_boost(codec, 0x2b, 0, 3, 40);
1550 override_mic_boost(codec, 0x29, 0, 3, 40);
ef4da458
TI
1551 if (spec->codec_type == VT1802)
1552 fix_vt1802_connections(codec);
30b45033 1553 add_secret_dac_path(codec);
620e2b28 1554
4b527b65
DH
1555 snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
1556 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1557
25eaba2f 1558 /* automatic parse from the BIOS config */
12daef65 1559 err = via_parse_auto_config(codec);
25eaba2f
LW
1560 if (err < 0) {
1561 via_free(codec);
1562 return err;
25eaba2f
LW
1563 }
1564
11890956 1565 if (spec->codec_type == VT1802)
4a918ffe 1566 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
11890956 1567 else
4a918ffe 1568 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
11890956 1569
25eaba2f
LW
1570 codec->patch_ops = via_patch_ops;
1571
3e95b9ab 1572 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
25eaba2f
LW
1573 return 0;
1574}
ab6734e7
LW
1575
1576/* for vt1812 */
1577
096a8854 1578static const struct hda_verb vt1812_init_verbs[] = {
ab6734e7
LW
1579 /* Enable Boost Volume backdoor */
1580 {0x1, 0xfb9, 0x24},
ab6734e7
LW
1581 /* Enable AOW0 to MW9 */
1582 {0x1, 0xfb8, 0xa8},
1583 { }
1584};
1585
3e95b9ab
LW
1586static void set_widgets_power_state_vt1812(struct hda_codec *codec)
1587{
1588 struct via_spec *spec = codec->spec;
3e95b9ab
LW
1589 unsigned int parm;
1590 unsigned int present;
3e95b9ab
LW
1591 /* inputs */
1592 /* PW 5/6/7 (29h/2ah/2bh) */
1593 parm = AC_PWRST_D3;
1594 set_pin_power_state(codec, 0x29, &parm);
1595 set_pin_power_state(codec, 0x2a, &parm);
1596 set_pin_power_state(codec, 0x2b, &parm);
1597 parm = AC_PWRST_D0;
1598 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
054d867e
TI
1599 update_power_state(codec, 0x1e, parm);
1600 update_power_state(codec, 0x1f, parm);
1601 update_power_state(codec, 0x10, parm);
1602 update_power_state(codec, 0x11, parm);
3e95b9ab
LW
1603
1604 /* outputs */
1605 /* AOW0 (8h)*/
054d867e 1606 update_power_state(codec, 0x8, AC_PWRST_D0);
3e95b9ab
LW
1607
1608 /* PW4 (28h), MW4 (18h), MUX4(38h) */
1609 parm = AC_PWRST_D3;
1610 set_pin_power_state(codec, 0x28, &parm);
054d867e
TI
1611 update_power_state(codec, 0x18, parm);
1612 update_power_state(codec, 0x38, parm);
3e95b9ab
LW
1613
1614 /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */
1615 parm = AC_PWRST_D3;
1616 set_pin_power_state(codec, 0x25, &parm);
054d867e
TI
1617 update_power_state(codec, 0x15, parm);
1618 update_power_state(codec, 0x35, parm);
b3f6008f 1619 if (spec->gen.indep_hp_enabled)
054d867e 1620 update_power_state(codec, 0x9, AC_PWRST_D0);
3e95b9ab
LW
1621
1622 /* Internal Speaker */
1623 /* PW0 (24h), MW0(14h), MUX0(34h) */
1624 present = snd_hda_jack_detect(codec, 0x25);
1625
1626 parm = AC_PWRST_D3;
1627 set_pin_power_state(codec, 0x24, &parm);
1628 if (present) {
054d867e
TI
1629 update_power_state(codec, 0x14, AC_PWRST_D3);
1630 update_power_state(codec, 0x34, AC_PWRST_D3);
3e95b9ab 1631 } else {
054d867e
TI
1632 update_power_state(codec, 0x14, AC_PWRST_D0);
1633 update_power_state(codec, 0x34, AC_PWRST_D0);
3e95b9ab
LW
1634 }
1635
1636
1637 /* Mono Out */
1638 /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */
1639 present = snd_hda_jack_detect(codec, 0x28);
1640
1641 parm = AC_PWRST_D3;
1642 set_pin_power_state(codec, 0x31, &parm);
1643 if (present) {
054d867e
TI
1644 update_power_state(codec, 0x1c, AC_PWRST_D3);
1645 update_power_state(codec, 0x3c, AC_PWRST_D3);
1646 update_power_state(codec, 0x3e, AC_PWRST_D3);
3e95b9ab 1647 } else {
054d867e
TI
1648 update_power_state(codec, 0x1c, AC_PWRST_D0);
1649 update_power_state(codec, 0x3c, AC_PWRST_D0);
1650 update_power_state(codec, 0x3e, AC_PWRST_D0);
3e95b9ab
LW
1651 }
1652
1653 /* PW15 (33h), MW15 (1dh), MUX15(3dh) */
1654 parm = AC_PWRST_D3;
1655 set_pin_power_state(codec, 0x33, &parm);
054d867e
TI
1656 update_power_state(codec, 0x1d, parm);
1657 update_power_state(codec, 0x3d, parm);
3e95b9ab
LW
1658
1659}
ab6734e7
LW
1660
1661/* patch for vt1812 */
1662static int patch_vt1812(struct hda_codec *codec)
1663{
1664 struct via_spec *spec;
1665 int err;
1666
1667 /* create a codec specific record */
5b0cb1d8 1668 spec = via_new_spec(codec);
ab6734e7
LW
1669 if (spec == NULL)
1670 return -ENOMEM;
1671
b3f6008f 1672 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
1673 override_mic_boost(codec, 0x2b, 0, 3, 40);
1674 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 1675 add_secret_dac_path(codec);
620e2b28 1676
ab6734e7 1677 /* automatic parse from the BIOS config */
12daef65 1678 err = via_parse_auto_config(codec);
ab6734e7
LW
1679 if (err < 0) {
1680 via_free(codec);
1681 return err;
ab6734e7
LW
1682 }
1683
096a8854 1684 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
ab6734e7 1685
ab6734e7
LW
1686 codec->patch_ops = via_patch_ops;
1687
3e95b9ab 1688 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
ab6734e7
LW
1689 return 0;
1690}
1691
43737e0a
LW
1692/* patch for vt3476 */
1693
1694static const struct hda_verb vt3476_init_verbs[] = {
1695 /* Enable DMic 8/16/32K */
1696 {0x1, 0xF7B, 0x30},
1697 /* Enable Boost Volume backdoor */
1698 {0x1, 0xFB9, 0x20},
1699 /* Enable AOW-MW9 path */
1700 {0x1, 0xFB8, 0x10},
1701 { }
1702};
1703
1704static void set_widgets_power_state_vt3476(struct hda_codec *codec)
1705{
1706 struct via_spec *spec = codec->spec;
1707 int imux_is_smixer;
1708 unsigned int parm, parm2;
1709 /* MUX10 (1eh) = stereo mixer */
1710 imux_is_smixer =
1711 snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 4;
1712 /* inputs */
1713 /* PW 5/6/7 (29h/2ah/2bh) */
1714 parm = AC_PWRST_D3;
1715 set_pin_power_state(codec, 0x29, &parm);
1716 set_pin_power_state(codec, 0x2a, &parm);
1717 set_pin_power_state(codec, 0x2b, &parm);
1718 if (imux_is_smixer)
1719 parm = AC_PWRST_D0;
1720 /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */
1721 update_power_state(codec, 0x1e, parm);
1722 update_power_state(codec, 0x1f, parm);
1723 update_power_state(codec, 0x10, parm);
1724 update_power_state(codec, 0x11, parm);
1725
1726 /* outputs */
1727 /* PW3 (27h), MW3(37h), AOW3 (bh) */
1728 if (spec->codec_type == VT1705CF) {
1729 parm = AC_PWRST_D3;
1730 update_power_state(codec, 0x27, parm);
1731 update_power_state(codec, 0x37, parm);
1732 } else {
1733 parm = AC_PWRST_D3;
1734 set_pin_power_state(codec, 0x27, &parm);
1735 update_power_state(codec, 0x37, parm);
1736 }
1737
1738 /* PW2 (26h), MW2(36h), AOW2 (ah) */
1739 parm = AC_PWRST_D3;
1740 set_pin_power_state(codec, 0x26, &parm);
1741 update_power_state(codec, 0x36, parm);
b3f6008f 1742 if (smart51_enabled(codec)) {
43737e0a
LW
1743 /* PW7(2bh), MW7(3bh), MUX7(1Bh) */
1744 set_pin_power_state(codec, 0x2b, &parm);
1745 update_power_state(codec, 0x3b, parm);
1746 update_power_state(codec, 0x1b, parm);
1747 }
1748 update_conv_power_state(codec, 0xa, parm, 2);
1749
1750 /* PW1 (25h), MW1(35h), AOW1 (9h) */
1751 parm = AC_PWRST_D3;
1752 set_pin_power_state(codec, 0x25, &parm);
1753 update_power_state(codec, 0x35, parm);
b3f6008f 1754 if (smart51_enabled(codec)) {
43737e0a
LW
1755 /* PW6(2ah), MW6(3ah), MUX6(1ah) */
1756 set_pin_power_state(codec, 0x2a, &parm);
1757 update_power_state(codec, 0x3a, parm);
1758 update_power_state(codec, 0x1a, parm);
1759 }
1760 update_conv_power_state(codec, 0x9, parm, 1);
1761
1762 /* PW4 (28h), MW4 (38h), MUX4(18h), AOW3(bh)/AOW0(8h) */
1763 parm = AC_PWRST_D3;
1764 set_pin_power_state(codec, 0x28, &parm);
1765 update_power_state(codec, 0x38, parm);
1766 update_power_state(codec, 0x18, parm);
b3f6008f 1767 if (spec->gen.indep_hp_enabled)
43737e0a
LW
1768 update_conv_power_state(codec, 0xb, parm, 3);
1769 parm2 = parm; /* for pin 0x0b */
1770
1771 /* PW0 (24h), MW0(34h), MW9(3fh), AOW0 (8h) */
1772 parm = AC_PWRST_D3;
1773 set_pin_power_state(codec, 0x24, &parm);
1774 update_power_state(codec, 0x34, parm);
b3f6008f 1775 if (!spec->gen.indep_hp_enabled && parm2 != AC_PWRST_D3)
43737e0a
LW
1776 parm = parm2;
1777 update_conv_power_state(codec, 0x8, parm, 0);
1778 /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */
1779 update_power_state(codec, 0x3f, imux_is_smixer ? AC_PWRST_D0 : parm);
1780}
1781
1782static int patch_vt3476(struct hda_codec *codec)
1783{
1784 struct via_spec *spec;
1785 int err;
1786
1787 /* create a codec specific record */
1788 spec = via_new_spec(codec);
1789 if (spec == NULL)
1790 return -ENOMEM;
1791
b3f6008f 1792 spec->gen.mixer_nid = 0x3f;
43737e0a
LW
1793 add_secret_dac_path(codec);
1794
1795 /* automatic parse from the BIOS config */
1796 err = via_parse_auto_config(codec);
1797 if (err < 0) {
1798 via_free(codec);
1799 return err;
1800 }
1801
1802 spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
1803
1804 codec->patch_ops = via_patch_ops;
1805
1806 spec->set_widgets_power_state = set_widgets_power_state_vt3476;
1807
1808 return 0;
1809}
1810
c577b8a1
JC
1811/*
1812 * patch entries
1813 */
90dd48a1 1814static const struct hda_codec_preset snd_hda_preset_via[] = {
3218c178
TI
1815 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
1816 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
1817 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
1818 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
1819 { .id = 0x1106e710, .name = "VT1709 10-Ch",
ddd304d8 1820 .patch = patch_vt1709},
3218c178 1821 { .id = 0x1106e711, .name = "VT1709 10-Ch",
ddd304d8 1822 .patch = patch_vt1709},
3218c178 1823 { .id = 0x1106e712, .name = "VT1709 10-Ch",
ddd304d8 1824 .patch = patch_vt1709},
3218c178 1825 { .id = 0x1106e713, .name = "VT1709 10-Ch",
ddd304d8 1826 .patch = patch_vt1709},
3218c178 1827 { .id = 0x1106e714, .name = "VT1709 6-Ch",
ddd304d8 1828 .patch = patch_vt1709},
3218c178 1829 { .id = 0x1106e715, .name = "VT1709 6-Ch",
ddd304d8 1830 .patch = patch_vt1709},
3218c178 1831 { .id = 0x1106e716, .name = "VT1709 6-Ch",
ddd304d8 1832 .patch = patch_vt1709},
3218c178 1833 { .id = 0x1106e717, .name = "VT1709 6-Ch",
ddd304d8 1834 .patch = patch_vt1709},
3218c178 1835 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
ddd304d8 1836 .patch = patch_vt1708B},
3218c178 1837 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
ddd304d8 1838 .patch = patch_vt1708B},
3218c178 1839 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
ddd304d8 1840 .patch = patch_vt1708B},
3218c178 1841 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
ddd304d8 1842 .patch = patch_vt1708B},
3218c178 1843 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
ddd304d8 1844 .patch = patch_vt1708B},
3218c178 1845 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
ddd304d8 1846 .patch = patch_vt1708B},
3218c178 1847 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
ddd304d8 1848 .patch = patch_vt1708B},
3218c178 1849 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
ddd304d8 1850 .patch = patch_vt1708B},
3218c178 1851 { .id = 0x11060397, .name = "VT1708S",
d949cac1 1852 .patch = patch_vt1708S},
3218c178 1853 { .id = 0x11061397, .name = "VT1708S",
d949cac1 1854 .patch = patch_vt1708S},
3218c178 1855 { .id = 0x11062397, .name = "VT1708S",
d949cac1 1856 .patch = patch_vt1708S},
3218c178 1857 { .id = 0x11063397, .name = "VT1708S",
d949cac1 1858 .patch = patch_vt1708S},
bc92df7f 1859 { .id = 0x11064397, .name = "VT1705",
d949cac1 1860 .patch = patch_vt1708S},
3218c178 1861 { .id = 0x11065397, .name = "VT1708S",
d949cac1 1862 .patch = patch_vt1708S},
3218c178 1863 { .id = 0x11066397, .name = "VT1708S",
d949cac1 1864 .patch = patch_vt1708S},
3218c178 1865 { .id = 0x11067397, .name = "VT1708S",
d949cac1 1866 .patch = patch_vt1708S},
3218c178 1867 { .id = 0x11060398, .name = "VT1702",
d949cac1 1868 .patch = patch_vt1702},
3218c178 1869 { .id = 0x11061398, .name = "VT1702",
d949cac1 1870 .patch = patch_vt1702},
3218c178 1871 { .id = 0x11062398, .name = "VT1702",
d949cac1 1872 .patch = patch_vt1702},
3218c178 1873 { .id = 0x11063398, .name = "VT1702",
d949cac1 1874 .patch = patch_vt1702},
3218c178 1875 { .id = 0x11064398, .name = "VT1702",
d949cac1 1876 .patch = patch_vt1702},
3218c178 1877 { .id = 0x11065398, .name = "VT1702",
d949cac1 1878 .patch = patch_vt1702},
3218c178 1879 { .id = 0x11066398, .name = "VT1702",
d949cac1 1880 .patch = patch_vt1702},
3218c178 1881 { .id = 0x11067398, .name = "VT1702",
d949cac1 1882 .patch = patch_vt1702},
eb7188ca
LW
1883 { .id = 0x11060428, .name = "VT1718S",
1884 .patch = patch_vt1718S},
1885 { .id = 0x11064428, .name = "VT1718S",
1886 .patch = patch_vt1718S},
bb3c6bfc
LW
1887 { .id = 0x11060441, .name = "VT2020",
1888 .patch = patch_vt1718S},
1889 { .id = 0x11064441, .name = "VT1828S",
1890 .patch = patch_vt1718S},
f3db423d
LW
1891 { .id = 0x11060433, .name = "VT1716S",
1892 .patch = patch_vt1716S},
1893 { .id = 0x1106a721, .name = "VT1716S",
1894 .patch = patch_vt1716S},
25eaba2f
LW
1895 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
1896 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
ab6734e7 1897 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
36dd5c4a
LW
1898 { .id = 0x11060440, .name = "VT1818S",
1899 .patch = patch_vt1708S},
11890956
LW
1900 { .id = 0x11060446, .name = "VT1802",
1901 .patch = patch_vt2002P},
1902 { .id = 0x11068446, .name = "VT1802",
1903 .patch = patch_vt2002P},
43737e0a
LW
1904 { .id = 0x11064760, .name = "VT1705CF",
1905 .patch = patch_vt3476},
6121b84a
LW
1906 { .id = 0x11064761, .name = "VT1708SCE",
1907 .patch = patch_vt3476},
1908 { .id = 0x11064762, .name = "VT1808",
1909 .patch = patch_vt3476},
c577b8a1
JC
1910 {} /* terminator */
1911};
1289e9e8
TI
1912
1913MODULE_ALIAS("snd-hda-codec-id:1106*");
1914
1915static struct hda_codec_preset_list via_list = {
1916 .preset = snd_hda_preset_via,
1917 .owner = THIS_MODULE,
1918};
1919
1920MODULE_LICENSE("GPL");
1921MODULE_DESCRIPTION("VIA HD-audio codec");
1922
1923static int __init patch_via_init(void)
1924{
1925 return snd_hda_add_codec_preset(&via_list);
1926}
1927
1928static void __exit patch_via_exit(void)
1929{
1930 snd_hda_delete_codec_preset(&via_list);
1931}
1932
1933module_init(patch_via_init)
1934module_exit(patch_via_exit)