]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] hda-codec - Add EAPD controls for ALC260 test model
[thirdparty/kernel/stable.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <sound/driver.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/pci.h>
31#include <sound/core.h>
32#include "hda_codec.h"
33#include "hda_local.h"
34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
e9edcee0
TI
63#ifdef CONFIG_SND_DEBUG
64 ALC880_TEST,
65#endif
df694daa 66 ALC880_AUTO,
16ded525
TI
67 ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72 ALC260_BASIC,
73 ALC260_HP,
df694daa
KY
74 ALC260_HP_3013,
75 ALC260_FUJITSU_S702X,
0bfc90e9 76 ALC260_ACER,
bc9f98a9
KY
77 ALC260_WILL,
78 ALC260_REPLACER_672V,
7cf51e48
JW
79#ifdef CONFIG_SND_DEBUG
80 ALC260_TEST,
81#endif
df694daa 82 ALC260_AUTO,
16ded525 83 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
84};
85
df694daa
KY
86/* ALC262 models */
87enum {
88 ALC262_BASIC,
ccc656ce
KY
89 ALC262_HIPPO,
90 ALC262_HIPPO_1,
834be88d 91 ALC262_FUJITSU,
9c7f852e 92 ALC262_HP_BPC,
cd7509a4
KY
93 ALC262_HP_BPC_D7000_WL,
94 ALC262_HP_BPC_D7000_WF,
66d2a9d6 95 ALC262_HP_TC_T5735,
304dcaac 96 ALC262_BENQ_ED8,
272a527c 97 ALC262_SONY_ASSAMD,
83c34218 98 ALC262_BENQ_T31,
f651b50b 99 ALC262_ULTRA,
df694daa
KY
100 ALC262_AUTO,
101 ALC262_MODEL_LAST /* last tag */
102};
103
a361d84b
KY
104/* ALC268 models */
105enum {
106 ALC268_3ST,
d1a991a6 107 ALC268_TOSHIBA,
d273809e 108 ALC268_ACER,
a361d84b
KY
109 ALC268_AUTO,
110 ALC268_MODEL_LAST /* last tag */
111};
112
f6a92248
KY
113/* ALC269 models */
114enum {
115 ALC269_BASIC,
116 ALC269_AUTO,
117 ALC269_MODEL_LAST /* last tag */
118};
119
df694daa
KY
120/* ALC861 models */
121enum {
122 ALC861_3ST,
9c7f852e 123 ALC660_3ST,
df694daa
KY
124 ALC861_3ST_DIG,
125 ALC861_6ST_DIG,
22309c3e 126 ALC861_UNIWILL_M31,
a53d1aec 127 ALC861_TOSHIBA,
7cdbff94 128 ALC861_ASUS,
56bb0cab 129 ALC861_ASUS_LAPTOP,
df694daa
KY
130 ALC861_AUTO,
131 ALC861_MODEL_LAST,
132};
133
f32610ed
JS
134/* ALC861-VD models */
135enum {
136 ALC660VD_3ST,
6963f84c 137 ALC660VD_3ST_DIG,
f32610ed
JS
138 ALC861VD_3ST,
139 ALC861VD_3ST_DIG,
140 ALC861VD_6ST_DIG,
bdd148a3 141 ALC861VD_LENOVO,
272a527c 142 ALC861VD_DALLAS,
d1a991a6 143 ALC861VD_HP,
f32610ed
JS
144 ALC861VD_AUTO,
145 ALC861VD_MODEL_LAST,
146};
147
bc9f98a9
KY
148/* ALC662 models */
149enum {
150 ALC662_3ST_2ch_DIG,
151 ALC662_3ST_6ch_DIG,
152 ALC662_3ST_6ch,
153 ALC662_5ST_DIG,
154 ALC662_LENOVO_101E,
291702f0 155 ALC662_ASUS_EEEPC_P701,
bc9f98a9
KY
156 ALC662_AUTO,
157 ALC662_MODEL_LAST,
158};
159
df694daa
KY
160/* ALC882 models */
161enum {
162 ALC882_3ST_DIG,
163 ALC882_6ST_DIG,
4b146cb0 164 ALC882_ARIMA,
bdd148a3 165 ALC882_W2JC,
272a527c
KY
166 ALC882_TARGA,
167 ALC882_ASUS_A7J,
914759b7 168 ALC882_ASUS_A7M,
9102cd1c 169 ALC885_MACPRO,
87350ad0 170 ALC885_MBP3,
c54728d8 171 ALC885_IMAC24,
272a527c 172 ALC882_AUTO,
df694daa
KY
173 ALC882_MODEL_LAST,
174};
175
9c7f852e
TI
176/* ALC883 models */
177enum {
178 ALC883_3ST_2ch_DIG,
179 ALC883_3ST_6ch_DIG,
180 ALC883_3ST_6ch,
181 ALC883_6ST_DIG,
ccc656ce
KY
182 ALC883_TARGA_DIG,
183 ALC883_TARGA_2ch_DIG,
bab282b9 184 ALC883_ACER,
2880a867 185 ALC883_ACER_ASPIRE,
c07584c8 186 ALC883_MEDION,
272a527c 187 ALC883_MEDION_MD2,
b373bdeb 188 ALC883_LAPTOP_EAPD,
bc9f98a9 189 ALC883_LENOVO_101E_2ch,
272a527c 190 ALC883_LENOVO_NB0763,
189609ae
KY
191 ALC888_LENOVO_MS7195_DIG,
192 ALC883_HAIER_W66,
4723c022
CM
193 ALC888_6ST_HP,
194 ALC888_3ST_HP,
a8848bd6 195 ALC883_MITAC,
9c7f852e
TI
196 ALC883_AUTO,
197 ALC883_MODEL_LAST,
198};
199
df694daa
KY
200/* for GPIO Poll */
201#define GPIO_MASK 0x03
202
1da177e4
LT
203struct alc_spec {
204 /* codec parameterization */
df694daa 205 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
206 unsigned int num_mixers;
207
df694daa 208 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
209 * don't forget NULL
210 * termination!
e9edcee0
TI
211 */
212 unsigned int num_init_verbs;
1da177e4 213
16ded525 214 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
215 struct hda_pcm_stream *stream_analog_playback;
216 struct hda_pcm_stream *stream_analog_capture;
217
f12ab1e0 218 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
219 struct hda_pcm_stream *stream_digital_playback;
220 struct hda_pcm_stream *stream_digital_capture;
221
222 /* playback */
16ded525
TI
223 struct hda_multi_out multiout; /* playback set-up
224 * max_channels, dacs must be set
225 * dig_out_nid and hp_nid are optional
226 */
1da177e4
LT
227
228 /* capture */
229 unsigned int num_adc_nids;
230 hda_nid_t *adc_nids;
16ded525 231 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
232
233 /* capture source */
a1e8d2da 234 unsigned int num_mux_defs;
1da177e4
LT
235 const struct hda_input_mux *input_mux;
236 unsigned int cur_mux[3];
237
238 /* channel model */
d2a6d7dc 239 const struct hda_channel_mode *channel_mode;
1da177e4 240 int num_channel_mode;
4e195a7b 241 int need_dac_fix;
1da177e4
LT
242
243 /* PCM information */
4c5186ed 244 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 245
e9edcee0
TI
246 /* dynamic controls, init_verbs and input_mux */
247 struct auto_pin_cfg autocfg;
248 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 249 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 250 struct hda_input_mux private_imux;
41923e44 251 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 252
ae6b813a
TI
253 /* hooks */
254 void (*init_hook)(struct hda_codec *codec);
255 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
256
834be88d
TI
257 /* for pin sensing */
258 unsigned int sense_updated: 1;
259 unsigned int jack_present: 1;
cb53c626
TI
260
261#ifdef CONFIG_SND_HDA_POWER_SAVE
262 struct hda_loopback_check loopback;
263#endif
df694daa
KY
264};
265
266/*
267 * configuration template - to be copied to the spec instance
268 */
269struct alc_config_preset {
9c7f852e
TI
270 struct snd_kcontrol_new *mixers[5]; /* should be identical size
271 * with spec
272 */
df694daa
KY
273 const struct hda_verb *init_verbs[5];
274 unsigned int num_dacs;
275 hda_nid_t *dac_nids;
276 hda_nid_t dig_out_nid; /* optional */
277 hda_nid_t hp_nid; /* optional */
278 unsigned int num_adc_nids;
279 hda_nid_t *adc_nids;
280 hda_nid_t dig_in_nid;
281 unsigned int num_channel_mode;
282 const struct hda_channel_mode *channel_mode;
4e195a7b 283 int need_dac_fix;
a1e8d2da 284 unsigned int num_mux_defs;
df694daa 285 const struct hda_input_mux *input_mux;
ae6b813a
TI
286 void (*unsol_event)(struct hda_codec *, unsigned int);
287 void (*init_hook)(struct hda_codec *);
cb53c626
TI
288#ifdef CONFIG_SND_HDA_POWER_SAVE
289 struct hda_amp_list *loopbacks;
290#endif
1da177e4
LT
291};
292
1da177e4
LT
293
294/*
295 * input MUX handling
296 */
9c7f852e
TI
297static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
298 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
299{
300 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
301 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
302 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
303 if (mux_idx >= spec->num_mux_defs)
304 mux_idx = 0;
305 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
306}
307
9c7f852e
TI
308static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
310{
311 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
312 struct alc_spec *spec = codec->spec;
313 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
314
315 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
316 return 0;
317}
318
9c7f852e
TI
319static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
320 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
321{
322 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
323 struct alc_spec *spec = codec->spec;
324 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da
JW
325 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
326 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
9c7f852e
TI
327 spec->adc_nids[adc_idx],
328 &spec->cur_mux[adc_idx]);
1da177e4
LT
329}
330
e9edcee0 331
1da177e4
LT
332/*
333 * channel mode setting
334 */
9c7f852e
TI
335static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
337{
338 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
340 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
341 spec->num_channel_mode);
1da177e4
LT
342}
343
9c7f852e
TI
344static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
345 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
346{
347 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348 struct alc_spec *spec = codec->spec;
d2a6d7dc 349 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
350 spec->num_channel_mode,
351 spec->multiout.max_channels);
1da177e4
LT
352}
353
9c7f852e
TI
354static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
356{
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
4e195a7b
TI
359 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
360 spec->num_channel_mode,
361 &spec->multiout.max_channels);
bd2033f2 362 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
363 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
364 return err;
1da177e4
LT
365}
366
a9430dd8 367/*
4c5186ed
JW
368 * Control the mode of pin widget settings via the mixer. "pc" is used
369 * instead of "%" to avoid consequences of accidently treating the % as
370 * being part of a format specifier. Maximum allowed length of a value is
371 * 63 characters plus NULL terminator.
7cf51e48
JW
372 *
373 * Note: some retasking pin complexes seem to ignore requests for input
374 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
375 * are requested. Therefore order this list so that this behaviour will not
376 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
377 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
378 * March 2006.
4c5186ed
JW
379 */
380static char *alc_pin_mode_names[] = {
7cf51e48
JW
381 "Mic 50pc bias", "Mic 80pc bias",
382 "Line in", "Line out", "Headphone out",
4c5186ed
JW
383};
384static unsigned char alc_pin_mode_values[] = {
7cf51e48 385 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
386};
387/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
388 * in the pin being assumed to be exclusively an input or an output pin. In
389 * addition, "input" pins may or may not process the mic bias option
390 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
391 * accept requests for bias as of chip versions up to March 2006) and/or
392 * wiring in the computer.
a9430dd8 393 */
a1e8d2da
JW
394#define ALC_PIN_DIR_IN 0x00
395#define ALC_PIN_DIR_OUT 0x01
396#define ALC_PIN_DIR_INOUT 0x02
397#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
398#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 399
a1e8d2da 400/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
401 * For each direction the minimum and maximum values are given.
402 */
a1e8d2da 403static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
404 { 0, 2 }, /* ALC_PIN_DIR_IN */
405 { 3, 4 }, /* ALC_PIN_DIR_OUT */
406 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
407 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
408 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
409};
410#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
411#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
412#define alc_pin_mode_n_items(_dir) \
413 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
414
9c7f852e
TI
415static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
416 struct snd_ctl_elem_info *uinfo)
a9430dd8 417{
4c5186ed
JW
418 unsigned int item_num = uinfo->value.enumerated.item;
419 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
420
421 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 422 uinfo->count = 1;
4c5186ed
JW
423 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
424
425 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
426 item_num = alc_pin_mode_min(dir);
427 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
428 return 0;
429}
430
9c7f852e
TI
431static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
432 struct snd_ctl_elem_value *ucontrol)
a9430dd8 433{
4c5186ed 434 unsigned int i;
a9430dd8
JW
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 437 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 438 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
439 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
440 AC_VERB_GET_PIN_WIDGET_CONTROL,
441 0x00);
a9430dd8 442
4c5186ed
JW
443 /* Find enumerated value for current pinctl setting */
444 i = alc_pin_mode_min(dir);
9c7f852e 445 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 446 i++;
9c7f852e 447 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
448 return 0;
449}
450
9c7f852e
TI
451static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
452 struct snd_ctl_elem_value *ucontrol)
a9430dd8 453{
4c5186ed 454 signed int change;
a9430dd8
JW
455 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
457 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
458 long val = *ucontrol->value.integer.value;
9c7f852e
TI
459 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
460 AC_VERB_GET_PIN_WIDGET_CONTROL,
461 0x00);
a9430dd8 462
f12ab1e0 463 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
464 val = alc_pin_mode_min(dir);
465
466 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
467 if (change) {
468 /* Set pin mode to that requested */
82beb8fd
TI
469 snd_hda_codec_write_cache(codec, nid, 0,
470 AC_VERB_SET_PIN_WIDGET_CONTROL,
471 alc_pin_mode_values[val]);
cdcd9268
JW
472
473 /* Also enable the retasking pin's input/output as required
474 * for the requested pin mode. Enum values of 2 or less are
475 * input modes.
476 *
477 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
478 * reduces noise slightly (particularly on input) so we'll
479 * do it. However, having both input and output buffers
480 * enabled simultaneously doesn't seem to be problematic if
481 * this turns out to be necessary in the future.
cdcd9268
JW
482 */
483 if (val <= 2) {
47fd830a
TI
484 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
485 HDA_AMP_MUTE, HDA_AMP_MUTE);
486 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
487 HDA_AMP_MUTE, 0);
cdcd9268 488 } else {
47fd830a
TI
489 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
490 HDA_AMP_MUTE, HDA_AMP_MUTE);
491 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
492 HDA_AMP_MUTE, 0);
cdcd9268
JW
493 }
494 }
a9430dd8
JW
495 return change;
496}
497
4c5186ed 498#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 499 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
500 .info = alc_pin_mode_info, \
501 .get = alc_pin_mode_get, \
502 .put = alc_pin_mode_put, \
503 .private_value = nid | (dir<<16) }
df694daa 504
5c8f858d
JW
505/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
506 * together using a mask with more than one bit set. This control is
507 * currently used only by the ALC260 test model. At this stage they are not
508 * needed for any "production" models.
509 */
510#ifdef CONFIG_SND_DEBUG
a5ce8890 511#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 512
9c7f852e
TI
513static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
515{
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 hda_nid_t nid = kcontrol->private_value & 0xffff;
518 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
519 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
520 unsigned int val = snd_hda_codec_read(codec, nid, 0,
521 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
522
523 *valp = (val & mask) != 0;
524 return 0;
525}
9c7f852e
TI
526static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
527 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
528{
529 signed int change;
530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
531 hda_nid_t nid = kcontrol->private_value & 0xffff;
532 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
533 long val = *ucontrol->value.integer.value;
9c7f852e
TI
534 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
535 AC_VERB_GET_GPIO_DATA,
536 0x00);
5c8f858d
JW
537
538 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
539 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
540 if (val == 0)
5c8f858d
JW
541 gpio_data &= ~mask;
542 else
543 gpio_data |= mask;
82beb8fd
TI
544 snd_hda_codec_write_cache(codec, nid, 0,
545 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
546
547 return change;
548}
549#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
550 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
551 .info = alc_gpio_data_info, \
552 .get = alc_gpio_data_get, \
553 .put = alc_gpio_data_put, \
554 .private_value = nid | (mask<<16) }
555#endif /* CONFIG_SND_DEBUG */
556
92621f13
JW
557/* A switch control to allow the enabling of the digital IO pins on the
558 * ALC260. This is incredibly simplistic; the intention of this control is
559 * to provide something in the test model allowing digital outputs to be
560 * identified if present. If models are found which can utilise these
561 * outputs a more complete mixer control can be devised for those models if
562 * necessary.
563 */
564#ifdef CONFIG_SND_DEBUG
a5ce8890 565#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 566
9c7f852e
TI
567static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
569{
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long *valp = ucontrol->value.integer.value;
9c7f852e 574 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 575 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
576
577 *valp = (val & mask) != 0;
578 return 0;
579}
9c7f852e
TI
580static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
582{
583 signed int change;
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
9c7f852e 588 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 589 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 590 0x00);
92621f13
JW
591
592 /* Set/unset the masked control bit(s) as needed */
9c7f852e 593 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
594 if (val==0)
595 ctrl_data &= ~mask;
596 else
597 ctrl_data |= mask;
82beb8fd
TI
598 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
599 ctrl_data);
92621f13
JW
600
601 return change;
602}
603#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
604 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
605 .info = alc_spdif_ctrl_info, \
606 .get = alc_spdif_ctrl_get, \
607 .put = alc_spdif_ctrl_put, \
608 .private_value = nid | (mask<<16) }
609#endif /* CONFIG_SND_DEBUG */
610
f8225f6d
JW
611/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
612 * Again, this is only used in the ALC26x test models to help identify when
613 * the EAPD line must be asserted for features to work.
614 */
615#ifdef CONFIG_SND_DEBUG
616#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
617
618static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
619 struct snd_ctl_elem_value *ucontrol)
620{
621 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
622 hda_nid_t nid = kcontrol->private_value & 0xffff;
623 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
624 long *valp = ucontrol->value.integer.value;
625 unsigned int val = snd_hda_codec_read(codec, nid, 0,
626 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
627
628 *valp = (val & mask) != 0;
629 return 0;
630}
631
632static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol)
634{
635 int change;
636 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
637 hda_nid_t nid = kcontrol->private_value & 0xffff;
638 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
639 long val = *ucontrol->value.integer.value;
640 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
641 AC_VERB_GET_EAPD_BTLENABLE,
642 0x00);
643
644 /* Set/unset the masked control bit(s) as needed */
645 change = (!val ? 0 : mask) != (ctrl_data & mask);
646 if (!val)
647 ctrl_data &= ~mask;
648 else
649 ctrl_data |= mask;
650 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
651 ctrl_data);
652
653 return change;
654}
655
656#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
657 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
658 .info = alc_eapd_ctrl_info, \
659 .get = alc_eapd_ctrl_get, \
660 .put = alc_eapd_ctrl_put, \
661 .private_value = nid | (mask<<16) }
662#endif /* CONFIG_SND_DEBUG */
663
df694daa
KY
664/*
665 * set up from the preset table
666 */
9c7f852e
TI
667static void setup_preset(struct alc_spec *spec,
668 const struct alc_config_preset *preset)
df694daa
KY
669{
670 int i;
671
672 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
673 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
674 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
675 i++)
676 spec->init_verbs[spec->num_init_verbs++] =
677 preset->init_verbs[i];
df694daa
KY
678
679 spec->channel_mode = preset->channel_mode;
680 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 681 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
682
683 spec->multiout.max_channels = spec->channel_mode[0].channels;
684
685 spec->multiout.num_dacs = preset->num_dacs;
686 spec->multiout.dac_nids = preset->dac_nids;
687 spec->multiout.dig_out_nid = preset->dig_out_nid;
688 spec->multiout.hp_nid = preset->hp_nid;
689
a1e8d2da 690 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 691 if (!spec->num_mux_defs)
a1e8d2da 692 spec->num_mux_defs = 1;
df694daa
KY
693 spec->input_mux = preset->input_mux;
694
695 spec->num_adc_nids = preset->num_adc_nids;
696 spec->adc_nids = preset->adc_nids;
697 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
698
699 spec->unsol_event = preset->unsol_event;
700 spec->init_hook = preset->init_hook;
cb53c626
TI
701#ifdef CONFIG_SND_HDA_POWER_SAVE
702 spec->loopback.amplist = preset->loopbacks;
703#endif
df694daa
KY
704}
705
bc9f98a9
KY
706/* Enable GPIO mask and set output */
707static struct hda_verb alc_gpio1_init_verbs[] = {
708 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
709 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
710 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
711 { }
712};
713
714static struct hda_verb alc_gpio2_init_verbs[] = {
715 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
716 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
717 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
718 { }
719};
720
bdd148a3
KY
721static struct hda_verb alc_gpio3_init_verbs[] = {
722 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
723 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
724 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
725 { }
726};
727
c9b58006
KY
728static void alc_sku_automute(struct hda_codec *codec)
729{
730 struct alc_spec *spec = codec->spec;
731 unsigned int mute;
732 unsigned int present;
733 unsigned int hp_nid = spec->autocfg.hp_pins[0];
734 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
735
736 /* need to execute and sync at first */
737 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
738 present = snd_hda_codec_read(codec, hp_nid, 0,
739 AC_VERB_GET_PIN_SENSE, 0);
740 spec->jack_present = (present & 0x80000000) != 0;
741 if (spec->jack_present) {
742 /* mute internal speaker */
743 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
744 HDA_AMP_MUTE, HDA_AMP_MUTE);
745 } else {
746 /* unmute internal speaker if necessary */
747 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
748 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
749 HDA_AMP_MUTE, mute);
750 }
751}
752
753/* unsolicited event for HP jack sensing */
754static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
755{
756 if (codec->vendor_id == 0x10ec0880)
757 res >>= 28;
758 else
759 res >>= 26;
760 if (res != ALC880_HP_EVENT)
761 return;
762
763 alc_sku_automute(codec);
764}
765
bc9f98a9
KY
766/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
767 * 31 ~ 16 : Manufacture ID
768 * 15 ~ 8 : SKU ID
769 * 7 ~ 0 : Assembly ID
770 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
771 */
772static void alc_subsystem_id(struct hda_codec *codec,
773 unsigned int porta, unsigned int porte,
774 unsigned int portd)
775{
c9b58006
KY
776 unsigned int ass, tmp, i;
777 unsigned nid;
778 struct alc_spec *spec = codec->spec;
bc9f98a9 779
c9b58006
KY
780 ass = codec->subsystem_id & 0xffff;
781 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
782 goto do_sku;
783
784 /*
785 * 31~30 : port conetcivity
786 * 29~21 : reserve
787 * 20 : PCBEEP input
788 * 19~16 : Check sum (15:1)
789 * 15~1 : Custom
790 * 0 : override
791 */
792 nid = 0x1d;
793 if (codec->vendor_id == 0x10ec0260)
794 nid = 0x17;
795 ass = snd_hda_codec_read(codec, nid, 0,
796 AC_VERB_GET_CONFIG_DEFAULT, 0);
797 if (!(ass & 1) && !(ass & 0x100000))
798 return;
799 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
800 return;
801
c9b58006
KY
802 /* check sum */
803 tmp = 0;
804 for (i = 1; i < 16; i++) {
805 if ((ass >> i) && 1)
806 tmp++;
807 }
808 if (((ass >> 16) & 0xf) != tmp)
809 return;
810do_sku:
811 /*
812 * 0 : override
813 * 1 : Swap Jack
814 * 2 : 0 --> Desktop, 1 --> Laptop
815 * 3~5 : External Amplifier control
816 * 7~6 : Reserved
817 */
bc9f98a9
KY
818 tmp = (ass & 0x38) >> 3; /* external Amp control */
819 switch (tmp) {
820 case 1:
821 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
822 break;
823 case 3:
824 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
825 break;
bdd148a3
KY
826 case 7:
827 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
828 break;
c9b58006 829 case 5: /* set EAPD output high */
bdd148a3 830 switch (codec->vendor_id) {
c9b58006
KY
831 case 0x10ec0260:
832 snd_hda_codec_write(codec, 0x0f, 0,
833 AC_VERB_SET_EAPD_BTLENABLE, 2);
834 snd_hda_codec_write(codec, 0x10, 0,
835 AC_VERB_SET_EAPD_BTLENABLE, 2);
836 break;
837 case 0x10ec0262:
bdd148a3
KY
838 case 0x10ec0267:
839 case 0x10ec0268:
c9b58006
KY
840 case 0x10ec0269:
841 case 0x10ec0862:
842 case 0x10ec0662:
bdd148a3
KY
843 snd_hda_codec_write(codec, 0x14, 0,
844 AC_VERB_SET_EAPD_BTLENABLE, 2);
845 snd_hda_codec_write(codec, 0x15, 0,
846 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 847 break;
bdd148a3 848 }
c9b58006
KY
849 switch (codec->vendor_id) {
850 case 0x10ec0260:
851 snd_hda_codec_write(codec, 0x1a, 0,
852 AC_VERB_SET_COEF_INDEX, 7);
853 tmp = snd_hda_codec_read(codec, 0x1a, 0,
854 AC_VERB_GET_PROC_COEF, 0);
855 snd_hda_codec_write(codec, 0x1a, 0,
856 AC_VERB_SET_COEF_INDEX, 7);
857 snd_hda_codec_write(codec, 0x1a, 0,
858 AC_VERB_SET_PROC_COEF,
859 tmp | 0x2010);
860 break;
861 case 0x10ec0262:
862 case 0x10ec0880:
863 case 0x10ec0882:
864 case 0x10ec0883:
865 case 0x10ec0885:
866 case 0x10ec0888:
867 snd_hda_codec_write(codec, 0x20, 0,
868 AC_VERB_SET_COEF_INDEX, 7);
869 tmp = snd_hda_codec_read(codec, 0x20, 0,
870 AC_VERB_GET_PROC_COEF, 0);
871 snd_hda_codec_write(codec, 0x20, 0,
872 AC_VERB_SET_COEF_INDEX, 7);
873 snd_hda_codec_write(codec, 0x20, 0,
874 AC_VERB_SET_PROC_COEF,
875 tmp | 0x2010);
876 break;
877 case 0x10ec0267:
878 case 0x10ec0268:
879 snd_hda_codec_write(codec, 0x20, 0,
880 AC_VERB_SET_COEF_INDEX, 7);
881 tmp = snd_hda_codec_read(codec, 0x20, 0,
882 AC_VERB_GET_PROC_COEF, 0);
883 snd_hda_codec_write(codec, 0x20, 0,
884 AC_VERB_SET_COEF_INDEX, 7);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_PROC_COEF,
887 tmp | 0x3000);
888 break;
bc9f98a9 889 }
c9b58006 890 default:
bc9f98a9
KY
891 break;
892 }
c9b58006
KY
893
894 /* is laptop and enable the function "Mute internal speaker
895 * when the external headphone out jack is plugged"
896 */
897 if (!(ass & 0x4) || !(ass & 0x8000))
898 return;
899 /*
900 * 10~8 : Jack location
901 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
902 * 14~13: Resvered
903 * 15 : 1 --> enable the function "Mute internal speaker
904 * when the external headphone out jack is plugged"
905 */
906 if (!spec->autocfg.speaker_pins[0]) {
907 if (spec->multiout.dac_nids[0])
908 spec->autocfg.speaker_pins[0] =
909 spec->multiout.dac_nids[0];
910 else
911 return;
912 }
913
914 if (!spec->autocfg.hp_pins[0]) {
915 tmp = (ass >> 11) & 0x3; /* HP to chassis */
916 if (tmp == 0)
917 spec->autocfg.hp_pins[0] = porta;
918 else if (tmp == 1)
919 spec->autocfg.hp_pins[0] = porte;
920 else if (tmp == 2)
921 spec->autocfg.hp_pins[0] = portd;
922 else
923 return;
924 }
925
926 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
927 AC_VERB_SET_UNSOLICITED_ENABLE,
928 AC_USRSP_EN | ALC880_HP_EVENT);
929 spec->unsol_event = alc_sku_unsol_event;
930 spec->init_hook = alc_sku_automute;
bc9f98a9
KY
931}
932
f95474ec
TI
933/*
934 * Fix-up pin default configurations
935 */
936
937struct alc_pincfg {
938 hda_nid_t nid;
939 u32 val;
940};
941
942static void alc_fix_pincfg(struct hda_codec *codec,
943 const struct snd_pci_quirk *quirk,
944 const struct alc_pincfg **pinfix)
945{
946 const struct alc_pincfg *cfg;
947
948 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
949 if (!quirk)
950 return;
951
952 cfg = pinfix[quirk->value];
953 for (; cfg->nid; cfg++) {
954 int i;
955 u32 val = cfg->val;
956 for (i = 0; i < 4; i++) {
957 snd_hda_codec_write(codec, cfg->nid, 0,
958 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
959 val & 0xff);
960 val >>= 8;
961 }
962 }
963}
964
1da177e4 965/*
e9edcee0
TI
966 * ALC880 3-stack model
967 *
968 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
969 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
970 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
971 */
972
e9edcee0
TI
973static hda_nid_t alc880_dac_nids[4] = {
974 /* front, rear, clfe, rear_surr */
975 0x02, 0x05, 0x04, 0x03
976};
977
978static hda_nid_t alc880_adc_nids[3] = {
979 /* ADC0-2 */
980 0x07, 0x08, 0x09,
981};
982
983/* The datasheet says the node 0x07 is connected from inputs,
984 * but it shows zero connection in the real implementation on some devices.
df694daa 985 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 986 */
e9edcee0
TI
987static hda_nid_t alc880_adc_nids_alt[2] = {
988 /* ADC1-2 */
989 0x08, 0x09,
990};
991
992#define ALC880_DIGOUT_NID 0x06
993#define ALC880_DIGIN_NID 0x0a
994
995static struct hda_input_mux alc880_capture_source = {
996 .num_items = 4,
997 .items = {
998 { "Mic", 0x0 },
999 { "Front Mic", 0x3 },
1000 { "Line", 0x2 },
1001 { "CD", 0x4 },
1002 },
1003};
1004
1005/* channel source setting (2/6 channel selection for 3-stack) */
1006/* 2ch mode */
1007static struct hda_verb alc880_threestack_ch2_init[] = {
1008 /* set line-in to input, mute it */
1009 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1010 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1011 /* set mic-in to input vref 80%, mute it */
1012 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1013 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1014 { } /* end */
1015};
1016
1017/* 6ch mode */
1018static struct hda_verb alc880_threestack_ch6_init[] = {
1019 /* set line-in to output, unmute it */
1020 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1021 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1022 /* set mic-in to output, unmute it */
1023 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1024 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1025 { } /* end */
1026};
1027
d2a6d7dc 1028static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1029 { 2, alc880_threestack_ch2_init },
1030 { 6, alc880_threestack_ch6_init },
1031};
1032
c8b6bf9b 1033static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1034 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1035 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1036 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1037 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1038 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1039 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1040 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1041 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1045 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1047 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1048 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1049 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1050 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1051 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1053 {
1054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1055 .name = "Channel Mode",
df694daa
KY
1056 .info = alc_ch_mode_info,
1057 .get = alc_ch_mode_get,
1058 .put = alc_ch_mode_put,
e9edcee0
TI
1059 },
1060 { } /* end */
1061};
1062
1063/* capture mixer elements */
c8b6bf9b 1064static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1065 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1066 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1067 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1068 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1070 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1071 {
1072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1073 /* The multiple "Capture Source" controls confuse alsamixer
1074 * So call somewhat different..
1075 * FIXME: the controls appear in the "playback" view!
1076 */
1077 /* .name = "Capture Source", */
1078 .name = "Input Source",
e9edcee0 1079 .count = 3,
1da177e4
LT
1080 .info = alc_mux_enum_info,
1081 .get = alc_mux_enum_get,
1082 .put = alc_mux_enum_put,
1083 },
1da177e4
LT
1084 { } /* end */
1085};
1086
e9edcee0 1087/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1088static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1089 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1090 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1091 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1092 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1093 {
1094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1095 /* The multiple "Capture Source" controls confuse alsamixer
1096 * So call somewhat different..
1097 * FIXME: the controls appear in the "playback" view!
1098 */
1099 /* .name = "Capture Source", */
1100 .name = "Input Source",
1101 .count = 2,
1102 .info = alc_mux_enum_info,
1103 .get = alc_mux_enum_get,
1104 .put = alc_mux_enum_put,
1105 },
1da177e4
LT
1106 { } /* end */
1107};
1108
e9edcee0
TI
1109
1110
1111/*
1112 * ALC880 5-stack model
1113 *
9c7f852e
TI
1114 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1115 * Side = 0x02 (0xd)
e9edcee0
TI
1116 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1117 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1118 */
1119
1120/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1121static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1122 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1123 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1124 { } /* end */
1125};
1126
e9edcee0
TI
1127/* channel source setting (6/8 channel selection for 5-stack) */
1128/* 6ch mode */
1129static struct hda_verb alc880_fivestack_ch6_init[] = {
1130 /* set line-in to input, mute it */
1131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1133 { } /* end */
1134};
1135
e9edcee0
TI
1136/* 8ch mode */
1137static struct hda_verb alc880_fivestack_ch8_init[] = {
1138 /* set line-in to output, unmute it */
1139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1141 { } /* end */
1142};
1143
d2a6d7dc 1144static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1145 { 6, alc880_fivestack_ch6_init },
1146 { 8, alc880_fivestack_ch8_init },
1147};
1148
1149
1150/*
1151 * ALC880 6-stack model
1152 *
9c7f852e
TI
1153 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1154 * Side = 0x05 (0x0f)
e9edcee0
TI
1155 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1156 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1157 */
1158
1159static hda_nid_t alc880_6st_dac_nids[4] = {
1160 /* front, rear, clfe, rear_surr */
1161 0x02, 0x03, 0x04, 0x05
f12ab1e0 1162};
e9edcee0
TI
1163
1164static struct hda_input_mux alc880_6stack_capture_source = {
1165 .num_items = 4,
1166 .items = {
1167 { "Mic", 0x0 },
1168 { "Front Mic", 0x1 },
1169 { "Line", 0x2 },
1170 { "CD", 0x4 },
1171 },
1172};
1173
1174/* fixed 8-channels */
d2a6d7dc 1175static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1176 { 8, NULL },
1177};
1178
c8b6bf9b 1179static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1181 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1182 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1183 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1184 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1185 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1186 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1187 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1188 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1189 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1190 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1191 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1198 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1199 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1200 {
1201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1202 .name = "Channel Mode",
df694daa
KY
1203 .info = alc_ch_mode_info,
1204 .get = alc_ch_mode_get,
1205 .put = alc_ch_mode_put,
16ded525
TI
1206 },
1207 { } /* end */
1208};
1209
e9edcee0
TI
1210
1211/*
1212 * ALC880 W810 model
1213 *
1214 * W810 has rear IO for:
1215 * Front (DAC 02)
1216 * Surround (DAC 03)
1217 * Center/LFE (DAC 04)
1218 * Digital out (06)
1219 *
1220 * The system also has a pair of internal speakers, and a headphone jack.
1221 * These are both connected to Line2 on the codec, hence to DAC 02.
1222 *
1223 * There is a variable resistor to control the speaker or headphone
1224 * volume. This is a hardware-only device without a software API.
1225 *
1226 * Plugging headphones in will disable the internal speakers. This is
1227 * implemented in hardware, not via the driver using jack sense. In
1228 * a similar fashion, plugging into the rear socket marked "front" will
1229 * disable both the speakers and headphones.
1230 *
1231 * For input, there's a microphone jack, and an "audio in" jack.
1232 * These may not do anything useful with this driver yet, because I
1233 * haven't setup any initialization verbs for these yet...
1234 */
1235
1236static hda_nid_t alc880_w810_dac_nids[3] = {
1237 /* front, rear/surround, clfe */
1238 0x02, 0x03, 0x04
16ded525
TI
1239};
1240
e9edcee0 1241/* fixed 6 channels */
d2a6d7dc 1242static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1243 { 6, NULL }
1244};
1245
1246/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1247static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1249 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1250 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1251 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1252 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1253 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1254 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1255 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1257 { } /* end */
1258};
1259
1260
1261/*
1262 * Z710V model
1263 *
1264 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1265 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1266 * Line = 0x1a
e9edcee0
TI
1267 */
1268
1269static hda_nid_t alc880_z71v_dac_nids[1] = {
1270 0x02
1271};
1272#define ALC880_Z71V_HP_DAC 0x03
1273
1274/* fixed 2 channels */
d2a6d7dc 1275static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1276 { 2, NULL }
1277};
1278
c8b6bf9b 1279static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1281 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1282 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1283 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1288 { } /* end */
1289};
1290
e9edcee0
TI
1291
1292/* FIXME! */
1293/*
1294 * ALC880 F1734 model
1295 *
1296 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1297 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1298 */
1299
1300static hda_nid_t alc880_f1734_dac_nids[1] = {
1301 0x03
1302};
1303#define ALC880_F1734_HP_DAC 0x02
1304
c8b6bf9b 1305static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1307 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1308 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1309 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1314 { } /* end */
1315};
1316
1317
1318/* FIXME! */
1319/*
1320 * ALC880 ASUS model
1321 *
1322 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1323 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1324 * Mic = 0x18, Line = 0x1a
1325 */
1326
1327#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1328#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1329
c8b6bf9b 1330static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1331 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1332 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1333 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1334 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1335 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1336 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1337 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1338 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1339 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1340 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1341 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1342 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1343 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1345 {
1346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1347 .name = "Channel Mode",
df694daa
KY
1348 .info = alc_ch_mode_info,
1349 .get = alc_ch_mode_get,
1350 .put = alc_ch_mode_put,
16ded525
TI
1351 },
1352 { } /* end */
1353};
e9edcee0
TI
1354
1355/* FIXME! */
1356/*
1357 * ALC880 ASUS W1V model
1358 *
1359 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1360 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1361 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1362 */
1363
1364/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1365static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1366 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1367 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1368 { } /* end */
1369};
1370
3c10a9d9 1371/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1372static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1373 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1374 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1375 { } /* end */
1376};
e9edcee0 1377
df694daa
KY
1378/* TCL S700 */
1379static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1380 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1381 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1384 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1385 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1386 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1387 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1388 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1389 {
1390 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1391 /* The multiple "Capture Source" controls confuse alsamixer
1392 * So call somewhat different..
1393 * FIXME: the controls appear in the "playback" view!
1394 */
1395 /* .name = "Capture Source", */
1396 .name = "Input Source",
1397 .count = 1,
1398 .info = alc_mux_enum_info,
1399 .get = alc_mux_enum_get,
1400 .put = alc_mux_enum_put,
1401 },
1402 { } /* end */
1403};
1404
ccc656ce
KY
1405/* Uniwill */
1406static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1407 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1408 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1409 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1410 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1411 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1412 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1413 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1414 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1421 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1422 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1423 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1424 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1425 {
1426 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1427 .name = "Channel Mode",
1428 .info = alc_ch_mode_info,
1429 .get = alc_ch_mode_get,
1430 .put = alc_ch_mode_put,
1431 },
1432 { } /* end */
1433};
1434
2cf9f0fc
TD
1435static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1437 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1438 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1439 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1440 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1441 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1442 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1443 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1444 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1445 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1446 { } /* end */
1447};
1448
ccc656ce
KY
1449static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1450 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1451 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1452 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1453 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1456 { } /* end */
1457};
1458
1da177e4 1459/*
e9edcee0 1460 * build control elements
1da177e4
LT
1461 */
1462static int alc_build_controls(struct hda_codec *codec)
1463{
1464 struct alc_spec *spec = codec->spec;
1465 int err;
1466 int i;
1467
1468 for (i = 0; i < spec->num_mixers; i++) {
1469 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1470 if (err < 0)
1471 return err;
1472 }
1473
1474 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1475 err = snd_hda_create_spdif_out_ctls(codec,
1476 spec->multiout.dig_out_nid);
1da177e4
LT
1477 if (err < 0)
1478 return err;
1479 }
1480 if (spec->dig_in_nid) {
1481 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1482 if (err < 0)
1483 return err;
1484 }
1485 return 0;
1486}
1487
e9edcee0 1488
1da177e4
LT
1489/*
1490 * initialize the codec volumes, etc
1491 */
1492
e9edcee0
TI
1493/*
1494 * generic initialization of ADC, input mixers and output mixers
1495 */
1496static struct hda_verb alc880_volume_init_verbs[] = {
1497 /*
1498 * Unmute ADC0-2 and set the default input to mic-in
1499 */
71fe7b82 1500 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1502 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1504 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1506
e9edcee0
TI
1507 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1508 * mixer widget
9c7f852e
TI
1509 * Note: PASD motherboards uses the Line In 2 as the input for front
1510 * panel mic (mic 2)
1da177e4 1511 */
e9edcee0 1512 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1520
e9edcee0
TI
1521 /*
1522 * Set up output mixers (0x0c - 0x0f)
1da177e4 1523 */
e9edcee0
TI
1524 /* set vol=0 to output mixers */
1525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1529 /* set up input amps for analog loopback */
1530 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1537 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1538 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1539
1540 { }
1541};
1542
e9edcee0
TI
1543/*
1544 * 3-stack pin configuration:
1545 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1546 */
1547static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1548 /*
1549 * preset connection lists of input pins
1550 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1551 */
1552 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1553 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1554 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1555
1556 /*
1557 * Set pin mode and muting
1558 */
1559 /* set front pin widgets 0x14 for output */
05acb863 1560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1562 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1563 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1564 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1565 /* Mic2 (as headphone out) for HP output */
1566 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1567 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1568 /* Line In pin widget for input */
05acb863 1569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1570 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1571 /* Line2 (as front mic) pin widget for input and vref at 80% */
1572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1573 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1574 /* CD pin widget for input */
05acb863 1575 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1576
e9edcee0
TI
1577 { }
1578};
1da177e4 1579
e9edcee0
TI
1580/*
1581 * 5-stack pin configuration:
1582 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1583 * line-in/side = 0x1a, f-mic = 0x1b
1584 */
1585static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1586 /*
1587 * preset connection lists of input pins
1588 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1589 */
e9edcee0
TI
1590 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1591 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1592
e9edcee0
TI
1593 /*
1594 * Set pin mode and muting
1da177e4 1595 */
e9edcee0
TI
1596 /* set pin widgets 0x14-0x17 for output */
1597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1599 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1600 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1601 /* unmute pins for output (no gain on this amp) */
1602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1604 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1606
1607 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1608 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1610 /* Mic2 (as headphone out) for HP output */
1611 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1613 /* Line In pin widget for input */
1614 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1615 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1616 /* Line2 (as front mic) pin widget for input and vref at 80% */
1617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1618 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1619 /* CD pin widget for input */
1620 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1621
1622 { }
1623};
1624
e9edcee0
TI
1625/*
1626 * W810 pin configuration:
1627 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1628 */
1629static struct hda_verb alc880_pin_w810_init_verbs[] = {
1630 /* hphone/speaker input selector: front DAC */
1631 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1632
05acb863 1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1635 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1636 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1637 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1639
e9edcee0 1640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1641 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1642
1da177e4
LT
1643 { }
1644};
1645
e9edcee0
TI
1646/*
1647 * Z71V pin configuration:
1648 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1649 */
1650static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1652 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1655
16ded525 1656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1657 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1658 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1659 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1660
1661 { }
1662};
1663
e9edcee0
TI
1664/*
1665 * 6-stack pin configuration:
9c7f852e
TI
1666 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1667 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1668 */
1669static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1670 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1671
16ded525 1672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1673 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1676 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1678 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1679 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680
16ded525 1681 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1683 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1684 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1687 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1688 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1689 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1690
e9edcee0
TI
1691 { }
1692};
1693
ccc656ce
KY
1694/*
1695 * Uniwill pin configuration:
1696 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1697 * line = 0x1a
1698 */
1699static struct hda_verb alc880_uniwill_init_verbs[] = {
1700 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1701
1702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1707 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1709 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1711 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1712 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1713 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1714 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1716
1717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1723 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1724 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1725 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1726
1727 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1728 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1729
1730 { }
1731};
1732
1733/*
1734* Uniwill P53
1735* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1736 */
1737static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1738 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1739
1740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1752
1753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1755 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1756 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1757 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1758 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1759
1760 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1761 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1762
1763 { }
1764};
1765
2cf9f0fc
TD
1766static struct hda_verb alc880_beep_init_verbs[] = {
1767 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1768 { }
1769};
1770
ccc656ce 1771/* toggle speaker-output according to the hp-jack state */
458a4fab 1772static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1773{
1774 unsigned int present;
f12ab1e0 1775 unsigned char bits;
ccc656ce
KY
1776
1777 present = snd_hda_codec_read(codec, 0x14, 0,
1778 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1779 bits = present ? HDA_AMP_MUTE : 0;
1780 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1781 HDA_AMP_MUTE, bits);
1782 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1783 HDA_AMP_MUTE, bits);
458a4fab
TI
1784}
1785
1786/* auto-toggle front mic */
1787static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1788{
1789 unsigned int present;
1790 unsigned char bits;
ccc656ce
KY
1791
1792 present = snd_hda_codec_read(codec, 0x18, 0,
1793 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1794 bits = present ? HDA_AMP_MUTE : 0;
1795 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1796}
1797
1798static void alc880_uniwill_automute(struct hda_codec *codec)
1799{
1800 alc880_uniwill_hp_automute(codec);
1801 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1802}
1803
1804static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1805 unsigned int res)
1806{
1807 /* Looks like the unsol event is incompatible with the standard
1808 * definition. 4bit tag is placed at 28 bit!
1809 */
458a4fab
TI
1810 switch (res >> 28) {
1811 case ALC880_HP_EVENT:
1812 alc880_uniwill_hp_automute(codec);
1813 break;
1814 case ALC880_MIC_EVENT:
1815 alc880_uniwill_mic_automute(codec);
1816 break;
1817 }
ccc656ce
KY
1818}
1819
1820static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1821{
1822 unsigned int present;
f12ab1e0 1823 unsigned char bits;
ccc656ce
KY
1824
1825 present = snd_hda_codec_read(codec, 0x14, 0,
1826 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1827 bits = present ? HDA_AMP_MUTE : 0;
1828 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1829}
1830
1831static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1832{
1833 unsigned int present;
1834
1835 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1836 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1837 present &= HDA_AMP_VOLMASK;
1838 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1839 HDA_AMP_VOLMASK, present);
1840 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1841 HDA_AMP_VOLMASK, present);
ccc656ce 1842}
47fd830a 1843
ccc656ce
KY
1844static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1845 unsigned int res)
1846{
1847 /* Looks like the unsol event is incompatible with the standard
1848 * definition. 4bit tag is placed at 28 bit!
1849 */
1850 if ((res >> 28) == ALC880_HP_EVENT)
1851 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1852 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1853 alc880_uniwill_p53_dcvol_automute(codec);
1854}
1855
e9edcee0
TI
1856/* FIXME! */
1857/*
1858 * F1734 pin configuration:
1859 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1860 */
1861static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1862 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1863 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1864 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1865 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1866
e9edcee0 1867 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1870 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1871
e9edcee0
TI
1872 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1873 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1880 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62
TI
1881
1882 { }
1883};
1884
e9edcee0
TI
1885/* FIXME! */
1886/*
1887 * ASUS pin configuration:
1888 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1889 */
1890static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1891 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1892 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1893 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1894 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1895
1896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1899 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1902 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1904
1905 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1906 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1910 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1913 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1914
e9edcee0
TI
1915 { }
1916};
16ded525 1917
e9edcee0 1918/* Enable GPIO mask and set output */
bc9f98a9
KY
1919#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1920#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1921
1922/* Clevo m520g init */
1923static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1924 /* headphone output */
1925 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1926 /* line-out */
1927 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 /* Line-in */
1930 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1932 /* CD */
1933 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1934 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 /* Mic1 (rear panel) */
1936 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1938 /* Mic2 (front panel) */
1939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1940 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1941 /* headphone */
1942 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1943 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1944 /* change to EAPD mode */
1945 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1946 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1947
1948 { }
16ded525
TI
1949};
1950
df694daa 1951static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
1952 /* change to EAPD mode */
1953 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1954 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1955
df694daa
KY
1956 /* Headphone output */
1957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1958 /* Front output*/
1959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1960 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1961
1962 /* Line In pin widget for input */
1963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1964 /* CD pin widget for input */
1965 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1967 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1968
1969 /* change to EAPD mode */
1970 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1971 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1972
1973 { }
1974};
16ded525 1975
e9edcee0 1976/*
ae6b813a
TI
1977 * LG m1 express dual
1978 *
1979 * Pin assignment:
1980 * Rear Line-In/Out (blue): 0x14
1981 * Build-in Mic-In: 0x15
1982 * Speaker-out: 0x17
1983 * HP-Out (green): 0x1b
1984 * Mic-In/Out (red): 0x19
1985 * SPDIF-Out: 0x1e
1986 */
1987
1988/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1989static hda_nid_t alc880_lg_dac_nids[3] = {
1990 0x05, 0x02, 0x03
1991};
1992
1993/* seems analog CD is not working */
1994static struct hda_input_mux alc880_lg_capture_source = {
1995 .num_items = 3,
1996 .items = {
1997 { "Mic", 0x1 },
1998 { "Line", 0x5 },
1999 { "Internal Mic", 0x6 },
2000 },
2001};
2002
2003/* 2,4,6 channel modes */
2004static struct hda_verb alc880_lg_ch2_init[] = {
2005 /* set line-in and mic-in to input */
2006 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2007 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2008 { }
2009};
2010
2011static struct hda_verb alc880_lg_ch4_init[] = {
2012 /* set line-in to out and mic-in to input */
2013 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2014 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2015 { }
2016};
2017
2018static struct hda_verb alc880_lg_ch6_init[] = {
2019 /* set line-in and mic-in to output */
2020 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2021 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2022 { }
2023};
2024
2025static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2026 { 2, alc880_lg_ch2_init },
2027 { 4, alc880_lg_ch4_init },
2028 { 6, alc880_lg_ch6_init },
2029};
2030
2031static struct snd_kcontrol_new alc880_lg_mixer[] = {
2032 /* FIXME: it's not really "master" but front channels */
2033 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2034 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
2035 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2036 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2037 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2038 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2039 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2040 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2045 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2046 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2047 {
2048 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2049 .name = "Channel Mode",
2050 .info = alc_ch_mode_info,
2051 .get = alc_ch_mode_get,
2052 .put = alc_ch_mode_put,
2053 },
2054 { } /* end */
2055};
2056
2057static struct hda_verb alc880_lg_init_verbs[] = {
2058 /* set capture source to mic-in */
2059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2061 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2062 /* mute all amp mixer inputs */
2063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2066 /* line-in to input */
2067 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2068 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2069 /* built-in mic */
2070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2072 /* speaker-out */
2073 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2074 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2075 /* mic-in to input */
2076 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2079 /* HP-out */
2080 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2081 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2083 /* jack sense */
2084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2085 { }
2086};
2087
2088/* toggle speaker-output according to the hp-jack state */
2089static void alc880_lg_automute(struct hda_codec *codec)
2090{
2091 unsigned int present;
f12ab1e0 2092 unsigned char bits;
ae6b813a
TI
2093
2094 present = snd_hda_codec_read(codec, 0x1b, 0,
2095 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2096 bits = present ? HDA_AMP_MUTE : 0;
2097 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2098 HDA_AMP_MUTE, bits);
ae6b813a
TI
2099}
2100
2101static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2102{
2103 /* Looks like the unsol event is incompatible with the standard
2104 * definition. 4bit tag is placed at 28 bit!
2105 */
2106 if ((res >> 28) == 0x01)
2107 alc880_lg_automute(codec);
2108}
2109
d681518a
TI
2110/*
2111 * LG LW20
2112 *
2113 * Pin assignment:
2114 * Speaker-out: 0x14
2115 * Mic-In: 0x18
e4f41da9
CM
2116 * Built-in Mic-In: 0x19
2117 * Line-In: 0x1b
2118 * HP-Out: 0x1a
d681518a
TI
2119 * SPDIF-Out: 0x1e
2120 */
2121
d681518a 2122static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2123 .num_items = 3,
d681518a
TI
2124 .items = {
2125 { "Mic", 0x0 },
2126 { "Internal Mic", 0x1 },
e4f41da9 2127 { "Line In", 0x2 },
d681518a
TI
2128 },
2129};
2130
0a8c5da3
CM
2131#define alc880_lg_lw_modes alc880_threestack_modes
2132
d681518a 2133static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2136 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2137 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2139 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2140 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2141 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2146 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2147 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2148 {
2149 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2150 .name = "Channel Mode",
2151 .info = alc_ch_mode_info,
2152 .get = alc_ch_mode_get,
2153 .put = alc_ch_mode_put,
2154 },
d681518a
TI
2155 { } /* end */
2156};
2157
2158static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2159 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2160 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2161 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2162
d681518a
TI
2163 /* set capture source to mic-in */
2164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2165 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2166 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2168 /* speaker-out */
2169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2171 /* HP-out */
d681518a
TI
2172 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2173 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2174 /* mic-in to input */
2175 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2176 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2177 /* built-in mic */
2178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2180 /* jack sense */
2181 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2182 { }
2183};
2184
2185/* toggle speaker-output according to the hp-jack state */
2186static void alc880_lg_lw_automute(struct hda_codec *codec)
2187{
2188 unsigned int present;
f12ab1e0 2189 unsigned char bits;
d681518a
TI
2190
2191 present = snd_hda_codec_read(codec, 0x1b, 0,
2192 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2193 bits = present ? HDA_AMP_MUTE : 0;
2194 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2195 HDA_AMP_MUTE, bits);
d681518a
TI
2196}
2197
2198static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2199{
2200 /* Looks like the unsol event is incompatible with the standard
2201 * definition. 4bit tag is placed at 28 bit!
2202 */
2203 if ((res >> 28) == 0x01)
2204 alc880_lg_lw_automute(codec);
2205}
2206
cb53c626
TI
2207#ifdef CONFIG_SND_HDA_POWER_SAVE
2208static struct hda_amp_list alc880_loopbacks[] = {
2209 { 0x0b, HDA_INPUT, 0 },
2210 { 0x0b, HDA_INPUT, 1 },
2211 { 0x0b, HDA_INPUT, 2 },
2212 { 0x0b, HDA_INPUT, 3 },
2213 { 0x0b, HDA_INPUT, 4 },
2214 { } /* end */
2215};
2216
2217static struct hda_amp_list alc880_lg_loopbacks[] = {
2218 { 0x0b, HDA_INPUT, 1 },
2219 { 0x0b, HDA_INPUT, 6 },
2220 { 0x0b, HDA_INPUT, 7 },
2221 { } /* end */
2222};
2223#endif
2224
ae6b813a
TI
2225/*
2226 * Common callbacks
e9edcee0
TI
2227 */
2228
1da177e4
LT
2229static int alc_init(struct hda_codec *codec)
2230{
2231 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2232 unsigned int i;
2233
2234 for (i = 0; i < spec->num_init_verbs; i++)
2235 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2236
2237 if (spec->init_hook)
2238 spec->init_hook(codec);
2239
1da177e4
LT
2240 return 0;
2241}
2242
ae6b813a
TI
2243static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2244{
2245 struct alc_spec *spec = codec->spec;
2246
2247 if (spec->unsol_event)
2248 spec->unsol_event(codec, res);
2249}
2250
cb53c626
TI
2251#ifdef CONFIG_SND_HDA_POWER_SAVE
2252static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2253{
2254 struct alc_spec *spec = codec->spec;
2255 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2256}
2257#endif
2258
1da177e4
LT
2259/*
2260 * Analog playback callbacks
2261 */
2262static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2263 struct hda_codec *codec,
c8b6bf9b 2264 struct snd_pcm_substream *substream)
1da177e4
LT
2265{
2266 struct alc_spec *spec = codec->spec;
2267 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2268}
2269
2270static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2271 struct hda_codec *codec,
2272 unsigned int stream_tag,
2273 unsigned int format,
c8b6bf9b 2274 struct snd_pcm_substream *substream)
1da177e4
LT
2275{
2276 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2277 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2278 stream_tag, format, substream);
1da177e4
LT
2279}
2280
2281static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2282 struct hda_codec *codec,
c8b6bf9b 2283 struct snd_pcm_substream *substream)
1da177e4
LT
2284{
2285 struct alc_spec *spec = codec->spec;
2286 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2287}
2288
2289/*
2290 * Digital out
2291 */
2292static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2293 struct hda_codec *codec,
c8b6bf9b 2294 struct snd_pcm_substream *substream)
1da177e4
LT
2295{
2296 struct alc_spec *spec = codec->spec;
2297 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2298}
2299
6b97eb45
TI
2300static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2301 struct hda_codec *codec,
2302 unsigned int stream_tag,
2303 unsigned int format,
2304 struct snd_pcm_substream *substream)
2305{
2306 struct alc_spec *spec = codec->spec;
2307 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2308 stream_tag, format, substream);
2309}
2310
1da177e4
LT
2311static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2312 struct hda_codec *codec,
c8b6bf9b 2313 struct snd_pcm_substream *substream)
1da177e4
LT
2314{
2315 struct alc_spec *spec = codec->spec;
2316 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2317}
2318
2319/*
2320 * Analog capture
2321 */
2322static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2323 struct hda_codec *codec,
2324 unsigned int stream_tag,
2325 unsigned int format,
c8b6bf9b 2326 struct snd_pcm_substream *substream)
1da177e4
LT
2327{
2328 struct alc_spec *spec = codec->spec;
2329
2330 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2331 stream_tag, 0, format);
2332 return 0;
2333}
2334
2335static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2336 struct hda_codec *codec,
c8b6bf9b 2337 struct snd_pcm_substream *substream)
1da177e4
LT
2338{
2339 struct alc_spec *spec = codec->spec;
2340
9c7f852e
TI
2341 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2342 0, 0, 0);
1da177e4
LT
2343 return 0;
2344}
2345
2346
2347/*
2348 */
2349static struct hda_pcm_stream alc880_pcm_analog_playback = {
2350 .substreams = 1,
2351 .channels_min = 2,
2352 .channels_max = 8,
e9edcee0 2353 /* NID is set in alc_build_pcms */
1da177e4
LT
2354 .ops = {
2355 .open = alc880_playback_pcm_open,
2356 .prepare = alc880_playback_pcm_prepare,
2357 .cleanup = alc880_playback_pcm_cleanup
2358 },
2359};
2360
2361static struct hda_pcm_stream alc880_pcm_analog_capture = {
2362 .substreams = 2,
2363 .channels_min = 2,
2364 .channels_max = 2,
e9edcee0 2365 /* NID is set in alc_build_pcms */
1da177e4
LT
2366 .ops = {
2367 .prepare = alc880_capture_pcm_prepare,
2368 .cleanup = alc880_capture_pcm_cleanup
2369 },
2370};
2371
2372static struct hda_pcm_stream alc880_pcm_digital_playback = {
2373 .substreams = 1,
2374 .channels_min = 2,
2375 .channels_max = 2,
2376 /* NID is set in alc_build_pcms */
2377 .ops = {
2378 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2379 .close = alc880_dig_playback_pcm_close,
2380 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2381 },
2382};
2383
2384static struct hda_pcm_stream alc880_pcm_digital_capture = {
2385 .substreams = 1,
2386 .channels_min = 2,
2387 .channels_max = 2,
2388 /* NID is set in alc_build_pcms */
2389};
2390
4c5186ed
JW
2391/* Used by alc_build_pcms to flag that a PCM has no playback stream */
2392static struct hda_pcm_stream alc_pcm_null_playback = {
2393 .substreams = 0,
2394 .channels_min = 0,
2395 .channels_max = 0,
2396};
2397
1da177e4
LT
2398static int alc_build_pcms(struct hda_codec *codec)
2399{
2400 struct alc_spec *spec = codec->spec;
2401 struct hda_pcm *info = spec->pcm_rec;
2402 int i;
2403
2404 codec->num_pcms = 1;
2405 codec->pcm_info = info;
2406
2407 info->name = spec->stream_name_analog;
4a471b7d
TI
2408 if (spec->stream_analog_playback) {
2409 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2410 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2412 }
2413 if (spec->stream_analog_capture) {
2414 snd_assert(spec->adc_nids, return -EINVAL);
2415 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2416 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2417 }
2418
2419 if (spec->channel_mode) {
2420 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2421 for (i = 0; i < spec->num_channel_mode; i++) {
2422 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2423 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2424 }
1da177e4
LT
2425 }
2426 }
2427
e08a007d 2428 /* SPDIF for stream index #1 */
1da177e4 2429 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2430 codec->num_pcms = 2;
c06134d7 2431 info = spec->pcm_rec + 1;
1da177e4 2432 info->name = spec->stream_name_digital;
4a471b7d
TI
2433 if (spec->multiout.dig_out_nid &&
2434 spec->stream_digital_playback) {
1da177e4
LT
2435 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2436 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2437 }
4a471b7d
TI
2438 if (spec->dig_in_nid &&
2439 spec->stream_digital_capture) {
1da177e4
LT
2440 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2441 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2442 }
2443 }
2444
e08a007d
TI
2445 /* If the use of more than one ADC is requested for the current
2446 * model, configure a second analog capture-only PCM.
2447 */
2448 /* Additional Analaog capture for index #2 */
2449 if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2450 spec->adc_nids) {
2451 codec->num_pcms = 3;
c06134d7 2452 info = spec->pcm_rec + 2;
e08a007d
TI
2453 info->name = spec->stream_name_analog;
2454 /* No playback stream for second PCM */
2455 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2456 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2457 if (spec->stream_analog_capture) {
2458 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2459 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2460 }
2461 }
2462
1da177e4
LT
2463 return 0;
2464}
2465
2466static void alc_free(struct hda_codec *codec)
2467{
e9edcee0
TI
2468 struct alc_spec *spec = codec->spec;
2469 unsigned int i;
2470
f12ab1e0 2471 if (!spec)
e9edcee0
TI
2472 return;
2473
2474 if (spec->kctl_alloc) {
2475 for (i = 0; i < spec->num_kctl_used; i++)
2476 kfree(spec->kctl_alloc[i].name);
2477 kfree(spec->kctl_alloc);
2478 }
2479 kfree(spec);
1da177e4
LT
2480}
2481
2482/*
2483 */
2484static struct hda_codec_ops alc_patch_ops = {
2485 .build_controls = alc_build_controls,
2486 .build_pcms = alc_build_pcms,
2487 .init = alc_init,
2488 .free = alc_free,
ae6b813a 2489 .unsol_event = alc_unsol_event,
cb53c626
TI
2490#ifdef CONFIG_SND_HDA_POWER_SAVE
2491 .check_power_status = alc_check_power_status,
2492#endif
1da177e4
LT
2493};
2494
2fa522be
TI
2495
2496/*
2497 * Test configuration for debugging
2498 *
2499 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2500 * enum controls.
2501 */
2502#ifdef CONFIG_SND_DEBUG
2503static hda_nid_t alc880_test_dac_nids[4] = {
2504 0x02, 0x03, 0x04, 0x05
2505};
2506
2507static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2508 .num_items = 7,
2fa522be
TI
2509 .items = {
2510 { "In-1", 0x0 },
2511 { "In-2", 0x1 },
2512 { "In-3", 0x2 },
2513 { "In-4", 0x3 },
2514 { "CD", 0x4 },
ae6b813a
TI
2515 { "Front", 0x5 },
2516 { "Surround", 0x6 },
2fa522be
TI
2517 },
2518};
2519
d2a6d7dc 2520static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2521 { 2, NULL },
fd2c326d 2522 { 4, NULL },
2fa522be 2523 { 6, NULL },
fd2c326d 2524 { 8, NULL },
2fa522be
TI
2525};
2526
9c7f852e
TI
2527static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2528 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2529{
2530 static char *texts[] = {
2531 "N/A", "Line Out", "HP Out",
2532 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2533 };
2534 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2535 uinfo->count = 1;
2536 uinfo->value.enumerated.items = 8;
2537 if (uinfo->value.enumerated.item >= 8)
2538 uinfo->value.enumerated.item = 7;
2539 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2540 return 0;
2541}
2542
9c7f852e
TI
2543static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2544 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2545{
2546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2547 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2548 unsigned int pin_ctl, item = 0;
2549
2550 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2551 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2552 if (pin_ctl & AC_PINCTL_OUT_EN) {
2553 if (pin_ctl & AC_PINCTL_HP_EN)
2554 item = 2;
2555 else
2556 item = 1;
2557 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2558 switch (pin_ctl & AC_PINCTL_VREFEN) {
2559 case AC_PINCTL_VREF_HIZ: item = 3; break;
2560 case AC_PINCTL_VREF_50: item = 4; break;
2561 case AC_PINCTL_VREF_GRD: item = 5; break;
2562 case AC_PINCTL_VREF_80: item = 6; break;
2563 case AC_PINCTL_VREF_100: item = 7; break;
2564 }
2565 }
2566 ucontrol->value.enumerated.item[0] = item;
2567 return 0;
2568}
2569
9c7f852e
TI
2570static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2571 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2572{
2573 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2574 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2575 static unsigned int ctls[] = {
2576 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2577 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2578 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2579 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2580 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2581 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2582 };
2583 unsigned int old_ctl, new_ctl;
2584
2585 old_ctl = snd_hda_codec_read(codec, nid, 0,
2586 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2587 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2588 if (old_ctl != new_ctl) {
82beb8fd
TI
2589 int val;
2590 snd_hda_codec_write_cache(codec, nid, 0,
2591 AC_VERB_SET_PIN_WIDGET_CONTROL,
2592 new_ctl);
47fd830a
TI
2593 val = ucontrol->value.enumerated.item[0] >= 3 ?
2594 HDA_AMP_MUTE : 0;
2595 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2596 HDA_AMP_MUTE, val);
2fa522be
TI
2597 return 1;
2598 }
2599 return 0;
2600}
2601
9c7f852e
TI
2602static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2603 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2604{
2605 static char *texts[] = {
2606 "Front", "Surround", "CLFE", "Side"
2607 };
2608 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2609 uinfo->count = 1;
2610 uinfo->value.enumerated.items = 4;
2611 if (uinfo->value.enumerated.item >= 4)
2612 uinfo->value.enumerated.item = 3;
2613 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2614 return 0;
2615}
2616
9c7f852e
TI
2617static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2618 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2619{
2620 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2621 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2622 unsigned int sel;
2623
2624 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2625 ucontrol->value.enumerated.item[0] = sel & 3;
2626 return 0;
2627}
2628
9c7f852e
TI
2629static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2630 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2631{
2632 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2633 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2634 unsigned int sel;
2635
2636 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2637 if (ucontrol->value.enumerated.item[0] != sel) {
2638 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2639 snd_hda_codec_write_cache(codec, nid, 0,
2640 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2641 return 1;
2642 }
2643 return 0;
2644}
2645
2646#define PIN_CTL_TEST(xname,nid) { \
2647 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2648 .name = xname, \
2649 .info = alc_test_pin_ctl_info, \
2650 .get = alc_test_pin_ctl_get, \
2651 .put = alc_test_pin_ctl_put, \
2652 .private_value = nid \
2653 }
2654
2655#define PIN_SRC_TEST(xname,nid) { \
2656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2657 .name = xname, \
2658 .info = alc_test_pin_src_info, \
2659 .get = alc_test_pin_src_get, \
2660 .put = alc_test_pin_src_put, \
2661 .private_value = nid \
2662 }
2663
c8b6bf9b 2664static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2667 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2668 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2669 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2670 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2671 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2672 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2673 PIN_CTL_TEST("Front Pin Mode", 0x14),
2674 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2675 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2676 PIN_CTL_TEST("Side Pin Mode", 0x17),
2677 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2678 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2679 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2680 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2681 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2682 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2683 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2684 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2685 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2686 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2687 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2688 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2689 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2690 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2691 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2692 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2693 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2694 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2695 {
2696 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2697 .name = "Channel Mode",
df694daa
KY
2698 .info = alc_ch_mode_info,
2699 .get = alc_ch_mode_get,
2700 .put = alc_ch_mode_put,
2fa522be
TI
2701 },
2702 { } /* end */
2703};
2704
2705static struct hda_verb alc880_test_init_verbs[] = {
2706 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2709 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2711 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2713 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2715 /* Vol output for 0x0c-0x0f */
05acb863
TI
2716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2717 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2718 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2719 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2720 /* Set output pins 0x14-0x17 */
05acb863
TI
2721 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2722 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2725 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2729 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2730 /* Set input pins 0x18-0x1c */
16ded525
TI
2731 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2733 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2736 /* Mute input pins 0x18-0x1b */
05acb863
TI
2737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2738 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2739 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2740 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2741 /* ADC set up */
05acb863 2742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2743 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2744 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2747 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2748 /* Analog input/passthru */
2749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2754 { }
2755};
2756#endif
2757
1da177e4
LT
2758/*
2759 */
2760
f5fcc13c
TI
2761static const char *alc880_models[ALC880_MODEL_LAST] = {
2762 [ALC880_3ST] = "3stack",
2763 [ALC880_TCL_S700] = "tcl",
2764 [ALC880_3ST_DIG] = "3stack-digout",
2765 [ALC880_CLEVO] = "clevo",
2766 [ALC880_5ST] = "5stack",
2767 [ALC880_5ST_DIG] = "5stack-digout",
2768 [ALC880_W810] = "w810",
2769 [ALC880_Z71V] = "z71v",
2770 [ALC880_6ST] = "6stack",
2771 [ALC880_6ST_DIG] = "6stack-digout",
2772 [ALC880_ASUS] = "asus",
2773 [ALC880_ASUS_W1V] = "asus-w1v",
2774 [ALC880_ASUS_DIG] = "asus-dig",
2775 [ALC880_ASUS_DIG2] = "asus-dig2",
2776 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2777 [ALC880_UNIWILL_P53] = "uniwill-p53",
2778 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2779 [ALC880_F1734] = "F1734",
2780 [ALC880_LG] = "lg",
2781 [ALC880_LG_LW] = "lg-lw",
2fa522be 2782#ifdef CONFIG_SND_DEBUG
f5fcc13c 2783 [ALC880_TEST] = "test",
2fa522be 2784#endif
f5fcc13c
TI
2785 [ALC880_AUTO] = "auto",
2786};
2787
2788static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2789 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2790 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2791 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2792 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2793 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2794 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2795 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2796 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2797 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2798 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2799 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2800 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2801 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2802 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2803 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2804 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2805 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2806 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2807 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2808 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2809 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2810 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2811 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2812 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2813 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2814 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2815 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2816 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2817 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2818 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2819 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2820 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2821 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2822 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2823 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2824 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2825 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2826 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2827 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2828 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2829 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2830 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2831 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2832 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2833 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2834 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2835 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2836 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2837 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2838 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2839 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2840 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2841 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2842 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2843 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2844 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2845 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2846 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2847 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2848 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2849 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2850 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2851 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2852 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2853 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2854 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2855 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2856 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2857 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2858 {}
2859};
2860
16ded525 2861/*
df694daa 2862 * ALC880 codec presets
16ded525 2863 */
16ded525
TI
2864static struct alc_config_preset alc880_presets[] = {
2865 [ALC880_3ST] = {
e9edcee0 2866 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2867 .init_verbs = { alc880_volume_init_verbs,
2868 alc880_pin_3stack_init_verbs },
16ded525 2869 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2870 .dac_nids = alc880_dac_nids,
16ded525
TI
2871 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2872 .channel_mode = alc880_threestack_modes,
4e195a7b 2873 .need_dac_fix = 1,
16ded525
TI
2874 .input_mux = &alc880_capture_source,
2875 },
2876 [ALC880_3ST_DIG] = {
e9edcee0 2877 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2878 .init_verbs = { alc880_volume_init_verbs,
2879 alc880_pin_3stack_init_verbs },
16ded525 2880 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2881 .dac_nids = alc880_dac_nids,
2882 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2883 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2884 .channel_mode = alc880_threestack_modes,
4e195a7b 2885 .need_dac_fix = 1,
16ded525
TI
2886 .input_mux = &alc880_capture_source,
2887 },
df694daa
KY
2888 [ALC880_TCL_S700] = {
2889 .mixers = { alc880_tcl_s700_mixer },
2890 .init_verbs = { alc880_volume_init_verbs,
2891 alc880_pin_tcl_S700_init_verbs,
2892 alc880_gpio2_init_verbs },
2893 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2894 .dac_nids = alc880_dac_nids,
2895 .hp_nid = 0x03,
2896 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2897 .channel_mode = alc880_2_jack_modes,
2898 .input_mux = &alc880_capture_source,
2899 },
16ded525 2900 [ALC880_5ST] = {
f12ab1e0
TI
2901 .mixers = { alc880_three_stack_mixer,
2902 alc880_five_stack_mixer},
2903 .init_verbs = { alc880_volume_init_verbs,
2904 alc880_pin_5stack_init_verbs },
16ded525
TI
2905 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2906 .dac_nids = alc880_dac_nids,
16ded525
TI
2907 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2908 .channel_mode = alc880_fivestack_modes,
2909 .input_mux = &alc880_capture_source,
2910 },
2911 [ALC880_5ST_DIG] = {
f12ab1e0
TI
2912 .mixers = { alc880_three_stack_mixer,
2913 alc880_five_stack_mixer },
2914 .init_verbs = { alc880_volume_init_verbs,
2915 alc880_pin_5stack_init_verbs },
16ded525
TI
2916 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2917 .dac_nids = alc880_dac_nids,
2918 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2919 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2920 .channel_mode = alc880_fivestack_modes,
2921 .input_mux = &alc880_capture_source,
2922 },
b6482d48
TI
2923 [ALC880_6ST] = {
2924 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
2925 .init_verbs = { alc880_volume_init_verbs,
2926 alc880_pin_6stack_init_verbs },
b6482d48
TI
2927 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2928 .dac_nids = alc880_6st_dac_nids,
2929 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2930 .channel_mode = alc880_sixstack_modes,
2931 .input_mux = &alc880_6stack_capture_source,
2932 },
16ded525 2933 [ALC880_6ST_DIG] = {
e9edcee0 2934 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
2935 .init_verbs = { alc880_volume_init_verbs,
2936 alc880_pin_6stack_init_verbs },
16ded525
TI
2937 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2938 .dac_nids = alc880_6st_dac_nids,
2939 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2940 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2941 .channel_mode = alc880_sixstack_modes,
2942 .input_mux = &alc880_6stack_capture_source,
2943 },
2944 [ALC880_W810] = {
e9edcee0 2945 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
2946 .init_verbs = { alc880_volume_init_verbs,
2947 alc880_pin_w810_init_verbs,
b0af0de5 2948 alc880_gpio2_init_verbs },
16ded525
TI
2949 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2950 .dac_nids = alc880_w810_dac_nids,
2951 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2952 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2953 .channel_mode = alc880_w810_modes,
2954 .input_mux = &alc880_capture_source,
2955 },
2956 [ALC880_Z71V] = {
e9edcee0 2957 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
2958 .init_verbs = { alc880_volume_init_verbs,
2959 alc880_pin_z71v_init_verbs },
16ded525
TI
2960 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2961 .dac_nids = alc880_z71v_dac_nids,
2962 .dig_out_nid = ALC880_DIGOUT_NID,
2963 .hp_nid = 0x03,
e9edcee0
TI
2964 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2965 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2966 .input_mux = &alc880_capture_source,
2967 },
2968 [ALC880_F1734] = {
e9edcee0 2969 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
2970 .init_verbs = { alc880_volume_init_verbs,
2971 alc880_pin_f1734_init_verbs },
e9edcee0
TI
2972 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2973 .dac_nids = alc880_f1734_dac_nids,
2974 .hp_nid = 0x02,
2975 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2976 .channel_mode = alc880_2_jack_modes,
16ded525
TI
2977 .input_mux = &alc880_capture_source,
2978 },
2979 [ALC880_ASUS] = {
e9edcee0 2980 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
2981 .init_verbs = { alc880_volume_init_verbs,
2982 alc880_pin_asus_init_verbs,
e9edcee0
TI
2983 alc880_gpio1_init_verbs },
2984 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2985 .dac_nids = alc880_asus_dac_nids,
2986 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2987 .channel_mode = alc880_asus_modes,
4e195a7b 2988 .need_dac_fix = 1,
16ded525
TI
2989 .input_mux = &alc880_capture_source,
2990 },
2991 [ALC880_ASUS_DIG] = {
e9edcee0 2992 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
2993 .init_verbs = { alc880_volume_init_verbs,
2994 alc880_pin_asus_init_verbs,
e9edcee0
TI
2995 alc880_gpio1_init_verbs },
2996 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2997 .dac_nids = alc880_asus_dac_nids,
16ded525 2998 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
2999 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3000 .channel_mode = alc880_asus_modes,
4e195a7b 3001 .need_dac_fix = 1,
16ded525
TI
3002 .input_mux = &alc880_capture_source,
3003 },
df694daa
KY
3004 [ALC880_ASUS_DIG2] = {
3005 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3006 .init_verbs = { alc880_volume_init_verbs,
3007 alc880_pin_asus_init_verbs,
df694daa
KY
3008 alc880_gpio2_init_verbs }, /* use GPIO2 */
3009 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3010 .dac_nids = alc880_asus_dac_nids,
3011 .dig_out_nid = ALC880_DIGOUT_NID,
3012 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3013 .channel_mode = alc880_asus_modes,
4e195a7b 3014 .need_dac_fix = 1,
df694daa
KY
3015 .input_mux = &alc880_capture_source,
3016 },
16ded525 3017 [ALC880_ASUS_W1V] = {
e9edcee0 3018 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3019 .init_verbs = { alc880_volume_init_verbs,
3020 alc880_pin_asus_init_verbs,
e9edcee0
TI
3021 alc880_gpio1_init_verbs },
3022 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3023 .dac_nids = alc880_asus_dac_nids,
16ded525 3024 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3025 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3026 .channel_mode = alc880_asus_modes,
4e195a7b 3027 .need_dac_fix = 1,
16ded525
TI
3028 .input_mux = &alc880_capture_source,
3029 },
3030 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3031 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3032 .init_verbs = { alc880_volume_init_verbs,
3033 alc880_pin_asus_init_verbs },
e9edcee0
TI
3034 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3035 .dac_nids = alc880_asus_dac_nids,
16ded525 3036 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3037 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3038 .channel_mode = alc880_asus_modes,
4e195a7b 3039 .need_dac_fix = 1,
16ded525
TI
3040 .input_mux = &alc880_capture_source,
3041 },
ccc656ce
KY
3042 [ALC880_UNIWILL] = {
3043 .mixers = { alc880_uniwill_mixer },
3044 .init_verbs = { alc880_volume_init_verbs,
3045 alc880_uniwill_init_verbs },
3046 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3047 .dac_nids = alc880_asus_dac_nids,
3048 .dig_out_nid = ALC880_DIGOUT_NID,
3049 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3050 .channel_mode = alc880_threestack_modes,
3051 .need_dac_fix = 1,
3052 .input_mux = &alc880_capture_source,
3053 .unsol_event = alc880_uniwill_unsol_event,
3054 .init_hook = alc880_uniwill_automute,
3055 },
3056 [ALC880_UNIWILL_P53] = {
3057 .mixers = { alc880_uniwill_p53_mixer },
3058 .init_verbs = { alc880_volume_init_verbs,
3059 alc880_uniwill_p53_init_verbs },
3060 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3061 .dac_nids = alc880_asus_dac_nids,
3062 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3063 .channel_mode = alc880_threestack_modes,
3064 .input_mux = &alc880_capture_source,
3065 .unsol_event = alc880_uniwill_p53_unsol_event,
3066 .init_hook = alc880_uniwill_p53_hp_automute,
3067 },
3068 [ALC880_FUJITSU] = {
f12ab1e0 3069 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3070 alc880_pcbeep_mixer, },
3071 .init_verbs = { alc880_volume_init_verbs,
3072 alc880_uniwill_p53_init_verbs,
3073 alc880_beep_init_verbs },
3074 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3075 .dac_nids = alc880_dac_nids,
d53d7d9e 3076 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3077 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3078 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3079 .input_mux = &alc880_capture_source,
3080 .unsol_event = alc880_uniwill_p53_unsol_event,
3081 .init_hook = alc880_uniwill_p53_hp_automute,
3082 },
df694daa
KY
3083 [ALC880_CLEVO] = {
3084 .mixers = { alc880_three_stack_mixer },
3085 .init_verbs = { alc880_volume_init_verbs,
3086 alc880_pin_clevo_init_verbs },
3087 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3088 .dac_nids = alc880_dac_nids,
3089 .hp_nid = 0x03,
3090 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3091 .channel_mode = alc880_threestack_modes,
4e195a7b 3092 .need_dac_fix = 1,
df694daa
KY
3093 .input_mux = &alc880_capture_source,
3094 },
ae6b813a
TI
3095 [ALC880_LG] = {
3096 .mixers = { alc880_lg_mixer },
3097 .init_verbs = { alc880_volume_init_verbs,
3098 alc880_lg_init_verbs },
3099 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3100 .dac_nids = alc880_lg_dac_nids,
3101 .dig_out_nid = ALC880_DIGOUT_NID,
3102 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3103 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3104 .need_dac_fix = 1,
ae6b813a
TI
3105 .input_mux = &alc880_lg_capture_source,
3106 .unsol_event = alc880_lg_unsol_event,
3107 .init_hook = alc880_lg_automute,
cb53c626
TI
3108#ifdef CONFIG_SND_HDA_POWER_SAVE
3109 .loopbacks = alc880_lg_loopbacks,
3110#endif
ae6b813a 3111 },
d681518a
TI
3112 [ALC880_LG_LW] = {
3113 .mixers = { alc880_lg_lw_mixer },
3114 .init_verbs = { alc880_volume_init_verbs,
3115 alc880_lg_lw_init_verbs },
0a8c5da3 3116 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3117 .dac_nids = alc880_dac_nids,
3118 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3119 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3120 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3121 .input_mux = &alc880_lg_lw_capture_source,
3122 .unsol_event = alc880_lg_lw_unsol_event,
3123 .init_hook = alc880_lg_lw_automute,
3124 },
16ded525
TI
3125#ifdef CONFIG_SND_DEBUG
3126 [ALC880_TEST] = {
e9edcee0
TI
3127 .mixers = { alc880_test_mixer },
3128 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3129 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3130 .dac_nids = alc880_test_dac_nids,
3131 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3132 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3133 .channel_mode = alc880_test_modes,
3134 .input_mux = &alc880_test_capture_source,
3135 },
3136#endif
3137};
3138
e9edcee0
TI
3139/*
3140 * Automatic parse of I/O pins from the BIOS configuration
3141 */
3142
3143#define NUM_CONTROL_ALLOC 32
3144#define NUM_VERB_ALLOC 32
3145
3146enum {
3147 ALC_CTL_WIDGET_VOL,
3148 ALC_CTL_WIDGET_MUTE,
3149 ALC_CTL_BIND_MUTE,
3150};
c8b6bf9b 3151static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3152 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3153 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3154 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3155};
3156
3157/* add dynamic controls */
f12ab1e0
TI
3158static int add_control(struct alc_spec *spec, int type, const char *name,
3159 unsigned long val)
e9edcee0 3160{
c8b6bf9b 3161 struct snd_kcontrol_new *knew;
e9edcee0
TI
3162
3163 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3164 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3165
f12ab1e0
TI
3166 /* array + terminator */
3167 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3168 if (!knew)
e9edcee0
TI
3169 return -ENOMEM;
3170 if (spec->kctl_alloc) {
f12ab1e0
TI
3171 memcpy(knew, spec->kctl_alloc,
3172 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3173 kfree(spec->kctl_alloc);
3174 }
3175 spec->kctl_alloc = knew;
3176 spec->num_kctl_alloc = num;
3177 }
3178
3179 knew = &spec->kctl_alloc[spec->num_kctl_used];
3180 *knew = alc880_control_templates[type];
543537bd 3181 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3182 if (!knew->name)
e9edcee0
TI
3183 return -ENOMEM;
3184 knew->private_value = val;
3185 spec->num_kctl_used++;
3186 return 0;
3187}
3188
3189#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3190#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3191#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3192#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3193#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3194#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3195#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3196#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3197#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3198#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3199#define ALC880_PIN_CD_NID 0x1c
3200
3201/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3202static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3203 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3204{
3205 hda_nid_t nid;
3206 int assigned[4];
3207 int i, j;
3208
3209 memset(assigned, 0, sizeof(assigned));
b0af0de5 3210 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3211
3212 /* check the pins hardwired to audio widget */
3213 for (i = 0; i < cfg->line_outs; i++) {
3214 nid = cfg->line_out_pins[i];
3215 if (alc880_is_fixed_pin(nid)) {
3216 int idx = alc880_fixed_pin_idx(nid);
5014f193 3217 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3218 assigned[idx] = 1;
3219 }
3220 }
3221 /* left pins can be connect to any audio widget */
3222 for (i = 0; i < cfg->line_outs; i++) {
3223 nid = cfg->line_out_pins[i];
3224 if (alc880_is_fixed_pin(nid))
3225 continue;
3226 /* search for an empty channel */
3227 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3228 if (!assigned[j]) {
3229 spec->multiout.dac_nids[i] =
3230 alc880_idx_to_dac(j);
e9edcee0
TI
3231 assigned[j] = 1;
3232 break;
3233 }
3234 }
3235 }
3236 spec->multiout.num_dacs = cfg->line_outs;
3237 return 0;
3238}
3239
3240/* add playback controls from the parsed DAC table */
df694daa
KY
3241static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3242 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3243{
3244 char name[32];
f12ab1e0
TI
3245 static const char *chname[4] = {
3246 "Front", "Surround", NULL /*CLFE*/, "Side"
3247 };
e9edcee0
TI
3248 hda_nid_t nid;
3249 int i, err;
3250
3251 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3252 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3253 continue;
3254 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3255 if (i == 2) {
3256 /* Center/LFE */
f12ab1e0
TI
3257 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3258 "Center Playback Volume",
3259 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3260 HDA_OUTPUT));
3261 if (err < 0)
e9edcee0 3262 return err;
f12ab1e0
TI
3263 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3264 "LFE Playback Volume",
3265 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3266 HDA_OUTPUT));
3267 if (err < 0)
e9edcee0 3268 return err;
f12ab1e0
TI
3269 err = add_control(spec, ALC_CTL_BIND_MUTE,
3270 "Center Playback Switch",
3271 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3272 HDA_INPUT));
3273 if (err < 0)
e9edcee0 3274 return err;
f12ab1e0
TI
3275 err = add_control(spec, ALC_CTL_BIND_MUTE,
3276 "LFE Playback Switch",
3277 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3278 HDA_INPUT));
3279 if (err < 0)
e9edcee0
TI
3280 return err;
3281 } else {
3282 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3283 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3284 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3285 HDA_OUTPUT));
3286 if (err < 0)
e9edcee0
TI
3287 return err;
3288 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3289 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3290 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3291 HDA_INPUT));
3292 if (err < 0)
e9edcee0
TI
3293 return err;
3294 }
3295 }
e9edcee0
TI
3296 return 0;
3297}
3298
8d88bc3d
TI
3299/* add playback controls for speaker and HP outputs */
3300static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3301 const char *pfx)
e9edcee0
TI
3302{
3303 hda_nid_t nid;
3304 int err;
8d88bc3d 3305 char name[32];
e9edcee0 3306
f12ab1e0 3307 if (!pin)
e9edcee0
TI
3308 return 0;
3309
3310 if (alc880_is_fixed_pin(pin)) {
3311 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3312 /* specify the DAC as the extra output */
f12ab1e0 3313 if (!spec->multiout.hp_nid)
e9edcee0 3314 spec->multiout.hp_nid = nid;
82bc955f
TI
3315 else
3316 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3317 /* control HP volume/switch on the output mixer amp */
3318 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3319 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3320 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3321 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3322 if (err < 0)
e9edcee0 3323 return err;
8d88bc3d 3324 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3325 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3326 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3327 if (err < 0)
e9edcee0
TI
3328 return err;
3329 } else if (alc880_is_multi_pin(pin)) {
3330 /* set manual connection */
e9edcee0 3331 /* we have only a switch on HP-out PIN */
8d88bc3d 3332 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3333 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3334 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3335 if (err < 0)
e9edcee0
TI
3336 return err;
3337 }
3338 return 0;
3339}
3340
3341/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3342static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3343 const char *ctlname,
df694daa 3344 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3345{
3346 char name[32];
df694daa 3347 int err;
e9edcee0
TI
3348
3349 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3350 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3351 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3352 if (err < 0)
e9edcee0
TI
3353 return err;
3354 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3355 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3356 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3357 if (err < 0)
e9edcee0
TI
3358 return err;
3359 return 0;
3360}
3361
3362/* create playback/capture controls for input pins */
df694daa
KY
3363static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3364 const struct auto_pin_cfg *cfg)
e9edcee0 3365{
e9edcee0 3366 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3367 int i, err, idx;
e9edcee0
TI
3368
3369 for (i = 0; i < AUTO_PIN_LAST; i++) {
3370 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3371 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3372 err = new_analog_input(spec, cfg->input_pins[i],
3373 auto_pin_cfg_labels[i],
df694daa 3374 idx, 0x0b);
e9edcee0
TI
3375 if (err < 0)
3376 return err;
f12ab1e0
TI
3377 imux->items[imux->num_items].label =
3378 auto_pin_cfg_labels[i];
3379 imux->items[imux->num_items].index =
3380 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3381 imux->num_items++;
3382 }
3383 }
3384 return 0;
3385}
3386
df694daa
KY
3387static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3388 hda_nid_t nid, int pin_type,
e9edcee0
TI
3389 int dac_idx)
3390{
3391 /* set as output */
f12ab1e0
TI
3392 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3393 pin_type);
3394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3395 AMP_OUT_UNMUTE);
e9edcee0
TI
3396 /* need the manual connection? */
3397 if (alc880_is_multi_pin(nid)) {
3398 struct alc_spec *spec = codec->spec;
3399 int idx = alc880_multi_pin_idx(nid);
3400 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3401 AC_VERB_SET_CONNECT_SEL,
3402 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3403 }
3404}
3405
baba8ee9
TI
3406static int get_pin_type(int line_out_type)
3407{
3408 if (line_out_type == AUTO_PIN_HP_OUT)
3409 return PIN_HP;
3410 else
3411 return PIN_OUT;
3412}
3413
e9edcee0
TI
3414static void alc880_auto_init_multi_out(struct hda_codec *codec)
3415{
3416 struct alc_spec *spec = codec->spec;
3417 int i;
bc9f98a9
KY
3418
3419 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3420 for (i = 0; i < spec->autocfg.line_outs; i++) {
3421 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3422 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3423 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3424 }
3425}
3426
8d88bc3d 3427static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3428{
3429 struct alc_spec *spec = codec->spec;
3430 hda_nid_t pin;
3431
82bc955f 3432 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3433 if (pin) /* connect to front */
3434 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3435 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3436 if (pin) /* connect to front */
3437 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3438}
3439
3440static void alc880_auto_init_analog_input(struct hda_codec *codec)
3441{
3442 struct alc_spec *spec = codec->spec;
3443 int i;
3444
3445 for (i = 0; i < AUTO_PIN_LAST; i++) {
3446 hda_nid_t nid = spec->autocfg.input_pins[i];
3447 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3448 snd_hda_codec_write(codec, nid, 0,
3449 AC_VERB_SET_PIN_WIDGET_CONTROL,
3450 i <= AUTO_PIN_FRONT_MIC ?
3451 PIN_VREF80 : PIN_IN);
e9edcee0 3452 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3453 snd_hda_codec_write(codec, nid, 0,
3454 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3455 AMP_OUT_MUTE);
3456 }
3457 }
3458}
3459
3460/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3461/* return 1 if successful, 0 if the proper config is not found,
3462 * or a negative error code
3463 */
e9edcee0
TI
3464static int alc880_parse_auto_config(struct hda_codec *codec)
3465{
3466 struct alc_spec *spec = codec->spec;
3467 int err;
df694daa 3468 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3469
f12ab1e0
TI
3470 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3471 alc880_ignore);
3472 if (err < 0)
e9edcee0 3473 return err;
f12ab1e0 3474 if (!spec->autocfg.line_outs)
e9edcee0 3475 return 0; /* can't find valid BIOS pin config */
df694daa 3476
f12ab1e0
TI
3477 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3478 if (err < 0)
3479 return err;
3480 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3481 if (err < 0)
3482 return err;
3483 err = alc880_auto_create_extra_out(spec,
3484 spec->autocfg.speaker_pins[0],
3485 "Speaker");
3486 if (err < 0)
3487 return err;
3488 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3489 "Headphone");
3490 if (err < 0)
3491 return err;
3492 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3493 if (err < 0)
e9edcee0
TI
3494 return err;
3495
3496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3497
3498 if (spec->autocfg.dig_out_pin)
3499 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3500 if (spec->autocfg.dig_in_pin)
3501 spec->dig_in_nid = ALC880_DIGIN_NID;
3502
3503 if (spec->kctl_alloc)
3504 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3505
3506 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3507
a1e8d2da 3508 spec->num_mux_defs = 1;
e9edcee0
TI
3509 spec->input_mux = &spec->private_imux;
3510
3511 return 1;
3512}
3513
ae6b813a
TI
3514/* additional initialization for auto-configuration model */
3515static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3516{
e9edcee0 3517 alc880_auto_init_multi_out(codec);
8d88bc3d 3518 alc880_auto_init_extra_out(codec);
e9edcee0 3519 alc880_auto_init_analog_input(codec);
e9edcee0
TI
3520}
3521
3522/*
3523 * OK, here we have finally the patch for ALC880
3524 */
3525
1da177e4
LT
3526static int patch_alc880(struct hda_codec *codec)
3527{
3528 struct alc_spec *spec;
3529 int board_config;
df694daa 3530 int err;
1da177e4 3531
e560d8d8 3532 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3533 if (spec == NULL)
3534 return -ENOMEM;
3535
3536 codec->spec = spec;
3537
f5fcc13c
TI
3538 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3539 alc880_models,
3540 alc880_cfg_tbl);
3541 if (board_config < 0) {
9c7f852e
TI
3542 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3543 "trying auto-probe from BIOS...\n");
e9edcee0 3544 board_config = ALC880_AUTO;
1da177e4 3545 }
1da177e4 3546
e9edcee0
TI
3547 if (board_config == ALC880_AUTO) {
3548 /* automatic parse from the BIOS config */
3549 err = alc880_parse_auto_config(codec);
3550 if (err < 0) {
3551 alc_free(codec);
3552 return err;
f12ab1e0 3553 } else if (!err) {
9c7f852e
TI
3554 printk(KERN_INFO
3555 "hda_codec: Cannot set up configuration "
3556 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3557 board_config = ALC880_3ST;
3558 }
1da177e4
LT
3559 }
3560
df694daa
KY
3561 if (board_config != ALC880_AUTO)
3562 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3563
3564 spec->stream_name_analog = "ALC880 Analog";
3565 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3566 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3567
3568 spec->stream_name_digital = "ALC880 Digital";
3569 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3570 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3571
f12ab1e0 3572 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3573 /* check whether NID 0x07 is valid */
54d17403 3574 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3575 /* get type */
3576 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3577 if (wcap != AC_WID_AUD_IN) {
3578 spec->adc_nids = alc880_adc_nids_alt;
3579 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3580 spec->mixers[spec->num_mixers] =
3581 alc880_capture_alt_mixer;
e9edcee0
TI
3582 spec->num_mixers++;
3583 } else {
3584 spec->adc_nids = alc880_adc_nids;
3585 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3586 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3587 spec->num_mixers++;
3588 }
3589 }
1da177e4
LT
3590
3591 codec->patch_ops = alc_patch_ops;
e9edcee0 3592 if (board_config == ALC880_AUTO)
ae6b813a 3593 spec->init_hook = alc880_auto_init;
cb53c626
TI
3594#ifdef CONFIG_SND_HDA_POWER_SAVE
3595 if (!spec->loopback.amplist)
3596 spec->loopback.amplist = alc880_loopbacks;
3597#endif
1da177e4
LT
3598
3599 return 0;
3600}
3601
e9edcee0 3602
1da177e4
LT
3603/*
3604 * ALC260 support
3605 */
3606
e9edcee0
TI
3607static hda_nid_t alc260_dac_nids[1] = {
3608 /* front */
3609 0x02,
3610};
3611
3612static hda_nid_t alc260_adc_nids[1] = {
3613 /* ADC0 */
3614 0x04,
3615};
3616
df694daa 3617static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3618 /* ADC1 */
3619 0x05,
3620};
3621
df694daa
KY
3622static hda_nid_t alc260_hp_adc_nids[2] = {
3623 /* ADC1, 0 */
3624 0x05, 0x04
3625};
3626
d57fdac0
JW
3627/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3628 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3629 */
3630static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3631 /* ADC0, ADC1 */
3632 0x04, 0x05
3633};
3634
e9edcee0
TI
3635#define ALC260_DIGOUT_NID 0x03
3636#define ALC260_DIGIN_NID 0x06
3637
3638static struct hda_input_mux alc260_capture_source = {
3639 .num_items = 4,
3640 .items = {
3641 { "Mic", 0x0 },
3642 { "Front Mic", 0x1 },
3643 { "Line", 0x2 },
3644 { "CD", 0x4 },
3645 },
3646};
3647
17e7aec6 3648/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3649 * headphone jack and the internal CD lines since these are the only pins at
3650 * which audio can appear. For flexibility, also allow the option of
3651 * recording the mixer output on the second ADC (ADC0 doesn't have a
3652 * connection to the mixer output).
a9430dd8 3653 */
a1e8d2da
JW
3654static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3655 {
3656 .num_items = 3,
3657 .items = {
3658 { "Mic/Line", 0x0 },
3659 { "CD", 0x4 },
3660 { "Headphone", 0x2 },
3661 },
a9430dd8 3662 },
a1e8d2da
JW
3663 {
3664 .num_items = 4,
3665 .items = {
3666 { "Mic/Line", 0x0 },
3667 { "CD", 0x4 },
3668 { "Headphone", 0x2 },
3669 { "Mixer", 0x5 },
3670 },
3671 },
3672
a9430dd8
JW
3673};
3674
a1e8d2da
JW
3675/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3676 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3677 */
a1e8d2da
JW
3678static struct hda_input_mux alc260_acer_capture_sources[2] = {
3679 {
3680 .num_items = 4,
3681 .items = {
3682 { "Mic", 0x0 },
3683 { "Line", 0x2 },
3684 { "CD", 0x4 },
3685 { "Headphone", 0x5 },
3686 },
3687 },
3688 {
3689 .num_items = 5,
3690 .items = {
3691 { "Mic", 0x0 },
3692 { "Line", 0x2 },
3693 { "CD", 0x4 },
3694 { "Headphone", 0x6 },
3695 { "Mixer", 0x5 },
3696 },
0bfc90e9
JW
3697 },
3698};
1da177e4
LT
3699/*
3700 * This is just place-holder, so there's something for alc_build_pcms to look
3701 * at when it calculates the maximum number of channels. ALC260 has no mixer
3702 * element which allows changing the channel mode, so the verb list is
3703 * never used.
3704 */
d2a6d7dc 3705static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3706 { 2, NULL },
3707};
3708
df694daa
KY
3709
3710/* Mixer combinations
3711 *
3712 * basic: base_output + input + pc_beep + capture
3713 * HP: base_output + input + capture_alt
3714 * HP_3013: hp_3013 + input + capture
3715 * fujitsu: fujitsu + capture
0bfc90e9 3716 * acer: acer + capture
df694daa
KY
3717 */
3718
3719static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3720 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3721 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3723 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3724 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3725 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3726 { } /* end */
f12ab1e0 3727};
1da177e4 3728
df694daa 3729static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3730 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3731 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3732 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3733 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3735 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3738 { } /* end */
3739};
3740
3741static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3742 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3743 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3744 { } /* end */
3745};
3746
3747static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3748 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3749 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3750 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3751 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3752 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3754 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3755 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3756 { } /* end */
3757};
3758
a1e8d2da
JW
3759/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3760 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3761 */
c8b6bf9b 3762static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3763 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3764 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3765 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3766 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3767 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3768 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3769 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 3770 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
3771 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3772 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3773 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3774 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
3775 { } /* end */
3776};
3777
a1e8d2da
JW
3778/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3779 * versions of the ALC260 don't act on requests to enable mic bias from NID
3780 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3781 * datasheet doesn't mention this restriction. At this stage it's not clear
3782 * whether this behaviour is intentional or is a hardware bug in chip
3783 * revisions available in early 2006. Therefore for now allow the
3784 * "Headphone Jack Mode" control to span all choices, but if it turns out
3785 * that the lack of mic bias for this NID is intentional we could change the
3786 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3787 *
3788 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3789 * don't appear to make the mic bias available from the "line" jack, even
3790 * though the NID used for this jack (0x14) can supply it. The theory is
3791 * that perhaps Acer have included blocking capacitors between the ALC260
3792 * and the output jack. If this turns out to be the case for all such
3793 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3794 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
3795 *
3796 * The C20x Tablet series have a mono internal speaker which is controlled
3797 * via the chip's Mono sum widget and pin complex, so include the necessary
3798 * controls for such models. On models without a "mono speaker" the control
3799 * won't do anything.
a1e8d2da 3800 */
0bfc90e9
JW
3801static struct snd_kcontrol_new alc260_acer_mixer[] = {
3802 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3803 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 3804 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
bd869485
JW
3805 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3806 HDA_OUTPUT),
3807 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3808 HDA_INPUT),
0bfc90e9
JW
3809 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3810 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3812 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3813 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3814 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3815 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3816 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3817 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3818 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3819 { } /* end */
3820};
3821
bc9f98a9
KY
3822/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3823 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
3824 */
3825static struct snd_kcontrol_new alc260_will_mixer[] = {
3826 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3827 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3829 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3830 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3831 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3832 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3833 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3834 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3835 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3836 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3837 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3838 { } /* end */
3839};
3840
3841/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3842 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3843 */
3844static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3845 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3846 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3848 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3849 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3850 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3851 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3852 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3853 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3854 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3855 { } /* end */
3856};
3857
df694daa
KY
3858/* capture mixer elements */
3859static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
3860 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3861 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
3862 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3863 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
3864 {
3865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
3866 /* The multiple "Capture Source" controls confuse alsamixer
3867 * So call somewhat different..
3868 * FIXME: the controls appear in the "playback" view!
3869 */
3870 /* .name = "Capture Source", */
3871 .name = "Input Source",
3872 .count = 2,
3873 .info = alc_mux_enum_info,
3874 .get = alc_mux_enum_get,
3875 .put = alc_mux_enum_put,
3876 },
3877 { } /* end */
3878};
3879
3880static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3881 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3882 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3883 {
3884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3885 /* The multiple "Capture Source" controls confuse alsamixer
3886 * So call somewhat different..
3887 * FIXME: the controls appear in the "playback" view!
3888 */
3889 /* .name = "Capture Source", */
3890 .name = "Input Source",
3891 .count = 1,
a9430dd8
JW
3892 .info = alc_mux_enum_info,
3893 .get = alc_mux_enum_get,
3894 .put = alc_mux_enum_put,
3895 },
3896 { } /* end */
3897};
3898
df694daa
KY
3899/*
3900 * initialization verbs
3901 */
1da177e4
LT
3902static struct hda_verb alc260_init_verbs[] = {
3903 /* Line In pin widget for input */
05acb863 3904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3905 /* CD pin widget for input */
05acb863 3906 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3907 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 3908 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 3909 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 3910 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 3911 /* LINE-2 is used for line-out in rear */
05acb863 3912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 3913 /* select line-out */
fd56f2db 3914 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 3915 /* LINE-OUT pin */
05acb863 3916 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 3917 /* enable HP */
05acb863 3918 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 3919 /* enable Mono */
05acb863
TI
3920 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3921 /* mute capture amp left and right */
16ded525 3922 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
3923 /* set connection select to line in (default select for this ADC) */
3924 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
3925 /* mute capture amp left and right */
3926 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3927 /* set connection select to line in (default select for this ADC) */
3928 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
3929 /* set vol=0 Line-Out mixer amp left and right */
3930 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3931 /* unmute pin widget amp left and right (no gain on this amp) */
3932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3933 /* set vol=0 HP mixer amp left and right */
3934 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3935 /* unmute pin widget amp left and right (no gain on this amp) */
3936 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3937 /* set vol=0 Mono mixer amp left and right */
3938 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3939 /* unmute pin widget amp left and right (no gain on this amp) */
3940 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3941 /* unmute LINE-2 out pin */
3942 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
3943 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3944 * Line In 2 = 0x03
3945 */
cb53c626
TI
3946 /* mute analog inputs */
3947 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3950 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 3952 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
3953 /* mute Front out path */
3954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3956 /* mute Headphone out path */
3957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3959 /* mute Mono out path */
3960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3961 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3962 { }
3963};
3964
474167d6 3965#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
3966static struct hda_verb alc260_hp_init_verbs[] = {
3967 /* Headphone and output */
3968 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3969 /* mono output */
3970 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3971 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3972 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3973 /* Mic2 (front panel) pin widget for input and vref at 80% */
3974 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3975 /* Line In pin widget for input */
3976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3977 /* Line-2 pin widget for output */
3978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3979 /* CD pin widget for input */
3980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3981 /* unmute amp left and right */
3982 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3983 /* set connection select to line in (default select for this ADC) */
3984 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3985 /* unmute Line-Out mixer amp left and right (volume = 0) */
3986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3987 /* mute pin widget amp left and right (no gain on this amp) */
3988 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3989 /* unmute HP mixer amp left and right (volume = 0) */
3990 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3991 /* mute pin widget amp left and right (no gain on this amp) */
3992 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
3993 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3994 * Line In 2 = 0x03
3995 */
cb53c626
TI
3996 /* mute analog inputs */
3997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4000 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4001 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4002 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4003 /* Unmute Front out path */
4004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4006 /* Unmute Headphone out path */
4007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4009 /* Unmute Mono out path */
4010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4011 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4012 { }
4013};
474167d6 4014#endif
df694daa
KY
4015
4016static struct hda_verb alc260_hp_3013_init_verbs[] = {
4017 /* Line out and output */
4018 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4019 /* mono output */
4020 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4021 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4022 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4023 /* Mic2 (front panel) pin widget for input and vref at 80% */
4024 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4025 /* Line In pin widget for input */
4026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4027 /* Headphone pin widget for output */
4028 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4029 /* CD pin widget for input */
4030 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4031 /* unmute amp left and right */
4032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4033 /* set connection select to line in (default select for this ADC) */
4034 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4035 /* unmute Line-Out mixer amp left and right (volume = 0) */
4036 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4037 /* mute pin widget amp left and right (no gain on this amp) */
4038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4039 /* unmute HP mixer amp left and right (volume = 0) */
4040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4041 /* mute pin widget amp left and right (no gain on this amp) */
4042 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4043 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4044 * Line In 2 = 0x03
4045 */
cb53c626
TI
4046 /* mute analog inputs */
4047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4048 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4052 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4053 /* Unmute Front out path */
4054 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4055 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4056 /* Unmute Headphone out path */
4057 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4059 /* Unmute Mono out path */
4060 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4061 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4062 { }
4063};
4064
a9430dd8 4065/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4066 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4067 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4068 */
4069static struct hda_verb alc260_fujitsu_init_verbs[] = {
4070 /* Disable all GPIOs */
4071 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4072 /* Internal speaker is connected to headphone pin */
4073 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4074 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4075 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4076 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4078 /* Ensure all other unused pins are disabled and muted. */
4079 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4080 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4081 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4082 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4083 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4084 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4085 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4086 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4087
4088 /* Disable digital (SPDIF) pins */
4089 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4090 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4091
f7ace40d
JW
4092 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4093 * when acting as an output.
4094 */
4095 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4096
f7ace40d 4097 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4098 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4099 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4101 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4104 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4105 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4106 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4107
f7ace40d
JW
4108 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4109 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4110 /* Unmute Line1 pin widget output buffer since it starts as an output.
4111 * If the pin mode is changed by the user the pin mode control will
4112 * take care of enabling the pin's input/output buffers as needed.
4113 * Therefore there's no need to enable the input buffer at this
4114 * stage.
cdcd9268 4115 */
f7ace40d 4116 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4117 /* Unmute input buffer of pin widget used for Line-in (no equiv
4118 * mixer ctrl)
4119 */
f7ace40d
JW
4120 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4121
4122 /* Mute capture amp left and right */
4123 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4124 /* Set ADC connection select to match default mixer setting - line
4125 * in (on mic1 pin)
4126 */
4127 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4128
4129 /* Do the same for the second ADC: mute capture input amp and
4130 * set ADC connection to line in (on mic1 pin)
4131 */
4132 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4133 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4134
4135 /* Mute all inputs to mixer widget (even unconnected ones) */
4136 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4138 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4141 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4143 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4144
4145 { }
a9430dd8
JW
4146};
4147
0bfc90e9
JW
4148/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4149 * similar laptops (adapted from Fujitsu init verbs).
4150 */
4151static struct hda_verb alc260_acer_init_verbs[] = {
4152 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4153 * the headphone jack. Turn this on and rely on the standard mute
4154 * methods whenever the user wants to turn these outputs off.
4155 */
4156 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4157 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4158 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4159 /* Internal speaker/Headphone jack is connected to Line-out pin */
4160 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4161 /* Internal microphone/Mic jack is connected to Mic1 pin */
4162 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4163 /* Line In jack is connected to Line1 pin */
4164 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4165 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4166 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4167 /* Ensure all other unused pins are disabled and muted. */
4168 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4170 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4171 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4172 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4173 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 /* Disable digital (SPDIF) pins */
4175 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4176 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4177
4178 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4179 * bus when acting as outputs.
4180 */
4181 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4182 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4183
4184 /* Start with output sum widgets muted and their output gains at min */
4185 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4186 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4187 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4188 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4189 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4191 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4192 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4193 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4194
f12ab1e0
TI
4195 /* Unmute Line-out pin widget amp left and right
4196 * (no equiv mixer ctrl)
4197 */
0bfc90e9 4198 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4199 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4200 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4201 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4202 * inputs. If the pin mode is changed by the user the pin mode control
4203 * will take care of enabling the pin's input/output buffers as needed.
4204 * Therefore there's no need to enable the input buffer at this
4205 * stage.
4206 */
4207 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4209
4210 /* Mute capture amp left and right */
4211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4212 /* Set ADC connection select to match default mixer setting - mic
4213 * (on mic1 pin)
4214 */
4215 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4216
4217 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4218 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4219 */
4220 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4221 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4222
4223 /* Mute all inputs to mixer widget (even unconnected ones) */
4224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4229 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4232
4233 { }
4234};
4235
bc9f98a9
KY
4236static struct hda_verb alc260_will_verbs[] = {
4237 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4238 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4239 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4240 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4241 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4242 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4243 {}
4244};
4245
4246static struct hda_verb alc260_replacer_672v_verbs[] = {
4247 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4248 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4249 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4250
4251 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4252 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4253 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4254
4255 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4256 {}
4257};
4258
4259/* toggle speaker-output according to the hp-jack state */
4260static void alc260_replacer_672v_automute(struct hda_codec *codec)
4261{
4262 unsigned int present;
4263
4264 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4265 present = snd_hda_codec_read(codec, 0x0f, 0,
4266 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4267 if (present) {
82beb8fd
TI
4268 snd_hda_codec_write_cache(codec, 0x01, 0,
4269 AC_VERB_SET_GPIO_DATA, 1);
4270 snd_hda_codec_write_cache(codec, 0x0f, 0,
4271 AC_VERB_SET_PIN_WIDGET_CONTROL,
4272 PIN_HP);
bc9f98a9 4273 } else {
82beb8fd
TI
4274 snd_hda_codec_write_cache(codec, 0x01, 0,
4275 AC_VERB_SET_GPIO_DATA, 0);
4276 snd_hda_codec_write_cache(codec, 0x0f, 0,
4277 AC_VERB_SET_PIN_WIDGET_CONTROL,
4278 PIN_OUT);
bc9f98a9
KY
4279 }
4280}
4281
4282static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4283 unsigned int res)
4284{
4285 if ((res >> 26) == ALC880_HP_EVENT)
4286 alc260_replacer_672v_automute(codec);
4287}
4288
7cf51e48
JW
4289/* Test configuration for debugging, modelled after the ALC880 test
4290 * configuration.
4291 */
4292#ifdef CONFIG_SND_DEBUG
4293static hda_nid_t alc260_test_dac_nids[1] = {
4294 0x02,
4295};
4296static hda_nid_t alc260_test_adc_nids[2] = {
4297 0x04, 0x05,
4298};
a1e8d2da
JW
4299/* For testing the ALC260, each input MUX needs its own definition since
4300 * the signal assignments are different. This assumes that the first ADC
4301 * is NID 0x04.
17e7aec6 4302 */
a1e8d2da
JW
4303static struct hda_input_mux alc260_test_capture_sources[2] = {
4304 {
4305 .num_items = 7,
4306 .items = {
4307 { "MIC1 pin", 0x0 },
4308 { "MIC2 pin", 0x1 },
4309 { "LINE1 pin", 0x2 },
4310 { "LINE2 pin", 0x3 },
4311 { "CD pin", 0x4 },
4312 { "LINE-OUT pin", 0x5 },
4313 { "HP-OUT pin", 0x6 },
4314 },
4315 },
4316 {
4317 .num_items = 8,
4318 .items = {
4319 { "MIC1 pin", 0x0 },
4320 { "MIC2 pin", 0x1 },
4321 { "LINE1 pin", 0x2 },
4322 { "LINE2 pin", 0x3 },
4323 { "CD pin", 0x4 },
4324 { "Mixer", 0x5 },
4325 { "LINE-OUT pin", 0x6 },
4326 { "HP-OUT pin", 0x7 },
4327 },
7cf51e48
JW
4328 },
4329};
4330static struct snd_kcontrol_new alc260_test_mixer[] = {
4331 /* Output driver widgets */
4332 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4333 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4334 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4335 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4336 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4337 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4338
a1e8d2da
JW
4339 /* Modes for retasking pin widgets
4340 * Note: the ALC260 doesn't seem to act on requests to enable mic
4341 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4342 * mention this restriction. At this stage it's not clear whether
4343 * this behaviour is intentional or is a hardware bug in chip
4344 * revisions available at least up until early 2006. Therefore for
4345 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4346 * choices, but if it turns out that the lack of mic bias for these
4347 * NIDs is intentional we could change their modes from
4348 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4349 */
7cf51e48
JW
4350 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4351 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4352 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4353 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4354 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4355 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4356
4357 /* Loopback mixer controls */
4358 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4359 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4360 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4361 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4362 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4363 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4364 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4365 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4366 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4367 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4368 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4369 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4370 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4371 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4372 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4373 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4374
4375 /* Controls for GPIO pins, assuming they are configured as outputs */
4376 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4377 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4378 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4379 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4380
92621f13
JW
4381 /* Switches to allow the digital IO pins to be enabled. The datasheet
4382 * is ambigious as to which NID is which; testing on laptops which
4383 * make this output available should provide clarification.
4384 */
4385 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4386 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4387
f8225f6d
JW
4388 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4389 * this output to turn on an external amplifier.
4390 */
4391 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4392 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4393
7cf51e48
JW
4394 { } /* end */
4395};
4396static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4397 /* Enable all GPIOs as outputs with an initial value of 0 */
4398 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4399 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4400 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4401
7cf51e48
JW
4402 /* Enable retasking pins as output, initially without power amp */
4403 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4404 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4407 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4408 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4409
92621f13
JW
4410 /* Disable digital (SPDIF) pins initially, but users can enable
4411 * them via a mixer switch. In the case of SPDIF-out, this initverb
4412 * payload also sets the generation to 0, output to be in "consumer"
4413 * PCM format, copyright asserted, no pre-emphasis and no validity
4414 * control.
4415 */
7cf51e48
JW
4416 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4417 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4418
f7ace40d 4419 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4420 * OUT1 sum bus when acting as an output.
4421 */
4422 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4423 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4424 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4425 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4426
4427 /* Start with output sum widgets muted and their output gains at min */
4428 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4433 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4434 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4435 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4436 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4437
cdcd9268
JW
4438 /* Unmute retasking pin widget output buffers since the default
4439 * state appears to be output. As the pin mode is changed by the
4440 * user the pin mode control will take care of enabling the pin's
4441 * input/output buffers as needed.
4442 */
7cf51e48
JW
4443 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4444 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4446 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4447 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4448 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4449 /* Also unmute the mono-out pin widget */
4450 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4451
7cf51e48
JW
4452 /* Mute capture amp left and right */
4453 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4454 /* Set ADC connection select to match default mixer setting (mic1
4455 * pin)
7cf51e48
JW
4456 */
4457 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4458
4459 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4460 * set ADC connection to mic1 pin
7cf51e48
JW
4461 */
4462 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4463 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4464
4465 /* Mute all inputs to mixer widget (even unconnected ones) */
4466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4470 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4471 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4472 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4474
4475 { }
4476};
4477#endif
4478
1da177e4
LT
4479static struct hda_pcm_stream alc260_pcm_analog_playback = {
4480 .substreams = 1,
4481 .channels_min = 2,
4482 .channels_max = 2,
1da177e4
LT
4483};
4484
4485static struct hda_pcm_stream alc260_pcm_analog_capture = {
4486 .substreams = 1,
4487 .channels_min = 2,
4488 .channels_max = 2,
1da177e4
LT
4489};
4490
a3bcba38
TI
4491#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4492#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4493
df694daa
KY
4494/*
4495 * for BIOS auto-configuration
4496 */
16ded525 4497
df694daa
KY
4498static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4499 const char *pfx)
4500{
4501 hda_nid_t nid_vol;
4502 unsigned long vol_val, sw_val;
4503 char name[32];
4504 int err;
4505
4506 if (nid >= 0x0f && nid < 0x11) {
4507 nid_vol = nid - 0x7;
4508 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4509 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4510 } else if (nid == 0x11) {
4511 nid_vol = nid - 0x7;
4512 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4513 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4514 } else if (nid >= 0x12 && nid <= 0x15) {
4515 nid_vol = 0x08;
4516 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4517 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4518 } else
4519 return 0; /* N/A */
4520
4521 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4522 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4523 if (err < 0)
df694daa
KY
4524 return err;
4525 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4526 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4527 if (err < 0)
df694daa
KY
4528 return err;
4529 return 1;
4530}
4531
4532/* add playback controls from the parsed DAC table */
4533static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4534 const struct auto_pin_cfg *cfg)
4535{
4536 hda_nid_t nid;
4537 int err;
4538
4539 spec->multiout.num_dacs = 1;
4540 spec->multiout.dac_nids = spec->private_dac_nids;
4541 spec->multiout.dac_nids[0] = 0x02;
4542
4543 nid = cfg->line_out_pins[0];
4544 if (nid) {
4545 err = alc260_add_playback_controls(spec, nid, "Front");
4546 if (err < 0)
4547 return err;
4548 }
4549
82bc955f 4550 nid = cfg->speaker_pins[0];
df694daa
KY
4551 if (nid) {
4552 err = alc260_add_playback_controls(spec, nid, "Speaker");
4553 if (err < 0)
4554 return err;
4555 }
4556
eb06ed8f 4557 nid = cfg->hp_pins[0];
df694daa
KY
4558 if (nid) {
4559 err = alc260_add_playback_controls(spec, nid, "Headphone");
4560 if (err < 0)
4561 return err;
4562 }
f12ab1e0 4563 return 0;
df694daa
KY
4564}
4565
4566/* create playback/capture controls for input pins */
4567static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4568 const struct auto_pin_cfg *cfg)
4569{
df694daa
KY
4570 struct hda_input_mux *imux = &spec->private_imux;
4571 int i, err, idx;
4572
4573 for (i = 0; i < AUTO_PIN_LAST; i++) {
4574 if (cfg->input_pins[i] >= 0x12) {
4575 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4576 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4577 auto_pin_cfg_labels[i], idx,
4578 0x07);
df694daa
KY
4579 if (err < 0)
4580 return err;
f12ab1e0
TI
4581 imux->items[imux->num_items].label =
4582 auto_pin_cfg_labels[i];
df694daa
KY
4583 imux->items[imux->num_items].index = idx;
4584 imux->num_items++;
4585 }
f12ab1e0 4586 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4587 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4588 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4589 auto_pin_cfg_labels[i], idx,
4590 0x07);
df694daa
KY
4591 if (err < 0)
4592 return err;
f12ab1e0
TI
4593 imux->items[imux->num_items].label =
4594 auto_pin_cfg_labels[i];
df694daa
KY
4595 imux->items[imux->num_items].index = idx;
4596 imux->num_items++;
4597 }
4598 }
4599 return 0;
4600}
4601
4602static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4603 hda_nid_t nid, int pin_type,
4604 int sel_idx)
4605{
4606 /* set as output */
f12ab1e0
TI
4607 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4608 pin_type);
4609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4610 AMP_OUT_UNMUTE);
df694daa
KY
4611 /* need the manual connection? */
4612 if (nid >= 0x12) {
4613 int idx = nid - 0x12;
4614 snd_hda_codec_write(codec, idx + 0x0b, 0,
4615 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4616 }
4617}
4618
4619static void alc260_auto_init_multi_out(struct hda_codec *codec)
4620{
4621 struct alc_spec *spec = codec->spec;
4622 hda_nid_t nid;
4623
bc9f98a9 4624 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4625 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4626 if (nid) {
4627 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4628 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4629 }
df694daa 4630
82bc955f 4631 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4632 if (nid)
4633 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4634
eb06ed8f 4635 nid = spec->autocfg.hp_pins[0];
df694daa 4636 if (nid)
baba8ee9 4637 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4638}
df694daa
KY
4639
4640#define ALC260_PIN_CD_NID 0x16
4641static void alc260_auto_init_analog_input(struct hda_codec *codec)
4642{
4643 struct alc_spec *spec = codec->spec;
4644 int i;
4645
4646 for (i = 0; i < AUTO_PIN_LAST; i++) {
4647 hda_nid_t nid = spec->autocfg.input_pins[i];
4648 if (nid >= 0x12) {
f12ab1e0
TI
4649 snd_hda_codec_write(codec, nid, 0,
4650 AC_VERB_SET_PIN_WIDGET_CONTROL,
4651 i <= AUTO_PIN_FRONT_MIC ?
4652 PIN_VREF80 : PIN_IN);
df694daa 4653 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4654 snd_hda_codec_write(codec, nid, 0,
4655 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4656 AMP_OUT_MUTE);
4657 }
4658 }
4659}
4660
4661/*
4662 * generic initialization of ADC, input mixers and output mixers
4663 */
4664static struct hda_verb alc260_volume_init_verbs[] = {
4665 /*
4666 * Unmute ADC0-1 and set the default input to mic-in
4667 */
4668 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4669 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4670 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4672
4673 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4674 * mixer widget
f12ab1e0
TI
4675 * Note: PASD motherboards uses the Line In 2 as the input for
4676 * front panel mic (mic 2)
df694daa
KY
4677 */
4678 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4679 /* mute analog inputs */
4680 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4684 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4685
4686 /*
4687 * Set up output mixers (0x08 - 0x0a)
4688 */
4689 /* set vol=0 to output mixers */
4690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4692 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4693 /* set up input amps for analog loopback */
4694 /* Amp Indices: DAC = 0, mixer = 1 */
4695 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4696 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4697 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4698 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4699 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4700 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4701
4702 { }
4703};
4704
4705static int alc260_parse_auto_config(struct hda_codec *codec)
4706{
4707 struct alc_spec *spec = codec->spec;
4708 unsigned int wcap;
4709 int err;
4710 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4711
f12ab1e0
TI
4712 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4713 alc260_ignore);
4714 if (err < 0)
df694daa 4715 return err;
f12ab1e0
TI
4716 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4717 if (err < 0)
4a471b7d 4718 return err;
f12ab1e0 4719 if (!spec->kctl_alloc)
df694daa 4720 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4721 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4722 if (err < 0)
df694daa
KY
4723 return err;
4724
4725 spec->multiout.max_channels = 2;
4726
4727 if (spec->autocfg.dig_out_pin)
4728 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4729 if (spec->kctl_alloc)
4730 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4731
4732 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4733
a1e8d2da 4734 spec->num_mux_defs = 1;
df694daa
KY
4735 spec->input_mux = &spec->private_imux;
4736
4737 /* check whether NID 0x04 is valid */
4a471b7d 4738 wcap = get_wcaps(codec, 0x04);
df694daa
KY
4739 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4740 if (wcap != AC_WID_AUD_IN) {
4741 spec->adc_nids = alc260_adc_nids_alt;
4742 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4743 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4744 } else {
4745 spec->adc_nids = alc260_adc_nids;
4746 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4747 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4748 }
4a471b7d 4749 spec->num_mixers++;
df694daa
KY
4750
4751 return 1;
4752}
4753
ae6b813a
TI
4754/* additional initialization for auto-configuration model */
4755static void alc260_auto_init(struct hda_codec *codec)
df694daa 4756{
df694daa
KY
4757 alc260_auto_init_multi_out(codec);
4758 alc260_auto_init_analog_input(codec);
df694daa
KY
4759}
4760
cb53c626
TI
4761#ifdef CONFIG_SND_HDA_POWER_SAVE
4762static struct hda_amp_list alc260_loopbacks[] = {
4763 { 0x07, HDA_INPUT, 0 },
4764 { 0x07, HDA_INPUT, 1 },
4765 { 0x07, HDA_INPUT, 2 },
4766 { 0x07, HDA_INPUT, 3 },
4767 { 0x07, HDA_INPUT, 4 },
4768 { } /* end */
4769};
4770#endif
4771
df694daa
KY
4772/*
4773 * ALC260 configurations
4774 */
f5fcc13c
TI
4775static const char *alc260_models[ALC260_MODEL_LAST] = {
4776 [ALC260_BASIC] = "basic",
4777 [ALC260_HP] = "hp",
4778 [ALC260_HP_3013] = "hp-3013",
4779 [ALC260_FUJITSU_S702X] = "fujitsu",
4780 [ALC260_ACER] = "acer",
bc9f98a9
KY
4781 [ALC260_WILL] = "will",
4782 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 4783#ifdef CONFIG_SND_DEBUG
f5fcc13c 4784 [ALC260_TEST] = "test",
7cf51e48 4785#endif
f5fcc13c
TI
4786 [ALC260_AUTO] = "auto",
4787};
4788
4789static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 4790 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 4791 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 4792 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 4793 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
4794 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4795 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4796 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4797 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4798 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4799 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4800 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4801 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4802 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4803 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4804 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4805 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 4806 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 4807 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
4808 {}
4809};
4810
4811static struct alc_config_preset alc260_presets[] = {
4812 [ALC260_BASIC] = {
4813 .mixers = { alc260_base_output_mixer,
4814 alc260_input_mixer,
4815 alc260_pc_beep_mixer,
4816 alc260_capture_mixer },
4817 .init_verbs = { alc260_init_verbs },
4818 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4819 .dac_nids = alc260_dac_nids,
4820 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4821 .adc_nids = alc260_adc_nids,
4822 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4823 .channel_mode = alc260_modes,
4824 .input_mux = &alc260_capture_source,
4825 },
4826 [ALC260_HP] = {
4827 .mixers = { alc260_base_output_mixer,
4828 alc260_input_mixer,
4829 alc260_capture_alt_mixer },
474167d6 4830 .init_verbs = { alc260_init_verbs },
df694daa
KY
4831 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4832 .dac_nids = alc260_dac_nids,
4833 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4834 .adc_nids = alc260_hp_adc_nids,
4835 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4836 .channel_mode = alc260_modes,
4837 .input_mux = &alc260_capture_source,
4838 },
4839 [ALC260_HP_3013] = {
4840 .mixers = { alc260_hp_3013_mixer,
4841 alc260_input_mixer,
4842 alc260_capture_alt_mixer },
4843 .init_verbs = { alc260_hp_3013_init_verbs },
4844 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4845 .dac_nids = alc260_dac_nids,
4846 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4847 .adc_nids = alc260_hp_adc_nids,
4848 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4849 .channel_mode = alc260_modes,
4850 .input_mux = &alc260_capture_source,
4851 },
4852 [ALC260_FUJITSU_S702X] = {
4853 .mixers = { alc260_fujitsu_mixer,
4854 alc260_capture_mixer },
4855 .init_verbs = { alc260_fujitsu_init_verbs },
4856 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4857 .dac_nids = alc260_dac_nids,
d57fdac0
JW
4858 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4859 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
4860 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4861 .channel_mode = alc260_modes,
a1e8d2da
JW
4862 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4863 .input_mux = alc260_fujitsu_capture_sources,
df694daa 4864 },
0bfc90e9
JW
4865 [ALC260_ACER] = {
4866 .mixers = { alc260_acer_mixer,
4867 alc260_capture_mixer },
4868 .init_verbs = { alc260_acer_init_verbs },
4869 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4870 .dac_nids = alc260_dac_nids,
4871 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4872 .adc_nids = alc260_dual_adc_nids,
4873 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4874 .channel_mode = alc260_modes,
a1e8d2da
JW
4875 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4876 .input_mux = alc260_acer_capture_sources,
0bfc90e9 4877 },
bc9f98a9
KY
4878 [ALC260_WILL] = {
4879 .mixers = { alc260_will_mixer,
4880 alc260_capture_mixer },
4881 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4882 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4883 .dac_nids = alc260_dac_nids,
4884 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4885 .adc_nids = alc260_adc_nids,
4886 .dig_out_nid = ALC260_DIGOUT_NID,
4887 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4888 .channel_mode = alc260_modes,
4889 .input_mux = &alc260_capture_source,
4890 },
4891 [ALC260_REPLACER_672V] = {
4892 .mixers = { alc260_replacer_672v_mixer,
4893 alc260_capture_mixer },
4894 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4895 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4896 .dac_nids = alc260_dac_nids,
4897 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4898 .adc_nids = alc260_adc_nids,
4899 .dig_out_nid = ALC260_DIGOUT_NID,
4900 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4901 .channel_mode = alc260_modes,
4902 .input_mux = &alc260_capture_source,
4903 .unsol_event = alc260_replacer_672v_unsol_event,
4904 .init_hook = alc260_replacer_672v_automute,
4905 },
7cf51e48
JW
4906#ifdef CONFIG_SND_DEBUG
4907 [ALC260_TEST] = {
4908 .mixers = { alc260_test_mixer,
4909 alc260_capture_mixer },
4910 .init_verbs = { alc260_test_init_verbs },
4911 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4912 .dac_nids = alc260_test_dac_nids,
4913 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4914 .adc_nids = alc260_test_adc_nids,
4915 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4916 .channel_mode = alc260_modes,
a1e8d2da
JW
4917 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4918 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
4919 },
4920#endif
df694daa
KY
4921};
4922
4923static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
4924{
4925 struct alc_spec *spec;
df694daa 4926 int err, board_config;
1da177e4 4927
e560d8d8 4928 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
4929 if (spec == NULL)
4930 return -ENOMEM;
4931
4932 codec->spec = spec;
4933
f5fcc13c
TI
4934 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4935 alc260_models,
4936 alc260_cfg_tbl);
4937 if (board_config < 0) {
9c7f852e
TI
4938 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4939 "trying auto-probe from BIOS...\n");
df694daa 4940 board_config = ALC260_AUTO;
16ded525 4941 }
1da177e4 4942
df694daa
KY
4943 if (board_config == ALC260_AUTO) {
4944 /* automatic parse from the BIOS config */
4945 err = alc260_parse_auto_config(codec);
4946 if (err < 0) {
4947 alc_free(codec);
4948 return err;
f12ab1e0 4949 } else if (!err) {
9c7f852e
TI
4950 printk(KERN_INFO
4951 "hda_codec: Cannot set up configuration "
4952 "from BIOS. Using base mode...\n");
df694daa
KY
4953 board_config = ALC260_BASIC;
4954 }
a9430dd8 4955 }
e9edcee0 4956
df694daa
KY
4957 if (board_config != ALC260_AUTO)
4958 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
4959
4960 spec->stream_name_analog = "ALC260 Analog";
4961 spec->stream_analog_playback = &alc260_pcm_analog_playback;
4962 spec->stream_analog_capture = &alc260_pcm_analog_capture;
4963
a3bcba38
TI
4964 spec->stream_name_digital = "ALC260 Digital";
4965 spec->stream_digital_playback = &alc260_pcm_digital_playback;
4966 spec->stream_digital_capture = &alc260_pcm_digital_capture;
4967
1da177e4 4968 codec->patch_ops = alc_patch_ops;
df694daa 4969 if (board_config == ALC260_AUTO)
ae6b813a 4970 spec->init_hook = alc260_auto_init;
cb53c626
TI
4971#ifdef CONFIG_SND_HDA_POWER_SAVE
4972 if (!spec->loopback.amplist)
4973 spec->loopback.amplist = alc260_loopbacks;
4974#endif
1da177e4
LT
4975
4976 return 0;
4977}
4978
e9edcee0 4979
1da177e4
LT
4980/*
4981 * ALC882 support
4982 *
4983 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4984 * configuration. Each pin widget can choose any input DACs and a mixer.
4985 * Each ADC is connected from a mixer of all inputs. This makes possible
4986 * 6-channel independent captures.
4987 *
4988 * In addition, an independent DAC for the multi-playback (not used in this
4989 * driver yet).
4990 */
df694daa
KY
4991#define ALC882_DIGOUT_NID 0x06
4992#define ALC882_DIGIN_NID 0x0a
1da177e4 4993
d2a6d7dc 4994static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
4995 { 8, NULL }
4996};
4997
4998static hda_nid_t alc882_dac_nids[4] = {
4999 /* front, rear, clfe, rear_surr */
5000 0x02, 0x03, 0x04, 0x05
5001};
5002
df694daa
KY
5003/* identical with ALC880 */
5004#define alc882_adc_nids alc880_adc_nids
5005#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4
LT
5006
5007/* input MUX */
5008/* FIXME: should be a matrix-type input source selection */
5009
5010static struct hda_input_mux alc882_capture_source = {
5011 .num_items = 4,
5012 .items = {
5013 { "Mic", 0x0 },
5014 { "Front Mic", 0x1 },
5015 { "Line", 0x2 },
5016 { "CD", 0x4 },
5017 },
5018};
1da177e4
LT
5019#define alc882_mux_enum_info alc_mux_enum_info
5020#define alc882_mux_enum_get alc_mux_enum_get
5021
f12ab1e0
TI
5022static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5023 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5024{
5025 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5026 struct alc_spec *spec = codec->spec;
5027 const struct hda_input_mux *imux = spec->input_mux;
5028 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5029 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5030 hda_nid_t nid = capture_mixers[adc_idx];
5031 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5032 unsigned int i, idx;
5033
5034 idx = ucontrol->value.enumerated.item[0];
5035 if (idx >= imux->num_items)
5036 idx = imux->num_items - 1;
82beb8fd 5037 if (*cur_val == idx)
1da177e4
LT
5038 return 0;
5039 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5040 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5041 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5042 imux->items[i].index,
47fd830a 5043 HDA_AMP_MUTE, v);
1da177e4
LT
5044 }
5045 *cur_val = idx;
5046 return 1;
5047}
5048
272a527c
KY
5049/*
5050 * 2ch mode
5051 */
5052static struct hda_verb alc882_3ST_ch2_init[] = {
5053 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5054 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5057 { } /* end */
5058};
5059
5060/*
5061 * 6ch mode
5062 */
5063static struct hda_verb alc882_3ST_ch6_init[] = {
5064 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5065 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5066 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5067 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5068 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5069 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5070 { } /* end */
5071};
5072
5073static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5074 { 2, alc882_3ST_ch2_init },
5075 { 6, alc882_3ST_ch6_init },
5076};
5077
df694daa
KY
5078/*
5079 * 6ch mode
5080 */
5081static struct hda_verb alc882_sixstack_ch6_init[] = {
5082 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5083 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5084 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5085 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5086 { } /* end */
5087};
5088
5089/*
5090 * 8ch mode
5091 */
5092static struct hda_verb alc882_sixstack_ch8_init[] = {
5093 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5094 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5095 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5096 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5097 { } /* end */
5098};
5099
5100static struct hda_channel_mode alc882_sixstack_modes[2] = {
5101 { 6, alc882_sixstack_ch6_init },
5102 { 8, alc882_sixstack_ch8_init },
5103};
5104
87350ad0
TI
5105/*
5106 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5107 */
5108
5109/*
5110 * 2ch mode
5111 */
5112static struct hda_verb alc885_mbp_ch2_init[] = {
5113 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5114 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5116 { } /* end */
5117};
5118
5119/*
5120 * 6ch mode
5121 */
5122static struct hda_verb alc885_mbp_ch6_init[] = {
5123 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5124 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5125 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5126 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5127 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5128 { } /* end */
5129};
5130
5131static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5132 { 2, alc885_mbp_ch2_init },
5133 { 6, alc885_mbp_ch6_init },
5134};
5135
5136
1da177e4
LT
5137/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5138 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5139 */
c8b6bf9b 5140static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5141 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5142 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5143 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5144 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5145 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5146 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5147 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5148 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5149 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5150 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5152 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5153 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5155 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5157 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5159 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5160 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5161 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5162 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5163 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5164 { } /* end */
5165};
5166
87350ad0
TI
5167static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5168 HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5169 HDA_BIND_MUTE ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5170 HDA_CODEC_MUTE ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5171 HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5172 HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5173 HDA_CODEC_MUTE ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5175 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5176 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5177 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5178 { } /* end */
5179};
bdd148a3
KY
5180static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5182 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5183 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5184 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5188 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5190 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5191 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5192 { } /* end */
5193};
5194
272a527c
KY
5195static struct snd_kcontrol_new alc882_targa_mixer[] = {
5196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5199 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5200 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5203 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5204 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5205 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5207 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5208 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5209 { } /* end */
5210};
5211
5212/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5213 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5214 */
5215static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5217 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5219 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5224 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5225 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5226 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5229 { } /* end */
5230};
5231
914759b7
TI
5232static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5233 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5234 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5235 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5238 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5239 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5241 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5242 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5243 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5244 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5245 { } /* end */
5246};
5247
df694daa
KY
5248static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5249 {
5250 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5251 .name = "Channel Mode",
5252 .info = alc_ch_mode_info,
5253 .get = alc_ch_mode_get,
5254 .put = alc_ch_mode_put,
5255 },
5256 { } /* end */
5257};
5258
1da177e4
LT
5259static struct hda_verb alc882_init_verbs[] = {
5260 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5261 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5262 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5264 /* Rear mixer */
05acb863
TI
5265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5267 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5268 /* CLFE mixer */
05acb863
TI
5269 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5270 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5271 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5272 /* Side mixer */
05acb863
TI
5273 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5274 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5276
e9edcee0 5277 /* Front Pin: output 0 (0x0c) */
05acb863 5278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5281 /* Rear Pin: output 1 (0x0d) */
05acb863 5282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5285 /* CLFE Pin: output 2 (0x0e) */
05acb863 5286 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5287 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5289 /* Side Pin: output 3 (0x0f) */
05acb863 5290 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5291 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5292 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5293 /* Mic (rear) pin: input vref at 80% */
16ded525 5294 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5296 /* Front Mic pin: input vref at 80% */
16ded525 5297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5299 /* Line In pin: input */
05acb863 5300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5301 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5302 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5304 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5305 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5306 /* CD pin widget for input */
05acb863 5307 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5308
5309 /* FIXME: use matrix-type input source selection */
5310 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5311 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5312 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5316 /* Input mixer2 */
05acb863
TI
5317 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5321 /* Input mixer3 */
05acb863
TI
5322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5326 /* ADC1: mute amp left and right */
5327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5328 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5329 /* ADC2: mute amp left and right */
5330 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5331 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5332 /* ADC3: mute amp left and right */
5333 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5334 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5335
5336 { }
5337};
5338
4b146cb0
TI
5339static struct hda_verb alc882_eapd_verbs[] = {
5340 /* change to EAPD mode */
5341 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5342 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5343 { }
4b146cb0
TI
5344};
5345
9102cd1c
TD
5346/* Mac Pro test */
5347static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5348 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5349 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5353 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5354 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5355 { } /* end */
5356};
5357
5358static struct hda_verb alc882_macpro_init_verbs[] = {
5359 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5362 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5363 /* Front Pin: output 0 (0x0c) */
5364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5367 /* Front Mic pin: input vref at 80% */
5368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5370 /* Speaker: output */
5371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5374 /* Headphone output (output 0 - 0x0c) */
5375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5377 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5378
5379 /* FIXME: use matrix-type input source selection */
5380 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5381 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5383 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5386 /* Input mixer2 */
5387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5391 /* Input mixer3 */
5392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5396 /* ADC1: mute amp left and right */
5397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5398 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5399 /* ADC2: mute amp left and right */
5400 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5401 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5402 /* ADC3: mute amp left and right */
5403 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5404 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5405
5406 { }
5407};
f12ab1e0 5408
87350ad0
TI
5409/* Macbook Pro rev3 */
5410static struct hda_verb alc885_mbp3_init_verbs[] = {
5411 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5415 /* Rear mixer */
5416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5419 /* Front Pin: output 0 (0x0c) */
5420 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5422 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5423 /* HP Pin: output 0 (0x0d) */
5424 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5425 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5426 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5427 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5428 /* Mic (rear) pin: input vref at 80% */
5429 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5431 /* Front Mic pin: input vref at 80% */
5432 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5433 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5434 /* Line In pin: use output 1 when in LineOut mode */
5435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5438
5439 /* FIXME: use matrix-type input source selection */
5440 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5441 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5446 /* Input mixer2 */
5447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5450 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5451 /* Input mixer3 */
5452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5456 /* ADC1: mute amp left and right */
5457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5458 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5459 /* ADC2: mute amp left and right */
5460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5461 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5462 /* ADC3: mute amp left and right */
5463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5464 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5465
5466 { }
5467};
5468
c54728d8
NF
5469/* iMac 24 mixer. */
5470static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5471 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5472 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5473 { } /* end */
5474};
5475
5476/* iMac 24 init verbs. */
5477static struct hda_verb alc885_imac24_init_verbs[] = {
5478 /* Internal speakers: output 0 (0x0c) */
5479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5481 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5482 /* Internal speakers: output 0 (0x0c) */
5483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5484 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5485 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5486 /* Headphone: output 0 (0x0c) */
5487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5488 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5489 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5490 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5491 /* Front Mic: input vref at 80% */
5492 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5494 { }
5495};
5496
5497/* Toggle speaker-output according to the hp-jack state */
5498static void alc885_imac24_automute(struct hda_codec *codec)
5499{
5500 unsigned int present;
5501
5502 present = snd_hda_codec_read(codec, 0x14, 0,
5503 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5504 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5505 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5506 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5507 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5508}
5509
5510/* Processes unsolicited events. */
5511static void alc885_imac24_unsol_event(struct hda_codec *codec,
5512 unsigned int res)
5513{
5514 /* Headphone insertion or removal. */
5515 if ((res >> 26) == ALC880_HP_EVENT)
5516 alc885_imac24_automute(codec);
5517}
5518
87350ad0
TI
5519static void alc885_mbp3_automute(struct hda_codec *codec)
5520{
5521 unsigned int present;
5522
5523 present = snd_hda_codec_read(codec, 0x15, 0,
5524 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5526 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5527 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5528 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5529
5530}
5531static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5532 unsigned int res)
5533{
5534 /* Headphone insertion or removal. */
5535 if ((res >> 26) == ALC880_HP_EVENT)
5536 alc885_mbp3_automute(codec);
5537}
5538
5539
272a527c
KY
5540static struct hda_verb alc882_targa_verbs[] = {
5541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5543
5544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5546
5547 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5548 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5549 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5550
5551 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5552 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5553 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5554 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5555 { } /* end */
5556};
5557
5558/* toggle speaker-output according to the hp-jack state */
5559static void alc882_targa_automute(struct hda_codec *codec)
5560{
5561 unsigned int present;
5562
5563 present = snd_hda_codec_read(codec, 0x14, 0,
5564 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5565 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5566 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5567 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5568 present ? 1 : 3);
272a527c
KY
5569}
5570
5571static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5572{
5573 /* Looks like the unsol event is incompatible with the standard
5574 * definition. 4bit tag is placed at 26 bit!
5575 */
5576 if (((res >> 26) == ALC880_HP_EVENT)) {
5577 alc882_targa_automute(codec);
5578 }
5579}
5580
5581static struct hda_verb alc882_asus_a7j_verbs[] = {
5582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5584
5585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5588
5589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5591 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5592
5593 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5594 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5595 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5596 { } /* end */
5597};
5598
914759b7
TI
5599static struct hda_verb alc882_asus_a7m_verbs[] = {
5600 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5601 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5602
5603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5604 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5606
5607 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5609 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5610
5611 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5612 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5613 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5614 { } /* end */
5615};
5616
9102cd1c
TD
5617static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5618{
5619 unsigned int gpiostate, gpiomask, gpiodir;
5620
5621 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5622 AC_VERB_GET_GPIO_DATA, 0);
5623
5624 if (!muted)
5625 gpiostate |= (1 << pin);
5626 else
5627 gpiostate &= ~(1 << pin);
5628
5629 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5630 AC_VERB_GET_GPIO_MASK, 0);
5631 gpiomask |= (1 << pin);
5632
5633 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5634 AC_VERB_GET_GPIO_DIRECTION, 0);
5635 gpiodir |= (1 << pin);
5636
5637
5638 snd_hda_codec_write(codec, codec->afg, 0,
5639 AC_VERB_SET_GPIO_MASK, gpiomask);
5640 snd_hda_codec_write(codec, codec->afg, 0,
5641 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5642
5643 msleep(1);
5644
5645 snd_hda_codec_write(codec, codec->afg, 0,
5646 AC_VERB_SET_GPIO_DATA, gpiostate);
5647}
5648
7debbe51
TI
5649/* set up GPIO at initialization */
5650static void alc885_macpro_init_hook(struct hda_codec *codec)
5651{
5652 alc882_gpio_mute(codec, 0, 0);
5653 alc882_gpio_mute(codec, 1, 0);
5654}
5655
5656/* set up GPIO and update auto-muting at initialization */
5657static void alc885_imac24_init_hook(struct hda_codec *codec)
5658{
5659 alc885_macpro_init_hook(codec);
5660 alc885_imac24_automute(codec);
5661}
5662
df694daa
KY
5663/*
5664 * generic initialization of ADC, input mixers and output mixers
5665 */
5666static struct hda_verb alc882_auto_init_verbs[] = {
5667 /*
5668 * Unmute ADC0-2 and set the default input to mic-in
5669 */
5670 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5672 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5675 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5676
cb53c626 5677 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5678 * mixer widget
f12ab1e0
TI
5679 * Note: PASD motherboards uses the Line In 2 as the input for
5680 * front panel mic (mic 2)
df694daa
KY
5681 */
5682 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5683 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5684 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5685 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5688
df694daa
KY
5689 /*
5690 * Set up output mixers (0x0c - 0x0f)
5691 */
5692 /* set vol=0 to output mixers */
5693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5694 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5695 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5697 /* set up input amps for analog loopback */
5698 /* Amp Indices: DAC = 0, mixer = 1 */
5699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5700 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5702 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5707 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5708 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5709
5710 /* FIXME: use matrix-type input source selection */
5711 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5712 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5713 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5714 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5717 /* Input mixer2 */
5718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5722 /* Input mixer3 */
5723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5727
5728 { }
5729};
5730
5731/* capture mixer elements */
5732static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5733 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5734 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5735 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5736 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5737 {
5738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5739 /* The multiple "Capture Source" controls confuse alsamixer
5740 * So call somewhat different..
5741 * FIXME: the controls appear in the "playback" view!
5742 */
5743 /* .name = "Capture Source", */
5744 .name = "Input Source",
5745 .count = 2,
5746 .info = alc882_mux_enum_info,
5747 .get = alc882_mux_enum_get,
5748 .put = alc882_mux_enum_put,
5749 },
5750 { } /* end */
5751};
5752
5753static struct snd_kcontrol_new alc882_capture_mixer[] = {
5754 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5755 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5756 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5757 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5758 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5759 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5760 {
5761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5762 /* The multiple "Capture Source" controls confuse alsamixer
5763 * So call somewhat different..
5764 * FIXME: the controls appear in the "playback" view!
5765 */
5766 /* .name = "Capture Source", */
5767 .name = "Input Source",
5768 .count = 3,
5769 .info = alc882_mux_enum_info,
5770 .get = alc882_mux_enum_get,
5771 .put = alc882_mux_enum_put,
5772 },
5773 { } /* end */
5774};
5775
cb53c626
TI
5776#ifdef CONFIG_SND_HDA_POWER_SAVE
5777#define alc882_loopbacks alc880_loopbacks
5778#endif
5779
df694daa
KY
5780/* pcm configuration: identiacal with ALC880 */
5781#define alc882_pcm_analog_playback alc880_pcm_analog_playback
5782#define alc882_pcm_analog_capture alc880_pcm_analog_capture
5783#define alc882_pcm_digital_playback alc880_pcm_digital_playback
5784#define alc882_pcm_digital_capture alc880_pcm_digital_capture
5785
5786/*
5787 * configuration and preset
5788 */
f5fcc13c
TI
5789static const char *alc882_models[ALC882_MODEL_LAST] = {
5790 [ALC882_3ST_DIG] = "3stack-dig",
5791 [ALC882_6ST_DIG] = "6stack-dig",
5792 [ALC882_ARIMA] = "arima",
bdd148a3 5793 [ALC882_W2JC] = "w2jc",
0438a00e
TI
5794 [ALC882_TARGA] = "targa",
5795 [ALC882_ASUS_A7J] = "asus-a7j",
5796 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 5797 [ALC885_MACPRO] = "macpro",
87350ad0 5798 [ALC885_MBP3] = "mbp3",
c54728d8 5799 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
5800 [ALC882_AUTO] = "auto",
5801};
5802
5803static struct snd_pci_quirk alc882_cfg_tbl[] = {
5804 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 5805 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 5806 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 5807 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 5808 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 5809 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 5810 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741
TI
5811 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5812 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
5813 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5814 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
5815 {}
5816};
5817
5818static struct alc_config_preset alc882_presets[] = {
5819 [ALC882_3ST_DIG] = {
5820 .mixers = { alc882_base_mixer },
5821 .init_verbs = { alc882_init_verbs },
5822 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5823 .dac_nids = alc882_dac_nids,
5824 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
5825 .dig_in_nid = ALC882_DIGIN_NID,
5826 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5827 .channel_mode = alc882_ch_modes,
4e195a7b 5828 .need_dac_fix = 1,
df694daa
KY
5829 .input_mux = &alc882_capture_source,
5830 },
5831 [ALC882_6ST_DIG] = {
5832 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5833 .init_verbs = { alc882_init_verbs },
5834 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5835 .dac_nids = alc882_dac_nids,
5836 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
5837 .dig_in_nid = ALC882_DIGIN_NID,
5838 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5839 .channel_mode = alc882_sixstack_modes,
5840 .input_mux = &alc882_capture_source,
5841 },
4b146cb0
TI
5842 [ALC882_ARIMA] = {
5843 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5844 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5845 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5846 .dac_nids = alc882_dac_nids,
5847 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5848 .channel_mode = alc882_sixstack_modes,
5849 .input_mux = &alc882_capture_source,
5850 },
bdd148a3
KY
5851 [ALC882_W2JC] = {
5852 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5853 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5854 alc880_gpio1_init_verbs },
5855 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5856 .dac_nids = alc882_dac_nids,
5857 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5858 .channel_mode = alc880_threestack_modes,
5859 .need_dac_fix = 1,
5860 .input_mux = &alc882_capture_source,
5861 .dig_out_nid = ALC882_DIGOUT_NID,
5862 },
87350ad0
TI
5863 [ALC885_MBP3] = {
5864 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5865 .init_verbs = { alc885_mbp3_init_verbs,
5866 alc880_gpio1_init_verbs },
5867 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5868 .dac_nids = alc882_dac_nids,
5869 .channel_mode = alc885_mbp_6ch_modes,
5870 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5871 .input_mux = &alc882_capture_source,
5872 .dig_out_nid = ALC882_DIGOUT_NID,
5873 .dig_in_nid = ALC882_DIGIN_NID,
5874 .unsol_event = alc885_mbp3_unsol_event,
5875 .init_hook = alc885_mbp3_automute,
5876 },
9102cd1c
TD
5877 [ALC885_MACPRO] = {
5878 .mixers = { alc882_macpro_mixer },
5879 .init_verbs = { alc882_macpro_init_verbs },
5880 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5881 .dac_nids = alc882_dac_nids,
5882 .dig_out_nid = ALC882_DIGOUT_NID,
5883 .dig_in_nid = ALC882_DIGIN_NID,
5884 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5885 .channel_mode = alc882_ch_modes,
5886 .input_mux = &alc882_capture_source,
7debbe51 5887 .init_hook = alc885_macpro_init_hook,
9102cd1c 5888 },
c54728d8
NF
5889 [ALC885_IMAC24] = {
5890 .mixers = { alc885_imac24_mixer },
5891 .init_verbs = { alc885_imac24_init_verbs },
5892 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5893 .dac_nids = alc882_dac_nids,
5894 .dig_out_nid = ALC882_DIGOUT_NID,
5895 .dig_in_nid = ALC882_DIGIN_NID,
5896 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5897 .channel_mode = alc882_ch_modes,
5898 .input_mux = &alc882_capture_source,
5899 .unsol_event = alc885_imac24_unsol_event,
7debbe51 5900 .init_hook = alc885_imac24_init_hook,
c54728d8 5901 },
272a527c
KY
5902 [ALC882_TARGA] = {
5903 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5904 alc882_capture_mixer },
5905 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5906 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5907 .dac_nids = alc882_dac_nids,
5908 .dig_out_nid = ALC882_DIGOUT_NID,
5909 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5910 .adc_nids = alc882_adc_nids,
5911 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5912 .channel_mode = alc882_3ST_6ch_modes,
5913 .need_dac_fix = 1,
5914 .input_mux = &alc882_capture_source,
5915 .unsol_event = alc882_targa_unsol_event,
5916 .init_hook = alc882_targa_automute,
5917 },
5918 [ALC882_ASUS_A7J] = {
5919 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5920 alc882_capture_mixer },
5921 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5922 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5923 .dac_nids = alc882_dac_nids,
5924 .dig_out_nid = ALC882_DIGOUT_NID,
5925 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5926 .adc_nids = alc882_adc_nids,
5927 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5928 .channel_mode = alc882_3ST_6ch_modes,
5929 .need_dac_fix = 1,
5930 .input_mux = &alc882_capture_source,
5931 },
914759b7
TI
5932 [ALC882_ASUS_A7M] = {
5933 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5934 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5935 alc880_gpio1_init_verbs,
5936 alc882_asus_a7m_verbs },
5937 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5938 .dac_nids = alc882_dac_nids,
5939 .dig_out_nid = ALC882_DIGOUT_NID,
5940 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5941 .channel_mode = alc880_threestack_modes,
5942 .need_dac_fix = 1,
5943 .input_mux = &alc882_capture_source,
5944 },
df694daa
KY
5945};
5946
5947
f95474ec
TI
5948/*
5949 * Pin config fixes
5950 */
5951enum {
5952 PINFIX_ABIT_AW9D_MAX
5953};
5954
5955static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5956 { 0x15, 0x01080104 }, /* side */
5957 { 0x16, 0x01011012 }, /* rear */
5958 { 0x17, 0x01016011 }, /* clfe */
5959 { }
5960};
5961
5962static const struct alc_pincfg *alc882_pin_fixes[] = {
5963 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5964};
5965
5966static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5967 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5968 {}
5969};
5970
df694daa
KY
5971/*
5972 * BIOS auto configuration
5973 */
5974static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5975 hda_nid_t nid, int pin_type,
5976 int dac_idx)
5977{
5978 /* set as output */
5979 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
5980 int idx;
5981
df694daa
KY
5982 if (spec->multiout.dac_nids[dac_idx] == 0x25)
5983 idx = 4;
5984 else
5985 idx = spec->multiout.dac_nids[dac_idx] - 2;
5986
f12ab1e0
TI
5987 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5988 pin_type);
5989 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5990 AMP_OUT_UNMUTE);
df694daa
KY
5991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5992
5993}
5994
5995static void alc882_auto_init_multi_out(struct hda_codec *codec)
5996{
5997 struct alc_spec *spec = codec->spec;
5998 int i;
5999
bc9f98a9 6000 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6001 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6002 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6003 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6004 if (nid)
baba8ee9 6005 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6006 i);
df694daa
KY
6007 }
6008}
6009
6010static void alc882_auto_init_hp_out(struct hda_codec *codec)
6011{
6012 struct alc_spec *spec = codec->spec;
6013 hda_nid_t pin;
6014
eb06ed8f 6015 pin = spec->autocfg.hp_pins[0];
df694daa 6016 if (pin) /* connect to front */
f12ab1e0
TI
6017 /* use dac 0 */
6018 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
df694daa
KY
6019}
6020
6021#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6022#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6023
6024static void alc882_auto_init_analog_input(struct hda_codec *codec)
6025{
6026 struct alc_spec *spec = codec->spec;
6027 int i;
6028
6029 for (i = 0; i < AUTO_PIN_LAST; i++) {
6030 hda_nid_t nid = spec->autocfg.input_pins[i];
6031 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6032 snd_hda_codec_write(codec, nid, 0,
6033 AC_VERB_SET_PIN_WIDGET_CONTROL,
6034 i <= AUTO_PIN_FRONT_MIC ?
6035 PIN_VREF80 : PIN_IN);
df694daa 6036 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6037 snd_hda_codec_write(codec, nid, 0,
6038 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6039 AMP_OUT_MUTE);
6040 }
6041 }
6042}
6043
776e184e
TI
6044/* add mic boosts if needed */
6045static int alc_auto_add_mic_boost(struct hda_codec *codec)
6046{
6047 struct alc_spec *spec = codec->spec;
6048 int err;
6049 hda_nid_t nid;
6050
6051 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6052 if (nid) {
6053 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6054 "Mic Boost",
6055 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6056 if (err < 0)
6057 return err;
6058 }
6059 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6060 if (nid) {
6061 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6062 "Front Mic Boost",
6063 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6064 if (err < 0)
6065 return err;
6066 }
6067 return 0;
6068}
6069
df694daa
KY
6070/* almost identical with ALC880 parser... */
6071static int alc882_parse_auto_config(struct hda_codec *codec)
6072{
6073 struct alc_spec *spec = codec->spec;
6074 int err = alc880_parse_auto_config(codec);
6075
6076 if (err < 0)
6077 return err;
776e184e
TI
6078 else if (!err)
6079 return 0; /* no config found */
6080
6081 err = alc_auto_add_mic_boost(codec);
6082 if (err < 0)
6083 return err;
6084
6085 /* hack - override the init verbs */
6086 spec->init_verbs[0] = alc882_auto_init_verbs;
6087
6088 return 1; /* config found */
df694daa
KY
6089}
6090
ae6b813a
TI
6091/* additional initialization for auto-configuration model */
6092static void alc882_auto_init(struct hda_codec *codec)
df694daa 6093{
df694daa
KY
6094 alc882_auto_init_multi_out(codec);
6095 alc882_auto_init_hp_out(codec);
6096 alc882_auto_init_analog_input(codec);
df694daa
KY
6097}
6098
df694daa
KY
6099static int patch_alc882(struct hda_codec *codec)
6100{
6101 struct alc_spec *spec;
6102 int err, board_config;
6103
6104 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6105 if (spec == NULL)
6106 return -ENOMEM;
6107
6108 codec->spec = spec;
6109
f5fcc13c
TI
6110 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6111 alc882_models,
6112 alc882_cfg_tbl);
df694daa
KY
6113
6114 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6115 /* Pick up systems that don't supply PCI SSID */
6116 switch (codec->subsystem_id) {
6117 case 0x106b0c00: /* Mac Pro */
6118 board_config = ALC885_MACPRO;
6119 break;
c54728d8
NF
6120 case 0x106b1000: /* iMac 24 */
6121 board_config = ALC885_IMAC24;
6122 break;
87350ad0
TI
6123 case 0x106b2c00: /* Macbook Pro rev3 */
6124 board_config = ALC885_MBP3;
6125 break;
081d17c4
TD
6126 default:
6127 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6128 "trying auto-probe from BIOS...\n");
6129 board_config = ALC882_AUTO;
6130 }
df694daa
KY
6131 }
6132
f95474ec
TI
6133 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6134
df694daa
KY
6135 if (board_config == ALC882_AUTO) {
6136 /* automatic parse from the BIOS config */
6137 err = alc882_parse_auto_config(codec);
6138 if (err < 0) {
6139 alc_free(codec);
6140 return err;
f12ab1e0 6141 } else if (!err) {
9c7f852e
TI
6142 printk(KERN_INFO
6143 "hda_codec: Cannot set up configuration "
6144 "from BIOS. Using base mode...\n");
df694daa
KY
6145 board_config = ALC882_3ST_DIG;
6146 }
6147 }
6148
6149 if (board_config != ALC882_AUTO)
6150 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6151
6152 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6153 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6154 spec->stream_analog_capture = &alc882_pcm_analog_capture;
1da177e4
LT
6155
6156 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6157 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6158 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6159
f12ab1e0 6160 if (!spec->adc_nids && spec->input_mux) {
df694daa 6161 /* check whether NID 0x07 is valid */
4a471b7d 6162 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6163 /* get type */
6164 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6165 if (wcap != AC_WID_AUD_IN) {
6166 spec->adc_nids = alc882_adc_nids_alt;
6167 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
f12ab1e0
TI
6168 spec->mixers[spec->num_mixers] =
6169 alc882_capture_alt_mixer;
df694daa
KY
6170 spec->num_mixers++;
6171 } else {
6172 spec->adc_nids = alc882_adc_nids;
6173 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6174 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6175 spec->num_mixers++;
6176 }
6177 }
1da177e4
LT
6178
6179 codec->patch_ops = alc_patch_ops;
df694daa 6180 if (board_config == ALC882_AUTO)
ae6b813a 6181 spec->init_hook = alc882_auto_init;
cb53c626
TI
6182#ifdef CONFIG_SND_HDA_POWER_SAVE
6183 if (!spec->loopback.amplist)
6184 spec->loopback.amplist = alc882_loopbacks;
6185#endif
df694daa
KY
6186
6187 return 0;
6188}
6189
6190/*
9c7f852e
TI
6191 * ALC883 support
6192 *
6193 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6194 * configuration. Each pin widget can choose any input DACs and a mixer.
6195 * Each ADC is connected from a mixer of all inputs. This makes possible
6196 * 6-channel independent captures.
6197 *
6198 * In addition, an independent DAC for the multi-playback (not used in this
6199 * driver yet).
df694daa 6200 */
9c7f852e
TI
6201#define ALC883_DIGOUT_NID 0x06
6202#define ALC883_DIGIN_NID 0x0a
df694daa 6203
9c7f852e
TI
6204static hda_nid_t alc883_dac_nids[4] = {
6205 /* front, rear, clfe, rear_surr */
6206 0x02, 0x04, 0x03, 0x05
6207};
df694daa 6208
9c7f852e
TI
6209static hda_nid_t alc883_adc_nids[2] = {
6210 /* ADC1-2 */
6211 0x08, 0x09,
6212};
f12ab1e0 6213
9c7f852e
TI
6214/* input MUX */
6215/* FIXME: should be a matrix-type input source selection */
df694daa 6216
9c7f852e
TI
6217static struct hda_input_mux alc883_capture_source = {
6218 .num_items = 4,
6219 .items = {
6220 { "Mic", 0x0 },
6221 { "Front Mic", 0x1 },
6222 { "Line", 0x2 },
6223 { "CD", 0x4 },
6224 },
6225};
bc9f98a9
KY
6226
6227static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6228 .num_items = 2,
6229 .items = {
6230 { "Mic", 0x1 },
6231 { "Line", 0x2 },
6232 },
6233};
6234
272a527c
KY
6235static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6236 .num_items = 4,
6237 .items = {
6238 { "Mic", 0x0 },
6239 { "iMic", 0x1 },
6240 { "Line", 0x2 },
6241 { "CD", 0x4 },
6242 },
6243};
6244
9c7f852e
TI
6245#define alc883_mux_enum_info alc_mux_enum_info
6246#define alc883_mux_enum_get alc_mux_enum_get
df694daa 6247
9c7f852e
TI
6248static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6249 struct snd_ctl_elem_value *ucontrol)
6250{
6251 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6252 struct alc_spec *spec = codec->spec;
6253 const struct hda_input_mux *imux = spec->input_mux;
6254 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6255 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6256 hda_nid_t nid = capture_mixers[adc_idx];
6257 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6258 unsigned int i, idx;
6259
6260 idx = ucontrol->value.enumerated.item[0];
6261 if (idx >= imux->num_items)
6262 idx = imux->num_items - 1;
82beb8fd 6263 if (*cur_val == idx)
9c7f852e
TI
6264 return 0;
6265 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
6266 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6267 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 6268 imux->items[i].index,
47fd830a 6269 HDA_AMP_MUTE, v);
9c7f852e
TI
6270 }
6271 *cur_val = idx;
6272 return 1;
6273}
f12ab1e0 6274
9c7f852e
TI
6275/*
6276 * 2ch mode
6277 */
6278static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6279 { 2, NULL }
6280};
6281
6282/*
6283 * 2ch mode
6284 */
6285static struct hda_verb alc883_3ST_ch2_init[] = {
6286 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6287 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6288 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6289 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6290 { } /* end */
6291};
6292
b201131c
TD
6293/*
6294 * 4ch mode
6295 */
6296static struct hda_verb alc883_3ST_ch4_init[] = {
6297 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6298 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6299 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6300 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6301 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6302 { } /* end */
6303};
6304
9c7f852e
TI
6305/*
6306 * 6ch mode
6307 */
6308static struct hda_verb alc883_3ST_ch6_init[] = {
6309 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6310 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6311 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6312 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6313 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6314 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6315 { } /* end */
6316};
6317
b201131c 6318static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6319 { 2, alc883_3ST_ch2_init },
b201131c 6320 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6321 { 6, alc883_3ST_ch6_init },
6322};
6323
6324/*
6325 * 6ch mode
6326 */
6327static struct hda_verb alc883_sixstack_ch6_init[] = {
6328 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6329 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6330 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6331 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6332 { } /* end */
6333};
6334
6335/*
6336 * 8ch mode
6337 */
6338static struct hda_verb alc883_sixstack_ch8_init[] = {
6339 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6343 { } /* end */
6344};
6345
6346static struct hda_channel_mode alc883_sixstack_modes[2] = {
6347 { 6, alc883_sixstack_ch6_init },
6348 { 8, alc883_sixstack_ch8_init },
6349};
6350
b373bdeb
AN
6351static struct hda_verb alc883_medion_eapd_verbs[] = {
6352 /* eanable EAPD on medion laptop */
6353 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6354 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6355 { }
6356};
6357
9c7f852e
TI
6358/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6359 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6360 */
6361
6362static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6363 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6364 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6367 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6368 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6369 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6370 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6371 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6372 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6376 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6377 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6379 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6381 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6382 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6384 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6385 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6386 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6387 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6388 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6389 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6390 {
6391 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6392 /* .name = "Capture Source", */
6393 .name = "Input Source",
6394 .count = 2,
6395 .info = alc883_mux_enum_info,
6396 .get = alc883_mux_enum_get,
6397 .put = alc883_mux_enum_put,
6398 },
df694daa 6399 { } /* end */
834be88d
TI
6400};
6401
a8848bd6
AS
6402static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6405 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6406 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6407 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6408 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6411 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6412 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6413 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6414 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6415 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6416 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6417 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6418 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6419 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6420 {
6421 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6422 /* .name = "Capture Source", */
6423 .name = "Input Source",
6424 .count = 2,
6425 .info = alc883_mux_enum_info,
6426 .get = alc883_mux_enum_get,
6427 .put = alc883_mux_enum_put,
6428 },
6429 { } /* end */
6430};
6431
9c7f852e
TI
6432static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6433 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6434 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6435 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6436 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6437 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6441 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6443 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6444 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6446 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6447 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6448 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6449 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6450 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6451 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6452 {
6453 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6454 /* .name = "Capture Source", */
6455 .name = "Input Source",
6456 .count = 2,
6457 .info = alc883_mux_enum_info,
6458 .get = alc883_mux_enum_get,
6459 .put = alc883_mux_enum_put,
6460 },
6461 { } /* end */
6462};
df694daa 6463
9c7f852e
TI
6464static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6465 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6466 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6475 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6476 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6477 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6479 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6481 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6482 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6483 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6484 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6485 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6486 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6487 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6488 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6489 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6490 {
6491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6492 /* .name = "Capture Source", */
6493 .name = "Input Source",
6494 .count = 2,
6495 .info = alc883_mux_enum_info,
6496 .get = alc883_mux_enum_get,
6497 .put = alc883_mux_enum_put,
6498 },
6499 { } /* end */
6500};
6501
d1d985f0 6502static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6504 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6505 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6506 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6507 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6508 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6509 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6510 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6511 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6512 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6513 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6517 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6519 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6520 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6521 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6522 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6523 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6524 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6525 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6526
6527 {
6528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6529 /* .name = "Capture Source", */
6530 .name = "Input Source",
6531 .count = 1,
6532 .info = alc883_mux_enum_info,
6533 .get = alc883_mux_enum_get,
6534 .put = alc883_mux_enum_put,
6535 },
6536 { } /* end */
6537};
6538
ccc656ce
KY
6539static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6542 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6543 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6544 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6546 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6548 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6549 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6550 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6551 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6552 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6554 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6556 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6557 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6558 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6559 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6560 {
6561 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6562 /* .name = "Capture Source", */
6563 .name = "Input Source",
6564 .count = 2,
6565 .info = alc883_mux_enum_info,
6566 .get = alc883_mux_enum_get,
6567 .put = alc883_mux_enum_put,
6568 },
6569 { } /* end */
f12ab1e0 6570};
ccc656ce
KY
6571
6572static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6573 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6575 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6576 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6577 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6581 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6582 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6583 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6584 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6585 {
6586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6587 /* .name = "Capture Source", */
6588 .name = "Input Source",
6589 .count = 2,
6590 .info = alc883_mux_enum_info,
6591 .get = alc883_mux_enum_get,
6592 .put = alc883_mux_enum_put,
6593 },
6594 { } /* end */
f12ab1e0 6595};
ccc656ce 6596
bc9f98a9
KY
6597static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6600 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6601 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6602 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6605 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6608 {
6609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6610 /* .name = "Capture Source", */
6611 .name = "Input Source",
6612 .count = 1,
6613 .info = alc883_mux_enum_info,
6614 .get = alc883_mux_enum_get,
6615 .put = alc883_mux_enum_put,
6616 },
6617 { } /* end */
f12ab1e0 6618};
bc9f98a9 6619
272a527c
KY
6620static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6621 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6622 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6627 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6628 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6629 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6630 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6631 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6632 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6634 {
6635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6636 /* .name = "Capture Source", */
6637 .name = "Input Source",
6638 .count = 2,
6639 .info = alc883_mux_enum_info,
6640 .get = alc883_mux_enum_get,
6641 .put = alc883_mux_enum_put,
6642 },
6643 { } /* end */
6644};
6645
6646static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6649 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6651 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6656 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6657 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6658 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6659 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6660 {
6661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6662 /* .name = "Capture Source", */
6663 .name = "Input Source",
6664 .count = 2,
6665 .info = alc883_mux_enum_info,
6666 .get = alc883_mux_enum_get,
6667 .put = alc883_mux_enum_put,
6668 },
6669 { } /* end */
6670};
6671
4723c022 6672static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6673 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6674 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6675 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6676 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6677 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6678 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6679 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6680 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6681 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6682 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6686 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6687 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6689 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6691 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6694 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6695 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6696 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6697 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6698 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6699 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6700 {
6701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6702 /* .name = "Capture Source", */
6703 .name = "Input Source",
6704 .count = 2,
6705 .info = alc883_mux_enum_info,
6706 .get = alc883_mux_enum_get,
6707 .put = alc883_mux_enum_put,
6708 },
6709 { } /* end */
6710};
6711
4723c022 6712static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6713 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6714 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6715 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6716 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6717 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6719 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6720 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6729 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6731 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6732 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6733 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6734 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6735 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6736 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6737 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6738 {
6739 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6740 /* .name = "Capture Source", */
6741 .name = "Input Source",
6742 .count = 2,
6743 .info = alc883_mux_enum_info,
6744 .get = alc883_mux_enum_get,
6745 .put = alc883_mux_enum_put,
6746 },
6747 { } /* end */
6748};
6749
2880a867 6750static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
6751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6752 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 6753 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
6754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
6756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6757 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6758 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
6759 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6760 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6761 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6762 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6763 {
6764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6765 /* .name = "Capture Source", */
6766 .name = "Input Source",
6767 .count = 2,
6768 .info = alc883_mux_enum_info,
6769 .get = alc883_mux_enum_get,
6770 .put = alc883_mux_enum_put,
6771 },
6772 { } /* end */
d1a991a6 6773};
2880a867 6774
9c7f852e
TI
6775static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6776 {
6777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6778 .name = "Channel Mode",
6779 .info = alc_ch_mode_info,
6780 .get = alc_ch_mode_get,
6781 .put = alc_ch_mode_put,
6782 },
6783 { } /* end */
6784};
6785
6786static struct hda_verb alc883_init_verbs[] = {
6787 /* ADC1: mute amp left and right */
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 6789 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
6790 /* ADC2: mute amp left and right */
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 6792 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
6793 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6797 /* Rear mixer */
6798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6799 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6801 /* CLFE mixer */
6802 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6805 /* Side mixer */
6806 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6807 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 6809
cb53c626
TI
6810 /* mute analog input loopbacks */
6811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6812 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 6816
9c7f852e
TI
6817 /* Front Pin: output 0 (0x0c) */
6818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6820 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6821 /* Rear Pin: output 1 (0x0d) */
6822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6825 /* CLFE Pin: output 2 (0x0e) */
6826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6828 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6829 /* Side Pin: output 3 (0x0f) */
6830 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6832 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6833 /* Mic (rear) pin: input vref at 80% */
6834 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6836 /* Front Mic pin: input vref at 80% */
6837 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6839 /* Line In pin: input */
6840 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6842 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6843 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6844 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6845 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6846 /* CD pin widget for input */
6847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6848
6849 /* FIXME: use matrix-type input source selection */
6850 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6851 /* Input mixer2 */
6852 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6853 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6854 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6855 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6856 /* Input mixer3 */
6857 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6861 { }
6862};
6863
a8848bd6
AS
6864/* toggle speaker-output according to the hp-jack state */
6865static void alc883_mitac_hp_automute(struct hda_codec *codec)
6866{
6867 unsigned int present;
6868
6869 present = snd_hda_codec_read(codec, 0x15, 0,
6870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6871 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6872 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6873 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
6874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6875}
6876
6877/* auto-toggle front mic */
6878/*
6879static void alc883_mitac_mic_automute(struct hda_codec *codec)
6880{
6881 unsigned int present;
6882 unsigned char bits;
6883
6884 present = snd_hda_codec_read(codec, 0x18, 0,
6885 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6886 bits = present ? HDA_AMP_MUTE : 0;
6887 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
6888}
6889*/
6890
6891static void alc883_mitac_automute(struct hda_codec *codec)
6892{
6893 alc883_mitac_hp_automute(codec);
6894 /* alc883_mitac_mic_automute(codec); */
6895}
6896
6897static void alc883_mitac_unsol_event(struct hda_codec *codec,
6898 unsigned int res)
6899{
6900 switch (res >> 26) {
6901 case ALC880_HP_EVENT:
6902 alc883_mitac_hp_automute(codec);
6903 break;
6904 case ALC880_MIC_EVENT:
6905 /* alc883_mitac_mic_automute(codec); */
6906 break;
6907 }
6908}
6909
6910static struct hda_verb alc883_mitac_verbs[] = {
6911 /* HP */
6912 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6914 /* Subwoofer */
6915 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
6916 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6917
6918 /* enable unsolicited event */
6919 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6920 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
6921
6922 { } /* end */
6923};
6924
ccc656ce
KY
6925static struct hda_verb alc883_tagra_verbs[] = {
6926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6928
6929 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6930 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6931
6932 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6934 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6935
6936 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
6937 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6938 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6939 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
6940
6941 { } /* end */
6942};
6943
bc9f98a9
KY
6944static struct hda_verb alc883_lenovo_101e_verbs[] = {
6945 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6946 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6947 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6948 { } /* end */
6949};
6950
272a527c
KY
6951static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6952 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6954 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6956 { } /* end */
6957};
6958
6959static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6962 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6963 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6965 { } /* end */
6966};
6967
189609ae
KY
6968static struct hda_verb alc883_haier_w66_verbs[] = {
6969 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6970 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6971
6972 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6973
6974 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6975 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6976 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6978 { } /* end */
6979};
6980
4723c022 6981static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
6982 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
6984 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
6985 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
6986 { }
6987};
6988
4723c022 6989static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
6990 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
6991 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
6992 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
6993 { }
6994};
6995
4723c022 6996static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
6997 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6998 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6999 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7000 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7001 { }
7002};
7003
4723c022 7004static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7005 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7006 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7007 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7008 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7009 { }
7010};
7011
4723c022
CM
7012static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7013 { 2, alc888_3st_hp_2ch_init },
7014 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7015};
7016
272a527c
KY
7017/* toggle front-jack and RCA according to the hp-jack state */
7018static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7019{
7020 unsigned int present;
7021
7022 present = snd_hda_codec_read(codec, 0x1b, 0,
7023 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7024 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7025 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7026 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7028}
7029
7030/* toggle RCA according to the front-jack state */
7031static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7032{
7033 unsigned int present;
7034
7035 present = snd_hda_codec_read(codec, 0x14, 0,
7036 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7037 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7038 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7039}
47fd830a 7040
272a527c
KY
7041static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7042 unsigned int res)
7043{
7044 if ((res >> 26) == ALC880_HP_EVENT)
7045 alc888_lenovo_ms7195_front_automute(codec);
7046 if ((res >> 26) == ALC880_FRONT_EVENT)
7047 alc888_lenovo_ms7195_rca_automute(codec);
7048}
7049
7050static struct hda_verb alc883_medion_md2_verbs[] = {
7051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7053
7054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7055
7056 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7057 { } /* end */
7058};
7059
7060/* toggle speaker-output according to the hp-jack state */
7061static void alc883_medion_md2_automute(struct hda_codec *codec)
7062{
7063 unsigned int present;
7064
7065 present = snd_hda_codec_read(codec, 0x14, 0,
7066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7067 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7068 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7069}
7070
7071static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7072 unsigned int res)
7073{
7074 if ((res >> 26) == ALC880_HP_EVENT)
7075 alc883_medion_md2_automute(codec);
7076}
7077
ccc656ce
KY
7078/* toggle speaker-output according to the hp-jack state */
7079static void alc883_tagra_automute(struct hda_codec *codec)
7080{
7081 unsigned int present;
f12ab1e0 7082 unsigned char bits;
ccc656ce
KY
7083
7084 present = snd_hda_codec_read(codec, 0x14, 0,
7085 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7086 bits = present ? HDA_AMP_MUTE : 0;
7087 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7088 HDA_AMP_MUTE, bits);
82beb8fd
TI
7089 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7090 present ? 1 : 3);
ccc656ce
KY
7091}
7092
7093static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7094{
7095 if ((res >> 26) == ALC880_HP_EVENT)
7096 alc883_tagra_automute(codec);
7097}
7098
189609ae
KY
7099static void alc883_haier_w66_automute(struct hda_codec *codec)
7100{
7101 unsigned int present;
7102 unsigned char bits;
7103
7104 present = snd_hda_codec_read(codec, 0x1b, 0,
7105 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7106 bits = present ? 0x80 : 0;
7107 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7108 0x80, bits);
7109}
7110
7111static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7112 unsigned int res)
7113{
7114 if ((res >> 26) == ALC880_HP_EVENT)
7115 alc883_haier_w66_automute(codec);
7116}
7117
bc9f98a9
KY
7118static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7119{
7120 unsigned int present;
f12ab1e0 7121 unsigned char bits;
bc9f98a9
KY
7122
7123 present = snd_hda_codec_read(codec, 0x14, 0,
7124 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7125 bits = present ? HDA_AMP_MUTE : 0;
7126 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7127 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7128}
7129
7130static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7131{
7132 unsigned int present;
f12ab1e0 7133 unsigned char bits;
bc9f98a9
KY
7134
7135 present = snd_hda_codec_read(codec, 0x1b, 0,
7136 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7137 bits = present ? HDA_AMP_MUTE : 0;
7138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7139 HDA_AMP_MUTE, bits);
7140 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7141 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7142}
7143
7144static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7145 unsigned int res)
7146{
7147 if ((res >> 26) == ALC880_HP_EVENT)
7148 alc883_lenovo_101e_all_automute(codec);
7149 if ((res >> 26) == ALC880_FRONT_EVENT)
7150 alc883_lenovo_101e_ispeaker_automute(codec);
7151}
7152
676a9b53
TI
7153/* toggle speaker-output according to the hp-jack state */
7154static void alc883_acer_aspire_automute(struct hda_codec *codec)
7155{
7156 unsigned int present;
7157
7158 present = snd_hda_codec_read(codec, 0x14, 0,
7159 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7160 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7161 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7162 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7163 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7164}
7165
7166static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7167 unsigned int res)
7168{
7169 if ((res >> 26) == ALC880_HP_EVENT)
7170 alc883_acer_aspire_automute(codec);
7171}
7172
d1a991a6
KY
7173static struct hda_verb alc883_acer_eapd_verbs[] = {
7174 /* HP Pin: output 0 (0x0c) */
7175 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7176 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7177 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7178 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7179 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7180 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7182 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7183 /* eanable EAPD on medion laptop */
7184 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7185 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7186 /* enable unsolicited event */
7187 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7188 { }
7189};
7190
9c7f852e
TI
7191/*
7192 * generic initialization of ADC, input mixers and output mixers
7193 */
7194static struct hda_verb alc883_auto_init_verbs[] = {
7195 /*
7196 * Unmute ADC0-2 and set the default input to mic-in
7197 */
7198 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7199 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7200 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7202
cb53c626 7203 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7204 * mixer widget
f12ab1e0
TI
7205 * Note: PASD motherboards uses the Line In 2 as the input for
7206 * front panel mic (mic 2)
9c7f852e
TI
7207 */
7208 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7214
7215 /*
7216 * Set up output mixers (0x0c - 0x0f)
7217 */
7218 /* set vol=0 to output mixers */
7219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7220 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7223 /* set up input amps for analog loopback */
7224 /* Amp Indices: DAC = 0, mixer = 1 */
7225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7227 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7229 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7231 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7233 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7234 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7235
7236 /* FIXME: use matrix-type input source selection */
7237 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7238 /* Input mixer1 */
7239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7242 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7244 /* Input mixer2 */
7245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7248 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7250
7251 { }
7252};
7253
7254/* capture mixer elements */
7255static struct snd_kcontrol_new alc883_capture_mixer[] = {
7256 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7257 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7258 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7259 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7260 {
7261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7262 /* The multiple "Capture Source" controls confuse alsamixer
7263 * So call somewhat different..
7264 * FIXME: the controls appear in the "playback" view!
7265 */
7266 /* .name = "Capture Source", */
7267 .name = "Input Source",
7268 .count = 2,
7269 .info = alc882_mux_enum_info,
7270 .get = alc882_mux_enum_get,
7271 .put = alc882_mux_enum_put,
7272 },
7273 { } /* end */
7274};
7275
cb53c626
TI
7276#ifdef CONFIG_SND_HDA_POWER_SAVE
7277#define alc883_loopbacks alc880_loopbacks
7278#endif
7279
9c7f852e
TI
7280/* pcm configuration: identiacal with ALC880 */
7281#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7282#define alc883_pcm_analog_capture alc880_pcm_analog_capture
7283#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7284#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7285
7286/*
7287 * configuration and preset
7288 */
f5fcc13c
TI
7289static const char *alc883_models[ALC883_MODEL_LAST] = {
7290 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7291 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7292 [ALC883_3ST_6ch] = "3stack-6ch",
7293 [ALC883_6ST_DIG] = "6stack-dig",
7294 [ALC883_TARGA_DIG] = "targa-dig",
7295 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7296 [ALC883_ACER] = "acer",
2880a867 7297 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7298 [ALC883_MEDION] = "medion",
272a527c 7299 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7300 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7301 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7302 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7303 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7304 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7305 [ALC888_6ST_HP] = "6stack-hp",
7306 [ALC888_3ST_HP] = "3stack-hp",
a8848bd6 7307 [ALC883_MITAC] = "mitac",
f5fcc13c
TI
7308 [ALC883_AUTO] = "auto",
7309};
7310
7311static struct snd_pci_quirk alc883_cfg_tbl[] = {
7312 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7313 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7314 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7315 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7316 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
febe3375 7317 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7318 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7319 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7320 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7321 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7322 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7323 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7324 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7325 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7326 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7327 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7328 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7329 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7330 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
f5fcc13c 7331 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7332 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7333 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7334 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7335 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7336 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7337 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7338 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7339 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7340 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7341 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7342 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7343 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7344 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7345 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741
TI
7346 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7347 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7348 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7349 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7350 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7351 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7352 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7353 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7354 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
189609ae 7355 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7356 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7357 {}
7358};
7359
7360static struct alc_config_preset alc883_presets[] = {
7361 [ALC883_3ST_2ch_DIG] = {
7362 .mixers = { alc883_3ST_2ch_mixer },
7363 .init_verbs = { alc883_init_verbs },
7364 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7365 .dac_nids = alc883_dac_nids,
7366 .dig_out_nid = ALC883_DIGOUT_NID,
7367 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7368 .adc_nids = alc883_adc_nids,
7369 .dig_in_nid = ALC883_DIGIN_NID,
7370 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7371 .channel_mode = alc883_3ST_2ch_modes,
7372 .input_mux = &alc883_capture_source,
7373 },
7374 [ALC883_3ST_6ch_DIG] = {
7375 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7376 .init_verbs = { alc883_init_verbs },
7377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7378 .dac_nids = alc883_dac_nids,
7379 .dig_out_nid = ALC883_DIGOUT_NID,
7380 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7381 .adc_nids = alc883_adc_nids,
7382 .dig_in_nid = ALC883_DIGIN_NID,
7383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7384 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7385 .need_dac_fix = 1,
9c7f852e 7386 .input_mux = &alc883_capture_source,
f12ab1e0 7387 },
9c7f852e
TI
7388 [ALC883_3ST_6ch] = {
7389 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7390 .init_verbs = { alc883_init_verbs },
7391 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7392 .dac_nids = alc883_dac_nids,
7393 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7394 .adc_nids = alc883_adc_nids,
7395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7396 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7397 .need_dac_fix = 1,
9c7f852e 7398 .input_mux = &alc883_capture_source,
f12ab1e0 7399 },
9c7f852e
TI
7400 [ALC883_6ST_DIG] = {
7401 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7402 .init_verbs = { alc883_init_verbs },
7403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7404 .dac_nids = alc883_dac_nids,
7405 .dig_out_nid = ALC883_DIGOUT_NID,
7406 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7407 .adc_nids = alc883_adc_nids,
7408 .dig_in_nid = ALC883_DIGIN_NID,
7409 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7410 .channel_mode = alc883_sixstack_modes,
7411 .input_mux = &alc883_capture_source,
7412 },
ccc656ce
KY
7413 [ALC883_TARGA_DIG] = {
7414 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7415 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7416 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7417 .dac_nids = alc883_dac_nids,
7418 .dig_out_nid = ALC883_DIGOUT_NID,
7419 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7420 .adc_nids = alc883_adc_nids,
7421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7422 .channel_mode = alc883_3ST_6ch_modes,
7423 .need_dac_fix = 1,
7424 .input_mux = &alc883_capture_source,
7425 .unsol_event = alc883_tagra_unsol_event,
7426 .init_hook = alc883_tagra_automute,
7427 },
7428 [ALC883_TARGA_2ch_DIG] = {
7429 .mixers = { alc883_tagra_2ch_mixer},
7430 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7432 .dac_nids = alc883_dac_nids,
7433 .dig_out_nid = ALC883_DIGOUT_NID,
7434 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7435 .adc_nids = alc883_adc_nids,
7436 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7437 .channel_mode = alc883_3ST_2ch_modes,
7438 .input_mux = &alc883_capture_source,
7439 .unsol_event = alc883_tagra_unsol_event,
7440 .init_hook = alc883_tagra_automute,
7441 },
bab282b9 7442 [ALC883_ACER] = {
676a9b53 7443 .mixers = { alc883_base_mixer },
bab282b9
VA
7444 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7445 * and the headphone jack. Turn this on and rely on the
7446 * standard mute methods whenever the user wants to turn
7447 * these outputs off.
7448 */
7449 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7450 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7451 .dac_nids = alc883_dac_nids,
7452 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7453 .adc_nids = alc883_adc_nids,
7454 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7455 .channel_mode = alc883_3ST_2ch_modes,
7456 .input_mux = &alc883_capture_source,
7457 },
2880a867 7458 [ALC883_ACER_ASPIRE] = {
676a9b53 7459 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7460 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7462 .dac_nids = alc883_dac_nids,
7463 .dig_out_nid = ALC883_DIGOUT_NID,
7464 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7465 .adc_nids = alc883_adc_nids,
7466 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7467 .channel_mode = alc883_3ST_2ch_modes,
7468 .input_mux = &alc883_capture_source,
676a9b53
TI
7469 .unsol_event = alc883_acer_aspire_unsol_event,
7470 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7471 },
c07584c8
TD
7472 [ALC883_MEDION] = {
7473 .mixers = { alc883_fivestack_mixer,
7474 alc883_chmode_mixer },
7475 .init_verbs = { alc883_init_verbs,
b373bdeb 7476 alc883_medion_eapd_verbs },
c07584c8
TD
7477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7478 .dac_nids = alc883_dac_nids,
7479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7480 .adc_nids = alc883_adc_nids,
7481 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7482 .channel_mode = alc883_sixstack_modes,
7483 .input_mux = &alc883_capture_source,
b373bdeb 7484 },
272a527c
KY
7485 [ALC883_MEDION_MD2] = {
7486 .mixers = { alc883_medion_md2_mixer},
7487 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7488 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7489 .dac_nids = alc883_dac_nids,
7490 .dig_out_nid = ALC883_DIGOUT_NID,
7491 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7492 .adc_nids = alc883_adc_nids,
7493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7494 .channel_mode = alc883_3ST_2ch_modes,
7495 .input_mux = &alc883_capture_source,
7496 .unsol_event = alc883_medion_md2_unsol_event,
7497 .init_hook = alc883_medion_md2_automute,
7498 },
b373bdeb 7499 [ALC883_LAPTOP_EAPD] = {
676a9b53 7500 .mixers = { alc883_base_mixer },
b373bdeb
AN
7501 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7502 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7503 .dac_nids = alc883_dac_nids,
7504 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7505 .adc_nids = alc883_adc_nids,
7506 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7507 .channel_mode = alc883_3ST_2ch_modes,
7508 .input_mux = &alc883_capture_source,
7509 },
bc9f98a9
KY
7510 [ALC883_LENOVO_101E_2ch] = {
7511 .mixers = { alc883_lenovo_101e_2ch_mixer},
7512 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7513 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7514 .dac_nids = alc883_dac_nids,
7515 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7516 .adc_nids = alc883_adc_nids,
7517 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7518 .channel_mode = alc883_3ST_2ch_modes,
7519 .input_mux = &alc883_lenovo_101e_capture_source,
7520 .unsol_event = alc883_lenovo_101e_unsol_event,
7521 .init_hook = alc883_lenovo_101e_all_automute,
7522 },
272a527c
KY
7523 [ALC883_LENOVO_NB0763] = {
7524 .mixers = { alc883_lenovo_nb0763_mixer },
7525 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7526 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7527 .dac_nids = alc883_dac_nids,
7528 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7529 .adc_nids = alc883_adc_nids,
7530 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7531 .channel_mode = alc883_3ST_2ch_modes,
7532 .need_dac_fix = 1,
7533 .input_mux = &alc883_lenovo_nb0763_capture_source,
7534 .unsol_event = alc883_medion_md2_unsol_event,
7535 .init_hook = alc883_medion_md2_automute,
7536 },
7537 [ALC888_LENOVO_MS7195_DIG] = {
7538 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7539 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7541 .dac_nids = alc883_dac_nids,
7542 .dig_out_nid = ALC883_DIGOUT_NID,
7543 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7544 .adc_nids = alc883_adc_nids,
7545 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7546 .channel_mode = alc883_3ST_6ch_modes,
7547 .need_dac_fix = 1,
7548 .input_mux = &alc883_capture_source,
7549 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7550 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7551 },
7552 [ALC883_HAIER_W66] = {
7553 .mixers = { alc883_tagra_2ch_mixer},
7554 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7555 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7556 .dac_nids = alc883_dac_nids,
7557 .dig_out_nid = ALC883_DIGOUT_NID,
7558 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7559 .adc_nids = alc883_adc_nids,
7560 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7561 .channel_mode = alc883_3ST_2ch_modes,
7562 .input_mux = &alc883_capture_source,
7563 .unsol_event = alc883_haier_w66_unsol_event,
7564 .init_hook = alc883_haier_w66_automute,
272a527c 7565 },
4723c022
CM
7566 [ALC888_6ST_HP] = {
7567 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7568 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7569 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7570 .dac_nids = alc883_dac_nids,
7571 .dig_out_nid = ALC883_DIGOUT_NID,
7572 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7573 .adc_nids = alc883_adc_nids,
7574 .dig_in_nid = ALC883_DIGIN_NID,
7575 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7576 .channel_mode = alc883_sixstack_modes,
7577 .input_mux = &alc883_capture_source,
7578 },
4723c022
CM
7579 [ALC888_3ST_HP] = {
7580 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7581 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7583 .dac_nids = alc883_dac_nids,
7584 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7585 .adc_nids = alc883_adc_nids,
4723c022
CM
7586 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7587 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7588 .need_dac_fix = 1,
7589 .input_mux = &alc883_capture_source,
7590 },
a8848bd6
AS
7591 [ALC883_MITAC] = {
7592 .mixers = { alc883_mitac_mixer },
7593 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7594 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7595 .dac_nids = alc883_dac_nids,
7596 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7597 .adc_nids = alc883_adc_nids,
7598 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7599 .channel_mode = alc883_3ST_2ch_modes,
7600 .input_mux = &alc883_capture_source,
7601 .unsol_event = alc883_mitac_unsol_event,
7602 .init_hook = alc883_mitac_automute,
7603 },
9c7f852e
TI
7604};
7605
7606
7607/*
7608 * BIOS auto configuration
7609 */
7610static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7611 hda_nid_t nid, int pin_type,
7612 int dac_idx)
7613{
7614 /* set as output */
7615 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7616 int idx;
7617
9c7f852e
TI
7618 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7619 idx = 4;
7620 else
7621 idx = spec->multiout.dac_nids[dac_idx] - 2;
7622
7623 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7624 pin_type);
7625 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7626 AMP_OUT_UNMUTE);
7627 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7628
7629}
7630
7631static void alc883_auto_init_multi_out(struct hda_codec *codec)
7632{
7633 struct alc_spec *spec = codec->spec;
7634 int i;
7635
bc9f98a9 7636 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7637 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7638 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7639 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7640 if (nid)
baba8ee9 7641 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7642 i);
9c7f852e
TI
7643 }
7644}
7645
7646static void alc883_auto_init_hp_out(struct hda_codec *codec)
7647{
7648 struct alc_spec *spec = codec->spec;
7649 hda_nid_t pin;
7650
eb06ed8f 7651 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7652 if (pin) /* connect to front */
7653 /* use dac 0 */
7654 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7655}
7656
7657#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7658#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7659
7660static void alc883_auto_init_analog_input(struct hda_codec *codec)
7661{
7662 struct alc_spec *spec = codec->spec;
7663 int i;
7664
7665 for (i = 0; i < AUTO_PIN_LAST; i++) {
7666 hda_nid_t nid = spec->autocfg.input_pins[i];
7667 if (alc883_is_input_pin(nid)) {
7668 snd_hda_codec_write(codec, nid, 0,
7669 AC_VERB_SET_PIN_WIDGET_CONTROL,
7670 (i <= AUTO_PIN_FRONT_MIC ?
7671 PIN_VREF80 : PIN_IN));
7672 if (nid != ALC883_PIN_CD_NID)
7673 snd_hda_codec_write(codec, nid, 0,
7674 AC_VERB_SET_AMP_GAIN_MUTE,
7675 AMP_OUT_MUTE);
7676 }
7677 }
7678}
7679
7680/* almost identical with ALC880 parser... */
7681static int alc883_parse_auto_config(struct hda_codec *codec)
7682{
7683 struct alc_spec *spec = codec->spec;
7684 int err = alc880_parse_auto_config(codec);
7685
7686 if (err < 0)
7687 return err;
776e184e
TI
7688 else if (!err)
7689 return 0; /* no config found */
7690
7691 err = alc_auto_add_mic_boost(codec);
7692 if (err < 0)
7693 return err;
7694
7695 /* hack - override the init verbs */
7696 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
7697 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7698 spec->num_mixers++;
776e184e
TI
7699
7700 return 1; /* config found */
9c7f852e
TI
7701}
7702
7703/* additional initialization for auto-configuration model */
7704static void alc883_auto_init(struct hda_codec *codec)
7705{
7706 alc883_auto_init_multi_out(codec);
7707 alc883_auto_init_hp_out(codec);
7708 alc883_auto_init_analog_input(codec);
7709}
7710
7711static int patch_alc883(struct hda_codec *codec)
7712{
7713 struct alc_spec *spec;
7714 int err, board_config;
7715
7716 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7717 if (spec == NULL)
7718 return -ENOMEM;
7719
7720 codec->spec = spec;
7721
f5fcc13c
TI
7722 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7723 alc883_models,
7724 alc883_cfg_tbl);
7725 if (board_config < 0) {
9c7f852e
TI
7726 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7727 "trying auto-probe from BIOS...\n");
7728 board_config = ALC883_AUTO;
7729 }
7730
7731 if (board_config == ALC883_AUTO) {
7732 /* automatic parse from the BIOS config */
7733 err = alc883_parse_auto_config(codec);
7734 if (err < 0) {
7735 alc_free(codec);
7736 return err;
f12ab1e0 7737 } else if (!err) {
9c7f852e
TI
7738 printk(KERN_INFO
7739 "hda_codec: Cannot set up configuration "
7740 "from BIOS. Using base mode...\n");
7741 board_config = ALC883_3ST_2ch_DIG;
7742 }
7743 }
7744
7745 if (board_config != ALC883_AUTO)
7746 setup_preset(spec, &alc883_presets[board_config]);
7747
7748 spec->stream_name_analog = "ALC883 Analog";
7749 spec->stream_analog_playback = &alc883_pcm_analog_playback;
7750 spec->stream_analog_capture = &alc883_pcm_analog_capture;
7751
7752 spec->stream_name_digital = "ALC883 Digital";
7753 spec->stream_digital_playback = &alc883_pcm_digital_playback;
7754 spec->stream_digital_capture = &alc883_pcm_digital_capture;
7755
f12ab1e0 7756 if (!spec->adc_nids && spec->input_mux) {
4b146cb0
TI
7757 spec->adc_nids = alc883_adc_nids;
7758 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7759 }
9c7f852e
TI
7760
7761 codec->patch_ops = alc_patch_ops;
7762 if (board_config == ALC883_AUTO)
7763 spec->init_hook = alc883_auto_init;
cb53c626
TI
7764#ifdef CONFIG_SND_HDA_POWER_SAVE
7765 if (!spec->loopback.amplist)
7766 spec->loopback.amplist = alc883_loopbacks;
7767#endif
9c7f852e
TI
7768
7769 return 0;
7770}
7771
7772/*
7773 * ALC262 support
7774 */
7775
7776#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
7777#define ALC262_DIGIN_NID ALC880_DIGIN_NID
7778
7779#define alc262_dac_nids alc260_dac_nids
7780#define alc262_adc_nids alc882_adc_nids
7781#define alc262_adc_nids_alt alc882_adc_nids_alt
7782
7783#define alc262_modes alc260_modes
7784#define alc262_capture_source alc882_capture_source
7785
7786static struct snd_kcontrol_new alc262_base_mixer[] = {
7787 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7788 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7789 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7790 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7792 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7796 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7797 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7798 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7799 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7800 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7801 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7802 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7803 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7804 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7805 { } /* end */
7806};
7807
ccc656ce
KY
7808static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7810 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7811 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7812 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7813 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7814 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7815 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7816 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
7818 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7819 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce
KY
7821 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7822 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7823 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7824 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7825 { } /* end */
7826};
7827
9c7f852e
TI
7828static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7830 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7832 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7833 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7834
7835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7837 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
7838 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7839 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 7840 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
7841 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7842 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7845 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7846 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7847 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7848 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7849 { } /* end */
7850};
7851
cd7509a4
KY
7852static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7854 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7857 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7858 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7859 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7860 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 7861 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
7862 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7863 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7866 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7867 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7868 { } /* end */
7869};
7870
7871static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7872 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7873 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 7874 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
7875 { } /* end */
7876};
7877
66d2a9d6
KY
7878static struct hda_bind_ctls alc262_hp_t5735_bind_front_vol = {
7879 .ops = &snd_hda_bind_vol,
7880 .values = {
7881 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7882 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
7883 0
7884 },
7885};
7886
7887static struct hda_bind_ctls alc262_hp_t5735_bind_front_sw = {
7888 .ops = &snd_hda_bind_sw,
7889 .values = {
7890 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
7891 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7892 0
7893 },
7894};
7895
7896/* mute/unmute internal speaker according to the hp jack and mute state */
7897static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
7898{
7899 struct alc_spec *spec = codec->spec;
7900 unsigned int mute;
7901
7902 if (force || !spec->sense_updated) {
7903 unsigned int present;
7904 present = snd_hda_codec_read(codec, 0x15, 0,
7905 AC_VERB_GET_PIN_SENSE, 0);
7906 spec->jack_present = (present & 0x80000000) != 0;
7907 spec->sense_updated = 1;
7908 }
7909 if (spec->jack_present)
7910 mute = (0x7080 | ((0)<<8)); /* mute internal speaker */
7911 else /* unmute internal speaker if necessary */
7912 mute = (0x7000 | ((0)<<8));
7913 snd_hda_codec_write(codec, 0x0c, 0,
7914 AC_VERB_SET_AMP_GAIN_MUTE, mute );
7915}
7916
7917static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
7918 unsigned int res)
7919{
7920 if ((res >> 26) != ALC880_HP_EVENT)
7921 return;
7922 alc262_hp_t5735_automute(codec, 1);
7923}
7924
7925static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
7926{
7927 alc262_hp_t5735_automute(codec, 1);
7928}
7929
7930static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
7931 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_t5735_bind_front_vol),
7932 HDA_BIND_SW("PCM Playback Switch",&alc262_hp_t5735_bind_front_sw),
7933 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7934 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7935 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7936 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7937 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7940 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7942 { } /* end */
7943};
7944
7945static struct hda_verb alc262_hp_t5735_verbs[] = {
7946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7948
7949 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7950 { }
7951};
7952
0724ea2a
TI
7953/* bind hp and internal speaker mute (with plug check) */
7954static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7955 struct snd_ctl_elem_value *ucontrol)
7956{
7957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7958 long *valp = ucontrol->value.integer.value;
7959 int change;
7960
7961 /* change hp mute */
7962 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7963 HDA_AMP_MUTE,
7964 valp[0] ? 0 : HDA_AMP_MUTE);
7965 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7966 HDA_AMP_MUTE,
7967 valp[1] ? 0 : HDA_AMP_MUTE);
7968 if (change) {
7969 /* change speaker according to HP jack state */
7970 struct alc_spec *spec = codec->spec;
7971 unsigned int mute;
7972 if (spec->jack_present)
7973 mute = HDA_AMP_MUTE;
7974 else
7975 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7976 HDA_OUTPUT, 0);
7977 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7978 HDA_AMP_MUTE, mute);
7979 }
7980 return change;
7981}
5b31954e 7982
272a527c 7983static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
7984 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7985 {
7986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7987 .name = "Master Playback Switch",
7988 .info = snd_hda_mixer_amp_switch_info,
7989 .get = snd_hda_mixer_amp_switch_get,
7990 .put = alc262_sony_master_sw_put,
7991 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7992 },
272a527c
KY
7993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7995 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7996 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7997 { } /* end */
7998};
7999
83c34218
KY
8000static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8002 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8006 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8007 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8008 { } /* end */
8009};
272a527c 8010
9c7f852e
TI
8011#define alc262_capture_mixer alc882_capture_mixer
8012#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8013
8014/*
8015 * generic initialization of ADC, input mixers and output mixers
8016 */
8017static struct hda_verb alc262_init_verbs[] = {
8018 /*
8019 * Unmute ADC0-2 and set the default input to mic-in
8020 */
8021 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8023 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8025 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027
cb53c626 8028 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8029 * mixer widget
f12ab1e0
TI
8030 * Note: PASD motherboards uses the Line In 2 as the input for
8031 * front panel mic (mic 2)
9c7f852e
TI
8032 */
8033 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8035 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8036 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8037 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8039
8040 /*
df694daa
KY
8041 * Set up output mixers (0x0c - 0x0e)
8042 */
8043 /* set vol=0 to output mixers */
8044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8045 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8046 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8047 /* set up input amps for analog loopback */
8048 /* Amp Indices: DAC = 0, mixer = 1 */
8049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8050 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8051 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8052 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8054 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8055
8056 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8060 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8061 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8062
8063 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8065 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8066 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8067 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8068
8069 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8070 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8071
8072 /* FIXME: use matrix-type input source selection */
8073 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8074 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8079 /* Input mixer2 */
8080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8084 /* Input mixer3 */
8085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8089
8090 { }
8091};
1da177e4 8092
ccc656ce
KY
8093static struct hda_verb alc262_hippo_unsol_verbs[] = {
8094 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8096 {}
8097};
8098
8099static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8103
8104 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8105 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8106 {}
8107};
8108
272a527c
KY
8109static struct hda_verb alc262_sony_unsol_verbs[] = {
8110 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8111 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8112 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8113
8114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8115 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8116};
8117
ccc656ce 8118/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8119static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8120{
8121 struct alc_spec *spec = codec->spec;
8122 unsigned int mute;
5b31954e 8123 unsigned int present;
ccc656ce 8124
5b31954e
TI
8125 /* need to execute and sync at first */
8126 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8127 present = snd_hda_codec_read(codec, 0x15, 0,
8128 AC_VERB_GET_PIN_SENSE, 0);
8129 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8130 if (spec->jack_present) {
8131 /* mute internal speaker */
47fd830a
TI
8132 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8133 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8134 } else {
8135 /* unmute internal speaker if necessary */
8136 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8137 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8138 HDA_AMP_MUTE, mute);
ccc656ce
KY
8139 }
8140}
8141
8142/* unsolicited event for HP jack sensing */
8143static void alc262_hippo_unsol_event(struct hda_codec *codec,
8144 unsigned int res)
8145{
8146 if ((res >> 26) != ALC880_HP_EVENT)
8147 return;
5b31954e 8148 alc262_hippo_automute(codec);
ccc656ce
KY
8149}
8150
5b31954e 8151static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8152{
ccc656ce 8153 unsigned int mute;
5b31954e 8154 unsigned int present;
ccc656ce 8155
5b31954e
TI
8156 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8157 present = snd_hda_codec_read(codec, 0x1b, 0,
8158 AC_VERB_GET_PIN_SENSE, 0);
8159 present = (present & 0x80000000) != 0;
8160 if (present) {
ccc656ce 8161 /* mute internal speaker */
47fd830a
TI
8162 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8163 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8164 } else {
8165 /* unmute internal speaker if necessary */
8166 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8167 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8168 HDA_AMP_MUTE, mute);
ccc656ce
KY
8169 }
8170}
8171
8172/* unsolicited event for HP jack sensing */
8173static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8174 unsigned int res)
8175{
8176 if ((res >> 26) != ALC880_HP_EVENT)
8177 return;
5b31954e 8178 alc262_hippo1_automute(codec);
ccc656ce
KY
8179}
8180
834be88d
TI
8181/*
8182 * fujitsu model
8183 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8184 */
8185
8186#define ALC_HP_EVENT 0x37
8187
8188static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8189 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8190 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8191 {}
8192};
8193
8194static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8195 .num_items = 3,
834be88d
TI
8196 .items = {
8197 { "Mic", 0x0 },
39d3ed38 8198 { "Int Mic", 0x1 },
834be88d
TI
8199 { "CD", 0x4 },
8200 },
8201};
8202
9c7f852e
TI
8203static struct hda_input_mux alc262_HP_capture_source = {
8204 .num_items = 5,
8205 .items = {
8206 { "Mic", 0x0 },
accbe498 8207 { "Front Mic", 0x1 },
9c7f852e
TI
8208 { "Line", 0x2 },
8209 { "CD", 0x4 },
8210 { "AUX IN", 0x6 },
8211 },
8212};
8213
accbe498 8214static struct hda_input_mux alc262_HP_D7000_capture_source = {
8215 .num_items = 4,
8216 .items = {
8217 { "Mic", 0x0 },
8218 { "Front Mic", 0x2 },
8219 { "Line", 0x1 },
8220 { "CD", 0x4 },
8221 },
8222};
8223
834be88d
TI
8224/* mute/unmute internal speaker according to the hp jack and mute state */
8225static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8226{
8227 struct alc_spec *spec = codec->spec;
8228 unsigned int mute;
8229
f12ab1e0 8230 if (force || !spec->sense_updated) {
834be88d
TI
8231 unsigned int present;
8232 /* need to execute and sync at first */
8233 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8234 present = snd_hda_codec_read(codec, 0x14, 0,
8235 AC_VERB_GET_PIN_SENSE, 0);
8236 spec->jack_present = (present & 0x80000000) != 0;
8237 spec->sense_updated = 1;
8238 }
8239 if (spec->jack_present) {
8240 /* mute internal speaker */
47fd830a
TI
8241 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8242 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8243 } else {
8244 /* unmute internal speaker if necessary */
8245 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8246 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8247 HDA_AMP_MUTE, mute);
834be88d
TI
8248 }
8249}
8250
8251/* unsolicited event for HP jack sensing */
8252static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8253 unsigned int res)
8254{
8255 if ((res >> 26) != ALC_HP_EVENT)
8256 return;
8257 alc262_fujitsu_automute(codec, 1);
8258}
8259
8260/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8261static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8262 .ops = &snd_hda_bind_vol,
8263 .values = {
8264 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8265 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8266 0
8267 },
8268};
834be88d
TI
8269
8270/* bind hp and internal speaker mute (with plug check) */
8271static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8272 struct snd_ctl_elem_value *ucontrol)
8273{
8274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8275 long *valp = ucontrol->value.integer.value;
8276 int change;
8277
8278 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8279 HDA_AMP_MUTE,
8280 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8281 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8282 HDA_AMP_MUTE,
8283 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8284 if (change)
8285 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8286 return change;
8287}
8288
8289static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8290 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8291 {
8292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8293 .name = "Master Playback Switch",
8294 .info = snd_hda_mixer_amp_switch_info,
8295 .get = snd_hda_mixer_amp_switch_get,
8296 .put = alc262_fujitsu_master_sw_put,
8297 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8298 },
8299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8303 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8304 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8305 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8306 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8307 { } /* end */
8308};
8309
304dcaac
TI
8310/* additional init verbs for Benq laptops */
8311static struct hda_verb alc262_EAPD_verbs[] = {
8312 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8313 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8314 {}
8315};
8316
83c34218
KY
8317static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8318 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8320
8321 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8322 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8323 {}
8324};
8325
f651b50b
TD
8326/* Samsung Q1 Ultra Vista model setup */
8327static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8332 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8334 { } /* end */
8335};
8336
8337static struct hda_verb alc262_ultra_verbs[] = {
8338 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8341 /* Mic is on Node 0x19 */
8342 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8343 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8345 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8349 {}
8350};
8351
8352static struct hda_input_mux alc262_ultra_capture_source = {
8353 .num_items = 1,
8354 .items = {
8355 { "Mic", 0x1 },
8356 },
8357};
8358
8359/* mute/unmute internal speaker according to the hp jack and mute state */
8360static void alc262_ultra_automute(struct hda_codec *codec)
8361{
8362 struct alc_spec *spec = codec->spec;
8363 unsigned int mute;
8364 unsigned int present;
8365
8366 /* need to execute and sync at first */
8367 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8368 present = snd_hda_codec_read(codec, 0x15, 0,
8369 AC_VERB_GET_PIN_SENSE, 0);
8370 spec->jack_present = (present & 0x80000000) != 0;
8371 if (spec->jack_present) {
8372 /* mute internal speaker */
8373 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8374 HDA_AMP_MUTE, HDA_AMP_MUTE);
8375 } else {
8376 /* unmute internal speaker if necessary */
8377 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8378 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8379 HDA_AMP_MUTE, mute);
8380 }
8381}
8382
8383/* unsolicited event for HP jack sensing */
8384static void alc262_ultra_unsol_event(struct hda_codec *codec,
8385 unsigned int res)
8386{
8387 if ((res >> 26) != ALC880_HP_EVENT)
8388 return;
8389 alc262_ultra_automute(codec);
8390}
8391
df694daa 8392/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8393static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8394 const struct auto_pin_cfg *cfg)
df694daa
KY
8395{
8396 hda_nid_t nid;
8397 int err;
8398
8399 spec->multiout.num_dacs = 1; /* only use one dac */
8400 spec->multiout.dac_nids = spec->private_dac_nids;
8401 spec->multiout.dac_nids[0] = 2;
8402
8403 nid = cfg->line_out_pins[0];
8404 if (nid) {
f12ab1e0
TI
8405 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8406 "Front Playback Volume",
8407 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8408 if (err < 0)
df694daa 8409 return err;
f12ab1e0
TI
8410 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8411 "Front Playback Switch",
8412 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8413 if (err < 0)
df694daa
KY
8414 return err;
8415 }
8416
82bc955f 8417 nid = cfg->speaker_pins[0];
df694daa
KY
8418 if (nid) {
8419 if (nid == 0x16) {
f12ab1e0
TI
8420 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8421 "Speaker Playback Volume",
8422 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8423 HDA_OUTPUT));
8424 if (err < 0)
df694daa 8425 return err;
f12ab1e0
TI
8426 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8427 "Speaker Playback Switch",
8428 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8429 HDA_OUTPUT));
8430 if (err < 0)
df694daa
KY
8431 return err;
8432 } else {
f12ab1e0
TI
8433 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8434 "Speaker Playback Switch",
8435 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8436 HDA_OUTPUT));
8437 if (err < 0)
df694daa
KY
8438 return err;
8439 }
8440 }
eb06ed8f 8441 nid = cfg->hp_pins[0];
df694daa
KY
8442 if (nid) {
8443 /* spec->multiout.hp_nid = 2; */
8444 if (nid == 0x16) {
f12ab1e0
TI
8445 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8446 "Headphone Playback Volume",
8447 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8448 HDA_OUTPUT));
8449 if (err < 0)
df694daa 8450 return err;
f12ab1e0
TI
8451 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8452 "Headphone Playback Switch",
8453 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8454 HDA_OUTPUT));
8455 if (err < 0)
df694daa
KY
8456 return err;
8457 } else {
f12ab1e0
TI
8458 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8459 "Headphone Playback Switch",
8460 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8461 HDA_OUTPUT));
8462 if (err < 0)
df694daa
KY
8463 return err;
8464 }
8465 }
f12ab1e0 8466 return 0;
df694daa
KY
8467}
8468
8469/* identical with ALC880 */
f12ab1e0
TI
8470#define alc262_auto_create_analog_input_ctls \
8471 alc880_auto_create_analog_input_ctls
df694daa
KY
8472
8473/*
8474 * generic initialization of ADC, input mixers and output mixers
8475 */
8476static struct hda_verb alc262_volume_init_verbs[] = {
8477 /*
8478 * Unmute ADC0-2 and set the default input to mic-in
8479 */
8480 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8482 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8484 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486
cb53c626 8487 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8488 * mixer widget
f12ab1e0
TI
8489 * Note: PASD motherboards uses the Line In 2 as the input for
8490 * front panel mic (mic 2)
df694daa
KY
8491 */
8492 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8498
8499 /*
8500 * Set up output mixers (0x0c - 0x0f)
8501 */
8502 /* set vol=0 to output mixers */
8503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8506
8507 /* set up input amps for analog loopback */
8508 /* Amp Indices: DAC = 0, mixer = 1 */
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8515
8516 /* FIXME: use matrix-type input source selection */
8517 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8518 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8523 /* Input mixer2 */
8524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8528 /* Input mixer3 */
8529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8533
8534 { }
8535};
8536
9c7f852e
TI
8537static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8538 /*
8539 * Unmute ADC0-2 and set the default input to mic-in
8540 */
8541 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8542 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8543 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8544 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8545 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8547
cb53c626 8548 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8549 * mixer widget
f12ab1e0
TI
8550 * Note: PASD motherboards uses the Line In 2 as the input for
8551 * front panel mic (mic 2)
9c7f852e
TI
8552 */
8553 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8554 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8557 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8558 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8559 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8560 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
8561
8562 /*
8563 * Set up output mixers (0x0c - 0x0e)
8564 */
8565 /* set vol=0 to output mixers */
8566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8569
8570 /* set up input amps for analog loopback */
8571 /* Amp Indices: DAC = 0, mixer = 1 */
8572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8575 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8578
8579 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8582
8583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8585
8586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8587 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8588
8589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8590 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8591 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8593 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8594
8595 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8599 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8600 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8601
8602
8603 /* FIXME: use matrix-type input source selection */
8604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8610 /* Input mixer2 */
8611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8615 /* Input mixer3 */
8616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8620
8621 { }
8622};
8623
cd7509a4
KY
8624static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8625 /*
8626 * Unmute ADC0-2 and set the default input to mic-in
8627 */
8628 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8629 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8630 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8632 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634
cb53c626 8635 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
8636 * mixer widget
8637 * Note: PASD motherboards uses the Line In 2 as the input for front
8638 * panel mic (mic 2)
8639 */
8640 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
8649 /*
8650 * Set up output mixers (0x0c - 0x0e)
8651 */
8652 /* set vol=0 to output mixers */
8653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8654 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8655 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656
8657 /* set up input amps for analog loopback */
8658 /* Amp Indices: DAC = 0, mixer = 1 */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8661 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8662 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8663 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665
8666
8667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
8668 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
8669 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
8670 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
8671 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
8672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
8673 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
8674
8675 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8677
8678 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8680
8681 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8684 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8685 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8686 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8687
8688 /* FIXME: use matrix-type input source selection */
8689 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8690 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8696 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8698 /* Input mixer2 */
8699 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8700 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8701 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8702 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8703 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8704 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8705 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8706 /* Input mixer3 */
8707 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8708 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8709 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8712 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8714
8715 { }
8716};
8717
cb53c626
TI
8718#ifdef CONFIG_SND_HDA_POWER_SAVE
8719#define alc262_loopbacks alc880_loopbacks
8720#endif
8721
df694daa
KY
8722/* pcm configuration: identiacal with ALC880 */
8723#define alc262_pcm_analog_playback alc880_pcm_analog_playback
8724#define alc262_pcm_analog_capture alc880_pcm_analog_capture
8725#define alc262_pcm_digital_playback alc880_pcm_digital_playback
8726#define alc262_pcm_digital_capture alc880_pcm_digital_capture
8727
8728/*
8729 * BIOS auto configuration
8730 */
8731static int alc262_parse_auto_config(struct hda_codec *codec)
8732{
8733 struct alc_spec *spec = codec->spec;
8734 int err;
8735 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8736
f12ab1e0
TI
8737 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8738 alc262_ignore);
8739 if (err < 0)
df694daa 8740 return err;
f12ab1e0 8741 if (!spec->autocfg.line_outs)
df694daa 8742 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
8743 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8744 if (err < 0)
8745 return err;
8746 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8747 if (err < 0)
df694daa
KY
8748 return err;
8749
8750 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8751
8752 if (spec->autocfg.dig_out_pin)
8753 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8754 if (spec->autocfg.dig_in_pin)
8755 spec->dig_in_nid = ALC262_DIGIN_NID;
8756
8757 if (spec->kctl_alloc)
8758 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8759
8760 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 8761 spec->num_mux_defs = 1;
df694daa
KY
8762 spec->input_mux = &spec->private_imux;
8763
776e184e
TI
8764 err = alc_auto_add_mic_boost(codec);
8765 if (err < 0)
8766 return err;
8767
df694daa
KY
8768 return 1;
8769}
8770
8771#define alc262_auto_init_multi_out alc882_auto_init_multi_out
8772#define alc262_auto_init_hp_out alc882_auto_init_hp_out
8773#define alc262_auto_init_analog_input alc882_auto_init_analog_input
8774
8775
8776/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 8777static void alc262_auto_init(struct hda_codec *codec)
df694daa 8778{
df694daa
KY
8779 alc262_auto_init_multi_out(codec);
8780 alc262_auto_init_hp_out(codec);
8781 alc262_auto_init_analog_input(codec);
df694daa
KY
8782}
8783
8784/*
8785 * configuration and preset
8786 */
f5fcc13c
TI
8787static const char *alc262_models[ALC262_MODEL_LAST] = {
8788 [ALC262_BASIC] = "basic",
8789 [ALC262_HIPPO] = "hippo",
8790 [ALC262_HIPPO_1] = "hippo_1",
8791 [ALC262_FUJITSU] = "fujitsu",
8792 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 8793 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 8794 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
f5fcc13c 8795 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
8796 [ALC262_BENQ_T31] = "benq-t31",
8797 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 8798 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
8799 [ALC262_AUTO] = "auto",
8800};
8801
8802static struct snd_pci_quirk alc262_cfg_tbl[] = {
8803 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8804 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 8805 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
8806 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8807 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 8808 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 8809 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 8810 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 8811 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 8812 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8813 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8814 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8815 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8816 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8817 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 8818 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 8819 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
8820 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8821 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8822 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
8823 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8824 ALC262_HP_TC_T5735),
ac3e3741 8825 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 8826 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 8827 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 8828 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
8829 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8830 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
f651b50b 8831 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
8832 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8833 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8834 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
8835 {}
8836};
8837
8838static struct alc_config_preset alc262_presets[] = {
8839 [ALC262_BASIC] = {
8840 .mixers = { alc262_base_mixer },
8841 .init_verbs = { alc262_init_verbs },
8842 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8843 .dac_nids = alc262_dac_nids,
8844 .hp_nid = 0x03,
8845 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8846 .channel_mode = alc262_modes,
a3bcba38 8847 .input_mux = &alc262_capture_source,
df694daa 8848 },
ccc656ce
KY
8849 [ALC262_HIPPO] = {
8850 .mixers = { alc262_base_mixer },
8851 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8852 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8853 .dac_nids = alc262_dac_nids,
8854 .hp_nid = 0x03,
8855 .dig_out_nid = ALC262_DIGOUT_NID,
8856 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8857 .channel_mode = alc262_modes,
8858 .input_mux = &alc262_capture_source,
8859 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8860 .init_hook = alc262_hippo_automute,
ccc656ce
KY
8861 },
8862 [ALC262_HIPPO_1] = {
8863 .mixers = { alc262_hippo1_mixer },
8864 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8865 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8866 .dac_nids = alc262_dac_nids,
8867 .hp_nid = 0x02,
8868 .dig_out_nid = ALC262_DIGOUT_NID,
8869 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8870 .channel_mode = alc262_modes,
8871 .input_mux = &alc262_capture_source,
8872 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 8873 .init_hook = alc262_hippo1_automute,
ccc656ce 8874 },
834be88d
TI
8875 [ALC262_FUJITSU] = {
8876 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
8877 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8878 alc262_fujitsu_unsol_verbs },
834be88d
TI
8879 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8880 .dac_nids = alc262_dac_nids,
8881 .hp_nid = 0x03,
8882 .dig_out_nid = ALC262_DIGOUT_NID,
8883 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8884 .channel_mode = alc262_modes,
8885 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 8886 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 8887 },
9c7f852e
TI
8888 [ALC262_HP_BPC] = {
8889 .mixers = { alc262_HP_BPC_mixer },
8890 .init_verbs = { alc262_HP_BPC_init_verbs },
8891 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8892 .dac_nids = alc262_dac_nids,
8893 .hp_nid = 0x03,
8894 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8895 .channel_mode = alc262_modes,
8896 .input_mux = &alc262_HP_capture_source,
f12ab1e0 8897 },
cd7509a4
KY
8898 [ALC262_HP_BPC_D7000_WF] = {
8899 .mixers = { alc262_HP_BPC_WildWest_mixer },
8900 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8901 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8902 .dac_nids = alc262_dac_nids,
8903 .hp_nid = 0x03,
8904 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8905 .channel_mode = alc262_modes,
accbe498 8906 .input_mux = &alc262_HP_D7000_capture_source,
f12ab1e0 8907 },
cd7509a4
KY
8908 [ALC262_HP_BPC_D7000_WL] = {
8909 .mixers = { alc262_HP_BPC_WildWest_mixer,
8910 alc262_HP_BPC_WildWest_option_mixer },
8911 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8912 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8913 .dac_nids = alc262_dac_nids,
8914 .hp_nid = 0x03,
8915 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8916 .channel_mode = alc262_modes,
accbe498 8917 .input_mux = &alc262_HP_D7000_capture_source,
f12ab1e0 8918 },
66d2a9d6
KY
8919 [ALC262_HP_TC_T5735] = {
8920 .mixers = { alc262_hp_t5735_mixer },
8921 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
8922 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8923 .dac_nids = alc262_dac_nids,
8924 .hp_nid = 0x03,
8925 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8926 .channel_mode = alc262_modes,
8927 .input_mux = &alc262_capture_source,
8928 .unsol_event = alc262_hp_t5735_unsol_event,
8929 .init_hook = alc262_hp_t5735_init_hook,
8930 },
304dcaac
TI
8931 [ALC262_BENQ_ED8] = {
8932 .mixers = { alc262_base_mixer },
8933 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8934 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8935 .dac_nids = alc262_dac_nids,
8936 .hp_nid = 0x03,
8937 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8938 .channel_mode = alc262_modes,
8939 .input_mux = &alc262_capture_source,
f12ab1e0 8940 },
272a527c
KY
8941 [ALC262_SONY_ASSAMD] = {
8942 .mixers = { alc262_sony_mixer },
8943 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8944 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8945 .dac_nids = alc262_dac_nids,
8946 .hp_nid = 0x02,
8947 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8948 .channel_mode = alc262_modes,
8949 .input_mux = &alc262_capture_source,
8950 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8951 .init_hook = alc262_hippo_automute,
83c34218
KY
8952 },
8953 [ALC262_BENQ_T31] = {
8954 .mixers = { alc262_benq_t31_mixer },
8955 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8956 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8957 .dac_nids = alc262_dac_nids,
8958 .hp_nid = 0x03,
8959 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8960 .channel_mode = alc262_modes,
8961 .input_mux = &alc262_capture_source,
8962 .unsol_event = alc262_hippo_unsol_event,
5b31954e 8963 .init_hook = alc262_hippo_automute,
272a527c 8964 },
f651b50b
TD
8965 [ALC262_ULTRA] = {
8966 .mixers = { alc262_ultra_mixer },
8967 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
8968 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8969 .dac_nids = alc262_dac_nids,
8970 .hp_nid = 0x03,
8971 .dig_out_nid = ALC262_DIGOUT_NID,
8972 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8973 .channel_mode = alc262_modes,
8974 .input_mux = &alc262_ultra_capture_source,
8975 .unsol_event = alc262_ultra_unsol_event,
8976 .init_hook = alc262_ultra_automute,
8977 },
df694daa
KY
8978};
8979
8980static int patch_alc262(struct hda_codec *codec)
8981{
8982 struct alc_spec *spec;
8983 int board_config;
8984 int err;
8985
dc041e0b 8986 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
8987 if (spec == NULL)
8988 return -ENOMEM;
8989
8990 codec->spec = spec;
8991#if 0
f12ab1e0
TI
8992 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
8993 * under-run
8994 */
df694daa
KY
8995 {
8996 int tmp;
8997 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8998 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8999 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9000 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9001 }
9002#endif
9003
f5fcc13c
TI
9004 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9005 alc262_models,
9006 alc262_cfg_tbl);
cd7509a4 9007
f5fcc13c 9008 if (board_config < 0) {
9c7f852e
TI
9009 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9010 "trying auto-probe from BIOS...\n");
df694daa
KY
9011 board_config = ALC262_AUTO;
9012 }
9013
9014 if (board_config == ALC262_AUTO) {
9015 /* automatic parse from the BIOS config */
9016 err = alc262_parse_auto_config(codec);
9017 if (err < 0) {
9018 alc_free(codec);
9019 return err;
f12ab1e0 9020 } else if (!err) {
9c7f852e
TI
9021 printk(KERN_INFO
9022 "hda_codec: Cannot set up configuration "
9023 "from BIOS. Using base mode...\n");
df694daa
KY
9024 board_config = ALC262_BASIC;
9025 }
9026 }
9027
9028 if (board_config != ALC262_AUTO)
9029 setup_preset(spec, &alc262_presets[board_config]);
9030
9031 spec->stream_name_analog = "ALC262 Analog";
9032 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9033 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9034
9035 spec->stream_name_digital = "ALC262 Digital";
9036 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9037 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9038
f12ab1e0 9039 if (!spec->adc_nids && spec->input_mux) {
df694daa 9040 /* check whether NID 0x07 is valid */
4a471b7d
TI
9041 unsigned int wcap = get_wcaps(codec, 0x07);
9042
f12ab1e0
TI
9043 /* get type */
9044 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9045 if (wcap != AC_WID_AUD_IN) {
9046 spec->adc_nids = alc262_adc_nids_alt;
9047 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
f12ab1e0
TI
9048 spec->mixers[spec->num_mixers] =
9049 alc262_capture_alt_mixer;
df694daa
KY
9050 spec->num_mixers++;
9051 } else {
9052 spec->adc_nids = alc262_adc_nids;
9053 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9054 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9055 spec->num_mixers++;
9056 }
9057 }
9058
9059 codec->patch_ops = alc_patch_ops;
9060 if (board_config == ALC262_AUTO)
ae6b813a 9061 spec->init_hook = alc262_auto_init;
cb53c626
TI
9062#ifdef CONFIG_SND_HDA_POWER_SAVE
9063 if (!spec->loopback.amplist)
9064 spec->loopback.amplist = alc262_loopbacks;
9065#endif
834be88d 9066
df694daa
KY
9067 return 0;
9068}
9069
a361d84b
KY
9070/*
9071 * ALC268 channel source setting (2 channel)
9072 */
9073#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9074#define alc268_modes alc260_modes
9075
9076static hda_nid_t alc268_dac_nids[2] = {
9077 /* front, hp */
9078 0x02, 0x03
9079};
9080
9081static hda_nid_t alc268_adc_nids[2] = {
9082 /* ADC0-1 */
9083 0x08, 0x07
9084};
9085
9086static hda_nid_t alc268_adc_nids_alt[1] = {
9087 /* ADC0 */
9088 0x08
9089};
9090
9091static struct snd_kcontrol_new alc268_base_mixer[] = {
9092 /* output mixer control */
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9094 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9095 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9098 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9099 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9100 { }
9101};
9102
d1a991a6
KY
9103static struct hda_verb alc268_eapd_verbs[] = {
9104 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9105 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9106 { }
9107};
9108
d273809e
TI
9109/* Toshiba specific */
9110#define alc268_toshiba_automute alc262_hippo_automute
9111
9112static struct hda_verb alc268_toshiba_verbs[] = {
9113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9114 { } /* end */
9115};
9116
9117/* Acer specific */
889c4395 9118/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9119static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9120 .ops = &snd_hda_bind_vol,
9121 .values = {
9122 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9123 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9124 0
9125 },
9126};
9127
889c4395
TI
9128/* mute/unmute internal speaker according to the hp jack and mute state */
9129static void alc268_acer_automute(struct hda_codec *codec, int force)
9130{
9131 struct alc_spec *spec = codec->spec;
9132 unsigned int mute;
9133
9134 if (force || !spec->sense_updated) {
9135 unsigned int present;
9136 present = snd_hda_codec_read(codec, 0x14, 0,
9137 AC_VERB_GET_PIN_SENSE, 0);
9138 spec->jack_present = (present & 0x80000000) != 0;
9139 spec->sense_updated = 1;
9140 }
9141 if (spec->jack_present)
9142 mute = HDA_AMP_MUTE; /* mute internal speaker */
9143 else /* unmute internal speaker if necessary */
9144 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9145 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9146 HDA_AMP_MUTE, mute);
9147}
9148
9149
9150/* bind hp and internal speaker mute (with plug check) */
9151static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9152 struct snd_ctl_elem_value *ucontrol)
9153{
9154 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9155 long *valp = ucontrol->value.integer.value;
9156 int change;
9157
9158 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9159 HDA_AMP_MUTE,
9160 valp[0] ? 0 : HDA_AMP_MUTE);
9161 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9162 HDA_AMP_MUTE,
9163 valp[1] ? 0 : HDA_AMP_MUTE);
9164 if (change)
9165 alc268_acer_automute(codec, 0);
9166 return change;
9167}
d273809e
TI
9168
9169static struct snd_kcontrol_new alc268_acer_mixer[] = {
9170 /* output mixer control */
9171 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9172 {
9173 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9174 .name = "Master Playback Switch",
9175 .info = snd_hda_mixer_amp_switch_info,
9176 .get = snd_hda_mixer_amp_switch_get,
9177 .put = alc268_acer_master_sw_put,
9178 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9179 },
33bf17ab
TI
9180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9181 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9183 { }
9184};
9185
9186static struct hda_verb alc268_acer_verbs[] = {
9187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9189
9190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9191 { }
9192};
9193
9194/* unsolicited event for HP jack sensing */
9195static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9196 unsigned int res)
9197{
889c4395 9198 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9199 return;
9200 alc268_toshiba_automute(codec);
9201}
9202
9203static void alc268_acer_unsol_event(struct hda_codec *codec,
9204 unsigned int res)
9205{
889c4395 9206 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9207 return;
9208 alc268_acer_automute(codec, 1);
9209}
9210
889c4395
TI
9211static void alc268_acer_init_hook(struct hda_codec *codec)
9212{
9213 alc268_acer_automute(codec, 1);
9214}
9215
a361d84b
KY
9216/*
9217 * generic initialization of ADC, input mixers and output mixers
9218 */
9219static struct hda_verb alc268_base_init_verbs[] = {
9220 /* Unmute DAC0-1 and set vol = 0 */
9221 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9222 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9223 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9224 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9225 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9227
9228 /*
9229 * Set up output mixers (0x0c - 0x0e)
9230 */
9231 /* set vol=0 to output mixers */
9232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9235 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9236
9237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9238 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9239
9240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9242 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9246 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9247 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9248
9249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9251 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9252 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9253 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9255 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9256 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9257
a9b3aa8a
JZ
9258 /* Unmute Selector 23h,24h and set the default input to mic-in */
9259
9260 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9261 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9262 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9264
a361d84b
KY
9265 { }
9266};
9267
9268/*
9269 * generic initialization of ADC, input mixers and output mixers
9270 */
9271static struct hda_verb alc268_volume_init_verbs[] = {
9272 /* set output DAC */
9273 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9274 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9275 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9276 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9277
9278 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9280 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9281 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9282 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9283
9284 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9286 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9289
9290 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9291 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9292 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9293 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9294
9295 /* set PCBEEP vol = 0 */
9296 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9297
9298 { }
9299};
9300
9301#define alc268_mux_enum_info alc_mux_enum_info
9302#define alc268_mux_enum_get alc_mux_enum_get
9303
9304static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9305 struct snd_ctl_elem_value *ucontrol)
9306{
9307 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9308 struct alc_spec *spec = codec->spec;
a9b3aa8a 9309
a361d84b
KY
9310 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9311 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9312 hda_nid_t nid = capture_mixers[adc_idx];
a361d84b 9313
a9b3aa8a
JZ
9314 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9315 nid,
9316 &spec->cur_mux[adc_idx]);
a361d84b
KY
9317}
9318
9319static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9320 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9321 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9322 {
9323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9324 /* The multiple "Capture Source" controls confuse alsamixer
9325 * So call somewhat different..
9326 * FIXME: the controls appear in the "playback" view!
9327 */
9328 /* .name = "Capture Source", */
9329 .name = "Input Source",
9330 .count = 1,
9331 .info = alc268_mux_enum_info,
9332 .get = alc268_mux_enum_get,
9333 .put = alc268_mux_enum_put,
9334 },
9335 { } /* end */
9336};
9337
9338static struct snd_kcontrol_new alc268_capture_mixer[] = {
9339 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9340 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9343 {
9344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9345 /* The multiple "Capture Source" controls confuse alsamixer
9346 * So call somewhat different..
9347 * FIXME: the controls appear in the "playback" view!
9348 */
9349 /* .name = "Capture Source", */
9350 .name = "Input Source",
9351 .count = 2,
9352 .info = alc268_mux_enum_info,
9353 .get = alc268_mux_enum_get,
9354 .put = alc268_mux_enum_put,
9355 },
9356 { } /* end */
9357};
9358
9359static struct hda_input_mux alc268_capture_source = {
9360 .num_items = 4,
9361 .items = {
9362 { "Mic", 0x0 },
9363 { "Front Mic", 0x1 },
9364 { "Line", 0x2 },
9365 { "CD", 0x3 },
9366 },
9367};
9368
9369/* create input playback/capture controls for the given pin */
9370static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9371 const char *ctlname, int idx)
9372{
9373 char name[32];
9374 int err;
9375
9376 sprintf(name, "%s Playback Volume", ctlname);
9377 if (nid == 0x14) {
9378 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9379 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9380 HDA_OUTPUT));
9381 if (err < 0)
9382 return err;
9383 } else if (nid == 0x15) {
9384 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9385 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9386 HDA_OUTPUT));
9387 if (err < 0)
9388 return err;
9389 } else
9390 return -1;
9391 sprintf(name, "%s Playback Switch", ctlname);
9392 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9393 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9394 if (err < 0)
9395 return err;
9396 return 0;
9397}
9398
9399/* add playback controls from the parsed DAC table */
9400static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9401 const struct auto_pin_cfg *cfg)
9402{
9403 hda_nid_t nid;
9404 int err;
9405
9406 spec->multiout.num_dacs = 2; /* only use one dac */
9407 spec->multiout.dac_nids = spec->private_dac_nids;
9408 spec->multiout.dac_nids[0] = 2;
9409 spec->multiout.dac_nids[1] = 3;
9410
9411 nid = cfg->line_out_pins[0];
9412 if (nid)
9413 alc268_new_analog_output(spec, nid, "Front", 0);
9414
9415 nid = cfg->speaker_pins[0];
9416 if (nid == 0x1d) {
9417 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9418 "Speaker Playback Volume",
9419 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9420 if (err < 0)
9421 return err;
9422 }
9423 nid = cfg->hp_pins[0];
9424 if (nid)
9425 alc268_new_analog_output(spec, nid, "Headphone", 0);
9426
9427 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9428 if (nid == 0x16) {
9429 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9430 "Mono Playback Switch",
9431 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9432 if (err < 0)
9433 return err;
9434 }
9435 return 0;
9436}
9437
9438/* create playback/capture controls for input pins */
9439static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9440 const struct auto_pin_cfg *cfg)
9441{
9442 struct hda_input_mux *imux = &spec->private_imux;
9443 int i, idx1;
9444
9445 for (i = 0; i < AUTO_PIN_LAST; i++) {
9446 switch(cfg->input_pins[i]) {
9447 case 0x18:
9448 idx1 = 0; /* Mic 1 */
9449 break;
9450 case 0x19:
9451 idx1 = 1; /* Mic 2 */
9452 break;
9453 case 0x1a:
9454 idx1 = 2; /* Line In */
9455 break;
9456 case 0x1c:
9457 idx1 = 3; /* CD */
9458 break;
9459 default:
9460 continue;
9461 }
9462 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9463 imux->items[imux->num_items].index = idx1;
9464 imux->num_items++;
9465 }
9466 return 0;
9467}
9468
9469static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9470{
9471 struct alc_spec *spec = codec->spec;
9472 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9473 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9474 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9475 unsigned int dac_vol1, dac_vol2;
9476
9477 if (speaker_nid) {
9478 snd_hda_codec_write(codec, speaker_nid, 0,
9479 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9480 snd_hda_codec_write(codec, 0x0f, 0,
9481 AC_VERB_SET_AMP_GAIN_MUTE,
9482 AMP_IN_UNMUTE(1));
9483 snd_hda_codec_write(codec, 0x10, 0,
9484 AC_VERB_SET_AMP_GAIN_MUTE,
9485 AMP_IN_UNMUTE(1));
9486 } else {
9487 snd_hda_codec_write(codec, 0x0f, 0,
9488 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9489 snd_hda_codec_write(codec, 0x10, 0,
9490 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9491 }
9492
9493 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9494 if (line_nid == 0x14)
9495 dac_vol2 = AMP_OUT_ZERO;
9496 else if (line_nid == 0x15)
9497 dac_vol1 = AMP_OUT_ZERO;
9498 if (hp_nid == 0x14)
9499 dac_vol2 = AMP_OUT_ZERO;
9500 else if (hp_nid == 0x15)
9501 dac_vol1 = AMP_OUT_ZERO;
9502 if (line_nid != 0x16 || hp_nid != 0x16 ||
9503 spec->autocfg.line_out_pins[1] != 0x16 ||
9504 spec->autocfg.line_out_pins[2] != 0x16)
9505 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9506
9507 snd_hda_codec_write(codec, 0x02, 0,
9508 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9509 snd_hda_codec_write(codec, 0x03, 0,
9510 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9511}
9512
9513/* pcm configuration: identiacal with ALC880 */
9514#define alc268_pcm_analog_playback alc880_pcm_analog_playback
9515#define alc268_pcm_analog_capture alc880_pcm_analog_capture
9516#define alc268_pcm_digital_playback alc880_pcm_digital_playback
9517
9518/*
9519 * BIOS auto configuration
9520 */
9521static int alc268_parse_auto_config(struct hda_codec *codec)
9522{
9523 struct alc_spec *spec = codec->spec;
9524 int err;
9525 static hda_nid_t alc268_ignore[] = { 0 };
9526
9527 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9528 alc268_ignore);
9529 if (err < 0)
9530 return err;
9531 if (!spec->autocfg.line_outs)
9532 return 0; /* can't find valid BIOS pin config */
9533
9534 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9535 if (err < 0)
9536 return err;
9537 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9538 if (err < 0)
9539 return err;
9540
9541 spec->multiout.max_channels = 2;
9542
9543 /* digital only support output */
9544 if (spec->autocfg.dig_out_pin)
9545 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9546
9547 if (spec->kctl_alloc)
9548 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9549
9550 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9551 spec->num_mux_defs = 1;
9552 spec->input_mux = &spec->private_imux;
9553
776e184e
TI
9554 err = alc_auto_add_mic_boost(codec);
9555 if (err < 0)
9556 return err;
9557
a361d84b
KY
9558 return 1;
9559}
9560
9561#define alc268_auto_init_multi_out alc882_auto_init_multi_out
9562#define alc268_auto_init_hp_out alc882_auto_init_hp_out
9563#define alc268_auto_init_analog_input alc882_auto_init_analog_input
9564
9565/* init callback for auto-configuration model -- overriding the default init */
9566static void alc268_auto_init(struct hda_codec *codec)
9567{
9568 alc268_auto_init_multi_out(codec);
9569 alc268_auto_init_hp_out(codec);
9570 alc268_auto_init_mono_speaker_out(codec);
9571 alc268_auto_init_analog_input(codec);
9572}
9573
9574/*
9575 * configuration and preset
9576 */
9577static const char *alc268_models[ALC268_MODEL_LAST] = {
9578 [ALC268_3ST] = "3stack",
983f8ae4 9579 [ALC268_TOSHIBA] = "toshiba",
d273809e 9580 [ALC268_ACER] = "acer",
a361d84b
KY
9581 [ALC268_AUTO] = "auto",
9582};
9583
9584static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741
TI
9585 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9586 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9587 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 9588 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 9589 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 9590 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 9591 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
a361d84b
KY
9592 {}
9593};
9594
9595static struct alc_config_preset alc268_presets[] = {
9596 [ALC268_3ST] = {
9597 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9598 .init_verbs = { alc268_base_init_verbs },
9599 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9600 .dac_nids = alc268_dac_nids,
9601 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9602 .adc_nids = alc268_adc_nids_alt,
9603 .hp_nid = 0x03,
9604 .dig_out_nid = ALC268_DIGOUT_NID,
9605 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9606 .channel_mode = alc268_modes,
9607 .input_mux = &alc268_capture_source,
9608 },
d1a991a6
KY
9609 [ALC268_TOSHIBA] = {
9610 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
d273809e
TI
9611 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9612 alc268_toshiba_verbs },
d1a991a6
KY
9613 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9614 .dac_nids = alc268_dac_nids,
9615 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9616 .adc_nids = alc268_adc_nids_alt,
9617 .hp_nid = 0x03,
9618 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9619 .channel_mode = alc268_modes,
9620 .input_mux = &alc268_capture_source,
d273809e
TI
9621 .unsol_event = alc268_toshiba_unsol_event,
9622 .init_hook = alc268_toshiba_automute,
9623 },
9624 [ALC268_ACER] = {
9625 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9626 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9627 alc268_acer_verbs },
9628 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9629 .dac_nids = alc268_dac_nids,
9630 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9631 .adc_nids = alc268_adc_nids_alt,
9632 .hp_nid = 0x02,
9633 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9634 .channel_mode = alc268_modes,
9635 .input_mux = &alc268_capture_source,
9636 .unsol_event = alc268_acer_unsol_event,
889c4395 9637 .init_hook = alc268_acer_init_hook,
d1a991a6 9638 },
a361d84b
KY
9639};
9640
9641static int patch_alc268(struct hda_codec *codec)
9642{
9643 struct alc_spec *spec;
9644 int board_config;
9645 int err;
9646
9647 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9648 if (spec == NULL)
9649 return -ENOMEM;
9650
9651 codec->spec = spec;
9652
9653 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9654 alc268_models,
9655 alc268_cfg_tbl);
9656
9657 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9658 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9659 "trying auto-probe from BIOS...\n");
9660 board_config = ALC268_AUTO;
9661 }
9662
9663 if (board_config == ALC268_AUTO) {
9664 /* automatic parse from the BIOS config */
9665 err = alc268_parse_auto_config(codec);
9666 if (err < 0) {
9667 alc_free(codec);
9668 return err;
9669 } else if (!err) {
9670 printk(KERN_INFO
9671 "hda_codec: Cannot set up configuration "
9672 "from BIOS. Using base mode...\n");
9673 board_config = ALC268_3ST;
9674 }
9675 }
9676
9677 if (board_config != ALC268_AUTO)
9678 setup_preset(spec, &alc268_presets[board_config]);
9679
9680 spec->stream_name_analog = "ALC268 Analog";
9681 spec->stream_analog_playback = &alc268_pcm_analog_playback;
9682 spec->stream_analog_capture = &alc268_pcm_analog_capture;
9683
9684 spec->stream_name_digital = "ALC268 Digital";
9685 spec->stream_digital_playback = &alc268_pcm_digital_playback;
9686
9687 if (board_config == ALC268_AUTO) {
9688 if (!spec->adc_nids && spec->input_mux) {
9689 /* check whether NID 0x07 is valid */
9690 unsigned int wcap = get_wcaps(codec, 0x07);
9691
9692 /* get type */
9693 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9694 if (wcap != AC_WID_AUD_IN) {
9695 spec->adc_nids = alc268_adc_nids_alt;
9696 spec->num_adc_nids =
9697 ARRAY_SIZE(alc268_adc_nids_alt);
9698 spec->mixers[spec->num_mixers] =
9699 alc268_capture_alt_mixer;
9700 spec->num_mixers++;
9701 } else {
9702 spec->adc_nids = alc268_adc_nids;
9703 spec->num_adc_nids =
9704 ARRAY_SIZE(alc268_adc_nids);
9705 spec->mixers[spec->num_mixers] =
9706 alc268_capture_mixer;
9707 spec->num_mixers++;
9708 }
9709 }
9710 }
9711 codec->patch_ops = alc_patch_ops;
9712 if (board_config == ALC268_AUTO)
9713 spec->init_hook = alc268_auto_init;
9714
9715 return 0;
9716}
9717
f6a92248
KY
9718/*
9719 * ALC269 channel source setting (2 channel)
9720 */
9721#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
9722
9723#define alc269_dac_nids alc260_dac_nids
9724
9725static hda_nid_t alc269_adc_nids[1] = {
9726 /* ADC1 */
9727 0x07,
9728};
9729
9730#define alc269_modes alc260_modes
9731#define alc269_capture_source alc880_lg_lw_capture_source
9732
9733static struct snd_kcontrol_new alc269_base_mixer[] = {
9734 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9735 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9736 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9737 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9738 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9739 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9740 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9741 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9743 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9745 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9746 { } /* end */
9747};
9748
9749/* capture mixer elements */
9750static struct snd_kcontrol_new alc269_capture_mixer[] = {
9751 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9752 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9753 {
9754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9755 /* The multiple "Capture Source" controls confuse alsamixer
9756 * So call somewhat different..
9757 * FIXME: the controls appear in the "playback" view!
9758 */
9759 /* .name = "Capture Source", */
9760 .name = "Input Source",
9761 .count = 1,
9762 .info = alc_mux_enum_info,
9763 .get = alc_mux_enum_get,
9764 .put = alc_mux_enum_put,
9765 },
9766 { } /* end */
9767};
9768
9769/*
9770 * generic initialization of ADC, input mixers and output mixers
9771 */
9772static struct hda_verb alc269_init_verbs[] = {
9773 /*
9774 * Unmute ADC0 and set the default input to mic-in
9775 */
9776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9777
9778 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
9779 * analog-loopback mixer widget
9780 * Note: PASD motherboards uses the Line In 2 as the input for
9781 * front panel mic (mic 2)
9782 */
9783 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9784 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9786 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9787 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9789
9790 /*
9791 * Set up output mixers (0x0c - 0x0e)
9792 */
9793 /* set vol=0 to output mixers */
9794 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9795 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9796
9797 /* set up input amps for analog loopback */
9798 /* Amp Indices: DAC = 0, mixer = 1 */
9799 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9802 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9805
9806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9808 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9812 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9813
9814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9816 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9817 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9821
9822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9824
9825 /* FIXME: use matrix-type input source selection */
9826 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
9827 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9828 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9829 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9830 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9831 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9832
9833 /* set EAPD */
9834 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9835 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9836 { }
9837};
9838
9839/* add playback controls from the parsed DAC table */
9840static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
9841 const struct auto_pin_cfg *cfg)
9842{
9843 hda_nid_t nid;
9844 int err;
9845
9846 spec->multiout.num_dacs = 1; /* only use one dac */
9847 spec->multiout.dac_nids = spec->private_dac_nids;
9848 spec->multiout.dac_nids[0] = 2;
9849
9850 nid = cfg->line_out_pins[0];
9851 if (nid) {
9852 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9853 "Front Playback Volume",
9854 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
9855 if (err < 0)
9856 return err;
9857 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9858 "Front Playback Switch",
9859 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9860 if (err < 0)
9861 return err;
9862 }
9863
9864 nid = cfg->speaker_pins[0];
9865 if (nid) {
9866 if (!cfg->line_out_pins[0]) {
9867 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9868 "Speaker Playback Volume",
9869 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9870 HDA_OUTPUT));
9871 if (err < 0)
9872 return err;
9873 }
9874 if (nid == 0x16) {
9875 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9876 "Speaker Playback Switch",
9877 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9878 HDA_OUTPUT));
9879 if (err < 0)
9880 return err;
9881 } else {
9882 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9883 "Speaker Playback Switch",
9884 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9885 HDA_OUTPUT));
9886 if (err < 0)
9887 return err;
9888 }
9889 }
9890 nid = cfg->hp_pins[0];
9891 if (nid) {
9892 /* spec->multiout.hp_nid = 2; */
9893 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
9894 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9895 "Headphone Playback Volume",
9896 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
9897 HDA_OUTPUT));
9898 if (err < 0)
9899 return err;
9900 }
9901 if (nid == 0x16) {
9902 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9903 "Headphone Playback Switch",
9904 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9905 HDA_OUTPUT));
9906 if (err < 0)
9907 return err;
9908 } else {
9909 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9910 "Headphone Playback Switch",
9911 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9912 HDA_OUTPUT));
9913 if (err < 0)
9914 return err;
9915 }
9916 }
9917 return 0;
9918}
9919
9920#define alc269_auto_create_analog_input_ctls \
9921 alc880_auto_create_analog_input_ctls
9922
9923#ifdef CONFIG_SND_HDA_POWER_SAVE
9924#define alc269_loopbacks alc880_loopbacks
9925#endif
9926
9927/* pcm configuration: identiacal with ALC880 */
9928#define alc269_pcm_analog_playback alc880_pcm_analog_playback
9929#define alc269_pcm_analog_capture alc880_pcm_analog_capture
9930#define alc269_pcm_digital_playback alc880_pcm_digital_playback
9931#define alc269_pcm_digital_capture alc880_pcm_digital_capture
9932
9933/*
9934 * BIOS auto configuration
9935 */
9936static int alc269_parse_auto_config(struct hda_codec *codec)
9937{
9938 struct alc_spec *spec = codec->spec;
9939 int err;
9940 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
9941
9942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9943 alc269_ignore);
9944 if (err < 0)
9945 return err;
9946
9947 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
9948 if (err < 0)
9949 return err;
9950 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
9951 if (err < 0)
9952 return err;
9953
9954 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9955
9956 if (spec->autocfg.dig_out_pin)
9957 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
9958
9959 if (spec->kctl_alloc)
9960 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9961
9962 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
9963 spec->num_mux_defs = 1;
9964 spec->input_mux = &spec->private_imux;
9965
9966 err = alc_auto_add_mic_boost(codec);
9967 if (err < 0)
9968 return err;
9969
9970 return 1;
9971}
9972
9973#define alc269_auto_init_multi_out alc882_auto_init_multi_out
9974#define alc269_auto_init_hp_out alc882_auto_init_hp_out
9975#define alc269_auto_init_analog_input alc882_auto_init_analog_input
9976
9977
9978/* init callback for auto-configuration model -- overriding the default init */
9979static void alc269_auto_init(struct hda_codec *codec)
9980{
9981 alc269_auto_init_multi_out(codec);
9982 alc269_auto_init_hp_out(codec);
9983 alc269_auto_init_analog_input(codec);
9984}
9985
9986/*
9987 * configuration and preset
9988 */
9989static const char *alc269_models[ALC269_MODEL_LAST] = {
9990 [ALC269_BASIC] = "basic",
9991};
9992
9993static struct snd_pci_quirk alc269_cfg_tbl[] = {
9994 {}
9995};
9996
9997static struct alc_config_preset alc269_presets[] = {
9998 [ALC269_BASIC] = {
9999 .mixers = { alc269_base_mixer },
10000 .init_verbs = { alc269_init_verbs },
10001 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10002 .dac_nids = alc269_dac_nids,
10003 .hp_nid = 0x03,
10004 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10005 .channel_mode = alc269_modes,
10006 .input_mux = &alc269_capture_source,
10007 },
10008};
10009
10010static int patch_alc269(struct hda_codec *codec)
10011{
10012 struct alc_spec *spec;
10013 int board_config;
10014 int err;
10015
10016 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10017 if (spec == NULL)
10018 return -ENOMEM;
10019
10020 codec->spec = spec;
10021
10022 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10023 alc269_models,
10024 alc269_cfg_tbl);
10025
10026 if (board_config < 0) {
10027 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10028 "trying auto-probe from BIOS...\n");
10029 board_config = ALC269_AUTO;
10030 }
10031
10032 if (board_config == ALC269_AUTO) {
10033 /* automatic parse from the BIOS config */
10034 err = alc269_parse_auto_config(codec);
10035 if (err < 0) {
10036 alc_free(codec);
10037 return err;
10038 } else if (!err) {
10039 printk(KERN_INFO
10040 "hda_codec: Cannot set up configuration "
10041 "from BIOS. Using base mode...\n");
10042 board_config = ALC269_BASIC;
10043 }
10044 }
10045
10046 if (board_config != ALC269_AUTO)
10047 setup_preset(spec, &alc269_presets[board_config]);
10048
10049 spec->stream_name_analog = "ALC269 Analog";
10050 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10051 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10052
10053 spec->stream_name_digital = "ALC269 Digital";
10054 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10055 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10056
10057 spec->adc_nids = alc269_adc_nids;
10058 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10059 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10060 spec->num_mixers++;
10061
10062 codec->patch_ops = alc_patch_ops;
10063 if (board_config == ALC269_AUTO)
10064 spec->init_hook = alc269_auto_init;
10065#ifdef CONFIG_SND_HDA_POWER_SAVE
10066 if (!spec->loopback.amplist)
10067 spec->loopback.amplist = alc269_loopbacks;
10068#endif
10069
10070 return 0;
10071}
10072
df694daa
KY
10073/*
10074 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10075 */
10076
10077/*
10078 * set the path ways for 2 channel output
10079 * need to set the codec line out and mic 1 pin widgets to inputs
10080 */
10081static struct hda_verb alc861_threestack_ch2_init[] = {
10082 /* set pin widget 1Ah (line in) for input */
10083 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10084 /* set pin widget 18h (mic1/2) for input, for mic also enable
10085 * the vref
10086 */
df694daa
KY
10087 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10088
9c7f852e
TI
10089 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10090#if 0
10091 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10092 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10093#endif
df694daa
KY
10094 { } /* end */
10095};
10096/*
10097 * 6ch mode
10098 * need to set the codec line out and mic 1 pin widgets to outputs
10099 */
10100static struct hda_verb alc861_threestack_ch6_init[] = {
10101 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10102 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10103 /* set pin widget 18h (mic1) for output (CLFE)*/
10104 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10105
10106 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10107 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10108
9c7f852e
TI
10109 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10110#if 0
10111 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10112 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10113#endif
df694daa
KY
10114 { } /* end */
10115};
10116
10117static struct hda_channel_mode alc861_threestack_modes[2] = {
10118 { 2, alc861_threestack_ch2_init },
10119 { 6, alc861_threestack_ch6_init },
10120};
22309c3e
TI
10121/* Set mic1 as input and unmute the mixer */
10122static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10123 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10125 { } /* end */
10126};
10127/* Set mic1 as output and mute mixer */
10128static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10129 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10130 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10131 { } /* end */
10132};
10133
10134static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10135 { 2, alc861_uniwill_m31_ch2_init },
10136 { 4, alc861_uniwill_m31_ch4_init },
10137};
df694daa 10138
7cdbff94
MD
10139/* Set mic1 and line-in as input and unmute the mixer */
10140static struct hda_verb alc861_asus_ch2_init[] = {
10141 /* set pin widget 1Ah (line in) for input */
10142 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10143 /* set pin widget 18h (mic1/2) for input, for mic also enable
10144 * the vref
10145 */
7cdbff94
MD
10146 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10147
10148 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10149#if 0
10150 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10151 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10152#endif
10153 { } /* end */
10154};
10155/* Set mic1 nad line-in as output and mute mixer */
10156static struct hda_verb alc861_asus_ch6_init[] = {
10157 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10158 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10159 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10160 /* set pin widget 18h (mic1) for output (CLFE)*/
10161 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10162 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10163 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10164 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10165
10166 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10167#if 0
10168 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10170#endif
10171 { } /* end */
10172};
10173
10174static struct hda_channel_mode alc861_asus_modes[2] = {
10175 { 2, alc861_asus_ch2_init },
10176 { 6, alc861_asus_ch6_init },
10177};
10178
df694daa
KY
10179/* patch-ALC861 */
10180
10181static struct snd_kcontrol_new alc861_base_mixer[] = {
10182 /* output mixer control */
10183 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10184 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10185 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10186 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10187 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10188
10189 /*Input mixer control */
10190 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10191 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10192 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10193 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10194 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10195 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10197 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10198 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10199 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10200
df694daa
KY
10201 /* Capture mixer control */
10202 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10203 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10204 {
10205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10206 .name = "Capture Source",
10207 .count = 1,
10208 .info = alc_mux_enum_info,
10209 .get = alc_mux_enum_get,
10210 .put = alc_mux_enum_put,
10211 },
10212 { } /* end */
10213};
10214
10215static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10216 /* output mixer control */
10217 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10218 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10219 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10220 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10221 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10222
10223 /* Input mixer control */
10224 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10225 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10226 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10227 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10228 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10229 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10231 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10234
df694daa
KY
10235 /* Capture mixer control */
10236 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10237 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10238 {
10239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10240 .name = "Capture Source",
10241 .count = 1,
10242 .info = alc_mux_enum_info,
10243 .get = alc_mux_enum_get,
10244 .put = alc_mux_enum_put,
10245 },
10246 {
10247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10248 .name = "Channel Mode",
10249 .info = alc_ch_mode_info,
10250 .get = alc_ch_mode_get,
10251 .put = alc_ch_mode_put,
10252 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10253 },
10254 { } /* end */
a53d1aec
TD
10255};
10256
d1d985f0 10257static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10258 /* output mixer control */
10259 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10261 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10262
10263 /*Capture mixer control */
10264 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10265 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10266 {
10267 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10268 .name = "Capture Source",
10269 .count = 1,
10270 .info = alc_mux_enum_info,
10271 .get = alc_mux_enum_get,
10272 .put = alc_mux_enum_put,
10273 },
10274
10275 { } /* end */
f12ab1e0 10276};
a53d1aec 10277
22309c3e
TI
10278static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10279 /* output mixer control */
10280 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10281 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10282 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10283 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10284 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10285
10286 /* Input mixer control */
10287 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10288 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10289 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10290 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10291 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10292 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10294 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10295 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10297
22309c3e
TI
10298 /* Capture mixer control */
10299 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10300 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10301 {
10302 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10303 .name = "Capture Source",
10304 .count = 1,
10305 .info = alc_mux_enum_info,
10306 .get = alc_mux_enum_get,
10307 .put = alc_mux_enum_put,
10308 },
10309 {
10310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10311 .name = "Channel Mode",
10312 .info = alc_ch_mode_info,
10313 .get = alc_ch_mode_get,
10314 .put = alc_ch_mode_put,
10315 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10316 },
10317 { } /* end */
f12ab1e0 10318};
7cdbff94
MD
10319
10320static struct snd_kcontrol_new alc861_asus_mixer[] = {
10321 /* output mixer control */
10322 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10323 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10324 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10325 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10326 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10327
10328 /* Input mixer control */
10329 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10330 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10331 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10332 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10333 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10334 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10336 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10337 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
10338 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10339
7cdbff94
MD
10340 /* Capture mixer control */
10341 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10342 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10343 {
10344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10345 .name = "Capture Source",
10346 .count = 1,
10347 .info = alc_mux_enum_info,
10348 .get = alc_mux_enum_get,
10349 .put = alc_mux_enum_put,
10350 },
10351 {
10352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10353 .name = "Channel Mode",
10354 .info = alc_ch_mode_info,
10355 .get = alc_ch_mode_get,
10356 .put = alc_ch_mode_put,
10357 .private_value = ARRAY_SIZE(alc861_asus_modes),
10358 },
10359 { }
56bb0cab
TI
10360};
10361
10362/* additional mixer */
d1d985f0 10363static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
10364 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10365 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10366 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10367 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10368 { }
10369};
7cdbff94 10370
df694daa
KY
10371/*
10372 * generic initialization of ADC, input mixers and output mixers
10373 */
10374static struct hda_verb alc861_base_init_verbs[] = {
10375 /*
10376 * Unmute ADC0 and set the default input to mic-in
10377 */
10378 /* port-A for surround (rear panel) */
10379 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10380 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10381 /* port-B for mic-in (rear panel) with vref */
10382 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10383 /* port-C for line-in (rear panel) */
10384 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10385 /* port-D for Front */
10386 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10387 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10388 /* port-E for HP out (front panel) */
10389 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10390 /* route front PCM to HP */
9dece1d7 10391 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10392 /* port-F for mic-in (front panel) with vref */
10393 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10394 /* port-G for CLFE (rear panel) */
10395 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10396 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10397 /* port-H for side (rear panel) */
10398 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10399 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10400 /* CD-in */
10401 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10402 /* route front mic to ADC1*/
10403 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10405
10406 /* Unmute DAC0~3 & spdif out*/
10407 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10408 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10409 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10410 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10411 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10412
10413 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10414 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10415 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10416 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10417 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10418
10419 /* Unmute Stereo Mixer 15 */
10420 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10424
10425 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10426 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10427 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10429 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10430 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10431 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10432 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10433 /* hp used DAC 3 (Front) */
10434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10435 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10436
10437 { }
10438};
10439
10440static struct hda_verb alc861_threestack_init_verbs[] = {
10441 /*
10442 * Unmute ADC0 and set the default input to mic-in
10443 */
10444 /* port-A for surround (rear panel) */
10445 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10446 /* port-B for mic-in (rear panel) with vref */
10447 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10448 /* port-C for line-in (rear panel) */
10449 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10450 /* port-D for Front */
10451 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10452 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10453 /* port-E for HP out (front panel) */
10454 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10455 /* route front PCM to HP */
9dece1d7 10456 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10457 /* port-F for mic-in (front panel) with vref */
10458 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10459 /* port-G for CLFE (rear panel) */
10460 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10461 /* port-H for side (rear panel) */
10462 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10463 /* CD-in */
10464 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10465 /* route front mic to ADC1*/
10466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10468 /* Unmute DAC0~3 & spdif out*/
10469 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10470 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10471 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10472 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10473 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10474
10475 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10476 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10477 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10478 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10479 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10480
10481 /* Unmute Stereo Mixer 15 */
10482 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10485 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10486
10487 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10489 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10490 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10492 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10494 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10495 /* hp used DAC 3 (Front) */
10496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10497 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10498 { }
10499};
22309c3e
TI
10500
10501static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
10502 /*
10503 * Unmute ADC0 and set the default input to mic-in
10504 */
10505 /* port-A for surround (rear panel) */
10506 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10507 /* port-B for mic-in (rear panel) with vref */
10508 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10509 /* port-C for line-in (rear panel) */
10510 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10511 /* port-D for Front */
10512 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10513 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10514 /* port-E for HP out (front panel) */
f12ab1e0
TI
10515 /* this has to be set to VREF80 */
10516 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 10517 /* route front PCM to HP */
9dece1d7 10518 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
10519 /* port-F for mic-in (front panel) with vref */
10520 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10521 /* port-G for CLFE (rear panel) */
10522 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10523 /* port-H for side (rear panel) */
10524 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10525 /* CD-in */
10526 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10527 /* route front mic to ADC1*/
10528 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10530 /* Unmute DAC0~3 & spdif out*/
10531 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10532 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10533 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10534 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10536
10537 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10538 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10539 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10540 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10541 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10542
10543 /* Unmute Stereo Mixer 15 */
10544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
10548
10549 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10550 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10551 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10552 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10554 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10557 /* hp used DAC 3 (Front) */
10558 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
10559 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10560 { }
10561};
10562
7cdbff94
MD
10563static struct hda_verb alc861_asus_init_verbs[] = {
10564 /*
10565 * Unmute ADC0 and set the default input to mic-in
10566 */
f12ab1e0
TI
10567 /* port-A for surround (rear panel)
10568 * according to codec#0 this is the HP jack
10569 */
7cdbff94
MD
10570 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
10571 /* route front PCM to HP */
10572 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
10573 /* port-B for mic-in (rear panel) with vref */
10574 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10575 /* port-C for line-in (rear panel) */
10576 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10577 /* port-D for Front */
10578 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10579 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10580 /* port-E for HP out (front panel) */
f12ab1e0
TI
10581 /* this has to be set to VREF80 */
10582 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 10583 /* route front PCM to HP */
9dece1d7 10584 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
10585 /* port-F for mic-in (front panel) with vref */
10586 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10587 /* port-G for CLFE (rear panel) */
10588 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10589 /* port-H for side (rear panel) */
10590 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10591 /* CD-in */
10592 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10593 /* route front mic to ADC1*/
10594 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10595 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10596 /* Unmute DAC0~3 & spdif out*/
10597 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10598 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10599 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10600 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10602 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10603 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10604 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10605 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10606 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10607
10608 /* Unmute Stereo Mixer 15 */
10609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10612 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
10613
10614 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10616 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10619 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10622 /* hp used DAC 3 (Front) */
10623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
10624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10625 { }
10626};
10627
56bb0cab
TI
10628/* additional init verbs for ASUS laptops */
10629static struct hda_verb alc861_asus_laptop_init_verbs[] = {
10630 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
10631 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
10632 { }
10633};
7cdbff94 10634
df694daa
KY
10635/*
10636 * generic initialization of ADC, input mixers and output mixers
10637 */
10638static struct hda_verb alc861_auto_init_verbs[] = {
10639 /*
10640 * Unmute ADC0 and set the default input to mic-in
10641 */
f12ab1e0 10642 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
10643 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10644
10645 /* Unmute DAC0~3 & spdif out*/
10646 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10647 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10648 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10649 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10651
10652 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10653 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10654 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10655 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10656 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10657
10658 /* Unmute Stereo Mixer 15 */
10659 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
10663
10664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10667 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10668 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10669 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10671 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10672
10673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10674 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
10675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10677 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10678 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
10679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 10681
f12ab1e0 10682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
10683
10684 { }
10685};
10686
a53d1aec
TD
10687static struct hda_verb alc861_toshiba_init_verbs[] = {
10688 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 10689
a53d1aec
TD
10690 { }
10691};
10692
10693/* toggle speaker-output according to the hp-jack state */
10694static void alc861_toshiba_automute(struct hda_codec *codec)
10695{
10696 unsigned int present;
10697
10698 present = snd_hda_codec_read(codec, 0x0f, 0,
10699 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
10700 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10701 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10702 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10703 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
10704}
10705
10706static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10707 unsigned int res)
10708{
a53d1aec
TD
10709 if ((res >> 26) == ALC880_HP_EVENT)
10710 alc861_toshiba_automute(codec);
10711}
10712
df694daa
KY
10713/* pcm configuration: identiacal with ALC880 */
10714#define alc861_pcm_analog_playback alc880_pcm_analog_playback
10715#define alc861_pcm_analog_capture alc880_pcm_analog_capture
10716#define alc861_pcm_digital_playback alc880_pcm_digital_playback
10717#define alc861_pcm_digital_capture alc880_pcm_digital_capture
10718
10719
10720#define ALC861_DIGOUT_NID 0x07
10721
10722static struct hda_channel_mode alc861_8ch_modes[1] = {
10723 { 8, NULL }
10724};
10725
10726static hda_nid_t alc861_dac_nids[4] = {
10727 /* front, surround, clfe, side */
10728 0x03, 0x06, 0x05, 0x04
10729};
10730
9c7f852e
TI
10731static hda_nid_t alc660_dac_nids[3] = {
10732 /* front, clfe, surround */
10733 0x03, 0x05, 0x06
10734};
10735
df694daa
KY
10736static hda_nid_t alc861_adc_nids[1] = {
10737 /* ADC0-2 */
10738 0x08,
10739};
10740
10741static struct hda_input_mux alc861_capture_source = {
10742 .num_items = 5,
10743 .items = {
10744 { "Mic", 0x0 },
10745 { "Front Mic", 0x3 },
10746 { "Line", 0x1 },
10747 { "CD", 0x4 },
10748 { "Mixer", 0x5 },
10749 },
10750};
10751
10752/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
10753static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10754 const struct auto_pin_cfg *cfg)
df694daa
KY
10755{
10756 int i;
10757 hda_nid_t nid;
10758
10759 spec->multiout.dac_nids = spec->private_dac_nids;
10760 for (i = 0; i < cfg->line_outs; i++) {
10761 nid = cfg->line_out_pins[i];
10762 if (nid) {
10763 if (i >= ARRAY_SIZE(alc861_dac_nids))
10764 continue;
10765 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10766 }
10767 }
10768 spec->multiout.num_dacs = cfg->line_outs;
10769 return 0;
10770}
10771
10772/* add playback controls from the parsed DAC table */
10773static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10774 const struct auto_pin_cfg *cfg)
10775{
10776 char name[32];
f12ab1e0
TI
10777 static const char *chname[4] = {
10778 "Front", "Surround", NULL /*CLFE*/, "Side"
10779 };
df694daa
KY
10780 hda_nid_t nid;
10781 int i, idx, err;
10782
10783 for (i = 0; i < cfg->line_outs; i++) {
10784 nid = spec->multiout.dac_nids[i];
f12ab1e0 10785 if (!nid)
df694daa
KY
10786 continue;
10787 if (nid == 0x05) {
10788 /* Center/LFE */
f12ab1e0
TI
10789 err = add_control(spec, ALC_CTL_BIND_MUTE,
10790 "Center Playback Switch",
10791 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10792 HDA_OUTPUT));
10793 if (err < 0)
df694daa 10794 return err;
f12ab1e0
TI
10795 err = add_control(spec, ALC_CTL_BIND_MUTE,
10796 "LFE Playback Switch",
10797 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10798 HDA_OUTPUT));
10799 if (err < 0)
df694daa
KY
10800 return err;
10801 } else {
f12ab1e0
TI
10802 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10803 idx++)
df694daa
KY
10804 if (nid == alc861_dac_nids[idx])
10805 break;
10806 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
10807 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10808 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10809 HDA_OUTPUT));
10810 if (err < 0)
df694daa
KY
10811 return err;
10812 }
10813 }
10814 return 0;
10815}
10816
10817static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10818{
10819 int err;
10820 hda_nid_t nid;
10821
f12ab1e0 10822 if (!pin)
df694daa
KY
10823 return 0;
10824
10825 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10826 nid = 0x03;
f12ab1e0
TI
10827 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10828 "Headphone Playback Switch",
10829 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10830 if (err < 0)
df694daa
KY
10831 return err;
10832 spec->multiout.hp_nid = nid;
10833 }
10834 return 0;
10835}
10836
10837/* create playback/capture controls for input pins */
f12ab1e0
TI
10838static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10839 const struct auto_pin_cfg *cfg)
df694daa 10840{
df694daa
KY
10841 struct hda_input_mux *imux = &spec->private_imux;
10842 int i, err, idx, idx1;
10843
10844 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 10845 switch (cfg->input_pins[i]) {
df694daa
KY
10846 case 0x0c:
10847 idx1 = 1;
f12ab1e0 10848 idx = 2; /* Line In */
df694daa
KY
10849 break;
10850 case 0x0f:
10851 idx1 = 2;
f12ab1e0 10852 idx = 2; /* Line In */
df694daa
KY
10853 break;
10854 case 0x0d:
10855 idx1 = 0;
f12ab1e0 10856 idx = 1; /* Mic In */
df694daa 10857 break;
f12ab1e0 10858 case 0x10:
df694daa 10859 idx1 = 3;
f12ab1e0 10860 idx = 1; /* Mic In */
df694daa
KY
10861 break;
10862 case 0x11:
10863 idx1 = 4;
f12ab1e0 10864 idx = 0; /* CD */
df694daa
KY
10865 break;
10866 default:
10867 continue;
10868 }
10869
4a471b7d
TI
10870 err = new_analog_input(spec, cfg->input_pins[i],
10871 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
10872 if (err < 0)
10873 return err;
10874
4a471b7d 10875 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 10876 imux->items[imux->num_items].index = idx1;
f12ab1e0 10877 imux->num_items++;
df694daa
KY
10878 }
10879 return 0;
10880}
10881
10882static struct snd_kcontrol_new alc861_capture_mixer[] = {
10883 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10884 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10885
10886 {
10887 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10888 /* The multiple "Capture Source" controls confuse alsamixer
10889 * So call somewhat different..
10890 *FIXME: the controls appear in the "playback" view!
10891 */
10892 /* .name = "Capture Source", */
10893 .name = "Input Source",
10894 .count = 1,
10895 .info = alc_mux_enum_info,
10896 .get = alc_mux_enum_get,
10897 .put = alc_mux_enum_put,
10898 },
10899 { } /* end */
10900};
10901
f12ab1e0
TI
10902static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10903 hda_nid_t nid,
df694daa
KY
10904 int pin_type, int dac_idx)
10905{
10906 /* set as output */
10907
f12ab1e0
TI
10908 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10909 pin_type);
10910 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10911 AMP_OUT_UNMUTE);
df694daa
KY
10912
10913}
10914
10915static void alc861_auto_init_multi_out(struct hda_codec *codec)
10916{
10917 struct alc_spec *spec = codec->spec;
10918 int i;
10919
bc9f98a9 10920 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
10921 for (i = 0; i < spec->autocfg.line_outs; i++) {
10922 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 10923 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 10924 if (nid)
baba8ee9 10925 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 10926 spec->multiout.dac_nids[i]);
df694daa
KY
10927 }
10928}
10929
10930static void alc861_auto_init_hp_out(struct hda_codec *codec)
10931{
10932 struct alc_spec *spec = codec->spec;
10933 hda_nid_t pin;
10934
eb06ed8f 10935 pin = spec->autocfg.hp_pins[0];
df694daa 10936 if (pin) /* connect to front */
f12ab1e0
TI
10937 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10938 spec->multiout.dac_nids[0]);
df694daa
KY
10939}
10940
10941static void alc861_auto_init_analog_input(struct hda_codec *codec)
10942{
10943 struct alc_spec *spec = codec->spec;
10944 int i;
10945
10946 for (i = 0; i < AUTO_PIN_LAST; i++) {
10947 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
10948 if (nid >= 0x0c && nid <= 0x11) {
10949 snd_hda_codec_write(codec, nid, 0,
10950 AC_VERB_SET_PIN_WIDGET_CONTROL,
10951 i <= AUTO_PIN_FRONT_MIC ?
10952 PIN_VREF80 : PIN_IN);
df694daa
KY
10953 }
10954 }
10955}
10956
10957/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
10958/* return 1 if successful, 0 if the proper config is not found,
10959 * or a negative error code
10960 */
df694daa
KY
10961static int alc861_parse_auto_config(struct hda_codec *codec)
10962{
10963 struct alc_spec *spec = codec->spec;
10964 int err;
10965 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10966
f12ab1e0
TI
10967 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10968 alc861_ignore);
10969 if (err < 0)
df694daa 10970 return err;
f12ab1e0 10971 if (!spec->autocfg.line_outs)
df694daa
KY
10972 return 0; /* can't find valid BIOS pin config */
10973
f12ab1e0
TI
10974 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10975 if (err < 0)
10976 return err;
10977 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10978 if (err < 0)
10979 return err;
10980 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10981 if (err < 0)
10982 return err;
10983 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10984 if (err < 0)
df694daa
KY
10985 return err;
10986
10987 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10988
10989 if (spec->autocfg.dig_out_pin)
10990 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10991
10992 if (spec->kctl_alloc)
10993 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10994
10995 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10996
a1e8d2da 10997 spec->num_mux_defs = 1;
df694daa
KY
10998 spec->input_mux = &spec->private_imux;
10999
11000 spec->adc_nids = alc861_adc_nids;
11001 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11002 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11003 spec->num_mixers++;
11004
11005 return 1;
11006}
11007
ae6b813a
TI
11008/* additional initialization for auto-configuration model */
11009static void alc861_auto_init(struct hda_codec *codec)
df694daa 11010{
df694daa
KY
11011 alc861_auto_init_multi_out(codec);
11012 alc861_auto_init_hp_out(codec);
11013 alc861_auto_init_analog_input(codec);
df694daa
KY
11014}
11015
cb53c626
TI
11016#ifdef CONFIG_SND_HDA_POWER_SAVE
11017static struct hda_amp_list alc861_loopbacks[] = {
11018 { 0x15, HDA_INPUT, 0 },
11019 { 0x15, HDA_INPUT, 1 },
11020 { 0x15, HDA_INPUT, 2 },
11021 { 0x15, HDA_INPUT, 3 },
11022 { } /* end */
11023};
11024#endif
11025
df694daa
KY
11026
11027/*
11028 * configuration and preset
11029 */
f5fcc13c
TI
11030static const char *alc861_models[ALC861_MODEL_LAST] = {
11031 [ALC861_3ST] = "3stack",
11032 [ALC660_3ST] = "3stack-660",
11033 [ALC861_3ST_DIG] = "3stack-dig",
11034 [ALC861_6ST_DIG] = "6stack-dig",
11035 [ALC861_UNIWILL_M31] = "uniwill-m31",
11036 [ALC861_TOSHIBA] = "toshiba",
11037 [ALC861_ASUS] = "asus",
11038 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11039 [ALC861_AUTO] = "auto",
11040};
11041
11042static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11043 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11044 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11045 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11046 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11047 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11048 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11049 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11050 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11051 * Any other models that need this preset?
11052 */
11053 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11054 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11055 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11056 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11057 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11058 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11059 /* FIXME: the below seems conflict */
11060 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11061 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11062 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11063 {}
11064};
11065
11066static struct alc_config_preset alc861_presets[] = {
11067 [ALC861_3ST] = {
11068 .mixers = { alc861_3ST_mixer },
11069 .init_verbs = { alc861_threestack_init_verbs },
11070 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11071 .dac_nids = alc861_dac_nids,
11072 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11073 .channel_mode = alc861_threestack_modes,
4e195a7b 11074 .need_dac_fix = 1,
df694daa
KY
11075 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11076 .adc_nids = alc861_adc_nids,
11077 .input_mux = &alc861_capture_source,
11078 },
11079 [ALC861_3ST_DIG] = {
11080 .mixers = { alc861_base_mixer },
11081 .init_verbs = { alc861_threestack_init_verbs },
11082 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11083 .dac_nids = alc861_dac_nids,
11084 .dig_out_nid = ALC861_DIGOUT_NID,
11085 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11086 .channel_mode = alc861_threestack_modes,
4e195a7b 11087 .need_dac_fix = 1,
df694daa
KY
11088 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11089 .adc_nids = alc861_adc_nids,
11090 .input_mux = &alc861_capture_source,
11091 },
11092 [ALC861_6ST_DIG] = {
11093 .mixers = { alc861_base_mixer },
11094 .init_verbs = { alc861_base_init_verbs },
11095 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11096 .dac_nids = alc861_dac_nids,
11097 .dig_out_nid = ALC861_DIGOUT_NID,
11098 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11099 .channel_mode = alc861_8ch_modes,
11100 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11101 .adc_nids = alc861_adc_nids,
11102 .input_mux = &alc861_capture_source,
11103 },
9c7f852e
TI
11104 [ALC660_3ST] = {
11105 .mixers = { alc861_3ST_mixer },
11106 .init_verbs = { alc861_threestack_init_verbs },
11107 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11108 .dac_nids = alc660_dac_nids,
11109 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11110 .channel_mode = alc861_threestack_modes,
4e195a7b 11111 .need_dac_fix = 1,
9c7f852e
TI
11112 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11113 .adc_nids = alc861_adc_nids,
11114 .input_mux = &alc861_capture_source,
11115 },
22309c3e
TI
11116 [ALC861_UNIWILL_M31] = {
11117 .mixers = { alc861_uniwill_m31_mixer },
11118 .init_verbs = { alc861_uniwill_m31_init_verbs },
11119 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11120 .dac_nids = alc861_dac_nids,
11121 .dig_out_nid = ALC861_DIGOUT_NID,
11122 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11123 .channel_mode = alc861_uniwill_m31_modes,
11124 .need_dac_fix = 1,
11125 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11126 .adc_nids = alc861_adc_nids,
11127 .input_mux = &alc861_capture_source,
11128 },
a53d1aec
TD
11129 [ALC861_TOSHIBA] = {
11130 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11131 .init_verbs = { alc861_base_init_verbs,
11132 alc861_toshiba_init_verbs },
a53d1aec
TD
11133 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11134 .dac_nids = alc861_dac_nids,
11135 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11136 .channel_mode = alc883_3ST_2ch_modes,
11137 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11138 .adc_nids = alc861_adc_nids,
11139 .input_mux = &alc861_capture_source,
11140 .unsol_event = alc861_toshiba_unsol_event,
11141 .init_hook = alc861_toshiba_automute,
11142 },
7cdbff94
MD
11143 [ALC861_ASUS] = {
11144 .mixers = { alc861_asus_mixer },
11145 .init_verbs = { alc861_asus_init_verbs },
11146 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11147 .dac_nids = alc861_dac_nids,
11148 .dig_out_nid = ALC861_DIGOUT_NID,
11149 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11150 .channel_mode = alc861_asus_modes,
11151 .need_dac_fix = 1,
11152 .hp_nid = 0x06,
11153 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11154 .adc_nids = alc861_adc_nids,
11155 .input_mux = &alc861_capture_source,
11156 },
56bb0cab
TI
11157 [ALC861_ASUS_LAPTOP] = {
11158 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11159 .init_verbs = { alc861_asus_init_verbs,
11160 alc861_asus_laptop_init_verbs },
11161 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11162 .dac_nids = alc861_dac_nids,
11163 .dig_out_nid = ALC861_DIGOUT_NID,
11164 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11165 .channel_mode = alc883_3ST_2ch_modes,
11166 .need_dac_fix = 1,
11167 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11168 .adc_nids = alc861_adc_nids,
11169 .input_mux = &alc861_capture_source,
11170 },
11171};
df694daa
KY
11172
11173
11174static int patch_alc861(struct hda_codec *codec)
11175{
11176 struct alc_spec *spec;
11177 int board_config;
11178 int err;
11179
dc041e0b 11180 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11181 if (spec == NULL)
11182 return -ENOMEM;
11183
f12ab1e0 11184 codec->spec = spec;
df694daa 11185
f5fcc13c
TI
11186 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11187 alc861_models,
11188 alc861_cfg_tbl);
9c7f852e 11189
f5fcc13c 11190 if (board_config < 0) {
9c7f852e
TI
11191 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11192 "trying auto-probe from BIOS...\n");
df694daa
KY
11193 board_config = ALC861_AUTO;
11194 }
11195
11196 if (board_config == ALC861_AUTO) {
11197 /* automatic parse from the BIOS config */
11198 err = alc861_parse_auto_config(codec);
11199 if (err < 0) {
11200 alc_free(codec);
11201 return err;
f12ab1e0 11202 } else if (!err) {
9c7f852e
TI
11203 printk(KERN_INFO
11204 "hda_codec: Cannot set up configuration "
11205 "from BIOS. Using base mode...\n");
df694daa
KY
11206 board_config = ALC861_3ST_DIG;
11207 }
11208 }
11209
11210 if (board_config != ALC861_AUTO)
11211 setup_preset(spec, &alc861_presets[board_config]);
11212
11213 spec->stream_name_analog = "ALC861 Analog";
11214 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11215 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11216
11217 spec->stream_name_digital = "ALC861 Digital";
11218 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11219 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11220
11221 codec->patch_ops = alc_patch_ops;
11222 if (board_config == ALC861_AUTO)
ae6b813a 11223 spec->init_hook = alc861_auto_init;
cb53c626
TI
11224#ifdef CONFIG_SND_HDA_POWER_SAVE
11225 if (!spec->loopback.amplist)
11226 spec->loopback.amplist = alc861_loopbacks;
11227#endif
df694daa 11228
1da177e4
LT
11229 return 0;
11230}
11231
f32610ed
JS
11232/*
11233 * ALC861-VD support
11234 *
11235 * Based on ALC882
11236 *
11237 * In addition, an independent DAC
11238 */
11239#define ALC861VD_DIGOUT_NID 0x06
11240
11241static hda_nid_t alc861vd_dac_nids[4] = {
11242 /* front, surr, clfe, side surr */
11243 0x02, 0x03, 0x04, 0x05
11244};
11245
11246/* dac_nids for ALC660vd are in a different order - according to
11247 * Realtek's driver.
11248 * This should probably tesult in a different mixer for 6stack models
11249 * of ALC660vd codecs, but for now there is only 3stack mixer
11250 * - and it is the same as in 861vd.
11251 * adc_nids in ALC660vd are (is) the same as in 861vd
11252 */
11253static hda_nid_t alc660vd_dac_nids[3] = {
11254 /* front, rear, clfe, rear_surr */
11255 0x02, 0x04, 0x03
11256};
11257
11258static hda_nid_t alc861vd_adc_nids[1] = {
11259 /* ADC0 */
11260 0x09,
11261};
11262
11263/* input MUX */
11264/* FIXME: should be a matrix-type input source selection */
11265static struct hda_input_mux alc861vd_capture_source = {
11266 .num_items = 4,
11267 .items = {
11268 { "Mic", 0x0 },
11269 { "Front Mic", 0x1 },
11270 { "Line", 0x2 },
11271 { "CD", 0x4 },
11272 },
11273};
11274
272a527c
KY
11275static struct hda_input_mux alc861vd_dallas_capture_source = {
11276 .num_items = 3,
11277 .items = {
11278 { "Front Mic", 0x0 },
11279 { "ATAPI Mic", 0x1 },
11280 { "Line In", 0x5 },
11281 },
11282};
11283
d1a991a6
KY
11284static struct hda_input_mux alc861vd_hp_capture_source = {
11285 .num_items = 2,
11286 .items = {
11287 { "Front Mic", 0x0 },
11288 { "ATAPI Mic", 0x1 },
11289 },
11290};
11291
f32610ed
JS
11292#define alc861vd_mux_enum_info alc_mux_enum_info
11293#define alc861vd_mux_enum_get alc_mux_enum_get
11294
11295static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11296 struct snd_ctl_elem_value *ucontrol)
11297{
11298 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11299 struct alc_spec *spec = codec->spec;
11300 const struct hda_input_mux *imux = spec->input_mux;
11301 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11302 static hda_nid_t capture_mixers[1] = { 0x22 };
11303 hda_nid_t nid = capture_mixers[adc_idx];
11304 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11305 unsigned int i, idx;
11306
11307 idx = ucontrol->value.enumerated.item[0];
11308 if (idx >= imux->num_items)
11309 idx = imux->num_items - 1;
82beb8fd 11310 if (*cur_val == idx)
f32610ed
JS
11311 return 0;
11312 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
11313 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11314 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11315 imux->items[i].index,
11316 HDA_AMP_MUTE, v);
f32610ed
JS
11317 }
11318 *cur_val = idx;
11319 return 1;
11320}
11321
11322/*
11323 * 2ch mode
11324 */
11325static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11326 { 2, NULL }
11327};
11328
11329/*
11330 * 6ch mode
11331 */
11332static struct hda_verb alc861vd_6stack_ch6_init[] = {
11333 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11334 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11335 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11336 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11337 { } /* end */
11338};
11339
11340/*
11341 * 8ch mode
11342 */
11343static struct hda_verb alc861vd_6stack_ch8_init[] = {
11344 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11345 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11346 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11347 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11348 { } /* end */
11349};
11350
11351static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11352 { 6, alc861vd_6stack_ch6_init },
11353 { 8, alc861vd_6stack_ch8_init },
11354};
11355
11356static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11357 {
11358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11359 .name = "Channel Mode",
11360 .info = alc_ch_mode_info,
11361 .get = alc_ch_mode_get,
11362 .put = alc_ch_mode_put,
11363 },
11364 { } /* end */
11365};
11366
11367static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11368 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11369 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11370
11371 {
11372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11373 /* The multiple "Capture Source" controls confuse alsamixer
11374 * So call somewhat different..
11375 *FIXME: the controls appear in the "playback" view!
11376 */
11377 /* .name = "Capture Source", */
11378 .name = "Input Source",
11379 .count = 1,
11380 .info = alc861vd_mux_enum_info,
11381 .get = alc861vd_mux_enum_get,
11382 .put = alc861vd_mux_enum_put,
11383 },
11384 { } /* end */
11385};
11386
11387/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11388 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11389 */
11390static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11391 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11392 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11393
11394 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11395 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11396
11397 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11398 HDA_OUTPUT),
11399 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11400 HDA_OUTPUT),
11401 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11402 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11403
11404 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11405 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11406
11407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11408
11409 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11412
11413 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11414 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11415 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11416
11417 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11418 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11419
11420 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11421 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11422
11423 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11424 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11425
11426 { } /* end */
11427};
11428
11429static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11430 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11432
11433 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11434
11435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11438
11439 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11442
11443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11445
11446 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11447 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11448
11449 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11450 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11451
11452 { } /* end */
11453};
11454
bdd148a3
KY
11455static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11456 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11457 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11458 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11459
11460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11461
11462 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11464 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11465
11466 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11467 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11468 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11469
11470 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11471 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11472
11473 { } /* end */
11474};
11475
272a527c
KY
11476/* Pin assignment: Front=0x14, HP = 0x15,
11477 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11478 */
11479static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11480 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11481 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11482 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11483 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11484 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11486 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11487 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
11489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
11490 { } /* end */
11491};
11492
d1a991a6
KY
11493/* Pin assignment: Speaker=0x14, Line-out = 0x15,
11494 * Front Mic=0x18, ATAPI Mic = 0x19,
11495 */
11496static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
11497 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11498 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11499 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11500 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11501 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11503 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11504 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11505
11506 { } /* end */
11507};
11508
f32610ed
JS
11509/*
11510 * generic initialization of ADC, input mixers and output mixers
11511 */
11512static struct hda_verb alc861vd_volume_init_verbs[] = {
11513 /*
11514 * Unmute ADC0 and set the default input to mic-in
11515 */
11516 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11517 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11518
11519 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
11520 * the analog-loopback mixer widget
11521 */
11522 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
11528
11529 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
11530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 11533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
11534
11535 /*
11536 * Set up output mixers (0x02 - 0x05)
11537 */
11538 /* set vol=0 to output mixers */
11539 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11540 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11541 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11542 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11543
11544 /* set up input amps for analog loopback */
11545 /* Amp Indices: DAC = 0, mixer = 1 */
11546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11548 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11550 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11551 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11552 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11553 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11554
11555 { }
11556};
11557
11558/*
11559 * 3-stack pin configuration:
11560 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
11561 */
11562static struct hda_verb alc861vd_3stack_init_verbs[] = {
11563 /*
11564 * Set pin mode and muting
11565 */
11566 /* set front pin widgets 0x14 for output */
11567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11568 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11569 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11570
11571 /* Mic (rear) pin: input vref at 80% */
11572 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11573 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11574 /* Front Mic pin: input vref at 80% */
11575 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11576 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11577 /* Line In pin: input */
11578 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11579 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11580 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11581 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11582 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11583 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11584 /* CD pin widget for input */
11585 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11586
11587 { }
11588};
11589
11590/*
11591 * 6-stack pin configuration:
11592 */
11593static struct hda_verb alc861vd_6stack_init_verbs[] = {
11594 /*
11595 * Set pin mode and muting
11596 */
11597 /* set front pin widgets 0x14 for output */
11598 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11599 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11601
11602 /* Rear Pin: output 1 (0x0d) */
11603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11606 /* CLFE Pin: output 2 (0x0e) */
11607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11609 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
11610 /* Side Pin: output 3 (0x0f) */
11611 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11612 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11613 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
11614
11615 /* Mic (rear) pin: input vref at 80% */
11616 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11617 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11618 /* Front Mic pin: input vref at 80% */
11619 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11620 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11621 /* Line In pin: input */
11622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11623 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11624 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11626 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11627 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11628 /* CD pin widget for input */
11629 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11630
11631 { }
11632};
11633
bdd148a3
KY
11634static struct hda_verb alc861vd_eapd_verbs[] = {
11635 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11636 { }
11637};
11638
11639static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
11640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11643 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11644 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11645 {}
11646};
11647
11648/* toggle speaker-output according to the hp-jack state */
11649static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
11650{
11651 unsigned int present;
11652 unsigned char bits;
11653
11654 present = snd_hda_codec_read(codec, 0x1b, 0,
11655 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11656 bits = present ? HDA_AMP_MUTE : 0;
11657 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11658 HDA_AMP_MUTE, bits);
bdd148a3
KY
11659}
11660
11661static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
11662{
11663 unsigned int present;
11664 unsigned char bits;
11665
11666 present = snd_hda_codec_read(codec, 0x18, 0,
11667 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11668 bits = present ? HDA_AMP_MUTE : 0;
11669 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
11670 HDA_AMP_MUTE, bits);
bdd148a3
KY
11671}
11672
11673static void alc861vd_lenovo_automute(struct hda_codec *codec)
11674{
11675 alc861vd_lenovo_hp_automute(codec);
11676 alc861vd_lenovo_mic_automute(codec);
11677}
11678
11679static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11680 unsigned int res)
11681{
11682 switch (res >> 26) {
11683 case ALC880_HP_EVENT:
11684 alc861vd_lenovo_hp_automute(codec);
11685 break;
11686 case ALC880_MIC_EVENT:
11687 alc861vd_lenovo_mic_automute(codec);
11688 break;
11689 }
11690}
11691
272a527c
KY
11692static struct hda_verb alc861vd_dallas_verbs[] = {
11693 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11694 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11695 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11696 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11697
11698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11699 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11702 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11705 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11706
11707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11711 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11713 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11714 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11715
11716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11720 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11723 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11724
11725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11729
11730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11731 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11733
11734 { } /* end */
11735};
11736
11737/* toggle speaker-output according to the hp-jack state */
11738static void alc861vd_dallas_automute(struct hda_codec *codec)
11739{
11740 unsigned int present;
11741
11742 present = snd_hda_codec_read(codec, 0x15, 0,
11743 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11745 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
11746}
11747
11748static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11749{
11750 if ((res >> 26) == ALC880_HP_EVENT)
11751 alc861vd_dallas_automute(codec);
11752}
11753
cb53c626
TI
11754#ifdef CONFIG_SND_HDA_POWER_SAVE
11755#define alc861vd_loopbacks alc880_loopbacks
11756#endif
11757
f32610ed
JS
11758/* pcm configuration: identiacal with ALC880 */
11759#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
11760#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
11761#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
11762#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
11763
11764/*
11765 * configuration and preset
11766 */
11767static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11768 [ALC660VD_3ST] = "3stack-660",
983f8ae4 11769 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
11770 [ALC861VD_3ST] = "3stack",
11771 [ALC861VD_3ST_DIG] = "3stack-digout",
11772 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 11773 [ALC861VD_LENOVO] = "lenovo",
272a527c 11774 [ALC861VD_DALLAS] = "dallas",
983f8ae4 11775 [ALC861VD_HP] = "hp",
f32610ed
JS
11776 [ALC861VD_AUTO] = "auto",
11777};
11778
11779static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
11780 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11781 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 11782 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 11783 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 11784 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 11785 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 11786 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 11787 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 11788 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 11789 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 11790 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
11791 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11792 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 11793 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
11794 {}
11795};
11796
11797static struct alc_config_preset alc861vd_presets[] = {
11798 [ALC660VD_3ST] = {
11799 .mixers = { alc861vd_3st_mixer },
11800 .init_verbs = { alc861vd_volume_init_verbs,
11801 alc861vd_3stack_init_verbs },
11802 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11803 .dac_nids = alc660vd_dac_nids,
11804 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11805 .adc_nids = alc861vd_adc_nids,
11806 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11807 .channel_mode = alc861vd_3stack_2ch_modes,
11808 .input_mux = &alc861vd_capture_source,
11809 },
6963f84c
MC
11810 [ALC660VD_3ST_DIG] = {
11811 .mixers = { alc861vd_3st_mixer },
11812 .init_verbs = { alc861vd_volume_init_verbs,
11813 alc861vd_3stack_init_verbs },
11814 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11815 .dac_nids = alc660vd_dac_nids,
11816 .dig_out_nid = ALC861VD_DIGOUT_NID,
11817 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11818 .adc_nids = alc861vd_adc_nids,
11819 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11820 .channel_mode = alc861vd_3stack_2ch_modes,
11821 .input_mux = &alc861vd_capture_source,
11822 },
f32610ed
JS
11823 [ALC861VD_3ST] = {
11824 .mixers = { alc861vd_3st_mixer },
11825 .init_verbs = { alc861vd_volume_init_verbs,
11826 alc861vd_3stack_init_verbs },
11827 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11828 .dac_nids = alc861vd_dac_nids,
11829 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11830 .channel_mode = alc861vd_3stack_2ch_modes,
11831 .input_mux = &alc861vd_capture_source,
11832 },
11833 [ALC861VD_3ST_DIG] = {
11834 .mixers = { alc861vd_3st_mixer },
11835 .init_verbs = { alc861vd_volume_init_verbs,
11836 alc861vd_3stack_init_verbs },
11837 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11838 .dac_nids = alc861vd_dac_nids,
11839 .dig_out_nid = ALC861VD_DIGOUT_NID,
11840 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11841 .channel_mode = alc861vd_3stack_2ch_modes,
11842 .input_mux = &alc861vd_capture_source,
11843 },
11844 [ALC861VD_6ST_DIG] = {
11845 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11846 .init_verbs = { alc861vd_volume_init_verbs,
11847 alc861vd_6stack_init_verbs },
11848 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11849 .dac_nids = alc861vd_dac_nids,
11850 .dig_out_nid = ALC861VD_DIGOUT_NID,
11851 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11852 .channel_mode = alc861vd_6stack_modes,
11853 .input_mux = &alc861vd_capture_source,
11854 },
bdd148a3
KY
11855 [ALC861VD_LENOVO] = {
11856 .mixers = { alc861vd_lenovo_mixer },
11857 .init_verbs = { alc861vd_volume_init_verbs,
11858 alc861vd_3stack_init_verbs,
11859 alc861vd_eapd_verbs,
11860 alc861vd_lenovo_unsol_verbs },
11861 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11862 .dac_nids = alc660vd_dac_nids,
11863 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11864 .adc_nids = alc861vd_adc_nids,
11865 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11866 .channel_mode = alc861vd_3stack_2ch_modes,
11867 .input_mux = &alc861vd_capture_source,
11868 .unsol_event = alc861vd_lenovo_unsol_event,
11869 .init_hook = alc861vd_lenovo_automute,
11870 },
272a527c
KY
11871 [ALC861VD_DALLAS] = {
11872 .mixers = { alc861vd_dallas_mixer },
11873 .init_verbs = { alc861vd_dallas_verbs },
11874 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11875 .dac_nids = alc861vd_dac_nids,
11876 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11877 .adc_nids = alc861vd_adc_nids,
11878 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11879 .channel_mode = alc861vd_3stack_2ch_modes,
11880 .input_mux = &alc861vd_dallas_capture_source,
11881 .unsol_event = alc861vd_dallas_unsol_event,
11882 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
11883 },
11884 [ALC861VD_HP] = {
11885 .mixers = { alc861vd_hp_mixer },
11886 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11887 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11888 .dac_nids = alc861vd_dac_nids,
11889 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11890 .dig_out_nid = ALC861VD_DIGOUT_NID,
11891 .adc_nids = alc861vd_adc_nids,
11892 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11893 .channel_mode = alc861vd_3stack_2ch_modes,
11894 .input_mux = &alc861vd_hp_capture_source,
11895 .unsol_event = alc861vd_dallas_unsol_event,
11896 .init_hook = alc861vd_dallas_automute,
11897 },
f32610ed
JS
11898};
11899
11900/*
11901 * BIOS auto configuration
11902 */
11903static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11904 hda_nid_t nid, int pin_type, int dac_idx)
11905{
11906 /* set as output */
11907 snd_hda_codec_write(codec, nid, 0,
11908 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11909 snd_hda_codec_write(codec, nid, 0,
11910 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11911}
11912
11913static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11914{
11915 struct alc_spec *spec = codec->spec;
11916 int i;
11917
bc9f98a9 11918 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
11919 for (i = 0; i <= HDA_SIDE; i++) {
11920 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11921 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
11922 if (nid)
11923 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 11924 pin_type, i);
f32610ed
JS
11925 }
11926}
11927
11928
11929static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11930{
11931 struct alc_spec *spec = codec->spec;
11932 hda_nid_t pin;
11933
11934 pin = spec->autocfg.hp_pins[0];
11935 if (pin) /* connect to front and use dac 0 */
11936 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11937}
11938
11939#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
11940#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
11941
11942static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11943{
11944 struct alc_spec *spec = codec->spec;
11945 int i;
11946
11947 for (i = 0; i < AUTO_PIN_LAST; i++) {
11948 hda_nid_t nid = spec->autocfg.input_pins[i];
11949 if (alc861vd_is_input_pin(nid)) {
11950 snd_hda_codec_write(codec, nid, 0,
11951 AC_VERB_SET_PIN_WIDGET_CONTROL,
11952 i <= AUTO_PIN_FRONT_MIC ?
11953 PIN_VREF80 : PIN_IN);
11954 if (nid != ALC861VD_PIN_CD_NID)
11955 snd_hda_codec_write(codec, nid, 0,
11956 AC_VERB_SET_AMP_GAIN_MUTE,
11957 AMP_OUT_MUTE);
11958 }
11959 }
11960}
11961
11962#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
11963#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
11964
11965/* add playback controls from the parsed DAC table */
11966/* Based on ALC880 version. But ALC861VD has separate,
11967 * different NIDs for mute/unmute switch and volume control */
11968static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11969 const struct auto_pin_cfg *cfg)
11970{
11971 char name[32];
11972 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11973 hda_nid_t nid_v, nid_s;
11974 int i, err;
11975
11976 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 11977 if (!spec->multiout.dac_nids[i])
f32610ed
JS
11978 continue;
11979 nid_v = alc861vd_idx_to_mixer_vol(
11980 alc880_dac_to_idx(
11981 spec->multiout.dac_nids[i]));
11982 nid_s = alc861vd_idx_to_mixer_switch(
11983 alc880_dac_to_idx(
11984 spec->multiout.dac_nids[i]));
11985
11986 if (i == 2) {
11987 /* Center/LFE */
f12ab1e0
TI
11988 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11989 "Center Playback Volume",
11990 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11991 HDA_OUTPUT));
11992 if (err < 0)
f32610ed 11993 return err;
f12ab1e0
TI
11994 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11995 "LFE Playback Volume",
11996 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11997 HDA_OUTPUT));
11998 if (err < 0)
f32610ed 11999 return err;
f12ab1e0
TI
12000 err = add_control(spec, ALC_CTL_BIND_MUTE,
12001 "Center Playback Switch",
12002 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12003 HDA_INPUT));
12004 if (err < 0)
f32610ed 12005 return err;
f12ab1e0
TI
12006 err = add_control(spec, ALC_CTL_BIND_MUTE,
12007 "LFE Playback Switch",
12008 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12009 HDA_INPUT));
12010 if (err < 0)
f32610ed
JS
12011 return err;
12012 } else {
12013 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12014 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12015 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12016 HDA_OUTPUT));
12017 if (err < 0)
f32610ed
JS
12018 return err;
12019 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12020 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12021 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12022 HDA_INPUT));
12023 if (err < 0)
f32610ed
JS
12024 return err;
12025 }
12026 }
12027 return 0;
12028}
12029
12030/* add playback controls for speaker and HP outputs */
12031/* Based on ALC880 version. But ALC861VD has separate,
12032 * different NIDs for mute/unmute switch and volume control */
12033static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12034 hda_nid_t pin, const char *pfx)
12035{
12036 hda_nid_t nid_v, nid_s;
12037 int err;
12038 char name[32];
12039
f12ab1e0 12040 if (!pin)
f32610ed
JS
12041 return 0;
12042
12043 if (alc880_is_fixed_pin(pin)) {
12044 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12045 /* specify the DAC as the extra output */
f12ab1e0 12046 if (!spec->multiout.hp_nid)
f32610ed
JS
12047 spec->multiout.hp_nid = nid_v;
12048 else
12049 spec->multiout.extra_out_nid[0] = nid_v;
12050 /* control HP volume/switch on the output mixer amp */
12051 nid_v = alc861vd_idx_to_mixer_vol(
12052 alc880_fixed_pin_idx(pin));
12053 nid_s = alc861vd_idx_to_mixer_switch(
12054 alc880_fixed_pin_idx(pin));
12055
12056 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12057 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12058 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12059 if (err < 0)
f32610ed
JS
12060 return err;
12061 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12062 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12063 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12064 if (err < 0)
f32610ed
JS
12065 return err;
12066 } else if (alc880_is_multi_pin(pin)) {
12067 /* set manual connection */
12068 /* we have only a switch on HP-out PIN */
12069 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12070 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12071 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12072 if (err < 0)
f32610ed
JS
12073 return err;
12074 }
12075 return 0;
12076}
12077
12078/* parse the BIOS configuration and set up the alc_spec
12079 * return 1 if successful, 0 if the proper config is not found,
12080 * or a negative error code
12081 * Based on ALC880 version - had to change it to override
12082 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12083static int alc861vd_parse_auto_config(struct hda_codec *codec)
12084{
12085 struct alc_spec *spec = codec->spec;
12086 int err;
12087 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12088
f12ab1e0
TI
12089 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12090 alc861vd_ignore);
12091 if (err < 0)
f32610ed 12092 return err;
f12ab1e0 12093 if (!spec->autocfg.line_outs)
f32610ed
JS
12094 return 0; /* can't find valid BIOS pin config */
12095
f12ab1e0
TI
12096 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12097 if (err < 0)
12098 return err;
12099 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12100 if (err < 0)
12101 return err;
12102 err = alc861vd_auto_create_extra_out(spec,
12103 spec->autocfg.speaker_pins[0],
12104 "Speaker");
12105 if (err < 0)
12106 return err;
12107 err = alc861vd_auto_create_extra_out(spec,
12108 spec->autocfg.hp_pins[0],
12109 "Headphone");
12110 if (err < 0)
12111 return err;
12112 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12113 if (err < 0)
f32610ed
JS
12114 return err;
12115
12116 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12117
12118 if (spec->autocfg.dig_out_pin)
12119 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12120
12121 if (spec->kctl_alloc)
12122 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12123
12124 spec->init_verbs[spec->num_init_verbs++]
12125 = alc861vd_volume_init_verbs;
12126
12127 spec->num_mux_defs = 1;
12128 spec->input_mux = &spec->private_imux;
12129
776e184e
TI
12130 err = alc_auto_add_mic_boost(codec);
12131 if (err < 0)
12132 return err;
12133
f32610ed
JS
12134 return 1;
12135}
12136
12137/* additional initialization for auto-configuration model */
12138static void alc861vd_auto_init(struct hda_codec *codec)
12139{
12140 alc861vd_auto_init_multi_out(codec);
12141 alc861vd_auto_init_hp_out(codec);
12142 alc861vd_auto_init_analog_input(codec);
12143}
12144
12145static int patch_alc861vd(struct hda_codec *codec)
12146{
12147 struct alc_spec *spec;
12148 int err, board_config;
12149
12150 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12151 if (spec == NULL)
12152 return -ENOMEM;
12153
12154 codec->spec = spec;
12155
12156 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12157 alc861vd_models,
12158 alc861vd_cfg_tbl);
12159
12160 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12161 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12162 "ALC861VD, trying auto-probe from BIOS...\n");
12163 board_config = ALC861VD_AUTO;
12164 }
12165
12166 if (board_config == ALC861VD_AUTO) {
12167 /* automatic parse from the BIOS config */
12168 err = alc861vd_parse_auto_config(codec);
12169 if (err < 0) {
12170 alc_free(codec);
12171 return err;
f12ab1e0 12172 } else if (!err) {
f32610ed
JS
12173 printk(KERN_INFO
12174 "hda_codec: Cannot set up configuration "
12175 "from BIOS. Using base mode...\n");
12176 board_config = ALC861VD_3ST;
12177 }
12178 }
12179
12180 if (board_config != ALC861VD_AUTO)
12181 setup_preset(spec, &alc861vd_presets[board_config]);
12182
12183 spec->stream_name_analog = "ALC861VD Analog";
12184 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12185 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12186
12187 spec->stream_name_digital = "ALC861VD Digital";
12188 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12189 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12190
12191 spec->adc_nids = alc861vd_adc_nids;
12192 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12193
12194 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12195 spec->num_mixers++;
12196
12197 codec->patch_ops = alc_patch_ops;
12198
12199 if (board_config == ALC861VD_AUTO)
12200 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12201#ifdef CONFIG_SND_HDA_POWER_SAVE
12202 if (!spec->loopback.amplist)
12203 spec->loopback.amplist = alc861vd_loopbacks;
12204#endif
f32610ed
JS
12205
12206 return 0;
12207}
12208
bc9f98a9
KY
12209/*
12210 * ALC662 support
12211 *
12212 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12213 * configuration. Each pin widget can choose any input DACs and a mixer.
12214 * Each ADC is connected from a mixer of all inputs. This makes possible
12215 * 6-channel independent captures.
12216 *
12217 * In addition, an independent DAC for the multi-playback (not used in this
12218 * driver yet).
12219 */
12220#define ALC662_DIGOUT_NID 0x06
12221#define ALC662_DIGIN_NID 0x0a
12222
12223static hda_nid_t alc662_dac_nids[4] = {
12224 /* front, rear, clfe, rear_surr */
12225 0x02, 0x03, 0x04
12226};
12227
12228static hda_nid_t alc662_adc_nids[1] = {
12229 /* ADC1-2 */
12230 0x09,
12231};
12232/* input MUX */
12233/* FIXME: should be a matrix-type input source selection */
12234
12235static struct hda_input_mux alc662_capture_source = {
12236 .num_items = 4,
12237 .items = {
12238 { "Mic", 0x0 },
12239 { "Front Mic", 0x1 },
12240 { "Line", 0x2 },
12241 { "CD", 0x4 },
12242 },
12243};
12244
12245static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12246 .num_items = 2,
12247 .items = {
12248 { "Mic", 0x1 },
12249 { "Line", 0x2 },
12250 },
12251};
291702f0
KY
12252
12253static struct hda_input_mux alc662_eeepc_capture_source = {
12254 .num_items = 2,
12255 .items = {
12256 { "i-Mic", 0x1 },
12257 { "e-Mic", 0x0 },
12258 },
12259};
12260
bc9f98a9
KY
12261#define alc662_mux_enum_info alc_mux_enum_info
12262#define alc662_mux_enum_get alc_mux_enum_get
12263
12264static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12265 struct snd_ctl_elem_value *ucontrol)
12266{
12267 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12268 struct alc_spec *spec = codec->spec;
12269 const struct hda_input_mux *imux = spec->input_mux;
12270 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
d1a991a6 12271 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
bc9f98a9
KY
12272 hda_nid_t nid = capture_mixers[adc_idx];
12273 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12274 unsigned int i, idx;
12275
12276 idx = ucontrol->value.enumerated.item[0];
12277 if (idx >= imux->num_items)
12278 idx = imux->num_items - 1;
82beb8fd 12279 if (*cur_val == idx)
bc9f98a9
KY
12280 return 0;
12281 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
12282 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12283 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12284 imux->items[i].index,
12285 HDA_AMP_MUTE, v);
bc9f98a9
KY
12286 }
12287 *cur_val = idx;
12288 return 1;
12289}
12290/*
12291 * 2ch mode
12292 */
12293static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12294 { 2, NULL }
12295};
12296
12297/*
12298 * 2ch mode
12299 */
12300static struct hda_verb alc662_3ST_ch2_init[] = {
12301 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12302 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12303 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12304 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12305 { } /* end */
12306};
12307
12308/*
12309 * 6ch mode
12310 */
12311static struct hda_verb alc662_3ST_ch6_init[] = {
12312 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12313 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12314 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12315 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12316 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12317 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12318 { } /* end */
12319};
12320
12321static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12322 { 2, alc662_3ST_ch2_init },
12323 { 6, alc662_3ST_ch6_init },
12324};
12325
12326/*
12327 * 2ch mode
12328 */
12329static struct hda_verb alc662_sixstack_ch6_init[] = {
12330 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12331 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12332 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12333 { } /* end */
12334};
12335
12336/*
12337 * 6ch mode
12338 */
12339static struct hda_verb alc662_sixstack_ch8_init[] = {
12340 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12341 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12342 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12343 { } /* end */
12344};
12345
12346static struct hda_channel_mode alc662_5stack_modes[2] = {
12347 { 2, alc662_sixstack_ch6_init },
12348 { 6, alc662_sixstack_ch8_init },
12349};
12350
12351/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12352 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12353 */
12354
12355static struct snd_kcontrol_new alc662_base_mixer[] = {
12356 /* output mixer control */
12357 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12358 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12359 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12360 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12363 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12364 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12366
12367 /*Input mixer control */
12368 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12369 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12370 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12371 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12372 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12373 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12374 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12375 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12376 { } /* end */
12377};
12378
12379static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12381 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12382 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12383 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12384 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12385 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12386 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12387 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12388 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12389 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12390 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12391 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12392 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12393 { } /* end */
12394};
12395
12396static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12398 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12400 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12401 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12402 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12403 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12404 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12406 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12407 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12408 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12409 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12412 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12413 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12414 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12415 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12416 { } /* end */
12417};
12418
12419static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12420 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12421 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12422 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12423 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
12424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
12429 { } /* end */
12430};
12431
291702f0
KY
12432static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12433 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12434
12435 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12437
12438 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12439 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12440 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12441
12442 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12443 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12444 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12445 { } /* end */
12446};
12447
bc9f98a9
KY
12448static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12449 {
12450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12451 .name = "Channel Mode",
12452 .info = alc_ch_mode_info,
12453 .get = alc_ch_mode_get,
12454 .put = alc_ch_mode_put,
12455 },
12456 { } /* end */
12457};
12458
12459static struct hda_verb alc662_init_verbs[] = {
12460 /* ADC: mute amp left and right */
12461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12462 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12463 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12464
cb53c626
TI
12465 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12466 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12467 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12468 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12469 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 12470
b60dd394
KY
12471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12474 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12477
12478 /* Front Pin: output 0 (0x0c) */
12479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12481
12482 /* Rear Pin: output 1 (0x0d) */
12483 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12485
12486 /* CLFE Pin: output 2 (0x0e) */
12487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12489
12490 /* Mic (rear) pin: input vref at 80% */
12491 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12492 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12493 /* Front Mic pin: input vref at 80% */
12494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12496 /* Line In pin: input */
12497 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12499 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12501 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12502 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12503 /* CD pin widget for input */
12504 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12505
12506 /* FIXME: use matrix-type input source selection */
12507 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12508 /* Input mixer */
12509 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12512 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
12513
12514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
12518 { }
12519};
12520
12521static struct hda_verb alc662_sue_init_verbs[] = {
12522 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
12523 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
12524 {}
12525};
12526
12527static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12528 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12530 {}
bc9f98a9
KY
12531};
12532
12533/*
12534 * generic initialization of ADC, input mixers and output mixers
12535 */
12536static struct hda_verb alc662_auto_init_verbs[] = {
12537 /*
12538 * Unmute ADC and set the default input to mic-in
12539 */
12540 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12542
12543 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12544 * mixer widget
12545 * Note: PASD motherboards uses the Line In 2 as the input for front
12546 * panel mic (mic 2)
12547 */
12548 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12549 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12550 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12551 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12552 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12553 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
12554
12555 /*
12556 * Set up output mixers (0x0c - 0x0f)
12557 */
12558 /* set vol=0 to output mixers */
12559 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12560 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12561 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12562
12563 /* set up input amps for analog loopback */
12564 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
12565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12571
12572
12573 /* FIXME: use matrix-type input source selection */
12574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12575 /* Input mixer */
12576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 12577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
12578 { }
12579};
12580
12581/* capture mixer elements */
12582static struct snd_kcontrol_new alc662_capture_mixer[] = {
12583 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12584 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12585 {
12586 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12587 /* The multiple "Capture Source" controls confuse alsamixer
12588 * So call somewhat different..
12589 * FIXME: the controls appear in the "playback" view!
12590 */
12591 /* .name = "Capture Source", */
12592 .name = "Input Source",
12593 .count = 1,
6e7939bb
HRK
12594 .info = alc662_mux_enum_info,
12595 .get = alc662_mux_enum_get,
12596 .put = alc662_mux_enum_put,
bc9f98a9
KY
12597 },
12598 { } /* end */
12599};
12600
12601static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
12602{
12603 unsigned int present;
f12ab1e0 12604 unsigned char bits;
bc9f98a9
KY
12605
12606 present = snd_hda_codec_read(codec, 0x14, 0,
12607 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12608 bits = present ? HDA_AMP_MUTE : 0;
12609 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12610 HDA_AMP_MUTE, bits);
bc9f98a9
KY
12611}
12612
12613static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
12614{
12615 unsigned int present;
f12ab1e0 12616 unsigned char bits;
bc9f98a9
KY
12617
12618 present = snd_hda_codec_read(codec, 0x1b, 0,
12619 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12620 bits = present ? HDA_AMP_MUTE : 0;
12621 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12622 HDA_AMP_MUTE, bits);
12623 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12624 HDA_AMP_MUTE, bits);
bc9f98a9
KY
12625}
12626
12627static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12628 unsigned int res)
12629{
12630 if ((res >> 26) == ALC880_HP_EVENT)
12631 alc662_lenovo_101e_all_automute(codec);
12632 if ((res >> 26) == ALC880_FRONT_EVENT)
12633 alc662_lenovo_101e_ispeaker_automute(codec);
12634}
12635
291702f0
KY
12636static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12637{
12638 unsigned int present;
12639
12640 present = snd_hda_codec_read(codec, 0x18, 0,
12641 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12642 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12643 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12644 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12645 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12646 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12647 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12648 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12649 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12650}
12651
12652/* unsolicited event for HP jack sensing */
12653static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12654 unsigned int res)
12655{
12656 if ((res >> 26) == ALC880_HP_EVENT)
12657 alc262_hippo1_automute( codec );
12658
12659 if ((res >> 26) == ALC880_MIC_EVENT)
12660 alc662_eeepc_mic_automute(codec);
12661}
12662
12663static void alc662_eeepc_inithook(struct hda_codec *codec)
12664{
12665 alc262_hippo1_automute( codec );
12666 alc662_eeepc_mic_automute(codec);
12667}
12668
cb53c626
TI
12669#ifdef CONFIG_SND_HDA_POWER_SAVE
12670#define alc662_loopbacks alc880_loopbacks
12671#endif
12672
bc9f98a9
KY
12673
12674/* pcm configuration: identiacal with ALC880 */
12675#define alc662_pcm_analog_playback alc880_pcm_analog_playback
12676#define alc662_pcm_analog_capture alc880_pcm_analog_capture
12677#define alc662_pcm_digital_playback alc880_pcm_digital_playback
12678#define alc662_pcm_digital_capture alc880_pcm_digital_capture
12679
12680/*
12681 * configuration and preset
12682 */
12683static const char *alc662_models[ALC662_MODEL_LAST] = {
12684 [ALC662_3ST_2ch_DIG] = "3stack-dig",
12685 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
12686 [ALC662_3ST_6ch] = "3stack-6ch",
12687 [ALC662_5ST_DIG] = "6stack-dig",
12688 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 12689 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
bc9f98a9
KY
12690 [ALC662_AUTO] = "auto",
12691};
12692
12693static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 12694 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
ac3e3741 12695 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
12696 {}
12697};
12698
12699static struct alc_config_preset alc662_presets[] = {
12700 [ALC662_3ST_2ch_DIG] = {
291702f0 12701 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
12702 .init_verbs = { alc662_init_verbs },
12703 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12704 .dac_nids = alc662_dac_nids,
12705 .dig_out_nid = ALC662_DIGOUT_NID,
12706 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12707 .adc_nids = alc662_adc_nids,
12708 .dig_in_nid = ALC662_DIGIN_NID,
12709 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12710 .channel_mode = alc662_3ST_2ch_modes,
12711 .input_mux = &alc662_capture_source,
12712 },
12713 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
12714 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12715 alc662_capture_mixer },
bc9f98a9
KY
12716 .init_verbs = { alc662_init_verbs },
12717 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12718 .dac_nids = alc662_dac_nids,
12719 .dig_out_nid = ALC662_DIGOUT_NID,
12720 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12721 .adc_nids = alc662_adc_nids,
12722 .dig_in_nid = ALC662_DIGIN_NID,
12723 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12724 .channel_mode = alc662_3ST_6ch_modes,
12725 .need_dac_fix = 1,
12726 .input_mux = &alc662_capture_source,
f12ab1e0 12727 },
bc9f98a9 12728 [ALC662_3ST_6ch] = {
291702f0
KY
12729 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12730 alc662_capture_mixer },
bc9f98a9
KY
12731 .init_verbs = { alc662_init_verbs },
12732 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12733 .dac_nids = alc662_dac_nids,
12734 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12735 .adc_nids = alc662_adc_nids,
12736 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12737 .channel_mode = alc662_3ST_6ch_modes,
12738 .need_dac_fix = 1,
12739 .input_mux = &alc662_capture_source,
f12ab1e0 12740 },
bc9f98a9 12741 [ALC662_5ST_DIG] = {
291702f0
KY
12742 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12743 alc662_capture_mixer },
bc9f98a9
KY
12744 .init_verbs = { alc662_init_verbs },
12745 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12746 .dac_nids = alc662_dac_nids,
12747 .dig_out_nid = ALC662_DIGOUT_NID,
12748 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12749 .adc_nids = alc662_adc_nids,
12750 .dig_in_nid = ALC662_DIGIN_NID,
12751 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12752 .channel_mode = alc662_5stack_modes,
12753 .input_mux = &alc662_capture_source,
12754 },
12755 [ALC662_LENOVO_101E] = {
291702f0 12756 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
12757 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12758 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12759 .dac_nids = alc662_dac_nids,
12760 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12761 .adc_nids = alc662_adc_nids,
12762 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12763 .channel_mode = alc662_3ST_2ch_modes,
12764 .input_mux = &alc662_lenovo_101e_capture_source,
12765 .unsol_event = alc662_lenovo_101e_unsol_event,
12766 .init_hook = alc662_lenovo_101e_all_automute,
12767 },
291702f0
KY
12768 [ALC662_ASUS_EEEPC_P701] = {
12769 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12770 .init_verbs = { alc662_init_verbs,
12771 alc662_eeepc_sue_init_verbs },
12772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12773 .dac_nids = alc662_dac_nids,
12774 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12775 .adc_nids = alc662_adc_nids,
12776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12777 .channel_mode = alc662_3ST_2ch_modes,
12778 .input_mux = &alc662_eeepc_capture_source,
12779 .unsol_event = alc662_eeepc_unsol_event,
12780 .init_hook = alc662_eeepc_inithook,
12781 },
bc9f98a9
KY
12782
12783};
12784
12785
12786/*
12787 * BIOS auto configuration
12788 */
12789
12790/* add playback controls from the parsed DAC table */
12791static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12792 const struct auto_pin_cfg *cfg)
12793{
12794 char name[32];
12795 static const char *chname[4] = {
12796 "Front", "Surround", NULL /*CLFE*/, "Side"
12797 };
12798 hda_nid_t nid;
12799 int i, err;
12800
12801 for (i = 0; i < cfg->line_outs; i++) {
12802 if (!spec->multiout.dac_nids[i])
12803 continue;
b60dd394 12804 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
12805 if (i == 2) {
12806 /* Center/LFE */
12807 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12808 "Center Playback Volume",
f12ab1e0
TI
12809 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12810 HDA_OUTPUT));
bc9f98a9
KY
12811 if (err < 0)
12812 return err;
12813 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12814 "LFE Playback Volume",
f12ab1e0
TI
12815 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12816 HDA_OUTPUT));
bc9f98a9
KY
12817 if (err < 0)
12818 return err;
12819 err = add_control(spec, ALC_CTL_BIND_MUTE,
12820 "Center Playback Switch",
f12ab1e0
TI
12821 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12822 HDA_INPUT));
bc9f98a9
KY
12823 if (err < 0)
12824 return err;
12825 err = add_control(spec, ALC_CTL_BIND_MUTE,
12826 "LFE Playback Switch",
f12ab1e0
TI
12827 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12828 HDA_INPUT));
bc9f98a9
KY
12829 if (err < 0)
12830 return err;
12831 } else {
12832 sprintf(name, "%s Playback Volume", chname[i]);
12833 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
12834 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12835 HDA_OUTPUT));
bc9f98a9
KY
12836 if (err < 0)
12837 return err;
12838 sprintf(name, "%s Playback Switch", chname[i]);
12839 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
12840 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12841 HDA_INPUT));
bc9f98a9
KY
12842 if (err < 0)
12843 return err;
12844 }
12845 }
12846 return 0;
12847}
12848
12849/* add playback controls for speaker and HP outputs */
12850static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12851 const char *pfx)
12852{
12853 hda_nid_t nid;
12854 int err;
12855 char name[32];
12856
12857 if (!pin)
12858 return 0;
12859
12860 if (alc880_is_fixed_pin(pin)) {
12861 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12862 /* printk("DAC nid=%x\n",nid); */
12863 /* specify the DAC as the extra output */
12864 if (!spec->multiout.hp_nid)
12865 spec->multiout.hp_nid = nid;
12866 else
12867 spec->multiout.extra_out_nid[0] = nid;
12868 /* control HP volume/switch on the output mixer amp */
12869 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12870 sprintf(name, "%s Playback Volume", pfx);
12871 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12872 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12873 if (err < 0)
12874 return err;
12875 sprintf(name, "%s Playback Switch", pfx);
12876 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12877 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12878 if (err < 0)
12879 return err;
12880 } else if (alc880_is_multi_pin(pin)) {
12881 /* set manual connection */
12882 /* we have only a switch on HP-out PIN */
12883 sprintf(name, "%s Playback Switch", pfx);
12884 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12885 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12886 if (err < 0)
12887 return err;
12888 }
12889 return 0;
12890}
12891
12892/* create playback/capture controls for input pins */
12893static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12894 const struct auto_pin_cfg *cfg)
12895{
12896 struct hda_input_mux *imux = &spec->private_imux;
12897 int i, err, idx;
12898
12899 for (i = 0; i < AUTO_PIN_LAST; i++) {
12900 if (alc880_is_input_pin(cfg->input_pins[i])) {
12901 idx = alc880_input_pin_idx(cfg->input_pins[i]);
12902 err = new_analog_input(spec, cfg->input_pins[i],
12903 auto_pin_cfg_labels[i],
12904 idx, 0x0b);
12905 if (err < 0)
12906 return err;
12907 imux->items[imux->num_items].label =
12908 auto_pin_cfg_labels[i];
12909 imux->items[imux->num_items].index =
12910 alc880_input_pin_idx(cfg->input_pins[i]);
12911 imux->num_items++;
12912 }
12913 }
12914 return 0;
12915}
12916
12917static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12918 hda_nid_t nid, int pin_type,
12919 int dac_idx)
12920{
12921 /* set as output */
12922 snd_hda_codec_write(codec, nid, 0,
12923 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12924 snd_hda_codec_write(codec, nid, 0,
12925 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12926 /* need the manual connection? */
12927 if (alc880_is_multi_pin(nid)) {
12928 struct alc_spec *spec = codec->spec;
12929 int idx = alc880_multi_pin_idx(nid);
12930 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12931 AC_VERB_SET_CONNECT_SEL,
12932 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12933 }
12934}
12935
12936static void alc662_auto_init_multi_out(struct hda_codec *codec)
12937{
12938 struct alc_spec *spec = codec->spec;
12939 int i;
12940
12941 for (i = 0; i <= HDA_SIDE; i++) {
12942 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12943 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 12944 if (nid)
baba8ee9 12945 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
12946 i);
12947 }
12948}
12949
12950static void alc662_auto_init_hp_out(struct hda_codec *codec)
12951{
12952 struct alc_spec *spec = codec->spec;
12953 hda_nid_t pin;
12954
12955 pin = spec->autocfg.hp_pins[0];
12956 if (pin) /* connect to front */
12957 /* use dac 0 */
12958 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12959}
12960
12961#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
12962#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
12963
12964static void alc662_auto_init_analog_input(struct hda_codec *codec)
12965{
12966 struct alc_spec *spec = codec->spec;
12967 int i;
12968
12969 for (i = 0; i < AUTO_PIN_LAST; i++) {
12970 hda_nid_t nid = spec->autocfg.input_pins[i];
12971 if (alc662_is_input_pin(nid)) {
12972 snd_hda_codec_write(codec, nid, 0,
12973 AC_VERB_SET_PIN_WIDGET_CONTROL,
12974 (i <= AUTO_PIN_FRONT_MIC ?
12975 PIN_VREF80 : PIN_IN));
12976 if (nid != ALC662_PIN_CD_NID)
12977 snd_hda_codec_write(codec, nid, 0,
12978 AC_VERB_SET_AMP_GAIN_MUTE,
12979 AMP_OUT_MUTE);
12980 }
12981 }
12982}
12983
12984static int alc662_parse_auto_config(struct hda_codec *codec)
12985{
12986 struct alc_spec *spec = codec->spec;
12987 int err;
12988 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12989
12990 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12991 alc662_ignore);
12992 if (err < 0)
12993 return err;
12994 if (!spec->autocfg.line_outs)
12995 return 0; /* can't find valid BIOS pin config */
12996
f12ab1e0
TI
12997 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12998 if (err < 0)
12999 return err;
13000 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13001 if (err < 0)
13002 return err;
13003 err = alc662_auto_create_extra_out(spec,
13004 spec->autocfg.speaker_pins[0],
13005 "Speaker");
13006 if (err < 0)
13007 return err;
13008 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13009 "Headphone");
13010 if (err < 0)
13011 return err;
13012 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13013 if (err < 0)
bc9f98a9
KY
13014 return err;
13015
13016 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13017
13018 if (spec->autocfg.dig_out_pin)
13019 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13020
13021 if (spec->kctl_alloc)
13022 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13023
13024 spec->num_mux_defs = 1;
13025 spec->input_mux = &spec->private_imux;
13026
8c87286f 13027 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13028 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13029 spec->num_mixers++;
8c87286f 13030 return 1;
bc9f98a9
KY
13031}
13032
13033/* additional initialization for auto-configuration model */
13034static void alc662_auto_init(struct hda_codec *codec)
13035{
13036 alc662_auto_init_multi_out(codec);
13037 alc662_auto_init_hp_out(codec);
13038 alc662_auto_init_analog_input(codec);
13039}
13040
13041static int patch_alc662(struct hda_codec *codec)
13042{
13043 struct alc_spec *spec;
13044 int err, board_config;
13045
13046 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13047 if (!spec)
13048 return -ENOMEM;
13049
13050 codec->spec = spec;
13051
13052 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13053 alc662_models,
13054 alc662_cfg_tbl);
13055 if (board_config < 0) {
13056 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13057 "trying auto-probe from BIOS...\n");
13058 board_config = ALC662_AUTO;
13059 }
13060
13061 if (board_config == ALC662_AUTO) {
13062 /* automatic parse from the BIOS config */
13063 err = alc662_parse_auto_config(codec);
13064 if (err < 0) {
13065 alc_free(codec);
13066 return err;
8c87286f 13067 } else if (!err) {
bc9f98a9
KY
13068 printk(KERN_INFO
13069 "hda_codec: Cannot set up configuration "
13070 "from BIOS. Using base mode...\n");
13071 board_config = ALC662_3ST_2ch_DIG;
13072 }
13073 }
13074
13075 if (board_config != ALC662_AUTO)
13076 setup_preset(spec, &alc662_presets[board_config]);
13077
13078 spec->stream_name_analog = "ALC662 Analog";
13079 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13080 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13081
13082 spec->stream_name_digital = "ALC662 Digital";
13083 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13084 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13085
13086 if (!spec->adc_nids && spec->input_mux) {
13087 spec->adc_nids = alc662_adc_nids;
13088 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13089 }
13090
13091 codec->patch_ops = alc_patch_ops;
13092 if (board_config == ALC662_AUTO)
13093 spec->init_hook = alc662_auto_init;
cb53c626
TI
13094#ifdef CONFIG_SND_HDA_POWER_SAVE
13095 if (!spec->loopback.amplist)
13096 spec->loopback.amplist = alc662_loopbacks;
13097#endif
bc9f98a9
KY
13098
13099 return 0;
13100}
13101
1da177e4
LT
13102/*
13103 * patch entries
13104 */
13105struct hda_codec_preset snd_hda_preset_realtek[] = {
13106 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13107 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13108 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13109 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13110 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13111 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13112 .patch = patch_alc861 },
f32610ed
JS
13113 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13114 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13115 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13116 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13117 .patch = patch_alc883 },
13118 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13119 .patch = patch_alc662 },
f32610ed 13120 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13121 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13122 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13123 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13124 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13125 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13126 {} /* terminator */
13127};