ALSA: hda - Fix power of pins used for mute LED with vrefs
[deliverable/linux.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;
1f2e99fe
LW
102 enum VIA_HDA_CODEC codec_type;
103
e9d010c2
TI
104 /* analog low-power control */
105 bool alc_mode;
106
1f2e99fe 107 /* work to check hp jack state */
187d333e 108 int hp_work_active;
e06e5a29 109 int vt1708_jack_detect;
1f2e99fe
LW
110};
111
0341ccd7 112static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
b3f6008f
TI
113static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
114 struct hda_codec *codec,
115 struct snd_pcm_substream *substream,
116 int action);
b3f6008f
TI
117
118static struct via_spec *via_new_spec(struct hda_codec *codec)
5b0cb1d8
JK
119{
120 struct via_spec *spec;
121
122 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
123 if (spec == NULL)
124 return NULL;
125
126 codec->spec = spec;
b3f6008f 127 snd_hda_gen_spec_init(&spec->gen);
0341ccd7
LW
128 spec->codec_type = get_codec_type(codec);
129 /* VT1708BCE & VT1708S are almost same */
130 if (spec->codec_type == VT1708BCE)
131 spec->codec_type = VT1708S;
13961170 132 spec->gen.indep_hp = 1;
05909d5c 133 spec->gen.keep_eapd_on = 1;
b3f6008f 134 spec->gen.pcm_playback_hook = via_playback_pcm_hook;
74f14b36 135 spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
688b12cc
TI
136 codec->power_mgmt = 1;
137 spec->gen.power_down_unused = 1;
5b0cb1d8
JK
138 return spec;
139}
140
744ff5f4 141static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
d7426329 142{
744ff5f4 143 u32 vendor_id = codec->vendor_id;
d7426329
HW
144 u16 ven_id = vendor_id >> 16;
145 u16 dev_id = vendor_id & 0xffff;
146 enum VIA_HDA_CODEC codec_type;
147
148 /* get codec type */
149 if (ven_id != 0x1106)
150 codec_type = UNKNOWN;
151 else if (dev_id >= 0x1708 && dev_id <= 0x170b)
152 codec_type = VT1708;
153 else if (dev_id >= 0xe710 && dev_id <= 0xe713)
154 codec_type = VT1709_10CH;
155 else if (dev_id >= 0xe714 && dev_id <= 0xe717)
156 codec_type = VT1709_6CH;
518bf3ba 157 else if (dev_id >= 0xe720 && dev_id <= 0xe723) {
d7426329 158 codec_type = VT1708B_8CH;
518bf3ba
LW
159 if (snd_hda_param_read(codec, 0x16, AC_PAR_CONNLIST_LEN) == 0x7)
160 codec_type = VT1708BCE;
161 } else if (dev_id >= 0xe724 && dev_id <= 0xe727)
d7426329
HW
162 codec_type = VT1708B_4CH;
163 else if ((dev_id & 0xfff) == 0x397
164 && (dev_id >> 12) < 8)
165 codec_type = VT1708S;
166 else if ((dev_id & 0xfff) == 0x398
167 && (dev_id >> 12) < 8)
168 codec_type = VT1702;
eb7188ca
LW
169 else if ((dev_id & 0xfff) == 0x428
170 && (dev_id >> 12) < 8)
171 codec_type = VT1718S;
f3db423d
LW
172 else if (dev_id == 0x0433 || dev_id == 0xa721)
173 codec_type = VT1716S;
bb3c6bfc
LW
174 else if (dev_id == 0x0441 || dev_id == 0x4441)
175 codec_type = VT1718S;
25eaba2f
LW
176 else if (dev_id == 0x0438 || dev_id == 0x4438)
177 codec_type = VT2002P;
ab6734e7
LW
178 else if (dev_id == 0x0448)
179 codec_type = VT1812;
36dd5c4a
LW
180 else if (dev_id == 0x0440)
181 codec_type = VT1708S;
11890956
LW
182 else if ((dev_id & 0xfff) == 0x446)
183 codec_type = VT1802;
43737e0a
LW
184 else if (dev_id == 0x4760)
185 codec_type = VT1705CF;
6121b84a
LW
186 else if (dev_id == 0x4761 || dev_id == 0x4762)
187 codec_type = VT1808;
d7426329
HW
188 else
189 codec_type = UNKNOWN;
190 return codec_type;
191};
192
ada509ec
TI
193static void analog_low_current_mode(struct hda_codec *codec);
194static bool is_aa_path_mute(struct hda_codec *codec);
1f2e99fe 195
187d333e
TI
196#define hp_detect_with_aa(codec) \
197 (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
198 !is_aa_path_mute(codec))
199
b3f6008f 200static void vt1708_stop_hp_work(struct hda_codec *codec)
1f2e99fe 201{
b3f6008f
TI
202 struct via_spec *spec = codec->spec;
203 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs)
1f2e99fe 204 return;
187d333e 205 if (spec->hp_work_active) {
b3f6008f 206 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1);
7eaa9161 207 codec->jackpoll_interval = 0;
b3f6008f
TI
208 cancel_delayed_work_sync(&codec->jackpoll_work);
209 spec->hp_work_active = false;
187d333e 210 }
1f2e99fe
LW
211}
212
b3f6008f 213static void vt1708_update_hp_work(struct hda_codec *codec)
1f2e99fe 214{
b3f6008f
TI
215 struct via_spec *spec = codec->spec;
216 if (spec->codec_type != VT1708 || !spec->gen.autocfg.hp_outs)
1f2e99fe 217 return;
05dc0fc9 218 if (spec->vt1708_jack_detect) {
187d333e 219 if (!spec->hp_work_active) {
b3f6008f
TI
220 codec->jackpoll_interval = msecs_to_jiffies(100);
221 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 0);
2f35c630 222 schedule_delayed_work(&codec->jackpoll_work, 0);
b3f6008f 223 spec->hp_work_active = true;
187d333e 224 }
b3f6008f
TI
225 } else if (!hp_detect_with_aa(codec))
226 vt1708_stop_hp_work(codec);
1f2e99fe 227}
f5271101 228
24088a58
TI
229static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
230 struct snd_ctl_elem_info *uinfo)
231{
dda415d4 232 return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
24088a58
TI
233}
234
235static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
236 struct snd_ctl_elem_value *ucontrol)
237{
238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
688b12cc 239 ucontrol->value.enumerated.item[0] = codec->power_mgmt;
24088a58
TI
240 return 0;
241}
242
243static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
244 struct snd_ctl_elem_value *ucontrol)
245{
246 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
247 struct via_spec *spec = codec->spec;
688b12cc 248 bool val = !!ucontrol->value.enumerated.item[0];
24088a58 249
688b12cc 250 if (val == codec->power_mgmt)
24088a58 251 return 0;
688b12cc
TI
252 codec->power_mgmt = val;
253 spec->gen.power_down_unused = val;
e9d010c2 254 analog_low_current_mode(codec);
24088a58
TI
255 return 1;
256}
257
b3f6008f
TI
258static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = {
259 {
24088a58
TI
260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
261 .name = "Dynamic Power-Control",
262 .info = via_pin_power_ctl_info,
263 .get = via_pin_power_ctl_get,
264 .put = via_pin_power_ctl_put,
b3f6008f
TI
265 },
266 {} /* terminator */
24088a58
TI
267};
268
269
b3f6008f
TI
270/* check AA path's mute status */
271static bool is_aa_path_mute(struct hda_codec *codec)
0aa62aef 272{
cdc1784d 273 struct via_spec *spec = codec->spec;
b3f6008f 274 const struct hda_amp_list *p;
0186f4f4 275 int ch, v;
cdc1784d 276
0186f4f4
TI
277 p = spec->gen.loopback.amplist;
278 if (!p)
279 return true;
280 for (; p->nid; p++) {
b3f6008f
TI
281 for (ch = 0; ch < 2; ch++) {
282 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
283 p->idx);
284 if (!(v & HDA_AMP_MUTE) && v > 0)
285 return false;
286 }
3b607e3d 287 }
b3f6008f 288 return true;
3b607e3d
TI
289}
290
b3f6008f
TI
291/* enter/exit analog low-current mode */
292static void __analog_low_current_mode(struct hda_codec *codec, bool force)
3b607e3d
TI
293{
294 struct via_spec *spec = codec->spec;
b3f6008f
TI
295 bool enable;
296 unsigned int verb, parm;
3b607e3d 297
688b12cc 298 if (!codec->power_mgmt)
b3f6008f
TI
299 enable = false;
300 else
301 enable = is_aa_path_mute(codec) && !spec->gen.active_streams;
302 if (enable == spec->alc_mode && !force)
3b607e3d 303 return;
b3f6008f 304 spec->alc_mode = enable;
3b607e3d 305
b3f6008f
TI
306 /* decide low current mode's verb & parameter */
307 switch (spec->codec_type) {
308 case VT1708B_8CH:
309 case VT1708B_4CH:
310 verb = 0xf70;
311 parm = enable ? 0x02 : 0x00; /* 0x02: 2/3x, 0x00: 1x */
312 break;
313 case VT1708S:
314 case VT1718S:
315 case VT1716S:
316 verb = 0xf73;
317 parm = enable ? 0x51 : 0xe1; /* 0x51: 4/28x, 0xe1: 1x */
318 break;
319 case VT1702:
320 verb = 0xf73;
321 parm = enable ? 0x01 : 0x1d; /* 0x01: 4/40x, 0x1d: 1x */
322 break;
323 case VT2002P:
324 case VT1812:
325 case VT1802:
326 verb = 0xf93;
327 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
328 break;
329 case VT1705CF:
330 case VT1808:
331 verb = 0xf82;
332 parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */
333 break;
334 default:
335 return; /* other codecs are not supported */
f5271101
LW
336 }
337 /* send verb */
b3f6008f 338 snd_hda_codec_write(codec, codec->afg, 0, verb, parm);
a86a88ea
TI
339}
340
b3f6008f
TI
341static void analog_low_current_mode(struct hda_codec *codec)
342{
343 return __analog_low_current_mode(codec, false);
344}
a86a88ea 345
b3f6008f 346static int via_build_controls(struct hda_codec *codec)
a86a88ea
TI
347{
348 struct via_spec *spec = codec->spec;
b3f6008f 349 int err, i;
a766d0d7 350
b3f6008f 351 err = snd_hda_gen_build_controls(codec);
a766d0d7
TI
352 if (err < 0)
353 return err;
c577b8a1 354
688b12cc 355 spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
c577b8a1 356
b3f6008f
TI
357 for (i = 0; i < spec->num_mixers; i++) {
358 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
359 if (err < 0)
360 return err;
361 }
a86a88ea
TI
362
363 return 0;
364}
365
b3f6008f
TI
366static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
367 struct hda_codec *codec,
368 struct snd_pcm_substream *substream,
369 int action)
a86a88ea 370{
b3f6008f
TI
371 analog_low_current_mode(codec);
372 vt1708_update_hp_work(codec);
a86a88ea
TI
373}
374
b3f6008f 375static void via_free(struct hda_codec *codec)
a86a88ea 376{
b3f6008f 377 vt1708_stop_hp_work(codec);
a8dca460 378 snd_hda_gen_free(codec);
a86a88ea
TI
379}
380
b3f6008f
TI
381#ifdef CONFIG_PM
382static int via_suspend(struct hda_codec *codec)
a86a88ea
TI
383{
384 struct via_spec *spec = codec->spec;
b3f6008f 385 vt1708_stop_hp_work(codec);
d7a99cce 386
2c38d990
TI
387 /* Fix pop noise on headphones */
388 if (spec->codec_type == VT1802)
389 snd_hda_shutup_pins(codec);
d7a99cce 390
a86a88ea
TI
391 return 0;
392}
b3f6008f 393#endif
a86a88ea 394
b3f6008f
TI
395#ifdef CONFIG_PM
396static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
a86a88ea
TI
397{
398 struct via_spec *spec = codec->spec;
b3f6008f
TI
399 analog_low_current_mode(codec);
400 vt1708_update_hp_work(codec);
401 return snd_hda_check_amp_list_power(codec, &spec->gen.loopback, nid);
402}
403#endif
a86a88ea 404
b3f6008f
TI
405/*
406 */
a86a88ea 407
b3f6008f 408static int via_init(struct hda_codec *codec);
a86a88ea 409
b3f6008f
TI
410static const struct hda_codec_ops via_patch_ops = {
411 .build_controls = via_build_controls,
412 .build_pcms = snd_hda_gen_build_pcms,
413 .init = via_init,
414 .free = via_free,
415 .unsol_event = snd_hda_jack_unsol_event,
416#ifdef CONFIG_PM
417 .suspend = via_suspend,
418 .check_power_status = via_check_power_status,
419#endif
420};
a86a88ea 421
c577b8a1 422
b3f6008f
TI
423static const struct hda_verb vt1708_init_verbs[] = {
424 /* power down jack detect function */
425 {0x1, 0xf81, 0x1},
426 { }
427};
76d9b0dd
HW
428static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
429{
430 unsigned int def_conf;
431 unsigned char seqassoc;
432
2f334f92 433 def_conf = snd_hda_codec_get_pincfg(codec, nid);
76d9b0dd
HW
434 seqassoc = (unsigned char) get_defcfg_association(def_conf);
435 seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf);
82ef9e45
LW
436 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE
437 && (seqassoc == 0xf0 || seqassoc == 0xff)) {
438 def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30));
439 snd_hda_codec_set_pincfg(codec, nid, def_conf);
76d9b0dd
HW
440 }
441
442 return;
443}
444
e06e5a29 445static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct via_spec *spec = codec->spec;
450
451 if (spec->codec_type != VT1708)
452 return 0;
e06e5a29 453 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
1f2e99fe
LW
454 return 0;
455}
456
e06e5a29 457static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
1f2e99fe
LW
458 struct snd_ctl_elem_value *ucontrol)
459{
460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
461 struct via_spec *spec = codec->spec;
187d333e 462 int val;
1f2e99fe
LW
463
464 if (spec->codec_type != VT1708)
465 return 0;
187d333e
TI
466 val = !!ucontrol->value.integer.value[0];
467 if (spec->vt1708_jack_detect == val)
468 return 0;
469 spec->vt1708_jack_detect = val;
b3f6008f 470 vt1708_update_hp_work(codec);
187d333e 471 return 1;
1f2e99fe
LW
472}
473
b3f6008f
TI
474static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
475 {
e06e5a29
TI
476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
477 .name = "Jack Detect",
478 .count = 1,
479 .info = snd_ctl_boolean_mono_info,
480 .get = vt1708_jack_detect_get,
481 .put = vt1708_jack_detect_put,
b3f6008f
TI
482 },
483 {} /* terminator */
1f2e99fe
LW
484};
485
4abdbd1c
TI
486static const struct badness_table via_main_out_badness = {
487 .no_primary_dac = 0x10000,
488 .no_dac = 0x4000,
489 .shared_primary = 0x10000,
490 .shared_surr = 0x20,
491 .shared_clfe = 0x20,
492 .shared_surr_main = 0x20,
493};
494static const struct badness_table via_extra_out_badness = {
495 .no_primary_dac = 0x4000,
496 .no_dac = 0x4000,
497 .shared_primary = 0x12,
498 .shared_surr = 0x20,
499 .shared_clfe = 0x20,
500 .shared_surr_main = 0x10,
501};
502
b3f6008f
TI
503static int via_parse_auto_config(struct hda_codec *codec)
504{
505 struct via_spec *spec = codec->spec;
506 int err;
507
4abdbd1c
TI
508 spec->gen.main_out_badness = &via_main_out_badness;
509 spec->gen.extra_out_badness = &via_extra_out_badness;
510
b3f6008f
TI
511 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0);
512 if (err < 0)
513 return err;
514
515 err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
516 if (err < 0)
517 return err;
518
688b12cc
TI
519 /* disable widget PM at start for compatibility */
520 codec->power_mgmt = 0;
521 spec->gen.power_down_unused = 0;
b3f6008f
TI
522 return 0;
523}
524
5d41762a
TI
525static int via_init(struct hda_codec *codec)
526{
527 struct via_spec *spec = codec->spec;
528 int i;
529
530 for (i = 0; i < spec->num_iverbs; i++)
531 snd_hda_sequence_write(codec, spec->init_verbs[i]);
25eaba2f 532
e9d010c2 533 /* init power states */
e9d010c2
TI
534 __analog_low_current_mode(codec, true);
535
b3f6008f 536 snd_hda_gen_init(codec);
4a918ffe 537
b3f6008f 538 vt1708_update_hp_work(codec);
25eaba2f 539
c577b8a1
JC
540 return 0;
541}
542
f672f65a
DH
543static int vt1708_build_controls(struct hda_codec *codec)
544{
545 /* In order not to create "Phantom Jack" controls,
546 temporary enable jackpoll */
547 int err;
548 int old_interval = codec->jackpoll_interval;
549 codec->jackpoll_interval = msecs_to_jiffies(100);
550 err = via_build_controls(codec);
551 codec->jackpoll_interval = old_interval;
552 return err;
553}
554
b3f6008f 555static int vt1708_build_pcms(struct hda_codec *codec)
337b9d02
TI
556{
557 struct via_spec *spec = codec->spec;
b3f6008f
TI
558 int i, err;
559
560 err = snd_hda_gen_build_pcms(codec);
561 if (err < 0 || codec->vendor_id != 0x11061708)
562 return err;
563
564 /* We got noisy outputs on the right channel on VT1708 when
565 * 24bit samples are used. Until any workaround is found,
566 * disable the 24bit format, so far.
567 */
bbbc7e85
TI
568 for (i = 0; i < ARRAY_SIZE(spec->gen.pcm_rec); i++) {
569 struct hda_pcm *info = spec->gen.pcm_rec[i];
570 if (!info)
571 continue;
b3f6008f
TI
572 if (!info->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams ||
573 info->pcm_type != HDA_PCM_TYPE_AUDIO)
574 continue;
575 info->stream[SNDRV_PCM_STREAM_PLAYBACK].formats =
576 SNDRV_PCM_FMTBIT_S16_LE;
337b9d02 577 }
b3f6008f 578
1c55d521 579 return 0;
337b9d02
TI
580}
581
c577b8a1
JC
582static int patch_vt1708(struct hda_codec *codec)
583{
584 struct via_spec *spec;
585 int err;
586
587 /* create a codec specific record */
5b0cb1d8 588 spec = via_new_spec(codec);
c577b8a1
JC
589 if (spec == NULL)
590 return -ENOMEM;
591
b3f6008f
TI
592 spec->gen.mixer_nid = 0x17;
593
594 /* set jackpoll_interval while parsing the codec */
595 codec->jackpoll_interval = msecs_to_jiffies(100);
596 spec->vt1708_jack_detect = 1;
597
598 /* don't support the input jack switching due to lack of unsol event */
599 /* (it may work with polling, though, but it needs testing) */
600 spec->gen.suppress_auto_mic = 1;
eb33ccf7
TI
601 /* Some machines show the broken speaker mute */
602 spec->gen.auto_mute_via_amp = 1;
620e2b28 603
12daef65
TI
604 /* Add HP and CD pin config connect bit re-config action */
605 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
606 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
607
c577b8a1 608 /* automatic parse from the BIOS config */
12daef65 609 err = via_parse_auto_config(codec);
c577b8a1
JC
610 if (err < 0) {
611 via_free(codec);
612 return err;
c577b8a1
JC
613 }
614
12daef65 615 /* add jack detect on/off control */
b3f6008f 616 spec->mixers[spec->num_mixers++] = vt1708_jack_detect_ctl;
c577b8a1 617
e322a36d
LW
618 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
619
c577b8a1 620 codec->patch_ops = via_patch_ops;
f672f65a 621 codec->patch_ops.build_controls = vt1708_build_controls;
b3f6008f
TI
622 codec->patch_ops.build_pcms = vt1708_build_pcms;
623
624 /* clear jackpoll_interval again; it's set dynamically */
625 codec->jackpoll_interval = 0;
c577b8a1 626
c577b8a1
JC
627 return 0;
628}
629
ddd304d8 630static int patch_vt1709(struct hda_codec *codec)
c577b8a1
JC
631{
632 struct via_spec *spec;
633 int err;
634
635 /* create a codec specific record */
5b0cb1d8 636 spec = via_new_spec(codec);
c577b8a1
JC
637 if (spec == NULL)
638 return -ENOMEM;
639
b3f6008f 640 spec->gen.mixer_nid = 0x18;
620e2b28 641
12daef65 642 err = via_parse_auto_config(codec);
c577b8a1
JC
643 if (err < 0) {
644 via_free(codec);
645 return err;
c577b8a1
JC
646 }
647
c577b8a1
JC
648 codec->patch_ops = via_patch_ops;
649
f7278fd0
JC
650 return 0;
651}
652
518bf3ba 653static int patch_vt1708S(struct hda_codec *codec);
ddd304d8 654static int patch_vt1708B(struct hda_codec *codec)
f7278fd0
JC
655{
656 struct via_spec *spec;
657 int err;
658
518bf3ba
LW
659 if (get_codec_type(codec) == VT1708BCE)
660 return patch_vt1708S(codec);
ddd304d8 661
f7278fd0 662 /* create a codec specific record */
5b0cb1d8 663 spec = via_new_spec(codec);
f7278fd0
JC
664 if (spec == NULL)
665 return -ENOMEM;
666
b3f6008f 667 spec->gen.mixer_nid = 0x16;
620e2b28 668
f7278fd0 669 /* automatic parse from the BIOS config */
12daef65 670 err = via_parse_auto_config(codec);
f7278fd0
JC
671 if (err < 0) {
672 via_free(codec);
673 return err;
f7278fd0
JC
674 }
675
f7278fd0 676 codec->patch_ops = via_patch_ops;
f7278fd0
JC
677 return 0;
678}
679
d949cac1 680/* Patch for VT1708S */
096a8854 681static const struct hda_verb vt1708S_init_verbs[] = {
d7426329
HW
682 /* Enable Mic Boost Volume backdoor */
683 {0x1, 0xf98, 0x1},
bc7e7e5c
LW
684 /* don't bybass mixer */
685 {0x1, 0xf88, 0xc0},
d949cac1
HW
686 { }
687};
688
6369bcfc
LW
689static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
690 int offset, int num_steps, int step_size)
691{
d045c5dc
TI
692 snd_hda_override_wcaps(codec, pin,
693 get_wcaps(codec, pin) | AC_WCAP_IN_AMP);
6369bcfc
LW
694 snd_hda_override_amp_caps(codec, pin, HDA_INPUT,
695 (offset << AC_AMPCAP_OFFSET_SHIFT) |
696 (num_steps << AC_AMPCAP_NUM_STEPS_SHIFT) |
697 (step_size << AC_AMPCAP_STEP_SIZE_SHIFT) |
698 (0 << AC_AMPCAP_MUTE_SHIFT));
699}
700
d949cac1
HW
701static int patch_vt1708S(struct hda_codec *codec)
702{
703 struct via_spec *spec;
704 int err;
705
706 /* create a codec specific record */
5b0cb1d8 707 spec = via_new_spec(codec);
d949cac1
HW
708 if (spec == NULL)
709 return -ENOMEM;
710
b3f6008f 711 spec->gen.mixer_nid = 0x16;
d7a99cce
TI
712 override_mic_boost(codec, 0x1a, 0, 3, 40);
713 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 714
518bf3ba
LW
715 /* correct names for VT1708BCE */
716 if (get_codec_type(codec) == VT1708BCE) {
717 kfree(codec->chip_name);
718 codec->chip_name = kstrdup("VT1708BCE", GFP_KERNEL);
6efdd851
TI
719 snprintf(codec->card->mixername,
720 sizeof(codec->card->mixername),
518bf3ba 721 "%s %s", codec->vendor_name, codec->chip_name);
970f630f 722 }
bc92df7f
LW
723 /* correct names for VT1705 */
724 if (codec->vendor_id == 0x11064397) {
725 kfree(codec->chip_name);
726 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
6efdd851
TI
727 snprintf(codec->card->mixername,
728 sizeof(codec->card->mixername),
bc92df7f
LW
729 "%s %s", codec->vendor_name, codec->chip_name);
730 }
b3f6008f
TI
731
732 /* automatic parse from the BIOS config */
733 err = via_parse_auto_config(codec);
734 if (err < 0) {
735 via_free(codec);
736 return err;
737 }
738
739 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
740
741 codec->patch_ops = via_patch_ops;
d949cac1
HW
742 return 0;
743}
744
745/* Patch for VT1702 */
746
096a8854 747static const struct hda_verb vt1702_init_verbs[] = {
bc7e7e5c
LW
748 /* mixer enable */
749 {0x1, 0xF88, 0x3},
750 /* GPIO 0~2 */
751 {0x1, 0xF82, 0x3F},
d949cac1
HW
752 { }
753};
754
d949cac1
HW
755static int patch_vt1702(struct hda_codec *codec)
756{
757 struct via_spec *spec;
758 int err;
d949cac1
HW
759
760 /* create a codec specific record */
5b0cb1d8 761 spec = via_new_spec(codec);
d949cac1
HW
762 if (spec == NULL)
763 return -ENOMEM;
764
b3f6008f 765 spec->gen.mixer_nid = 0x1a;
620e2b28 766
12daef65
TI
767 /* limit AA path volume to 0 dB */
768 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
769 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
770 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
771 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
772 (1 << AC_AMPCAP_MUTE_SHIFT));
773
d949cac1 774 /* automatic parse from the BIOS config */
12daef65 775 err = via_parse_auto_config(codec);
d949cac1
HW
776 if (err < 0) {
777 via_free(codec);
778 return err;
d949cac1
HW
779 }
780
096a8854 781 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
d949cac1 782
d949cac1 783 codec->patch_ops = via_patch_ops;
d949cac1
HW
784 return 0;
785}
786
eb7188ca
LW
787/* Patch for VT1718S */
788
096a8854 789static const struct hda_verb vt1718S_init_verbs[] = {
4ab2d53a
LW
790 /* Enable MW0 adjust Gain 5 */
791 {0x1, 0xfb2, 0x10},
eb7188ca
LW
792 /* Enable Boost Volume backdoor */
793 {0x1, 0xf88, 0x8},
5d41762a 794
eb7188ca
LW
795 { }
796};
797
30b45033
TI
798/* Add a connection to the primary DAC from AA-mixer for some codecs
799 * This isn't listed from the raw info, but the chip has a secret connection.
800 */
801static int add_secret_dac_path(struct hda_codec *codec)
802{
803 struct via_spec *spec = codec->spec;
804 int i, nums;
805 hda_nid_t conn[8];
806 hda_nid_t nid;
807
b3f6008f 808 if (!spec->gen.mixer_nid)
30b45033 809 return 0;
b3f6008f 810 nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn,
30b45033
TI
811 ARRAY_SIZE(conn) - 1);
812 for (i = 0; i < nums; i++) {
813 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
814 return 0;
815 }
816
817 /* find the primary DAC and add to the connection list */
818 nid = codec->start_nid;
819 for (i = 0; i < codec->num_nodes; i++, nid++) {
820 unsigned int caps = get_wcaps(codec, nid);
821 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
822 !(caps & AC_WCAP_DIGITAL)) {
823 conn[nums++] = nid;
824 return snd_hda_override_conn_list(codec,
b3f6008f 825 spec->gen.mixer_nid,
30b45033
TI
826 nums, conn);
827 }
828 }
829 return 0;
830}
831
832
eb7188ca
LW
833static int patch_vt1718S(struct hda_codec *codec)
834{
835 struct via_spec *spec;
836 int err;
837
838 /* create a codec specific record */
5b0cb1d8 839 spec = via_new_spec(codec);
eb7188ca
LW
840 if (spec == NULL)
841 return -ENOMEM;
842
b3f6008f 843 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
844 override_mic_boost(codec, 0x2b, 0, 3, 40);
845 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 846 add_secret_dac_path(codec);
620e2b28 847
eb7188ca 848 /* automatic parse from the BIOS config */
12daef65 849 err = via_parse_auto_config(codec);
eb7188ca
LW
850 if (err < 0) {
851 via_free(codec);
852 return err;
eb7188ca
LW
853 }
854
096a8854 855 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
eb7188ca 856
eb7188ca 857 codec->patch_ops = via_patch_ops;
eb7188ca
LW
858 return 0;
859}
f3db423d
LW
860
861/* Patch for VT1716S */
862
863static int vt1716s_dmic_info(struct snd_kcontrol *kcontrol,
864 struct snd_ctl_elem_info *uinfo)
865{
866 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
867 uinfo->count = 1;
868 uinfo->value.integer.min = 0;
869 uinfo->value.integer.max = 1;
870 return 0;
871}
872
873static int vt1716s_dmic_get(struct snd_kcontrol *kcontrol,
874 struct snd_ctl_elem_value *ucontrol)
875{
876 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
877 int index = 0;
878
879 index = snd_hda_codec_read(codec, 0x26, 0,
880 AC_VERB_GET_CONNECT_SEL, 0);
881 if (index != -1)
882 *ucontrol->value.integer.value = index;
883
884 return 0;
885}
886
887static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
888 struct snd_ctl_elem_value *ucontrol)
889{
890 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
891 struct via_spec *spec = codec->spec;
892 int index = *ucontrol->value.integer.value;
893
894 snd_hda_codec_write(codec, 0x26, 0,
895 AC_VERB_SET_CONNECT_SEL, index);
896 spec->dmic_enabled = index;
f3db423d
LW
897 return 1;
898}
899
90dd48a1 900static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
f3db423d
LW
901 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
902 {
903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
904 .name = "Digital Mic Capture Switch",
5b0cb1d8 905 .subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
f3db423d
LW
906 .count = 1,
907 .info = vt1716s_dmic_info,
908 .get = vt1716s_dmic_get,
909 .put = vt1716s_dmic_put,
910 },
911 {} /* end */
912};
913
914
915/* mono-out mixer elements */
90dd48a1 916static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
f3db423d
LW
917 HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
918 { } /* end */
919};
920
096a8854 921static const struct hda_verb vt1716S_init_verbs[] = {
f3db423d
LW
922 /* Enable Boost Volume backdoor */
923 {0x1, 0xf8a, 0x80},
924 /* don't bybass mixer */
925 {0x1, 0xf88, 0xc0},
926 /* Enable mono output */
927 {0x1, 0xf90, 0x08},
928 { }
929};
930
f3db423d
LW
931static int patch_vt1716S(struct hda_codec *codec)
932{
933 struct via_spec *spec;
934 int err;
935
936 /* create a codec specific record */
5b0cb1d8 937 spec = via_new_spec(codec);
f3db423d
LW
938 if (spec == NULL)
939 return -ENOMEM;
940
b3f6008f 941 spec->gen.mixer_nid = 0x16;
d7a99cce
TI
942 override_mic_boost(codec, 0x1a, 0, 3, 40);
943 override_mic_boost(codec, 0x1e, 0, 3, 40);
620e2b28 944
f3db423d 945 /* automatic parse from the BIOS config */
12daef65 946 err = via_parse_auto_config(codec);
f3db423d
LW
947 if (err < 0) {
948 via_free(codec);
949 return err;
f3db423d
LW
950 }
951
096a8854 952 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
f3db423d 953
b3f6008f 954 spec->mixers[spec->num_mixers++] = vt1716s_dmic_mixer;
f3db423d
LW
955 spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
956
957 codec->patch_ops = via_patch_ops;
f3db423d
LW
958 return 0;
959}
25eaba2f
LW
960
961/* for vt2002P */
962
096a8854 963static const struct hda_verb vt2002P_init_verbs[] = {
eadb9a80
LW
964 /* Class-D speaker related verbs */
965 {0x1, 0xfe0, 0x4},
966 {0x1, 0xfe9, 0x80},
967 {0x1, 0xfe2, 0x22},
25eaba2f
LW
968 /* Enable Boost Volume backdoor */
969 {0x1, 0xfb9, 0x24},
25eaba2f
LW
970 /* Enable AOW0 to MW9 */
971 {0x1, 0xfb8, 0x88},
972 { }
973};
4a918ffe 974
096a8854 975static const struct hda_verb vt1802_init_verbs[] = {
11890956
LW
976 /* Enable Boost Volume backdoor */
977 {0x1, 0xfb9, 0x24},
11890956
LW
978 /* Enable AOW0 to MW9 */
979 {0x1, 0xfb8, 0x88},
980 { }
981};
25eaba2f 982
4b527b65
DH
983/*
984 * pin fix-up
985 */
986enum {
987 VIA_FIXUP_INTMIC_BOOST,
d5266125 988 VIA_FIXUP_ASUS_G75,
4b527b65
DH
989};
990
991static void via_fixup_intmic_boost(struct hda_codec *codec,
992 const struct hda_fixup *fix, int action)
993{
994 if (action == HDA_FIXUP_ACT_PRE_PROBE)
995 override_mic_boost(codec, 0x30, 0, 2, 40);
996}
997
998static const struct hda_fixup via_fixups[] = {
999 [VIA_FIXUP_INTMIC_BOOST] = {
1000 .type = HDA_FIXUP_FUNC,
1001 .v.func = via_fixup_intmic_boost,
1002 },
d5266125
TI
1003 [VIA_FIXUP_ASUS_G75] = {
1004 .type = HDA_FIXUP_PINS,
1005 .v.pins = (const struct hda_pintbl[]) {
1006 /* set 0x24 and 0x33 as speakers */
1007 { 0x24, 0x991301f0 },
1008 { 0x33, 0x991301f1 }, /* subwoofer */
1009 { }
1010 }
1011 },
4b527b65
DH
1012};
1013
1014static const struct snd_pci_quirk vt2002p_fixups[] = {
d5266125 1015 SND_PCI_QUIRK(0x1043, 0x1487, "Asus G75", VIA_FIXUP_ASUS_G75),
4b527b65
DH
1016 SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
1017 {}
1018};
1019
ef4da458
TI
1020/* NIDs 0x24 and 0x33 on VT1802 have connections to non-existing NID 0x3e
1021 * Replace this with mixer NID 0x1c
1022 */
1023static void fix_vt1802_connections(struct hda_codec *codec)
1024{
1025 static hda_nid_t conn_24[] = { 0x14, 0x1c };
1026 static hda_nid_t conn_33[] = { 0x1c };
1027
1028 snd_hda_override_conn_list(codec, 0x24, ARRAY_SIZE(conn_24), conn_24);
1029 snd_hda_override_conn_list(codec, 0x33, ARRAY_SIZE(conn_33), conn_33);
1030}
1031
25eaba2f
LW
1032/* patch for vt2002P */
1033static int patch_vt2002P(struct hda_codec *codec)
1034{
1035 struct via_spec *spec;
1036 int err;
1037
1038 /* create a codec specific record */
5b0cb1d8 1039 spec = via_new_spec(codec);
25eaba2f
LW
1040 if (spec == NULL)
1041 return -ENOMEM;
1042
b3f6008f 1043 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
1044 override_mic_boost(codec, 0x2b, 0, 3, 40);
1045 override_mic_boost(codec, 0x29, 0, 3, 40);
ef4da458
TI
1046 if (spec->codec_type == VT1802)
1047 fix_vt1802_connections(codec);
30b45033 1048 add_secret_dac_path(codec);
620e2b28 1049
4b527b65
DH
1050 snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
1051 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1052
25eaba2f 1053 /* automatic parse from the BIOS config */
12daef65 1054 err = via_parse_auto_config(codec);
25eaba2f
LW
1055 if (err < 0) {
1056 via_free(codec);
1057 return err;
25eaba2f
LW
1058 }
1059
11890956 1060 if (spec->codec_type == VT1802)
4a918ffe 1061 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
11890956 1062 else
4a918ffe 1063 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
11890956 1064
25eaba2f 1065 codec->patch_ops = via_patch_ops;
25eaba2f
LW
1066 return 0;
1067}
ab6734e7
LW
1068
1069/* for vt1812 */
1070
096a8854 1071static const struct hda_verb vt1812_init_verbs[] = {
ab6734e7
LW
1072 /* Enable Boost Volume backdoor */
1073 {0x1, 0xfb9, 0x24},
ab6734e7
LW
1074 /* Enable AOW0 to MW9 */
1075 {0x1, 0xfb8, 0xa8},
1076 { }
1077};
1078
ab6734e7
LW
1079/* patch for vt1812 */
1080static int patch_vt1812(struct hda_codec *codec)
1081{
1082 struct via_spec *spec;
1083 int err;
1084
1085 /* create a codec specific record */
5b0cb1d8 1086 spec = via_new_spec(codec);
ab6734e7
LW
1087 if (spec == NULL)
1088 return -ENOMEM;
1089
b3f6008f 1090 spec->gen.mixer_nid = 0x21;
d7a99cce
TI
1091 override_mic_boost(codec, 0x2b, 0, 3, 40);
1092 override_mic_boost(codec, 0x29, 0, 3, 40);
30b45033 1093 add_secret_dac_path(codec);
620e2b28 1094
ab6734e7 1095 /* automatic parse from the BIOS config */
12daef65 1096 err = via_parse_auto_config(codec);
ab6734e7
LW
1097 if (err < 0) {
1098 via_free(codec);
1099 return err;
ab6734e7
LW
1100 }
1101
096a8854 1102 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
ab6734e7 1103
ab6734e7 1104 codec->patch_ops = via_patch_ops;
ab6734e7
LW
1105 return 0;
1106}
1107
43737e0a
LW
1108/* patch for vt3476 */
1109
1110static const struct hda_verb vt3476_init_verbs[] = {
1111 /* Enable DMic 8/16/32K */
1112 {0x1, 0xF7B, 0x30},
1113 /* Enable Boost Volume backdoor */
1114 {0x1, 0xFB9, 0x20},
1115 /* Enable AOW-MW9 path */
1116 {0x1, 0xFB8, 0x10},
1117 { }
1118};
1119
43737e0a
LW
1120static int patch_vt3476(struct hda_codec *codec)
1121{
1122 struct via_spec *spec;
1123 int err;
1124
1125 /* create a codec specific record */
1126 spec = via_new_spec(codec);
1127 if (spec == NULL)
1128 return -ENOMEM;
1129
b3f6008f 1130 spec->gen.mixer_nid = 0x3f;
43737e0a
LW
1131 add_secret_dac_path(codec);
1132
1133 /* automatic parse from the BIOS config */
1134 err = via_parse_auto_config(codec);
1135 if (err < 0) {
1136 via_free(codec);
1137 return err;
1138 }
1139
1140 spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
1141
1142 codec->patch_ops = via_patch_ops;
43737e0a
LW
1143 return 0;
1144}
1145
c577b8a1
JC
1146/*
1147 * patch entries
1148 */
90dd48a1 1149static const struct hda_codec_preset snd_hda_preset_via[] = {
3218c178
TI
1150 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
1151 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
1152 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
1153 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
1154 { .id = 0x1106e710, .name = "VT1709 10-Ch",
ddd304d8 1155 .patch = patch_vt1709},
3218c178 1156 { .id = 0x1106e711, .name = "VT1709 10-Ch",
ddd304d8 1157 .patch = patch_vt1709},
3218c178 1158 { .id = 0x1106e712, .name = "VT1709 10-Ch",
ddd304d8 1159 .patch = patch_vt1709},
3218c178 1160 { .id = 0x1106e713, .name = "VT1709 10-Ch",
ddd304d8 1161 .patch = patch_vt1709},
3218c178 1162 { .id = 0x1106e714, .name = "VT1709 6-Ch",
ddd304d8 1163 .patch = patch_vt1709},
3218c178 1164 { .id = 0x1106e715, .name = "VT1709 6-Ch",
ddd304d8 1165 .patch = patch_vt1709},
3218c178 1166 { .id = 0x1106e716, .name = "VT1709 6-Ch",
ddd304d8 1167 .patch = patch_vt1709},
3218c178 1168 { .id = 0x1106e717, .name = "VT1709 6-Ch",
ddd304d8 1169 .patch = patch_vt1709},
3218c178 1170 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
ddd304d8 1171 .patch = patch_vt1708B},
3218c178 1172 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
ddd304d8 1173 .patch = patch_vt1708B},
3218c178 1174 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
ddd304d8 1175 .patch = patch_vt1708B},
3218c178 1176 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
ddd304d8 1177 .patch = patch_vt1708B},
3218c178 1178 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
ddd304d8 1179 .patch = patch_vt1708B},
3218c178 1180 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
ddd304d8 1181 .patch = patch_vt1708B},
3218c178 1182 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
ddd304d8 1183 .patch = patch_vt1708B},
3218c178 1184 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
ddd304d8 1185 .patch = patch_vt1708B},
3218c178 1186 { .id = 0x11060397, .name = "VT1708S",
d949cac1 1187 .patch = patch_vt1708S},
3218c178 1188 { .id = 0x11061397, .name = "VT1708S",
d949cac1 1189 .patch = patch_vt1708S},
3218c178 1190 { .id = 0x11062397, .name = "VT1708S",
d949cac1 1191 .patch = patch_vt1708S},
3218c178 1192 { .id = 0x11063397, .name = "VT1708S",
d949cac1 1193 .patch = patch_vt1708S},
bc92df7f 1194 { .id = 0x11064397, .name = "VT1705",
d949cac1 1195 .patch = patch_vt1708S},
3218c178 1196 { .id = 0x11065397, .name = "VT1708S",
d949cac1 1197 .patch = patch_vt1708S},
3218c178 1198 { .id = 0x11066397, .name = "VT1708S",
d949cac1 1199 .patch = patch_vt1708S},
3218c178 1200 { .id = 0x11067397, .name = "VT1708S",
d949cac1 1201 .patch = patch_vt1708S},
3218c178 1202 { .id = 0x11060398, .name = "VT1702",
d949cac1 1203 .patch = patch_vt1702},
3218c178 1204 { .id = 0x11061398, .name = "VT1702",
d949cac1 1205 .patch = patch_vt1702},
3218c178 1206 { .id = 0x11062398, .name = "VT1702",
d949cac1 1207 .patch = patch_vt1702},
3218c178 1208 { .id = 0x11063398, .name = "VT1702",
d949cac1 1209 .patch = patch_vt1702},
3218c178 1210 { .id = 0x11064398, .name = "VT1702",
d949cac1 1211 .patch = patch_vt1702},
3218c178 1212 { .id = 0x11065398, .name = "VT1702",
d949cac1 1213 .patch = patch_vt1702},
3218c178 1214 { .id = 0x11066398, .name = "VT1702",
d949cac1 1215 .patch = patch_vt1702},
3218c178 1216 { .id = 0x11067398, .name = "VT1702",
d949cac1 1217 .patch = patch_vt1702},
eb7188ca
LW
1218 { .id = 0x11060428, .name = "VT1718S",
1219 .patch = patch_vt1718S},
1220 { .id = 0x11064428, .name = "VT1718S",
1221 .patch = patch_vt1718S},
bb3c6bfc
LW
1222 { .id = 0x11060441, .name = "VT2020",
1223 .patch = patch_vt1718S},
1224 { .id = 0x11064441, .name = "VT1828S",
1225 .patch = patch_vt1718S},
f3db423d
LW
1226 { .id = 0x11060433, .name = "VT1716S",
1227 .patch = patch_vt1716S},
1228 { .id = 0x1106a721, .name = "VT1716S",
1229 .patch = patch_vt1716S},
25eaba2f
LW
1230 { .id = 0x11060438, .name = "VT2002P", .patch = patch_vt2002P},
1231 { .id = 0x11064438, .name = "VT2002P", .patch = patch_vt2002P},
ab6734e7 1232 { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812},
36dd5c4a
LW
1233 { .id = 0x11060440, .name = "VT1818S",
1234 .patch = patch_vt1708S},
11890956
LW
1235 { .id = 0x11060446, .name = "VT1802",
1236 .patch = patch_vt2002P},
1237 { .id = 0x11068446, .name = "VT1802",
1238 .patch = patch_vt2002P},
43737e0a
LW
1239 { .id = 0x11064760, .name = "VT1705CF",
1240 .patch = patch_vt3476},
6121b84a
LW
1241 { .id = 0x11064761, .name = "VT1708SCE",
1242 .patch = patch_vt3476},
1243 { .id = 0x11064762, .name = "VT1808",
1244 .patch = patch_vt3476},
c577b8a1
JC
1245 {} /* terminator */
1246};
1289e9e8
TI
1247
1248MODULE_ALIAS("snd-hda-codec-id:1106*");
1249
d8a766a1 1250static struct hda_codec_driver via_driver = {
1289e9e8 1251 .preset = snd_hda_preset_via,
1289e9e8
TI
1252};
1253
1254MODULE_LICENSE("GPL");
1255MODULE_DESCRIPTION("VIA HD-audio codec");
1256
d8a766a1 1257module_hda_codec_driver(via_driver);
This page took 0.525729 seconds and 5 git commands to generate.