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