]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] hda-codec - Fix auto-configuration of Realtek codecs
[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
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
31#include "hda_codec.h"
32#include "hda_local.h"
33
ccc656ce
KY
34#define ALC880_FRONT_EVENT 0x01
35#define ALC880_DCVOL_EVENT 0x02
36#define ALC880_HP_EVENT 0x04
37#define ALC880_MIC_EVENT 0x08
1da177e4
LT
38
39/* ALC880 board config type */
40enum {
1da177e4
LT
41 ALC880_3ST,
42 ALC880_3ST_DIG,
43 ALC880_5ST,
44 ALC880_5ST_DIG,
45 ALC880_W810,
dfc0ff62 46 ALC880_Z71V,
b6482d48 47 ALC880_6ST,
16ded525
TI
48 ALC880_6ST_DIG,
49 ALC880_F1734,
50 ALC880_ASUS,
51 ALC880_ASUS_DIG,
52 ALC880_ASUS_W1V,
df694daa 53 ALC880_ASUS_DIG2,
2cf9f0fc 54 ALC880_FUJITSU,
16ded525 55 ALC880_UNIWILL_DIG,
ccc656ce
KY
56 ALC880_UNIWILL,
57 ALC880_UNIWILL_P53,
df694daa
KY
58 ALC880_CLEVO,
59 ALC880_TCL_S700,
ae6b813a 60 ALC880_LG,
d681518a 61 ALC880_LG_LW,
e9edcee0
TI
62#ifdef CONFIG_SND_DEBUG
63 ALC880_TEST,
64#endif
df694daa 65 ALC880_AUTO,
16ded525
TI
66 ALC880_MODEL_LAST /* last tag */
67};
68
69/* ALC260 models */
70enum {
71 ALC260_BASIC,
72 ALC260_HP,
df694daa
KY
73 ALC260_HP_3013,
74 ALC260_FUJITSU_S702X,
0bfc90e9 75 ALC260_ACER,
bc9f98a9
KY
76 ALC260_WILL,
77 ALC260_REPLACER_672V,
7cf51e48
JW
78#ifdef CONFIG_SND_DEBUG
79 ALC260_TEST,
80#endif
df694daa 81 ALC260_AUTO,
16ded525 82 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
83};
84
df694daa
KY
85/* ALC262 models */
86enum {
87 ALC262_BASIC,
ccc656ce
KY
88 ALC262_HIPPO,
89 ALC262_HIPPO_1,
834be88d 90 ALC262_FUJITSU,
9c7f852e 91 ALC262_HP_BPC,
cd7509a4
KY
92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF,
66d2a9d6 94 ALC262_HP_TC_T5735,
8c427226 95 ALC262_HP_RP5700,
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,
3866f0b0 109 ALC268_DELL,
f12462c5 110 ALC268_ZEPTO,
86c53bd2
JW
111#ifdef CONFIG_SND_DEBUG
112 ALC268_TEST,
113#endif
a361d84b
KY
114 ALC268_AUTO,
115 ALC268_MODEL_LAST /* last tag */
116};
117
f6a92248
KY
118/* ALC269 models */
119enum {
120 ALC269_BASIC,
121 ALC269_AUTO,
122 ALC269_MODEL_LAST /* last tag */
123};
124
df694daa
KY
125/* ALC861 models */
126enum {
127 ALC861_3ST,
9c7f852e 128 ALC660_3ST,
df694daa
KY
129 ALC861_3ST_DIG,
130 ALC861_6ST_DIG,
22309c3e 131 ALC861_UNIWILL_M31,
a53d1aec 132 ALC861_TOSHIBA,
7cdbff94 133 ALC861_ASUS,
56bb0cab 134 ALC861_ASUS_LAPTOP,
df694daa
KY
135 ALC861_AUTO,
136 ALC861_MODEL_LAST,
137};
138
f32610ed
JS
139/* ALC861-VD models */
140enum {
141 ALC660VD_3ST,
6963f84c 142 ALC660VD_3ST_DIG,
f32610ed
JS
143 ALC861VD_3ST,
144 ALC861VD_3ST_DIG,
145 ALC861VD_6ST_DIG,
bdd148a3 146 ALC861VD_LENOVO,
272a527c 147 ALC861VD_DALLAS,
d1a991a6 148 ALC861VD_HP,
f32610ed
JS
149 ALC861VD_AUTO,
150 ALC861VD_MODEL_LAST,
151};
152
bc9f98a9
KY
153/* ALC662 models */
154enum {
155 ALC662_3ST_2ch_DIG,
156 ALC662_3ST_6ch_DIG,
157 ALC662_3ST_6ch,
158 ALC662_5ST_DIG,
159 ALC662_LENOVO_101E,
291702f0 160 ALC662_ASUS_EEEPC_P701,
8c427226 161 ALC662_ASUS_EEEPC_EP20,
bc9f98a9
KY
162 ALC662_AUTO,
163 ALC662_MODEL_LAST,
164};
165
df694daa
KY
166/* ALC882 models */
167enum {
168 ALC882_3ST_DIG,
169 ALC882_6ST_DIG,
4b146cb0 170 ALC882_ARIMA,
bdd148a3 171 ALC882_W2JC,
272a527c
KY
172 ALC882_TARGA,
173 ALC882_ASUS_A7J,
914759b7 174 ALC882_ASUS_A7M,
9102cd1c 175 ALC885_MACPRO,
87350ad0 176 ALC885_MBP3,
c54728d8 177 ALC885_IMAC24,
272a527c 178 ALC882_AUTO,
df694daa
KY
179 ALC882_MODEL_LAST,
180};
181
9c7f852e
TI
182/* ALC883 models */
183enum {
184 ALC883_3ST_2ch_DIG,
185 ALC883_3ST_6ch_DIG,
186 ALC883_3ST_6ch,
187 ALC883_6ST_DIG,
ccc656ce
KY
188 ALC883_TARGA_DIG,
189 ALC883_TARGA_2ch_DIG,
bab282b9 190 ALC883_ACER,
2880a867 191 ALC883_ACER_ASPIRE,
c07584c8 192 ALC883_MEDION,
272a527c 193 ALC883_MEDION_MD2,
b373bdeb 194 ALC883_LAPTOP_EAPD,
bc9f98a9 195 ALC883_LENOVO_101E_2ch,
272a527c 196 ALC883_LENOVO_NB0763,
189609ae
KY
197 ALC888_LENOVO_MS7195_DIG,
198 ALC883_HAIER_W66,
4723c022
CM
199 ALC888_6ST_HP,
200 ALC888_3ST_HP,
5795b9e6 201 ALC888_6ST_DELL,
a8848bd6 202 ALC883_MITAC,
9c7f852e
TI
203 ALC883_AUTO,
204 ALC883_MODEL_LAST,
205};
206
df694daa
KY
207/* for GPIO Poll */
208#define GPIO_MASK 0x03
209
1da177e4
LT
210struct alc_spec {
211 /* codec parameterization */
df694daa 212 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
213 unsigned int num_mixers;
214
df694daa 215 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
216 * don't forget NULL
217 * termination!
e9edcee0
TI
218 */
219 unsigned int num_init_verbs;
1da177e4 220
16ded525 221 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
222 struct hda_pcm_stream *stream_analog_playback;
223 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
224 struct hda_pcm_stream *stream_analog_alt_playback;
225 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 226
f12ab1e0 227 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
228 struct hda_pcm_stream *stream_digital_playback;
229 struct hda_pcm_stream *stream_digital_capture;
230
231 /* playback */
16ded525
TI
232 struct hda_multi_out multiout; /* playback set-up
233 * max_channels, dacs must be set
234 * dig_out_nid and hp_nid are optional
235 */
6330079f 236 hda_nid_t alt_dac_nid;
1da177e4
LT
237
238 /* capture */
239 unsigned int num_adc_nids;
240 hda_nid_t *adc_nids;
e1406348 241 hda_nid_t *capsrc_nids;
16ded525 242 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
243
244 /* capture source */
a1e8d2da 245 unsigned int num_mux_defs;
1da177e4
LT
246 const struct hda_input_mux *input_mux;
247 unsigned int cur_mux[3];
248
249 /* channel model */
d2a6d7dc 250 const struct hda_channel_mode *channel_mode;
1da177e4 251 int num_channel_mode;
4e195a7b 252 int need_dac_fix;
1da177e4
LT
253
254 /* PCM information */
4c5186ed 255 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 256
e9edcee0
TI
257 /* dynamic controls, init_verbs and input_mux */
258 struct auto_pin_cfg autocfg;
259 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 260 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 261 struct hda_input_mux private_imux;
41923e44 262 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 263
ae6b813a
TI
264 /* hooks */
265 void (*init_hook)(struct hda_codec *codec);
266 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
267
834be88d
TI
268 /* for pin sensing */
269 unsigned int sense_updated: 1;
270 unsigned int jack_present: 1;
bec15c3a 271 unsigned int master_sw: 1;
cb53c626 272
2134ea4f
TI
273 /* for virtual master */
274 hda_nid_t vmaster_nid;
275 u32 vmaster_tlv[4];
cb53c626
TI
276#ifdef CONFIG_SND_HDA_POWER_SAVE
277 struct hda_loopback_check loopback;
278#endif
df694daa
KY
279};
280
281/*
282 * configuration template - to be copied to the spec instance
283 */
284struct alc_config_preset {
9c7f852e
TI
285 struct snd_kcontrol_new *mixers[5]; /* should be identical size
286 * with spec
287 */
df694daa
KY
288 const struct hda_verb *init_verbs[5];
289 unsigned int num_dacs;
290 hda_nid_t *dac_nids;
291 hda_nid_t dig_out_nid; /* optional */
292 hda_nid_t hp_nid; /* optional */
293 unsigned int num_adc_nids;
294 hda_nid_t *adc_nids;
e1406348 295 hda_nid_t *capsrc_nids;
df694daa
KY
296 hda_nid_t dig_in_nid;
297 unsigned int num_channel_mode;
298 const struct hda_channel_mode *channel_mode;
4e195a7b 299 int need_dac_fix;
a1e8d2da 300 unsigned int num_mux_defs;
df694daa 301 const struct hda_input_mux *input_mux;
ae6b813a
TI
302 void (*unsol_event)(struct hda_codec *, unsigned int);
303 void (*init_hook)(struct hda_codec *);
cb53c626
TI
304#ifdef CONFIG_SND_HDA_POWER_SAVE
305 struct hda_amp_list *loopbacks;
306#endif
1da177e4
LT
307};
308
1da177e4
LT
309
310/*
311 * input MUX handling
312 */
9c7f852e
TI
313static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
314 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
315{
316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
317 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
318 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
319 if (mux_idx >= spec->num_mux_defs)
320 mux_idx = 0;
321 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
322}
323
9c7f852e
TI
324static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
326{
327 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
328 struct alc_spec *spec = codec->spec;
329 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330
331 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
332 return 0;
333}
334
9c7f852e
TI
335static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
337{
338 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct alc_spec *spec = codec->spec;
340 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
a1e8d2da 341 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
e1406348
TI
342 hda_nid_t nid = spec->capsrc_nids ?
343 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
a1e8d2da 344 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
e1406348 345 nid, &spec->cur_mux[adc_idx]);
1da177e4
LT
346}
347
e9edcee0 348
1da177e4
LT
349/*
350 * channel mode setting
351 */
9c7f852e
TI
352static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
353 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
354{
355 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
356 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
357 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
358 spec->num_channel_mode);
1da177e4
LT
359}
360
9c7f852e
TI
361static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
363{
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 struct alc_spec *spec = codec->spec;
d2a6d7dc 366 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e
TI
367 spec->num_channel_mode,
368 spec->multiout.max_channels);
1da177e4
LT
369}
370
9c7f852e
TI
371static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
372 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
373{
374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
375 struct alc_spec *spec = codec->spec;
4e195a7b
TI
376 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
377 spec->num_channel_mode,
378 &spec->multiout.max_channels);
bd2033f2 379 if (err >= 0 && spec->need_dac_fix)
4e195a7b
TI
380 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
381 return err;
1da177e4
LT
382}
383
a9430dd8 384/*
4c5186ed
JW
385 * Control the mode of pin widget settings via the mixer. "pc" is used
386 * instead of "%" to avoid consequences of accidently treating the % as
387 * being part of a format specifier. Maximum allowed length of a value is
388 * 63 characters plus NULL terminator.
7cf51e48
JW
389 *
390 * Note: some retasking pin complexes seem to ignore requests for input
391 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
392 * are requested. Therefore order this list so that this behaviour will not
393 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
394 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
395 * March 2006.
4c5186ed
JW
396 */
397static char *alc_pin_mode_names[] = {
7cf51e48
JW
398 "Mic 50pc bias", "Mic 80pc bias",
399 "Line in", "Line out", "Headphone out",
4c5186ed
JW
400};
401static unsigned char alc_pin_mode_values[] = {
7cf51e48 402 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
403};
404/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
405 * in the pin being assumed to be exclusively an input or an output pin. In
406 * addition, "input" pins may or may not process the mic bias option
407 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
408 * accept requests for bias as of chip versions up to March 2006) and/or
409 * wiring in the computer.
a9430dd8 410 */
a1e8d2da
JW
411#define ALC_PIN_DIR_IN 0x00
412#define ALC_PIN_DIR_OUT 0x01
413#define ALC_PIN_DIR_INOUT 0x02
414#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
415#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 416
a1e8d2da 417/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
418 * For each direction the minimum and maximum values are given.
419 */
a1e8d2da 420static signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
421 { 0, 2 }, /* ALC_PIN_DIR_IN */
422 { 3, 4 }, /* ALC_PIN_DIR_OUT */
423 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
424 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
425 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
426};
427#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
428#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
429#define alc_pin_mode_n_items(_dir) \
430 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
431
9c7f852e
TI
432static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_info *uinfo)
a9430dd8 434{
4c5186ed
JW
435 unsigned int item_num = uinfo->value.enumerated.item;
436 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
437
438 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 439 uinfo->count = 1;
4c5186ed
JW
440 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
441
442 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
443 item_num = alc_pin_mode_min(dir);
444 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
445 return 0;
446}
447
9c7f852e
TI
448static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
449 struct snd_ctl_elem_value *ucontrol)
a9430dd8 450{
4c5186ed 451 unsigned int i;
a9430dd8
JW
452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
453 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 454 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 455 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
456 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
457 AC_VERB_GET_PIN_WIDGET_CONTROL,
458 0x00);
a9430dd8 459
4c5186ed
JW
460 /* Find enumerated value for current pinctl setting */
461 i = alc_pin_mode_min(dir);
9c7f852e 462 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
4c5186ed 463 i++;
9c7f852e 464 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
465 return 0;
466}
467
9c7f852e
TI
468static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
a9430dd8 470{
4c5186ed 471 signed int change;
a9430dd8
JW
472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
473 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
474 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
475 long val = *ucontrol->value.integer.value;
9c7f852e
TI
476 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
477 AC_VERB_GET_PIN_WIDGET_CONTROL,
478 0x00);
a9430dd8 479
f12ab1e0 480 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
481 val = alc_pin_mode_min(dir);
482
483 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
484 if (change) {
485 /* Set pin mode to that requested */
82beb8fd
TI
486 snd_hda_codec_write_cache(codec, nid, 0,
487 AC_VERB_SET_PIN_WIDGET_CONTROL,
488 alc_pin_mode_values[val]);
cdcd9268
JW
489
490 /* Also enable the retasking pin's input/output as required
491 * for the requested pin mode. Enum values of 2 or less are
492 * input modes.
493 *
494 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
495 * reduces noise slightly (particularly on input) so we'll
496 * do it. However, having both input and output buffers
497 * enabled simultaneously doesn't seem to be problematic if
498 * this turns out to be necessary in the future.
cdcd9268
JW
499 */
500 if (val <= 2) {
47fd830a
TI
501 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
502 HDA_AMP_MUTE, HDA_AMP_MUTE);
503 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
504 HDA_AMP_MUTE, 0);
cdcd9268 505 } else {
47fd830a
TI
506 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
507 HDA_AMP_MUTE, HDA_AMP_MUTE);
508 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
509 HDA_AMP_MUTE, 0);
cdcd9268
JW
510 }
511 }
a9430dd8
JW
512 return change;
513}
514
4c5186ed 515#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 516 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
4c5186ed
JW
517 .info = alc_pin_mode_info, \
518 .get = alc_pin_mode_get, \
519 .put = alc_pin_mode_put, \
520 .private_value = nid | (dir<<16) }
df694daa 521
5c8f858d
JW
522/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
523 * together using a mask with more than one bit set. This control is
524 * currently used only by the ALC260 test model. At this stage they are not
525 * needed for any "production" models.
526 */
527#ifdef CONFIG_SND_DEBUG
a5ce8890 528#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 529
9c7f852e
TI
530static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
531 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
532{
533 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
534 hda_nid_t nid = kcontrol->private_value & 0xffff;
535 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
536 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
537 unsigned int val = snd_hda_codec_read(codec, nid, 0,
538 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
539
540 *valp = (val & mask) != 0;
541 return 0;
542}
9c7f852e
TI
543static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
545{
546 signed int change;
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 hda_nid_t nid = kcontrol->private_value & 0xffff;
549 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
550 long val = *ucontrol->value.integer.value;
9c7f852e
TI
551 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
552 AC_VERB_GET_GPIO_DATA,
553 0x00);
5c8f858d
JW
554
555 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
556 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
557 if (val == 0)
5c8f858d
JW
558 gpio_data &= ~mask;
559 else
560 gpio_data |= mask;
82beb8fd
TI
561 snd_hda_codec_write_cache(codec, nid, 0,
562 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
563
564 return change;
565}
566#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
567 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
568 .info = alc_gpio_data_info, \
569 .get = alc_gpio_data_get, \
570 .put = alc_gpio_data_put, \
571 .private_value = nid | (mask<<16) }
572#endif /* CONFIG_SND_DEBUG */
573
92621f13
JW
574/* A switch control to allow the enabling of the digital IO pins on the
575 * ALC260. This is incredibly simplistic; the intention of this control is
576 * to provide something in the test model allowing digital outputs to be
577 * identified if present. If models are found which can utilise these
578 * outputs a more complete mixer control can be devised for those models if
579 * necessary.
580 */
581#ifdef CONFIG_SND_DEBUG
a5ce8890 582#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 583
9c7f852e
TI
584static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
586{
587 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
588 hda_nid_t nid = kcontrol->private_value & 0xffff;
589 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
590 long *valp = ucontrol->value.integer.value;
9c7f852e 591 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 592 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
593
594 *valp = (val & mask) != 0;
595 return 0;
596}
9c7f852e
TI
597static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
598 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
599{
600 signed int change;
601 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
602 hda_nid_t nid = kcontrol->private_value & 0xffff;
603 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
604 long val = *ucontrol->value.integer.value;
9c7f852e 605 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 606 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 607 0x00);
92621f13
JW
608
609 /* Set/unset the masked control bit(s) as needed */
9c7f852e 610 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
611 if (val==0)
612 ctrl_data &= ~mask;
613 else
614 ctrl_data |= mask;
82beb8fd
TI
615 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
616 ctrl_data);
92621f13
JW
617
618 return change;
619}
620#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
621 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
622 .info = alc_spdif_ctrl_info, \
623 .get = alc_spdif_ctrl_get, \
624 .put = alc_spdif_ctrl_put, \
625 .private_value = nid | (mask<<16) }
626#endif /* CONFIG_SND_DEBUG */
627
f8225f6d
JW
628/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
629 * Again, this is only used in the ALC26x test models to help identify when
630 * the EAPD line must be asserted for features to work.
631 */
632#ifdef CONFIG_SND_DEBUG
633#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
634
635static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
636 struct snd_ctl_elem_value *ucontrol)
637{
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long *valp = ucontrol->value.integer.value;
642 unsigned int val = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
644
645 *valp = (val & mask) != 0;
646 return 0;
647}
648
649static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
650 struct snd_ctl_elem_value *ucontrol)
651{
652 int change;
653 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
654 hda_nid_t nid = kcontrol->private_value & 0xffff;
655 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
656 long val = *ucontrol->value.integer.value;
657 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
658 AC_VERB_GET_EAPD_BTLENABLE,
659 0x00);
660
661 /* Set/unset the masked control bit(s) as needed */
662 change = (!val ? 0 : mask) != (ctrl_data & mask);
663 if (!val)
664 ctrl_data &= ~mask;
665 else
666 ctrl_data |= mask;
667 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
668 ctrl_data);
669
670 return change;
671}
672
673#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
674 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
675 .info = alc_eapd_ctrl_info, \
676 .get = alc_eapd_ctrl_get, \
677 .put = alc_eapd_ctrl_put, \
678 .private_value = nid | (mask<<16) }
679#endif /* CONFIG_SND_DEBUG */
680
df694daa
KY
681/*
682 * set up from the preset table
683 */
9c7f852e
TI
684static void setup_preset(struct alc_spec *spec,
685 const struct alc_config_preset *preset)
df694daa
KY
686{
687 int i;
688
689 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
690 spec->mixers[spec->num_mixers++] = preset->mixers[i];
9c7f852e
TI
691 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
692 i++)
693 spec->init_verbs[spec->num_init_verbs++] =
694 preset->init_verbs[i];
df694daa
KY
695
696 spec->channel_mode = preset->channel_mode;
697 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 698 spec->need_dac_fix = preset->need_dac_fix;
df694daa
KY
699
700 spec->multiout.max_channels = spec->channel_mode[0].channels;
701
702 spec->multiout.num_dacs = preset->num_dacs;
703 spec->multiout.dac_nids = preset->dac_nids;
704 spec->multiout.dig_out_nid = preset->dig_out_nid;
705 spec->multiout.hp_nid = preset->hp_nid;
706
a1e8d2da 707 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 708 if (!spec->num_mux_defs)
a1e8d2da 709 spec->num_mux_defs = 1;
df694daa
KY
710 spec->input_mux = preset->input_mux;
711
712 spec->num_adc_nids = preset->num_adc_nids;
713 spec->adc_nids = preset->adc_nids;
e1406348 714 spec->capsrc_nids = preset->capsrc_nids;
df694daa 715 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
716
717 spec->unsol_event = preset->unsol_event;
718 spec->init_hook = preset->init_hook;
cb53c626
TI
719#ifdef CONFIG_SND_HDA_POWER_SAVE
720 spec->loopback.amplist = preset->loopbacks;
721#endif
df694daa
KY
722}
723
bc9f98a9
KY
724/* Enable GPIO mask and set output */
725static struct hda_verb alc_gpio1_init_verbs[] = {
726 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
727 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
728 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
729 { }
730};
731
732static struct hda_verb alc_gpio2_init_verbs[] = {
733 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
734 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
735 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
736 { }
737};
738
bdd148a3
KY
739static struct hda_verb alc_gpio3_init_verbs[] = {
740 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
741 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
742 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
743 { }
744};
745
c9b58006
KY
746static void alc_sku_automute(struct hda_codec *codec)
747{
748 struct alc_spec *spec = codec->spec;
c9b58006
KY
749 unsigned int present;
750 unsigned int hp_nid = spec->autocfg.hp_pins[0];
751 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
752
753 /* need to execute and sync at first */
754 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
755 present = snd_hda_codec_read(codec, hp_nid, 0,
756 AC_VERB_GET_PIN_SENSE, 0);
757 spec->jack_present = (present & 0x80000000) != 0;
f6c7e546
TI
758 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
759 spec->jack_present ? 0 : PIN_OUT);
c9b58006
KY
760}
761
762/* unsolicited event for HP jack sensing */
763static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
764{
765 if (codec->vendor_id == 0x10ec0880)
766 res >>= 28;
767 else
768 res >>= 26;
769 if (res != ALC880_HP_EVENT)
770 return;
771
772 alc_sku_automute(codec);
773}
774
bc9f98a9
KY
775/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
776 * 31 ~ 16 : Manufacture ID
777 * 15 ~ 8 : SKU ID
778 * 7 ~ 0 : Assembly ID
779 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
780 */
781static void alc_subsystem_id(struct hda_codec *codec,
782 unsigned int porta, unsigned int porte,
783 unsigned int portd)
784{
c9b58006
KY
785 unsigned int ass, tmp, i;
786 unsigned nid;
787 struct alc_spec *spec = codec->spec;
bc9f98a9 788
c9b58006
KY
789 ass = codec->subsystem_id & 0xffff;
790 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
791 goto do_sku;
792
793 /*
794 * 31~30 : port conetcivity
795 * 29~21 : reserve
796 * 20 : PCBEEP input
797 * 19~16 : Check sum (15:1)
798 * 15~1 : Custom
799 * 0 : override
800 */
801 nid = 0x1d;
802 if (codec->vendor_id == 0x10ec0260)
803 nid = 0x17;
804 ass = snd_hda_codec_read(codec, nid, 0,
805 AC_VERB_GET_CONFIG_DEFAULT, 0);
806 if (!(ass & 1) && !(ass & 0x100000))
807 return;
808 if ((ass >> 30) != 1) /* no physical connection */
bc9f98a9
KY
809 return;
810
c9b58006
KY
811 /* check sum */
812 tmp = 0;
813 for (i = 1; i < 16; i++) {
8c427226 814 if ((ass >> i) & 1)
c9b58006
KY
815 tmp++;
816 }
817 if (((ass >> 16) & 0xf) != tmp)
818 return;
819do_sku:
820 /*
821 * 0 : override
822 * 1 : Swap Jack
823 * 2 : 0 --> Desktop, 1 --> Laptop
824 * 3~5 : External Amplifier control
825 * 7~6 : Reserved
826 */
bc9f98a9
KY
827 tmp = (ass & 0x38) >> 3; /* external Amp control */
828 switch (tmp) {
829 case 1:
830 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
831 break;
832 case 3:
833 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
834 break;
bdd148a3
KY
835 case 7:
836 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
837 break;
c9b58006 838 case 5: /* set EAPD output high */
bdd148a3 839 switch (codec->vendor_id) {
c9b58006
KY
840 case 0x10ec0260:
841 snd_hda_codec_write(codec, 0x0f, 0,
842 AC_VERB_SET_EAPD_BTLENABLE, 2);
843 snd_hda_codec_write(codec, 0x10, 0,
844 AC_VERB_SET_EAPD_BTLENABLE, 2);
845 break;
846 case 0x10ec0262:
bdd148a3
KY
847 case 0x10ec0267:
848 case 0x10ec0268:
c9b58006
KY
849 case 0x10ec0269:
850 case 0x10ec0862:
851 case 0x10ec0662:
bdd148a3
KY
852 snd_hda_codec_write(codec, 0x14, 0,
853 AC_VERB_SET_EAPD_BTLENABLE, 2);
854 snd_hda_codec_write(codec, 0x15, 0,
855 AC_VERB_SET_EAPD_BTLENABLE, 2);
c9b58006 856 break;
bdd148a3 857 }
c9b58006
KY
858 switch (codec->vendor_id) {
859 case 0x10ec0260:
860 snd_hda_codec_write(codec, 0x1a, 0,
861 AC_VERB_SET_COEF_INDEX, 7);
862 tmp = snd_hda_codec_read(codec, 0x1a, 0,
863 AC_VERB_GET_PROC_COEF, 0);
864 snd_hda_codec_write(codec, 0x1a, 0,
865 AC_VERB_SET_COEF_INDEX, 7);
866 snd_hda_codec_write(codec, 0x1a, 0,
867 AC_VERB_SET_PROC_COEF,
868 tmp | 0x2010);
869 break;
870 case 0x10ec0262:
871 case 0x10ec0880:
872 case 0x10ec0882:
873 case 0x10ec0883:
874 case 0x10ec0885:
875 case 0x10ec0888:
876 snd_hda_codec_write(codec, 0x20, 0,
877 AC_VERB_SET_COEF_INDEX, 7);
878 tmp = snd_hda_codec_read(codec, 0x20, 0,
879 AC_VERB_GET_PROC_COEF, 0);
880 snd_hda_codec_write(codec, 0x20, 0,
881 AC_VERB_SET_COEF_INDEX, 7);
882 snd_hda_codec_write(codec, 0x20, 0,
883 AC_VERB_SET_PROC_COEF,
884 tmp | 0x2010);
885 break;
886 case 0x10ec0267:
887 case 0x10ec0268:
888 snd_hda_codec_write(codec, 0x20, 0,
889 AC_VERB_SET_COEF_INDEX, 7);
890 tmp = snd_hda_codec_read(codec, 0x20, 0,
891 AC_VERB_GET_PROC_COEF, 0);
892 snd_hda_codec_write(codec, 0x20, 0,
893 AC_VERB_SET_COEF_INDEX, 7);
894 snd_hda_codec_write(codec, 0x20, 0,
895 AC_VERB_SET_PROC_COEF,
896 tmp | 0x3000);
897 break;
bc9f98a9 898 }
c9b58006 899 default:
bc9f98a9
KY
900 break;
901 }
c9b58006 902
8c427226 903 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
904 * when the external headphone out jack is plugged"
905 */
8c427226 906 if (!(ass & 0x8000))
c9b58006
KY
907 return;
908 /*
909 * 10~8 : Jack location
910 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
911 * 14~13: Resvered
912 * 15 : 1 --> enable the function "Mute internal speaker
913 * when the external headphone out jack is plugged"
914 */
915 if (!spec->autocfg.speaker_pins[0]) {
8c427226 916 if (spec->autocfg.line_out_pins[0])
c9b58006 917 spec->autocfg.speaker_pins[0] =
8c427226 918 spec->autocfg.line_out_pins[0];
c9b58006
KY
919 else
920 return;
921 }
922
923 if (!spec->autocfg.hp_pins[0]) {
924 tmp = (ass >> 11) & 0x3; /* HP to chassis */
925 if (tmp == 0)
926 spec->autocfg.hp_pins[0] = porta;
927 else if (tmp == 1)
928 spec->autocfg.hp_pins[0] = porte;
929 else if (tmp == 2)
930 spec->autocfg.hp_pins[0] = portd;
931 else
932 return;
933 }
934
935 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
936 AC_VERB_SET_UNSOLICITED_ENABLE,
937 AC_USRSP_EN | ALC880_HP_EVENT);
938 spec->unsol_event = alc_sku_unsol_event;
939 spec->init_hook = alc_sku_automute;
bc9f98a9
KY
940}
941
f95474ec
TI
942/*
943 * Fix-up pin default configurations
944 */
945
946struct alc_pincfg {
947 hda_nid_t nid;
948 u32 val;
949};
950
951static void alc_fix_pincfg(struct hda_codec *codec,
952 const struct snd_pci_quirk *quirk,
953 const struct alc_pincfg **pinfix)
954{
955 const struct alc_pincfg *cfg;
956
957 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
958 if (!quirk)
959 return;
960
961 cfg = pinfix[quirk->value];
962 for (; cfg->nid; cfg++) {
963 int i;
964 u32 val = cfg->val;
965 for (i = 0; i < 4; i++) {
966 snd_hda_codec_write(codec, cfg->nid, 0,
967 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
968 val & 0xff);
969 val >>= 8;
970 }
971 }
972}
973
1da177e4 974/*
e9edcee0
TI
975 * ALC880 3-stack model
976 *
977 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
978 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
979 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
980 */
981
e9edcee0
TI
982static hda_nid_t alc880_dac_nids[4] = {
983 /* front, rear, clfe, rear_surr */
984 0x02, 0x05, 0x04, 0x03
985};
986
987static hda_nid_t alc880_adc_nids[3] = {
988 /* ADC0-2 */
989 0x07, 0x08, 0x09,
990};
991
992/* The datasheet says the node 0x07 is connected from inputs,
993 * but it shows zero connection in the real implementation on some devices.
df694daa 994 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 995 */
e9edcee0
TI
996static hda_nid_t alc880_adc_nids_alt[2] = {
997 /* ADC1-2 */
998 0x08, 0x09,
999};
1000
1001#define ALC880_DIGOUT_NID 0x06
1002#define ALC880_DIGIN_NID 0x0a
1003
1004static struct hda_input_mux alc880_capture_source = {
1005 .num_items = 4,
1006 .items = {
1007 { "Mic", 0x0 },
1008 { "Front Mic", 0x3 },
1009 { "Line", 0x2 },
1010 { "CD", 0x4 },
1011 },
1012};
1013
1014/* channel source setting (2/6 channel selection for 3-stack) */
1015/* 2ch mode */
1016static struct hda_verb alc880_threestack_ch2_init[] = {
1017 /* set line-in to input, mute it */
1018 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1019 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1020 /* set mic-in to input vref 80%, mute it */
1021 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1022 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1023 { } /* end */
1024};
1025
1026/* 6ch mode */
1027static struct hda_verb alc880_threestack_ch6_init[] = {
1028 /* set line-in to output, unmute it */
1029 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1030 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1031 /* set mic-in to output, unmute it */
1032 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1033 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1034 { } /* end */
1035};
1036
d2a6d7dc 1037static struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
1038 { 2, alc880_threestack_ch2_init },
1039 { 6, alc880_threestack_ch6_init },
1040};
1041
c8b6bf9b 1042static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 1043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 1045 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1046 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
1047 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1048 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1049 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1050 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
1051 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1052 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1053 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1054 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1057 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1059 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1060 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
e9edcee0
TI
1061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1062 {
1063 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1064 .name = "Channel Mode",
df694daa
KY
1065 .info = alc_ch_mode_info,
1066 .get = alc_ch_mode_get,
1067 .put = alc_ch_mode_put,
e9edcee0
TI
1068 },
1069 { } /* end */
1070};
1071
1072/* capture mixer elements */
c8b6bf9b 1073static struct snd_kcontrol_new alc880_capture_mixer[] = {
e9edcee0
TI
1074 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1075 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1076 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1077 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1078 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1079 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1080 {
1081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1082 /* The multiple "Capture Source" controls confuse alsamixer
1083 * So call somewhat different..
1da177e4
LT
1084 */
1085 /* .name = "Capture Source", */
1086 .name = "Input Source",
e9edcee0 1087 .count = 3,
1da177e4
LT
1088 .info = alc_mux_enum_info,
1089 .get = alc_mux_enum_get,
1090 .put = alc_mux_enum_put,
1091 },
1da177e4
LT
1092 { } /* end */
1093};
1094
e9edcee0 1095/* capture mixer elements (in case NID 0x07 not available) */
c8b6bf9b 1096static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
71fe7b82
TI
1097 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1098 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1099 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1100 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1da177e4
LT
1101 {
1102 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1103 /* The multiple "Capture Source" controls confuse alsamixer
1104 * So call somewhat different..
1da177e4
LT
1105 */
1106 /* .name = "Capture Source", */
1107 .name = "Input Source",
1108 .count = 2,
1109 .info = alc_mux_enum_info,
1110 .get = alc_mux_enum_get,
1111 .put = alc_mux_enum_put,
1112 },
1da177e4
LT
1113 { } /* end */
1114};
1115
e9edcee0
TI
1116
1117
1118/*
1119 * ALC880 5-stack model
1120 *
9c7f852e
TI
1121 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1122 * Side = 0x02 (0xd)
e9edcee0
TI
1123 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1124 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1125 */
1126
1127/* additional mixers to alc880_three_stack_mixer */
c8b6bf9b 1128static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 1129 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1130 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
1131 { } /* end */
1132};
1133
e9edcee0
TI
1134/* channel source setting (6/8 channel selection for 5-stack) */
1135/* 6ch mode */
1136static struct hda_verb alc880_fivestack_ch6_init[] = {
1137 /* set line-in to input, mute it */
1138 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1139 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
1140 { } /* end */
1141};
1142
e9edcee0
TI
1143/* 8ch mode */
1144static struct hda_verb alc880_fivestack_ch8_init[] = {
1145 /* set line-in to output, unmute it */
1146 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1147 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1148 { } /* end */
1149};
1150
d2a6d7dc 1151static struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
1152 { 6, alc880_fivestack_ch6_init },
1153 { 8, alc880_fivestack_ch8_init },
1154};
1155
1156
1157/*
1158 * ALC880 6-stack model
1159 *
9c7f852e
TI
1160 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1161 * Side = 0x05 (0x0f)
e9edcee0
TI
1162 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1163 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1164 */
1165
1166static hda_nid_t alc880_6st_dac_nids[4] = {
1167 /* front, rear, clfe, rear_surr */
1168 0x02, 0x03, 0x04, 0x05
f12ab1e0 1169};
e9edcee0
TI
1170
1171static struct hda_input_mux alc880_6stack_capture_source = {
1172 .num_items = 4,
1173 .items = {
1174 { "Mic", 0x0 },
1175 { "Front Mic", 0x1 },
1176 { "Line", 0x2 },
1177 { "CD", 0x4 },
1178 },
1179};
1180
1181/* fixed 8-channels */
d2a6d7dc 1182static struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
1183 { 8, NULL },
1184};
1185
c8b6bf9b 1186static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 1187 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1188 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1189 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1190 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1191 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1192 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1193 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1194 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 1195 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 1196 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
1197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1199 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1200 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1201 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1203 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1204 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1205 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1206 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
16ded525
TI
1207 {
1208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1209 .name = "Channel Mode",
df694daa
KY
1210 .info = alc_ch_mode_info,
1211 .get = alc_ch_mode_get,
1212 .put = alc_ch_mode_put,
16ded525
TI
1213 },
1214 { } /* end */
1215};
1216
e9edcee0
TI
1217
1218/*
1219 * ALC880 W810 model
1220 *
1221 * W810 has rear IO for:
1222 * Front (DAC 02)
1223 * Surround (DAC 03)
1224 * Center/LFE (DAC 04)
1225 * Digital out (06)
1226 *
1227 * The system also has a pair of internal speakers, and a headphone jack.
1228 * These are both connected to Line2 on the codec, hence to DAC 02.
1229 *
1230 * There is a variable resistor to control the speaker or headphone
1231 * volume. This is a hardware-only device without a software API.
1232 *
1233 * Plugging headphones in will disable the internal speakers. This is
1234 * implemented in hardware, not via the driver using jack sense. In
1235 * a similar fashion, plugging into the rear socket marked "front" will
1236 * disable both the speakers and headphones.
1237 *
1238 * For input, there's a microphone jack, and an "audio in" jack.
1239 * These may not do anything useful with this driver yet, because I
1240 * haven't setup any initialization verbs for these yet...
1241 */
1242
1243static hda_nid_t alc880_w810_dac_nids[3] = {
1244 /* front, rear/surround, clfe */
1245 0x02, 0x03, 0x04
16ded525
TI
1246};
1247
e9edcee0 1248/* fixed 6 channels */
d2a6d7dc 1249static struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
1250 { 6, NULL }
1251};
1252
1253/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
c8b6bf9b 1254static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 1255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1256 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1257 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1258 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1259 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1260 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1261 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1262 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
1263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1264 { } /* end */
1265};
1266
1267
1268/*
1269 * Z710V model
1270 *
1271 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
1272 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1273 * Line = 0x1a
e9edcee0
TI
1274 */
1275
1276static hda_nid_t alc880_z71v_dac_nids[1] = {
1277 0x02
1278};
1279#define ALC880_Z71V_HP_DAC 0x03
1280
1281/* fixed 2 channels */
d2a6d7dc 1282static struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
1283 { 2, NULL }
1284};
1285
c8b6bf9b 1286static struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 1287 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1288 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 1289 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1290 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1291 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1292 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
1293 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1294 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1295 { } /* end */
1296};
1297
e9edcee0 1298
e9edcee0
TI
1299/*
1300 * ALC880 F1734 model
1301 *
1302 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1303 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1304 */
1305
1306static hda_nid_t alc880_f1734_dac_nids[1] = {
1307 0x03
1308};
1309#define ALC880_F1734_HP_DAC 0x02
1310
c8b6bf9b 1311static struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 1312 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1313 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
1314 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1315 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
1316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1317 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
1318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
1320 { } /* end */
1321};
1322
937b4160
TI
1323static struct hda_input_mux alc880_f1734_capture_source = {
1324 .num_items = 2,
1325 .items = {
1326 { "Mic", 0x1 },
1327 { "CD", 0x4 },
1328 },
1329};
1330
e9edcee0 1331
e9edcee0
TI
1332/*
1333 * ALC880 ASUS model
1334 *
1335 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1336 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1337 * Mic = 0x18, Line = 0x1a
1338 */
1339
1340#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1341#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1342
c8b6bf9b 1343static struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 1344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 1345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 1346 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 1347 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
1348 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1349 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
1350 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1351 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
1352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1354 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1355 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
1356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
1358 {
1359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1360 .name = "Channel Mode",
df694daa
KY
1361 .info = alc_ch_mode_info,
1362 .get = alc_ch_mode_get,
1363 .put = alc_ch_mode_put,
16ded525
TI
1364 },
1365 { } /* end */
1366};
e9edcee0 1367
e9edcee0
TI
1368/*
1369 * ALC880 ASUS W1V model
1370 *
1371 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1372 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1373 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1374 */
1375
1376/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1377static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
1378 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1379 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1380 { } /* end */
1381};
1382
3c10a9d9 1383/* additional mixers to alc880_asus_mixer */
c8b6bf9b 1384static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
3c10a9d9
TI
1385 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1386 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1387 { } /* end */
1388};
e9edcee0 1389
df694daa
KY
1390/* TCL S700 */
1391static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1392 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1393 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1394 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1395 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1396 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1399 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1400 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1401 {
1402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1403 /* The multiple "Capture Source" controls confuse alsamixer
1404 * So call somewhat different..
df694daa
KY
1405 */
1406 /* .name = "Capture Source", */
1407 .name = "Input Source",
1408 .count = 1,
1409 .info = alc_mux_enum_info,
1410 .get = alc_mux_enum_get,
1411 .put = alc_mux_enum_put,
1412 },
1413 { } /* end */
1414};
1415
ccc656ce
KY
1416/* Uniwill */
1417static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
1418 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1419 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1420 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1421 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1422 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1423 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1424 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1425 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1434 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1435 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1436 {
1437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1438 .name = "Channel Mode",
1439 .info = alc_ch_mode_info,
1440 .get = alc_ch_mode_get,
1441 .put = alc_ch_mode_put,
1442 },
1443 { } /* end */
1444};
1445
2cf9f0fc
TD
1446static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1448 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1449 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1450 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1451 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1452 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1453 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1454 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1455 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1456 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1457 { } /* end */
1458};
1459
ccc656ce 1460static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
1461 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1462 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1463 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1464 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
1465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1467 { } /* end */
1468};
1469
2134ea4f
TI
1470/*
1471 * virtual master controls
1472 */
1473
1474/*
1475 * slave controls for virtual master
1476 */
1477static const char *alc_slave_vols[] = {
1478 "Front Playback Volume",
1479 "Surround Playback Volume",
1480 "Center Playback Volume",
1481 "LFE Playback Volume",
1482 "Side Playback Volume",
1483 "Headphone Playback Volume",
1484 "Speaker Playback Volume",
1485 "Mono Playback Volume",
2134ea4f
TI
1486 "Line-Out Playback Volume",
1487 NULL,
1488};
1489
1490static const char *alc_slave_sws[] = {
1491 "Front Playback Switch",
1492 "Surround Playback Switch",
1493 "Center Playback Switch",
1494 "LFE Playback Switch",
1495 "Side Playback Switch",
1496 "Headphone Playback Switch",
1497 "Speaker Playback Switch",
1498 "Mono Playback Switch",
edb54a55 1499 "IEC958 Playback Switch",
2134ea4f
TI
1500 NULL,
1501};
1502
1da177e4 1503/*
e9edcee0 1504 * build control elements
1da177e4
LT
1505 */
1506static int alc_build_controls(struct hda_codec *codec)
1507{
1508 struct alc_spec *spec = codec->spec;
1509 int err;
1510 int i;
1511
1512 for (i = 0; i < spec->num_mixers; i++) {
1513 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1514 if (err < 0)
1515 return err;
1516 }
1517
1518 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
1519 err = snd_hda_create_spdif_out_ctls(codec,
1520 spec->multiout.dig_out_nid);
1da177e4
LT
1521 if (err < 0)
1522 return err;
1523 }
1524 if (spec->dig_in_nid) {
1525 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1526 if (err < 0)
1527 return err;
1528 }
2134ea4f
TI
1529
1530 /* if we have no master control, let's create it */
1531 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1532 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1533 HDA_OUTPUT, spec->vmaster_tlv);
1534 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1535 spec->vmaster_tlv, alc_slave_vols);
1536 if (err < 0)
1537 return err;
1538 }
1539 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1540 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1541 NULL, alc_slave_sws);
1542 if (err < 0)
1543 return err;
1544 }
1545
1da177e4
LT
1546 return 0;
1547}
1548
e9edcee0 1549
1da177e4
LT
1550/*
1551 * initialize the codec volumes, etc
1552 */
1553
e9edcee0
TI
1554/*
1555 * generic initialization of ADC, input mixers and output mixers
1556 */
1557static struct hda_verb alc880_volume_init_verbs[] = {
1558 /*
1559 * Unmute ADC0-2 and set the default input to mic-in
1560 */
71fe7b82 1561 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1563 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1564 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1565 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1566 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1567
e9edcee0
TI
1568 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1569 * mixer widget
9c7f852e
TI
1570 * Note: PASD motherboards uses the Line In 2 as the input for front
1571 * panel mic (mic 2)
1da177e4 1572 */
e9edcee0 1573 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1581
e9edcee0
TI
1582 /*
1583 * Set up output mixers (0x0c - 0x0f)
1da177e4 1584 */
e9edcee0
TI
1585 /* set vol=0 to output mixers */
1586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1587 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1588 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1589 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1590 /* set up input amps for analog loopback */
1591 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1595 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1596 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1597 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1598 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1599 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1600
1601 { }
1602};
1603
e9edcee0
TI
1604/*
1605 * 3-stack pin configuration:
1606 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1607 */
1608static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1609 /*
1610 * preset connection lists of input pins
1611 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1612 */
1613 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1614 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1615 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1616
1617 /*
1618 * Set pin mode and muting
1619 */
1620 /* set front pin widgets 0x14 for output */
05acb863 1621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1622 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1623 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1626 /* Mic2 (as headphone out) for HP output */
1627 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1628 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1629 /* Line In pin widget for input */
05acb863 1630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632 /* Line2 (as front mic) pin widget for input and vref at 80% */
1633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1634 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1635 /* CD pin widget for input */
05acb863 1636 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1637
e9edcee0
TI
1638 { }
1639};
1da177e4 1640
e9edcee0
TI
1641/*
1642 * 5-stack pin configuration:
1643 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1644 * line-in/side = 0x1a, f-mic = 0x1b
1645 */
1646static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1647 /*
1648 * preset connection lists of input pins
1649 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1650 */
e9edcee0
TI
1651 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1652 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1653
e9edcee0
TI
1654 /*
1655 * Set pin mode and muting
1da177e4 1656 */
e9edcee0
TI
1657 /* set pin widgets 0x14-0x17 for output */
1658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1660 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1661 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1662 /* unmute pins for output (no gain on this amp) */
1663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1666 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1667
1668 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1669 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1670 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1671 /* Mic2 (as headphone out) for HP output */
1672 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1673 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1674 /* Line In pin widget for input */
1675 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1677 /* Line2 (as front mic) pin widget for input and vref at 80% */
1678 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1679 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1680 /* CD pin widget for input */
1681 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1682
1683 { }
1684};
1685
e9edcee0
TI
1686/*
1687 * W810 pin configuration:
1688 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1689 */
1690static struct hda_verb alc880_pin_w810_init_verbs[] = {
1691 /* hphone/speaker input selector: front DAC */
1692 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1693
05acb863 1694 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1695 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1696 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1698 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1700
e9edcee0 1701 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1702 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1703
1da177e4
LT
1704 { }
1705};
1706
e9edcee0
TI
1707/*
1708 * Z71V pin configuration:
1709 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1710 */
1711static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1712 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1713 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1715 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1716
16ded525 1717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1718 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1719 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1720 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1721
1722 { }
1723};
1724
e9edcee0
TI
1725/*
1726 * 6-stack pin configuration:
9c7f852e
TI
1727 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1728 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1729 */
1730static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1731 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1732
16ded525 1733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1737 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1738 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1739 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1740 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1741
16ded525 1742 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1743 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1745 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1749 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1750 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1751
e9edcee0
TI
1752 { }
1753};
1754
ccc656ce
KY
1755/*
1756 * Uniwill pin configuration:
1757 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1758 * line = 0x1a
1759 */
1760static struct hda_verb alc880_uniwill_init_verbs[] = {
1761 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1762
1763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1766 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1771 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1772 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1773 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1774 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1775 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1776 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1777
1778 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1782 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1784 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1785 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1787
1788 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1789 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1790
1791 { }
1792};
1793
1794/*
1795* Uniwill P53
1796* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1797 */
1798static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1799 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1800
1801 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1802 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1803 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1812 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1813
1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1818 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1819 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1820
1821 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1822 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1823
1824 { }
1825};
1826
2cf9f0fc
TD
1827static struct hda_verb alc880_beep_init_verbs[] = {
1828 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1829 { }
1830};
1831
ccc656ce 1832/* toggle speaker-output according to the hp-jack state */
458a4fab 1833static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1834{
1835 unsigned int present;
f12ab1e0 1836 unsigned char bits;
ccc656ce
KY
1837
1838 present = snd_hda_codec_read(codec, 0x14, 0,
1839 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1840 bits = present ? HDA_AMP_MUTE : 0;
1841 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1842 HDA_AMP_MUTE, bits);
1843 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1844 HDA_AMP_MUTE, bits);
458a4fab
TI
1845}
1846
1847/* auto-toggle front mic */
1848static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1849{
1850 unsigned int present;
1851 unsigned char bits;
ccc656ce
KY
1852
1853 present = snd_hda_codec_read(codec, 0x18, 0,
1854 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1855 bits = present ? HDA_AMP_MUTE : 0;
1856 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1857}
1858
1859static void alc880_uniwill_automute(struct hda_codec *codec)
1860{
1861 alc880_uniwill_hp_automute(codec);
1862 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1863}
1864
1865static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1866 unsigned int res)
1867{
1868 /* Looks like the unsol event is incompatible with the standard
1869 * definition. 4bit tag is placed at 28 bit!
1870 */
458a4fab
TI
1871 switch (res >> 28) {
1872 case ALC880_HP_EVENT:
1873 alc880_uniwill_hp_automute(codec);
1874 break;
1875 case ALC880_MIC_EVENT:
1876 alc880_uniwill_mic_automute(codec);
1877 break;
1878 }
ccc656ce
KY
1879}
1880
1881static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1882{
1883 unsigned int present;
f12ab1e0 1884 unsigned char bits;
ccc656ce
KY
1885
1886 present = snd_hda_codec_read(codec, 0x14, 0,
1887 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1888 bits = present ? HDA_AMP_MUTE : 0;
1889 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1890}
1891
1892static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1893{
1894 unsigned int present;
1895
1896 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1897 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1898 present &= HDA_AMP_VOLMASK;
1899 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1900 HDA_AMP_VOLMASK, present);
1901 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1902 HDA_AMP_VOLMASK, present);
ccc656ce 1903}
47fd830a 1904
ccc656ce
KY
1905static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1906 unsigned int res)
1907{
1908 /* Looks like the unsol event is incompatible with the standard
1909 * definition. 4bit tag is placed at 28 bit!
1910 */
1911 if ((res >> 28) == ALC880_HP_EVENT)
1912 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1913 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1914 alc880_uniwill_p53_dcvol_automute(codec);
1915}
1916
e9edcee0
TI
1917/*
1918 * F1734 pin configuration:
1919 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1920 */
1921static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1922 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1923 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1924 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1925 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1926
e9edcee0 1927 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1928 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1930 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1931
e9edcee0
TI
1932 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1933 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1936 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1937 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1940 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 1941
937b4160
TI
1942 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1943 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1944
dfc0ff62
TI
1945 { }
1946};
1947
e9edcee0
TI
1948/*
1949 * ASUS pin configuration:
1950 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1951 */
1952static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1953 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1954 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1955 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1956 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1957
1958 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1961 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1962 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1963 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1964 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1965 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1966
1967 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1969 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1973 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1975 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1976
e9edcee0
TI
1977 { }
1978};
16ded525 1979
e9edcee0 1980/* Enable GPIO mask and set output */
bc9f98a9
KY
1981#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1982#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1983
1984/* Clevo m520g init */
1985static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1986 /* headphone output */
1987 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1988 /* line-out */
1989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1990 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1991 /* Line-in */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1993 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1994 /* CD */
1995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1996 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997 /* Mic1 (rear panel) */
1998 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1999 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 /* Mic2 (front panel) */
2001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 /* headphone */
2004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2005 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006 /* change to EAPD mode */
2007 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2008 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2009
2010 { }
16ded525
TI
2011};
2012
df694daa 2013static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2014 /* change to EAPD mode */
2015 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2016 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2017
df694daa
KY
2018 /* Headphone output */
2019 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2020 /* Front output*/
2021 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2022 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2023
2024 /* Line In pin widget for input */
2025 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2026 /* CD pin widget for input */
2027 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2028 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2029 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2030
2031 /* change to EAPD mode */
2032 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2033 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2034
2035 { }
2036};
16ded525 2037
e9edcee0 2038/*
ae6b813a
TI
2039 * LG m1 express dual
2040 *
2041 * Pin assignment:
2042 * Rear Line-In/Out (blue): 0x14
2043 * Build-in Mic-In: 0x15
2044 * Speaker-out: 0x17
2045 * HP-Out (green): 0x1b
2046 * Mic-In/Out (red): 0x19
2047 * SPDIF-Out: 0x1e
2048 */
2049
2050/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2051static hda_nid_t alc880_lg_dac_nids[3] = {
2052 0x05, 0x02, 0x03
2053};
2054
2055/* seems analog CD is not working */
2056static struct hda_input_mux alc880_lg_capture_source = {
2057 .num_items = 3,
2058 .items = {
2059 { "Mic", 0x1 },
2060 { "Line", 0x5 },
2061 { "Internal Mic", 0x6 },
2062 },
2063};
2064
2065/* 2,4,6 channel modes */
2066static struct hda_verb alc880_lg_ch2_init[] = {
2067 /* set line-in and mic-in to input */
2068 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2069 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2070 { }
2071};
2072
2073static struct hda_verb alc880_lg_ch4_init[] = {
2074 /* set line-in to out and mic-in to input */
2075 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2076 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2077 { }
2078};
2079
2080static struct hda_verb alc880_lg_ch6_init[] = {
2081 /* set line-in and mic-in to output */
2082 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2083 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2084 { }
2085};
2086
2087static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2088 { 2, alc880_lg_ch2_init },
2089 { 4, alc880_lg_ch4_init },
2090 { 6, alc880_lg_ch6_init },
2091};
2092
2093static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2094 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2095 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2096 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2097 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2098 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2099 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2100 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2101 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2104 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2105 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2106 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2107 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2108 {
2109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2110 .name = "Channel Mode",
2111 .info = alc_ch_mode_info,
2112 .get = alc_ch_mode_get,
2113 .put = alc_ch_mode_put,
2114 },
2115 { } /* end */
2116};
2117
2118static struct hda_verb alc880_lg_init_verbs[] = {
2119 /* set capture source to mic-in */
2120 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2121 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2122 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2123 /* mute all amp mixer inputs */
2124 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2125 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2126 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2127 /* line-in to input */
2128 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2130 /* built-in mic */
2131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2132 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2133 /* speaker-out */
2134 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2135 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2136 /* mic-in to input */
2137 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2138 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2139 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2140 /* HP-out */
2141 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2143 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2144 /* jack sense */
2145 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2146 { }
2147};
2148
2149/* toggle speaker-output according to the hp-jack state */
2150static void alc880_lg_automute(struct hda_codec *codec)
2151{
2152 unsigned int present;
f12ab1e0 2153 unsigned char bits;
ae6b813a
TI
2154
2155 present = snd_hda_codec_read(codec, 0x1b, 0,
2156 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2157 bits = present ? HDA_AMP_MUTE : 0;
2158 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2159 HDA_AMP_MUTE, bits);
ae6b813a
TI
2160}
2161
2162static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2163{
2164 /* Looks like the unsol event is incompatible with the standard
2165 * definition. 4bit tag is placed at 28 bit!
2166 */
2167 if ((res >> 28) == 0x01)
2168 alc880_lg_automute(codec);
2169}
2170
d681518a
TI
2171/*
2172 * LG LW20
2173 *
2174 * Pin assignment:
2175 * Speaker-out: 0x14
2176 * Mic-In: 0x18
e4f41da9
CM
2177 * Built-in Mic-In: 0x19
2178 * Line-In: 0x1b
2179 * HP-Out: 0x1a
d681518a
TI
2180 * SPDIF-Out: 0x1e
2181 */
2182
d681518a 2183static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2184 .num_items = 3,
d681518a
TI
2185 .items = {
2186 { "Mic", 0x0 },
2187 { "Internal Mic", 0x1 },
e4f41da9 2188 { "Line In", 0x2 },
d681518a
TI
2189 },
2190};
2191
0a8c5da3
CM
2192#define alc880_lg_lw_modes alc880_threestack_modes
2193
d681518a 2194static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2196 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2198 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2199 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2200 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2202 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2203 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2204 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2205 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2206 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2207 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2208 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2209 {
2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2211 .name = "Channel Mode",
2212 .info = alc_ch_mode_info,
2213 .get = alc_ch_mode_get,
2214 .put = alc_ch_mode_put,
2215 },
d681518a
TI
2216 { } /* end */
2217};
2218
2219static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2220 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2221 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2222 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2223
d681518a
TI
2224 /* set capture source to mic-in */
2225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2226 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2227 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2228 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2229 /* speaker-out */
2230 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2232 /* HP-out */
d681518a
TI
2233 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2234 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2235 /* mic-in to input */
2236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238 /* built-in mic */
2239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2241 /* jack sense */
2242 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2243 { }
2244};
2245
2246/* toggle speaker-output according to the hp-jack state */
2247static void alc880_lg_lw_automute(struct hda_codec *codec)
2248{
2249 unsigned int present;
f12ab1e0 2250 unsigned char bits;
d681518a
TI
2251
2252 present = snd_hda_codec_read(codec, 0x1b, 0,
2253 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2254 bits = present ? HDA_AMP_MUTE : 0;
2255 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2256 HDA_AMP_MUTE, bits);
d681518a
TI
2257}
2258
2259static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2260{
2261 /* Looks like the unsol event is incompatible with the standard
2262 * definition. 4bit tag is placed at 28 bit!
2263 */
2264 if ((res >> 28) == 0x01)
2265 alc880_lg_lw_automute(codec);
2266}
2267
cb53c626
TI
2268#ifdef CONFIG_SND_HDA_POWER_SAVE
2269static struct hda_amp_list alc880_loopbacks[] = {
2270 { 0x0b, HDA_INPUT, 0 },
2271 { 0x0b, HDA_INPUT, 1 },
2272 { 0x0b, HDA_INPUT, 2 },
2273 { 0x0b, HDA_INPUT, 3 },
2274 { 0x0b, HDA_INPUT, 4 },
2275 { } /* end */
2276};
2277
2278static struct hda_amp_list alc880_lg_loopbacks[] = {
2279 { 0x0b, HDA_INPUT, 1 },
2280 { 0x0b, HDA_INPUT, 6 },
2281 { 0x0b, HDA_INPUT, 7 },
2282 { } /* end */
2283};
2284#endif
2285
ae6b813a
TI
2286/*
2287 * Common callbacks
e9edcee0
TI
2288 */
2289
1da177e4
LT
2290static int alc_init(struct hda_codec *codec)
2291{
2292 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2293 unsigned int i;
2294
2295 for (i = 0; i < spec->num_init_verbs; i++)
2296 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2297
2298 if (spec->init_hook)
2299 spec->init_hook(codec);
2300
1da177e4
LT
2301 return 0;
2302}
2303
ae6b813a
TI
2304static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2305{
2306 struct alc_spec *spec = codec->spec;
2307
2308 if (spec->unsol_event)
2309 spec->unsol_event(codec, res);
2310}
2311
cb53c626
TI
2312#ifdef CONFIG_SND_HDA_POWER_SAVE
2313static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2314{
2315 struct alc_spec *spec = codec->spec;
2316 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2317}
2318#endif
2319
1da177e4
LT
2320/*
2321 * Analog playback callbacks
2322 */
2323static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2324 struct hda_codec *codec,
c8b6bf9b 2325 struct snd_pcm_substream *substream)
1da177e4
LT
2326{
2327 struct alc_spec *spec = codec->spec;
2328 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2329}
2330
2331static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2332 struct hda_codec *codec,
2333 unsigned int stream_tag,
2334 unsigned int format,
c8b6bf9b 2335 struct snd_pcm_substream *substream)
1da177e4
LT
2336{
2337 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2338 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2339 stream_tag, format, substream);
1da177e4
LT
2340}
2341
2342static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2343 struct hda_codec *codec,
c8b6bf9b 2344 struct snd_pcm_substream *substream)
1da177e4
LT
2345{
2346 struct alc_spec *spec = codec->spec;
2347 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2348}
2349
2350/*
2351 * Digital out
2352 */
2353static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2354 struct hda_codec *codec,
c8b6bf9b 2355 struct snd_pcm_substream *substream)
1da177e4
LT
2356{
2357 struct alc_spec *spec = codec->spec;
2358 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2359}
2360
6b97eb45
TI
2361static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2362 struct hda_codec *codec,
2363 unsigned int stream_tag,
2364 unsigned int format,
2365 struct snd_pcm_substream *substream)
2366{
2367 struct alc_spec *spec = codec->spec;
2368 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2369 stream_tag, format, substream);
2370}
2371
1da177e4
LT
2372static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2373 struct hda_codec *codec,
c8b6bf9b 2374 struct snd_pcm_substream *substream)
1da177e4
LT
2375{
2376 struct alc_spec *spec = codec->spec;
2377 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2378}
2379
2380/*
2381 * Analog capture
2382 */
6330079f 2383static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2384 struct hda_codec *codec,
2385 unsigned int stream_tag,
2386 unsigned int format,
c8b6bf9b 2387 struct snd_pcm_substream *substream)
1da177e4
LT
2388{
2389 struct alc_spec *spec = codec->spec;
2390
6330079f 2391 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2392 stream_tag, 0, format);
2393 return 0;
2394}
2395
6330079f 2396static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2397 struct hda_codec *codec,
c8b6bf9b 2398 struct snd_pcm_substream *substream)
1da177e4
LT
2399{
2400 struct alc_spec *spec = codec->spec;
2401
6330079f 2402 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
9c7f852e 2403 0, 0, 0);
1da177e4
LT
2404 return 0;
2405}
2406
2407
2408/*
2409 */
2410static struct hda_pcm_stream alc880_pcm_analog_playback = {
2411 .substreams = 1,
2412 .channels_min = 2,
2413 .channels_max = 8,
e9edcee0 2414 /* NID is set in alc_build_pcms */
1da177e4
LT
2415 .ops = {
2416 .open = alc880_playback_pcm_open,
2417 .prepare = alc880_playback_pcm_prepare,
2418 .cleanup = alc880_playback_pcm_cleanup
2419 },
2420};
2421
2422static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2423 .substreams = 1,
2424 .channels_min = 2,
2425 .channels_max = 2,
2426 /* NID is set in alc_build_pcms */
2427};
2428
2429static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2430 .substreams = 1,
2431 .channels_min = 2,
2432 .channels_max = 2,
2433 /* NID is set in alc_build_pcms */
2434};
2435
2436static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2437 .substreams = 2, /* can be overridden */
1da177e4
LT
2438 .channels_min = 2,
2439 .channels_max = 2,
e9edcee0 2440 /* NID is set in alc_build_pcms */
1da177e4 2441 .ops = {
6330079f
TI
2442 .prepare = alc880_alt_capture_pcm_prepare,
2443 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2444 },
2445};
2446
2447static struct hda_pcm_stream alc880_pcm_digital_playback = {
2448 .substreams = 1,
2449 .channels_min = 2,
2450 .channels_max = 2,
2451 /* NID is set in alc_build_pcms */
2452 .ops = {
2453 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2454 .close = alc880_dig_playback_pcm_close,
2455 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2456 },
2457};
2458
2459static struct hda_pcm_stream alc880_pcm_digital_capture = {
2460 .substreams = 1,
2461 .channels_min = 2,
2462 .channels_max = 2,
2463 /* NID is set in alc_build_pcms */
2464};
2465
4c5186ed 2466/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2467static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2468 .substreams = 0,
2469 .channels_min = 0,
2470 .channels_max = 0,
2471};
2472
1da177e4
LT
2473static int alc_build_pcms(struct hda_codec *codec)
2474{
2475 struct alc_spec *spec = codec->spec;
2476 struct hda_pcm *info = spec->pcm_rec;
2477 int i;
2478
2479 codec->num_pcms = 1;
2480 codec->pcm_info = info;
2481
2482 info->name = spec->stream_name_analog;
4a471b7d
TI
2483 if (spec->stream_analog_playback) {
2484 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2485 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2486 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2487 }
2488 if (spec->stream_analog_capture) {
2489 snd_assert(spec->adc_nids, return -EINVAL);
2490 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2491 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2492 }
2493
2494 if (spec->channel_mode) {
2495 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2496 for (i = 0; i < spec->num_channel_mode; i++) {
2497 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2498 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2499 }
1da177e4
LT
2500 }
2501 }
2502
e08a007d 2503 /* SPDIF for stream index #1 */
1da177e4 2504 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2505 codec->num_pcms = 2;
c06134d7 2506 info = spec->pcm_rec + 1;
1da177e4 2507 info->name = spec->stream_name_digital;
7ba72ba1 2508 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2509 if (spec->multiout.dig_out_nid &&
2510 spec->stream_digital_playback) {
1da177e4
LT
2511 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2512 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2513 }
4a471b7d
TI
2514 if (spec->dig_in_nid &&
2515 spec->stream_digital_capture) {
1da177e4
LT
2516 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2517 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2518 }
2519 }
2520
e08a007d
TI
2521 /* If the use of more than one ADC is requested for the current
2522 * model, configure a second analog capture-only PCM.
2523 */
2524 /* Additional Analaog capture for index #2 */
6330079f
TI
2525 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2526 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2527 codec->num_pcms = 3;
c06134d7 2528 info = spec->pcm_rec + 2;
e08a007d 2529 info->name = spec->stream_name_analog;
6330079f
TI
2530 if (spec->alt_dac_nid) {
2531 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2532 *spec->stream_analog_alt_playback;
2533 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2534 spec->alt_dac_nid;
2535 } else {
2536 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2537 alc_pcm_null_stream;
2538 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2539 }
2540 if (spec->num_adc_nids > 1) {
2541 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2542 *spec->stream_analog_alt_capture;
2543 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2544 spec->adc_nids[1];
2545 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2546 spec->num_adc_nids - 1;
2547 } else {
2548 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2549 alc_pcm_null_stream;
2550 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2551 }
2552 }
2553
1da177e4
LT
2554 return 0;
2555}
2556
2557static void alc_free(struct hda_codec *codec)
2558{
e9edcee0
TI
2559 struct alc_spec *spec = codec->spec;
2560 unsigned int i;
2561
f12ab1e0 2562 if (!spec)
e9edcee0
TI
2563 return;
2564
2565 if (spec->kctl_alloc) {
2566 for (i = 0; i < spec->num_kctl_used; i++)
2567 kfree(spec->kctl_alloc[i].name);
2568 kfree(spec->kctl_alloc);
2569 }
2570 kfree(spec);
1da177e4
LT
2571}
2572
2573/*
2574 */
2575static struct hda_codec_ops alc_patch_ops = {
2576 .build_controls = alc_build_controls,
2577 .build_pcms = alc_build_pcms,
2578 .init = alc_init,
2579 .free = alc_free,
ae6b813a 2580 .unsol_event = alc_unsol_event,
cb53c626
TI
2581#ifdef CONFIG_SND_HDA_POWER_SAVE
2582 .check_power_status = alc_check_power_status,
2583#endif
1da177e4
LT
2584};
2585
2fa522be
TI
2586
2587/*
2588 * Test configuration for debugging
2589 *
2590 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2591 * enum controls.
2592 */
2593#ifdef CONFIG_SND_DEBUG
2594static hda_nid_t alc880_test_dac_nids[4] = {
2595 0x02, 0x03, 0x04, 0x05
2596};
2597
2598static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2599 .num_items = 7,
2fa522be
TI
2600 .items = {
2601 { "In-1", 0x0 },
2602 { "In-2", 0x1 },
2603 { "In-3", 0x2 },
2604 { "In-4", 0x3 },
2605 { "CD", 0x4 },
ae6b813a
TI
2606 { "Front", 0x5 },
2607 { "Surround", 0x6 },
2fa522be
TI
2608 },
2609};
2610
d2a6d7dc 2611static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2612 { 2, NULL },
fd2c326d 2613 { 4, NULL },
2fa522be 2614 { 6, NULL },
fd2c326d 2615 { 8, NULL },
2fa522be
TI
2616};
2617
9c7f852e
TI
2618static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2619 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2620{
2621 static char *texts[] = {
2622 "N/A", "Line Out", "HP Out",
2623 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2624 };
2625 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2626 uinfo->count = 1;
2627 uinfo->value.enumerated.items = 8;
2628 if (uinfo->value.enumerated.item >= 8)
2629 uinfo->value.enumerated.item = 7;
2630 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2631 return 0;
2632}
2633
9c7f852e
TI
2634static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2635 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2636{
2637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2638 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2639 unsigned int pin_ctl, item = 0;
2640
2641 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2642 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2643 if (pin_ctl & AC_PINCTL_OUT_EN) {
2644 if (pin_ctl & AC_PINCTL_HP_EN)
2645 item = 2;
2646 else
2647 item = 1;
2648 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2649 switch (pin_ctl & AC_PINCTL_VREFEN) {
2650 case AC_PINCTL_VREF_HIZ: item = 3; break;
2651 case AC_PINCTL_VREF_50: item = 4; break;
2652 case AC_PINCTL_VREF_GRD: item = 5; break;
2653 case AC_PINCTL_VREF_80: item = 6; break;
2654 case AC_PINCTL_VREF_100: item = 7; break;
2655 }
2656 }
2657 ucontrol->value.enumerated.item[0] = item;
2658 return 0;
2659}
2660
9c7f852e
TI
2661static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2662 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2663{
2664 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2665 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2666 static unsigned int ctls[] = {
2667 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2668 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2669 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2670 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2671 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2672 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2673 };
2674 unsigned int old_ctl, new_ctl;
2675
2676 old_ctl = snd_hda_codec_read(codec, nid, 0,
2677 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2678 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2679 if (old_ctl != new_ctl) {
82beb8fd
TI
2680 int val;
2681 snd_hda_codec_write_cache(codec, nid, 0,
2682 AC_VERB_SET_PIN_WIDGET_CONTROL,
2683 new_ctl);
47fd830a
TI
2684 val = ucontrol->value.enumerated.item[0] >= 3 ?
2685 HDA_AMP_MUTE : 0;
2686 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2687 HDA_AMP_MUTE, val);
2fa522be
TI
2688 return 1;
2689 }
2690 return 0;
2691}
2692
9c7f852e
TI
2693static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2694 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2695{
2696 static char *texts[] = {
2697 "Front", "Surround", "CLFE", "Side"
2698 };
2699 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2700 uinfo->count = 1;
2701 uinfo->value.enumerated.items = 4;
2702 if (uinfo->value.enumerated.item >= 4)
2703 uinfo->value.enumerated.item = 3;
2704 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2705 return 0;
2706}
2707
9c7f852e
TI
2708static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2709 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2710{
2711 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2712 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2713 unsigned int sel;
2714
2715 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2716 ucontrol->value.enumerated.item[0] = sel & 3;
2717 return 0;
2718}
2719
9c7f852e
TI
2720static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2721 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2722{
2723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2724 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2725 unsigned int sel;
2726
2727 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2728 if (ucontrol->value.enumerated.item[0] != sel) {
2729 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2730 snd_hda_codec_write_cache(codec, nid, 0,
2731 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2732 return 1;
2733 }
2734 return 0;
2735}
2736
2737#define PIN_CTL_TEST(xname,nid) { \
2738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2739 .name = xname, \
2740 .info = alc_test_pin_ctl_info, \
2741 .get = alc_test_pin_ctl_get, \
2742 .put = alc_test_pin_ctl_put, \
2743 .private_value = nid \
2744 }
2745
2746#define PIN_SRC_TEST(xname,nid) { \
2747 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2748 .name = xname, \
2749 .info = alc_test_pin_src_info, \
2750 .get = alc_test_pin_src_get, \
2751 .put = alc_test_pin_src_put, \
2752 .private_value = nid \
2753 }
2754
c8b6bf9b 2755static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2757 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2758 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2759 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2760 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2761 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2762 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2763 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2764 PIN_CTL_TEST("Front Pin Mode", 0x14),
2765 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2766 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2767 PIN_CTL_TEST("Side Pin Mode", 0x17),
2768 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2769 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2770 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2771 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2772 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2773 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2774 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2775 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2776 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2777 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2778 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2779 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2780 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2781 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2782 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2783 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2784 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2785 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2786 {
2787 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2788 .name = "Channel Mode",
df694daa
KY
2789 .info = alc_ch_mode_info,
2790 .get = alc_ch_mode_get,
2791 .put = alc_ch_mode_put,
2fa522be
TI
2792 },
2793 { } /* end */
2794};
2795
2796static struct hda_verb alc880_test_init_verbs[] = {
2797 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2798 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2799 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2800 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2802 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2803 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2804 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2805 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2806 /* Vol output for 0x0c-0x0f */
05acb863
TI
2807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2811 /* Set output pins 0x14-0x17 */
05acb863
TI
2812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2813 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2814 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2815 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2816 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2817 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2818 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2819 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2820 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2821 /* Set input pins 0x18-0x1c */
16ded525
TI
2822 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2823 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2824 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2825 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2826 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2827 /* Mute input pins 0x18-0x1b */
05acb863
TI
2828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2829 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2830 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2831 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2832 /* ADC set up */
05acb863 2833 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2834 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2835 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2836 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2837 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2838 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2839 /* Analog input/passthru */
2840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2844 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2845 { }
2846};
2847#endif
2848
1da177e4
LT
2849/*
2850 */
2851
f5fcc13c
TI
2852static const char *alc880_models[ALC880_MODEL_LAST] = {
2853 [ALC880_3ST] = "3stack",
2854 [ALC880_TCL_S700] = "tcl",
2855 [ALC880_3ST_DIG] = "3stack-digout",
2856 [ALC880_CLEVO] = "clevo",
2857 [ALC880_5ST] = "5stack",
2858 [ALC880_5ST_DIG] = "5stack-digout",
2859 [ALC880_W810] = "w810",
2860 [ALC880_Z71V] = "z71v",
2861 [ALC880_6ST] = "6stack",
2862 [ALC880_6ST_DIG] = "6stack-digout",
2863 [ALC880_ASUS] = "asus",
2864 [ALC880_ASUS_W1V] = "asus-w1v",
2865 [ALC880_ASUS_DIG] = "asus-dig",
2866 [ALC880_ASUS_DIG2] = "asus-dig2",
2867 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2868 [ALC880_UNIWILL_P53] = "uniwill-p53",
2869 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2870 [ALC880_F1734] = "F1734",
2871 [ALC880_LG] = "lg",
2872 [ALC880_LG_LW] = "lg-lw",
2fa522be 2873#ifdef CONFIG_SND_DEBUG
f5fcc13c 2874 [ALC880_TEST] = "test",
2fa522be 2875#endif
f5fcc13c
TI
2876 [ALC880_AUTO] = "auto",
2877};
2878
2879static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2880 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2881 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2882 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2883 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2884 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2885 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2886 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2887 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2888 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2889 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2890 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2891 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2892 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2893 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2894 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2895 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2896 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2897 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2898 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2899 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2900 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2901 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2902 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2903 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2904 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2905 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2906 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2907 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2908 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2909 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2910 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2911 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2912 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2913 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2914 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2915 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2916 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2917 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2918 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2919 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2920 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2921 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2922 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2923 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2924 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2925 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2926 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2927 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2928 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2929 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2930 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2931 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2932 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2933 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2934 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2935 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2936 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2937 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2938 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2939 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2940 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2941 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2942 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2943 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2944 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2945 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2946 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2947 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2948 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2949 {}
2950};
2951
16ded525 2952/*
df694daa 2953 * ALC880 codec presets
16ded525 2954 */
16ded525
TI
2955static struct alc_config_preset alc880_presets[] = {
2956 [ALC880_3ST] = {
e9edcee0 2957 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2958 .init_verbs = { alc880_volume_init_verbs,
2959 alc880_pin_3stack_init_verbs },
16ded525 2960 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2961 .dac_nids = alc880_dac_nids,
16ded525
TI
2962 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2963 .channel_mode = alc880_threestack_modes,
4e195a7b 2964 .need_dac_fix = 1,
16ded525
TI
2965 .input_mux = &alc880_capture_source,
2966 },
2967 [ALC880_3ST_DIG] = {
e9edcee0 2968 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2969 .init_verbs = { alc880_volume_init_verbs,
2970 alc880_pin_3stack_init_verbs },
16ded525 2971 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2972 .dac_nids = alc880_dac_nids,
2973 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2974 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2975 .channel_mode = alc880_threestack_modes,
4e195a7b 2976 .need_dac_fix = 1,
16ded525
TI
2977 .input_mux = &alc880_capture_source,
2978 },
df694daa
KY
2979 [ALC880_TCL_S700] = {
2980 .mixers = { alc880_tcl_s700_mixer },
2981 .init_verbs = { alc880_volume_init_verbs,
2982 alc880_pin_tcl_S700_init_verbs,
2983 alc880_gpio2_init_verbs },
2984 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2985 .dac_nids = alc880_dac_nids,
2986 .hp_nid = 0x03,
2987 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2988 .channel_mode = alc880_2_jack_modes,
2989 .input_mux = &alc880_capture_source,
2990 },
16ded525 2991 [ALC880_5ST] = {
f12ab1e0
TI
2992 .mixers = { alc880_three_stack_mixer,
2993 alc880_five_stack_mixer},
2994 .init_verbs = { alc880_volume_init_verbs,
2995 alc880_pin_5stack_init_verbs },
16ded525
TI
2996 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2997 .dac_nids = alc880_dac_nids,
16ded525
TI
2998 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2999 .channel_mode = alc880_fivestack_modes,
3000 .input_mux = &alc880_capture_source,
3001 },
3002 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3003 .mixers = { alc880_three_stack_mixer,
3004 alc880_five_stack_mixer },
3005 .init_verbs = { alc880_volume_init_verbs,
3006 alc880_pin_5stack_init_verbs },
16ded525
TI
3007 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3008 .dac_nids = alc880_dac_nids,
3009 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3010 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3011 .channel_mode = alc880_fivestack_modes,
3012 .input_mux = &alc880_capture_source,
3013 },
b6482d48
TI
3014 [ALC880_6ST] = {
3015 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3016 .init_verbs = { alc880_volume_init_verbs,
3017 alc880_pin_6stack_init_verbs },
b6482d48
TI
3018 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3019 .dac_nids = alc880_6st_dac_nids,
3020 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3021 .channel_mode = alc880_sixstack_modes,
3022 .input_mux = &alc880_6stack_capture_source,
3023 },
16ded525 3024 [ALC880_6ST_DIG] = {
e9edcee0 3025 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3026 .init_verbs = { alc880_volume_init_verbs,
3027 alc880_pin_6stack_init_verbs },
16ded525
TI
3028 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3029 .dac_nids = alc880_6st_dac_nids,
3030 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3031 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3032 .channel_mode = alc880_sixstack_modes,
3033 .input_mux = &alc880_6stack_capture_source,
3034 },
3035 [ALC880_W810] = {
e9edcee0 3036 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3037 .init_verbs = { alc880_volume_init_verbs,
3038 alc880_pin_w810_init_verbs,
b0af0de5 3039 alc880_gpio2_init_verbs },
16ded525
TI
3040 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3041 .dac_nids = alc880_w810_dac_nids,
3042 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3043 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3044 .channel_mode = alc880_w810_modes,
3045 .input_mux = &alc880_capture_source,
3046 },
3047 [ALC880_Z71V] = {
e9edcee0 3048 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3049 .init_verbs = { alc880_volume_init_verbs,
3050 alc880_pin_z71v_init_verbs },
16ded525
TI
3051 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3052 .dac_nids = alc880_z71v_dac_nids,
3053 .dig_out_nid = ALC880_DIGOUT_NID,
3054 .hp_nid = 0x03,
e9edcee0
TI
3055 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3056 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3057 .input_mux = &alc880_capture_source,
3058 },
3059 [ALC880_F1734] = {
e9edcee0 3060 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3061 .init_verbs = { alc880_volume_init_verbs,
3062 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3063 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3064 .dac_nids = alc880_f1734_dac_nids,
3065 .hp_nid = 0x02,
3066 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3067 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3068 .input_mux = &alc880_f1734_capture_source,
3069 .unsol_event = alc880_uniwill_p53_unsol_event,
3070 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3071 },
3072 [ALC880_ASUS] = {
e9edcee0 3073 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3074 .init_verbs = { alc880_volume_init_verbs,
3075 alc880_pin_asus_init_verbs,
e9edcee0
TI
3076 alc880_gpio1_init_verbs },
3077 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3078 .dac_nids = alc880_asus_dac_nids,
3079 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3080 .channel_mode = alc880_asus_modes,
4e195a7b 3081 .need_dac_fix = 1,
16ded525
TI
3082 .input_mux = &alc880_capture_source,
3083 },
3084 [ALC880_ASUS_DIG] = {
e9edcee0 3085 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3086 .init_verbs = { alc880_volume_init_verbs,
3087 alc880_pin_asus_init_verbs,
e9edcee0
TI
3088 alc880_gpio1_init_verbs },
3089 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3090 .dac_nids = alc880_asus_dac_nids,
16ded525 3091 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3092 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3093 .channel_mode = alc880_asus_modes,
4e195a7b 3094 .need_dac_fix = 1,
16ded525
TI
3095 .input_mux = &alc880_capture_source,
3096 },
df694daa
KY
3097 [ALC880_ASUS_DIG2] = {
3098 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3099 .init_verbs = { alc880_volume_init_verbs,
3100 alc880_pin_asus_init_verbs,
df694daa
KY
3101 alc880_gpio2_init_verbs }, /* use GPIO2 */
3102 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3103 .dac_nids = alc880_asus_dac_nids,
3104 .dig_out_nid = ALC880_DIGOUT_NID,
3105 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3106 .channel_mode = alc880_asus_modes,
4e195a7b 3107 .need_dac_fix = 1,
df694daa
KY
3108 .input_mux = &alc880_capture_source,
3109 },
16ded525 3110 [ALC880_ASUS_W1V] = {
e9edcee0 3111 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3112 .init_verbs = { alc880_volume_init_verbs,
3113 alc880_pin_asus_init_verbs,
e9edcee0
TI
3114 alc880_gpio1_init_verbs },
3115 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3116 .dac_nids = alc880_asus_dac_nids,
16ded525 3117 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3118 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3119 .channel_mode = alc880_asus_modes,
4e195a7b 3120 .need_dac_fix = 1,
16ded525
TI
3121 .input_mux = &alc880_capture_source,
3122 },
3123 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3124 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3125 .init_verbs = { alc880_volume_init_verbs,
3126 alc880_pin_asus_init_verbs },
e9edcee0
TI
3127 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3128 .dac_nids = alc880_asus_dac_nids,
16ded525 3129 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3130 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3131 .channel_mode = alc880_asus_modes,
4e195a7b 3132 .need_dac_fix = 1,
16ded525
TI
3133 .input_mux = &alc880_capture_source,
3134 },
ccc656ce
KY
3135 [ALC880_UNIWILL] = {
3136 .mixers = { alc880_uniwill_mixer },
3137 .init_verbs = { alc880_volume_init_verbs,
3138 alc880_uniwill_init_verbs },
3139 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3140 .dac_nids = alc880_asus_dac_nids,
3141 .dig_out_nid = ALC880_DIGOUT_NID,
3142 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3143 .channel_mode = alc880_threestack_modes,
3144 .need_dac_fix = 1,
3145 .input_mux = &alc880_capture_source,
3146 .unsol_event = alc880_uniwill_unsol_event,
3147 .init_hook = alc880_uniwill_automute,
3148 },
3149 [ALC880_UNIWILL_P53] = {
3150 .mixers = { alc880_uniwill_p53_mixer },
3151 .init_verbs = { alc880_volume_init_verbs,
3152 alc880_uniwill_p53_init_verbs },
3153 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3154 .dac_nids = alc880_asus_dac_nids,
3155 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3156 .channel_mode = alc880_threestack_modes,
3157 .input_mux = &alc880_capture_source,
3158 .unsol_event = alc880_uniwill_p53_unsol_event,
3159 .init_hook = alc880_uniwill_p53_hp_automute,
3160 },
3161 [ALC880_FUJITSU] = {
f12ab1e0 3162 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3163 alc880_pcbeep_mixer, },
3164 .init_verbs = { alc880_volume_init_verbs,
3165 alc880_uniwill_p53_init_verbs,
3166 alc880_beep_init_verbs },
3167 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3168 .dac_nids = alc880_dac_nids,
d53d7d9e 3169 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3170 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3171 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3172 .input_mux = &alc880_capture_source,
3173 .unsol_event = alc880_uniwill_p53_unsol_event,
3174 .init_hook = alc880_uniwill_p53_hp_automute,
3175 },
df694daa
KY
3176 [ALC880_CLEVO] = {
3177 .mixers = { alc880_three_stack_mixer },
3178 .init_verbs = { alc880_volume_init_verbs,
3179 alc880_pin_clevo_init_verbs },
3180 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3181 .dac_nids = alc880_dac_nids,
3182 .hp_nid = 0x03,
3183 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3184 .channel_mode = alc880_threestack_modes,
4e195a7b 3185 .need_dac_fix = 1,
df694daa
KY
3186 .input_mux = &alc880_capture_source,
3187 },
ae6b813a
TI
3188 [ALC880_LG] = {
3189 .mixers = { alc880_lg_mixer },
3190 .init_verbs = { alc880_volume_init_verbs,
3191 alc880_lg_init_verbs },
3192 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3193 .dac_nids = alc880_lg_dac_nids,
3194 .dig_out_nid = ALC880_DIGOUT_NID,
3195 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3196 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3197 .need_dac_fix = 1,
ae6b813a
TI
3198 .input_mux = &alc880_lg_capture_source,
3199 .unsol_event = alc880_lg_unsol_event,
3200 .init_hook = alc880_lg_automute,
cb53c626
TI
3201#ifdef CONFIG_SND_HDA_POWER_SAVE
3202 .loopbacks = alc880_lg_loopbacks,
3203#endif
ae6b813a 3204 },
d681518a
TI
3205 [ALC880_LG_LW] = {
3206 .mixers = { alc880_lg_lw_mixer },
3207 .init_verbs = { alc880_volume_init_verbs,
3208 alc880_lg_lw_init_verbs },
0a8c5da3 3209 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3210 .dac_nids = alc880_dac_nids,
3211 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3212 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3213 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3214 .input_mux = &alc880_lg_lw_capture_source,
3215 .unsol_event = alc880_lg_lw_unsol_event,
3216 .init_hook = alc880_lg_lw_automute,
3217 },
16ded525
TI
3218#ifdef CONFIG_SND_DEBUG
3219 [ALC880_TEST] = {
e9edcee0
TI
3220 .mixers = { alc880_test_mixer },
3221 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3222 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3223 .dac_nids = alc880_test_dac_nids,
3224 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3225 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3226 .channel_mode = alc880_test_modes,
3227 .input_mux = &alc880_test_capture_source,
3228 },
3229#endif
3230};
3231
e9edcee0
TI
3232/*
3233 * Automatic parse of I/O pins from the BIOS configuration
3234 */
3235
3236#define NUM_CONTROL_ALLOC 32
3237#define NUM_VERB_ALLOC 32
3238
3239enum {
3240 ALC_CTL_WIDGET_VOL,
3241 ALC_CTL_WIDGET_MUTE,
3242 ALC_CTL_BIND_MUTE,
3243};
c8b6bf9b 3244static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3245 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3246 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3247 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3248};
3249
3250/* add dynamic controls */
f12ab1e0
TI
3251static int add_control(struct alc_spec *spec, int type, const char *name,
3252 unsigned long val)
e9edcee0 3253{
c8b6bf9b 3254 struct snd_kcontrol_new *knew;
e9edcee0
TI
3255
3256 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3257 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3258
f12ab1e0
TI
3259 /* array + terminator */
3260 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3261 if (!knew)
e9edcee0
TI
3262 return -ENOMEM;
3263 if (spec->kctl_alloc) {
f12ab1e0
TI
3264 memcpy(knew, spec->kctl_alloc,
3265 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3266 kfree(spec->kctl_alloc);
3267 }
3268 spec->kctl_alloc = knew;
3269 spec->num_kctl_alloc = num;
3270 }
3271
3272 knew = &spec->kctl_alloc[spec->num_kctl_used];
3273 *knew = alc880_control_templates[type];
543537bd 3274 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3275 if (!knew->name)
e9edcee0
TI
3276 return -ENOMEM;
3277 knew->private_value = val;
3278 spec->num_kctl_used++;
3279 return 0;
3280}
3281
3282#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3283#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3284#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3285#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3286#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3287#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3288#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3289#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3290#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3291#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3292#define ALC880_PIN_CD_NID 0x1c
3293
3294/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3295static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3296 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3297{
3298 hda_nid_t nid;
3299 int assigned[4];
3300 int i, j;
3301
3302 memset(assigned, 0, sizeof(assigned));
b0af0de5 3303 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3304
3305 /* check the pins hardwired to audio widget */
3306 for (i = 0; i < cfg->line_outs; i++) {
3307 nid = cfg->line_out_pins[i];
3308 if (alc880_is_fixed_pin(nid)) {
3309 int idx = alc880_fixed_pin_idx(nid);
5014f193 3310 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3311 assigned[idx] = 1;
3312 }
3313 }
3314 /* left pins can be connect to any audio widget */
3315 for (i = 0; i < cfg->line_outs; i++) {
3316 nid = cfg->line_out_pins[i];
3317 if (alc880_is_fixed_pin(nid))
3318 continue;
3319 /* search for an empty channel */
3320 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3321 if (!assigned[j]) {
3322 spec->multiout.dac_nids[i] =
3323 alc880_idx_to_dac(j);
e9edcee0
TI
3324 assigned[j] = 1;
3325 break;
3326 }
3327 }
3328 }
3329 spec->multiout.num_dacs = cfg->line_outs;
3330 return 0;
3331}
3332
3333/* add playback controls from the parsed DAC table */
df694daa
KY
3334static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3335 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3336{
3337 char name[32];
f12ab1e0
TI
3338 static const char *chname[4] = {
3339 "Front", "Surround", NULL /*CLFE*/, "Side"
3340 };
e9edcee0
TI
3341 hda_nid_t nid;
3342 int i, err;
3343
3344 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3345 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3346 continue;
3347 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3348 if (i == 2) {
3349 /* Center/LFE */
f12ab1e0
TI
3350 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3351 "Center Playback Volume",
3352 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3353 HDA_OUTPUT));
3354 if (err < 0)
e9edcee0 3355 return err;
f12ab1e0
TI
3356 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3357 "LFE Playback Volume",
3358 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3359 HDA_OUTPUT));
3360 if (err < 0)
e9edcee0 3361 return err;
f12ab1e0
TI
3362 err = add_control(spec, ALC_CTL_BIND_MUTE,
3363 "Center Playback Switch",
3364 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3365 HDA_INPUT));
3366 if (err < 0)
e9edcee0 3367 return err;
f12ab1e0
TI
3368 err = add_control(spec, ALC_CTL_BIND_MUTE,
3369 "LFE Playback Switch",
3370 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3371 HDA_INPUT));
3372 if (err < 0)
e9edcee0
TI
3373 return err;
3374 } else {
3375 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3376 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3377 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3378 HDA_OUTPUT));
3379 if (err < 0)
e9edcee0
TI
3380 return err;
3381 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3382 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3383 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3384 HDA_INPUT));
3385 if (err < 0)
e9edcee0
TI
3386 return err;
3387 }
3388 }
e9edcee0
TI
3389 return 0;
3390}
3391
8d88bc3d
TI
3392/* add playback controls for speaker and HP outputs */
3393static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3394 const char *pfx)
e9edcee0
TI
3395{
3396 hda_nid_t nid;
3397 int err;
8d88bc3d 3398 char name[32];
e9edcee0 3399
f12ab1e0 3400 if (!pin)
e9edcee0
TI
3401 return 0;
3402
3403 if (alc880_is_fixed_pin(pin)) {
3404 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3405 /* specify the DAC as the extra output */
f12ab1e0 3406 if (!spec->multiout.hp_nid)
e9edcee0 3407 spec->multiout.hp_nid = nid;
82bc955f
TI
3408 else
3409 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3410 /* control HP volume/switch on the output mixer amp */
3411 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3412 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3413 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3414 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3415 if (err < 0)
e9edcee0 3416 return err;
8d88bc3d 3417 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3418 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3419 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3420 if (err < 0)
e9edcee0
TI
3421 return err;
3422 } else if (alc880_is_multi_pin(pin)) {
3423 /* set manual connection */
e9edcee0 3424 /* we have only a switch on HP-out PIN */
8d88bc3d 3425 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3426 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3427 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3428 if (err < 0)
e9edcee0
TI
3429 return err;
3430 }
3431 return 0;
3432}
3433
3434/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3435static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3436 const char *ctlname,
df694daa 3437 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3438{
3439 char name[32];
df694daa 3440 int err;
e9edcee0
TI
3441
3442 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3443 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3444 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3445 if (err < 0)
e9edcee0
TI
3446 return err;
3447 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3448 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3449 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3450 if (err < 0)
e9edcee0
TI
3451 return err;
3452 return 0;
3453}
3454
3455/* create playback/capture controls for input pins */
df694daa
KY
3456static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3457 const struct auto_pin_cfg *cfg)
e9edcee0 3458{
e9edcee0 3459 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3460 int i, err, idx;
e9edcee0
TI
3461
3462 for (i = 0; i < AUTO_PIN_LAST; i++) {
3463 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3464 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3465 err = new_analog_input(spec, cfg->input_pins[i],
3466 auto_pin_cfg_labels[i],
df694daa 3467 idx, 0x0b);
e9edcee0
TI
3468 if (err < 0)
3469 return err;
f12ab1e0
TI
3470 imux->items[imux->num_items].label =
3471 auto_pin_cfg_labels[i];
3472 imux->items[imux->num_items].index =
3473 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3474 imux->num_items++;
3475 }
3476 }
3477 return 0;
3478}
3479
f6c7e546
TI
3480static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3481 unsigned int pin_type)
3482{
3483 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3484 pin_type);
3485 /* unmute pin */
3486 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, 0xff, 0x00);
3487}
3488
df694daa
KY
3489static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3490 hda_nid_t nid, int pin_type,
e9edcee0
TI
3491 int dac_idx)
3492{
f6c7e546 3493 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3494 /* need the manual connection? */
3495 if (alc880_is_multi_pin(nid)) {
3496 struct alc_spec *spec = codec->spec;
3497 int idx = alc880_multi_pin_idx(nid);
3498 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3499 AC_VERB_SET_CONNECT_SEL,
3500 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3501 }
3502}
3503
baba8ee9
TI
3504static int get_pin_type(int line_out_type)
3505{
3506 if (line_out_type == AUTO_PIN_HP_OUT)
3507 return PIN_HP;
3508 else
3509 return PIN_OUT;
3510}
3511
e9edcee0
TI
3512static void alc880_auto_init_multi_out(struct hda_codec *codec)
3513{
3514 struct alc_spec *spec = codec->spec;
3515 int i;
bc9f98a9
KY
3516
3517 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3518 for (i = 0; i < spec->autocfg.line_outs; i++) {
3519 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3520 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3521 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3522 }
3523}
3524
8d88bc3d 3525static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3526{
3527 struct alc_spec *spec = codec->spec;
3528 hda_nid_t pin;
3529
82bc955f 3530 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3531 if (pin) /* connect to front */
3532 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3533 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3534 if (pin) /* connect to front */
3535 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3536}
3537
3538static void alc880_auto_init_analog_input(struct hda_codec *codec)
3539{
3540 struct alc_spec *spec = codec->spec;
3541 int i;
3542
3543 for (i = 0; i < AUTO_PIN_LAST; i++) {
3544 hda_nid_t nid = spec->autocfg.input_pins[i];
3545 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3546 snd_hda_codec_write(codec, nid, 0,
3547 AC_VERB_SET_PIN_WIDGET_CONTROL,
3548 i <= AUTO_PIN_FRONT_MIC ?
3549 PIN_VREF80 : PIN_IN);
e9edcee0 3550 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3551 snd_hda_codec_write(codec, nid, 0,
3552 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3553 AMP_OUT_MUTE);
3554 }
3555 }
3556}
3557
3558/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3559/* return 1 if successful, 0 if the proper config is not found,
3560 * or a negative error code
3561 */
e9edcee0
TI
3562static int alc880_parse_auto_config(struct hda_codec *codec)
3563{
3564 struct alc_spec *spec = codec->spec;
3565 int err;
df694daa 3566 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3567
f12ab1e0
TI
3568 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3569 alc880_ignore);
3570 if (err < 0)
e9edcee0 3571 return err;
f12ab1e0 3572 if (!spec->autocfg.line_outs)
e9edcee0 3573 return 0; /* can't find valid BIOS pin config */
df694daa 3574
f12ab1e0
TI
3575 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3576 if (err < 0)
3577 return err;
3578 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3579 if (err < 0)
3580 return err;
3581 err = alc880_auto_create_extra_out(spec,
3582 spec->autocfg.speaker_pins[0],
3583 "Speaker");
3584 if (err < 0)
3585 return err;
3586 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3587 "Headphone");
3588 if (err < 0)
3589 return err;
3590 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3591 if (err < 0)
e9edcee0
TI
3592 return err;
3593
3594 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3595
3596 if (spec->autocfg.dig_out_pin)
3597 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3598 if (spec->autocfg.dig_in_pin)
3599 spec->dig_in_nid = ALC880_DIGIN_NID;
3600
3601 if (spec->kctl_alloc)
3602 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3603
3604 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3605
a1e8d2da 3606 spec->num_mux_defs = 1;
e9edcee0
TI
3607 spec->input_mux = &spec->private_imux;
3608
3609 return 1;
3610}
3611
ae6b813a
TI
3612/* additional initialization for auto-configuration model */
3613static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3614{
f6c7e546 3615 struct alc_spec *spec = codec->spec;
e9edcee0 3616 alc880_auto_init_multi_out(codec);
8d88bc3d 3617 alc880_auto_init_extra_out(codec);
e9edcee0 3618 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3619 if (spec->unsol_event)
3620 alc_sku_automute(codec);
e9edcee0
TI
3621}
3622
3623/*
3624 * OK, here we have finally the patch for ALC880
3625 */
3626
1da177e4
LT
3627static int patch_alc880(struct hda_codec *codec)
3628{
3629 struct alc_spec *spec;
3630 int board_config;
df694daa 3631 int err;
1da177e4 3632
e560d8d8 3633 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3634 if (spec == NULL)
3635 return -ENOMEM;
3636
3637 codec->spec = spec;
3638
f5fcc13c
TI
3639 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3640 alc880_models,
3641 alc880_cfg_tbl);
3642 if (board_config < 0) {
9c7f852e
TI
3643 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3644 "trying auto-probe from BIOS...\n");
e9edcee0 3645 board_config = ALC880_AUTO;
1da177e4 3646 }
1da177e4 3647
e9edcee0
TI
3648 if (board_config == ALC880_AUTO) {
3649 /* automatic parse from the BIOS config */
3650 err = alc880_parse_auto_config(codec);
3651 if (err < 0) {
3652 alc_free(codec);
3653 return err;
f12ab1e0 3654 } else if (!err) {
9c7f852e
TI
3655 printk(KERN_INFO
3656 "hda_codec: Cannot set up configuration "
3657 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3658 board_config = ALC880_3ST;
3659 }
1da177e4
LT
3660 }
3661
df694daa
KY
3662 if (board_config != ALC880_AUTO)
3663 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3664
3665 spec->stream_name_analog = "ALC880 Analog";
3666 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3667 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3668 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3669
3670 spec->stream_name_digital = "ALC880 Digital";
3671 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3672 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3673
f12ab1e0 3674 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3675 /* check whether NID 0x07 is valid */
54d17403 3676 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3677 /* get type */
3678 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3679 if (wcap != AC_WID_AUD_IN) {
3680 spec->adc_nids = alc880_adc_nids_alt;
3681 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3682 spec->mixers[spec->num_mixers] =
3683 alc880_capture_alt_mixer;
e9edcee0
TI
3684 spec->num_mixers++;
3685 } else {
3686 spec->adc_nids = alc880_adc_nids;
3687 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3688 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3689 spec->num_mixers++;
3690 }
3691 }
1da177e4 3692
2134ea4f
TI
3693 spec->vmaster_nid = 0x0c;
3694
1da177e4 3695 codec->patch_ops = alc_patch_ops;
e9edcee0 3696 if (board_config == ALC880_AUTO)
ae6b813a 3697 spec->init_hook = alc880_auto_init;
cb53c626
TI
3698#ifdef CONFIG_SND_HDA_POWER_SAVE
3699 if (!spec->loopback.amplist)
3700 spec->loopback.amplist = alc880_loopbacks;
3701#endif
1da177e4
LT
3702
3703 return 0;
3704}
3705
e9edcee0 3706
1da177e4
LT
3707/*
3708 * ALC260 support
3709 */
3710
e9edcee0
TI
3711static hda_nid_t alc260_dac_nids[1] = {
3712 /* front */
3713 0x02,
3714};
3715
3716static hda_nid_t alc260_adc_nids[1] = {
3717 /* ADC0 */
3718 0x04,
3719};
3720
df694daa 3721static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3722 /* ADC1 */
3723 0x05,
3724};
3725
df694daa
KY
3726static hda_nid_t alc260_hp_adc_nids[2] = {
3727 /* ADC1, 0 */
3728 0x05, 0x04
3729};
3730
d57fdac0
JW
3731/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3732 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3733 */
3734static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3735 /* ADC0, ADC1 */
3736 0x04, 0x05
3737};
3738
e9edcee0
TI
3739#define ALC260_DIGOUT_NID 0x03
3740#define ALC260_DIGIN_NID 0x06
3741
3742static struct hda_input_mux alc260_capture_source = {
3743 .num_items = 4,
3744 .items = {
3745 { "Mic", 0x0 },
3746 { "Front Mic", 0x1 },
3747 { "Line", 0x2 },
3748 { "CD", 0x4 },
3749 },
3750};
3751
17e7aec6 3752/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3753 * headphone jack and the internal CD lines since these are the only pins at
3754 * which audio can appear. For flexibility, also allow the option of
3755 * recording the mixer output on the second ADC (ADC0 doesn't have a
3756 * connection to the mixer output).
a9430dd8 3757 */
a1e8d2da
JW
3758static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3759 {
3760 .num_items = 3,
3761 .items = {
3762 { "Mic/Line", 0x0 },
3763 { "CD", 0x4 },
3764 { "Headphone", 0x2 },
3765 },
a9430dd8 3766 },
a1e8d2da
JW
3767 {
3768 .num_items = 4,
3769 .items = {
3770 { "Mic/Line", 0x0 },
3771 { "CD", 0x4 },
3772 { "Headphone", 0x2 },
3773 { "Mixer", 0x5 },
3774 },
3775 },
3776
a9430dd8
JW
3777};
3778
a1e8d2da
JW
3779/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3780 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3781 */
a1e8d2da
JW
3782static struct hda_input_mux alc260_acer_capture_sources[2] = {
3783 {
3784 .num_items = 4,
3785 .items = {
3786 { "Mic", 0x0 },
3787 { "Line", 0x2 },
3788 { "CD", 0x4 },
3789 { "Headphone", 0x5 },
3790 },
3791 },
3792 {
3793 .num_items = 5,
3794 .items = {
3795 { "Mic", 0x0 },
3796 { "Line", 0x2 },
3797 { "CD", 0x4 },
3798 { "Headphone", 0x6 },
3799 { "Mixer", 0x5 },
3800 },
0bfc90e9
JW
3801 },
3802};
1da177e4
LT
3803/*
3804 * This is just place-holder, so there's something for alc_build_pcms to look
3805 * at when it calculates the maximum number of channels. ALC260 has no mixer
3806 * element which allows changing the channel mode, so the verb list is
3807 * never used.
3808 */
d2a6d7dc 3809static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3810 { 2, NULL },
3811};
3812
df694daa
KY
3813
3814/* Mixer combinations
3815 *
3816 * basic: base_output + input + pc_beep + capture
3817 * HP: base_output + input + capture_alt
3818 * HP_3013: hp_3013 + input + capture
3819 * fujitsu: fujitsu + capture
0bfc90e9 3820 * acer: acer + capture
df694daa
KY
3821 */
3822
3823static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3824 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3825 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3826 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3827 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3828 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3829 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3830 { } /* end */
f12ab1e0 3831};
1da177e4 3832
df694daa 3833static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
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("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3837 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3838 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3839 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3841 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3842 { } /* end */
3843};
3844
3845static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3846 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3847 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3848 { } /* end */
3849};
3850
bec15c3a
TI
3851/* update HP, line and mono out pins according to the master switch */
3852static void alc260_hp_master_update(struct hda_codec *codec,
3853 hda_nid_t hp, hda_nid_t line,
3854 hda_nid_t mono)
3855{
3856 struct alc_spec *spec = codec->spec;
3857 unsigned int val = spec->master_sw ? PIN_HP : 0;
3858 /* change HP and line-out pins */
3859 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3860 val);
3861 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3862 val);
3863 /* mono (speaker) depending on the HP jack sense */
3864 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3865 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3866 val);
3867}
3868
3869static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3870 struct snd_ctl_elem_value *ucontrol)
3871{
3872 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3873 struct alc_spec *spec = codec->spec;
3874 *ucontrol->value.integer.value = spec->master_sw;
3875 return 0;
3876}
3877
3878static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3879 struct snd_ctl_elem_value *ucontrol)
3880{
3881 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3882 struct alc_spec *spec = codec->spec;
3883 int val = !!*ucontrol->value.integer.value;
3884 hda_nid_t hp, line, mono;
3885
3886 if (val == spec->master_sw)
3887 return 0;
3888 spec->master_sw = val;
3889 hp = (kcontrol->private_value >> 16) & 0xff;
3890 line = (kcontrol->private_value >> 8) & 0xff;
3891 mono = kcontrol->private_value & 0xff;
3892 alc260_hp_master_update(codec, hp, line, mono);
3893 return 1;
3894}
3895
3896static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3897 {
3898 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3899 .name = "Master Playback Switch",
3900 .info = snd_ctl_boolean_mono_info,
3901 .get = alc260_hp_master_sw_get,
3902 .put = alc260_hp_master_sw_put,
3903 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3904 },
3905 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3906 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3907 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3908 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3909 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3910 HDA_OUTPUT),
3911 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3912 { } /* end */
3913};
3914
3915static struct hda_verb alc260_hp_unsol_verbs[] = {
3916 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3917 {},
3918};
3919
3920static void alc260_hp_automute(struct hda_codec *codec)
3921{
3922 struct alc_spec *spec = codec->spec;
3923 unsigned int present;
3924
3925 present = snd_hda_codec_read(codec, 0x10, 0,
3926 AC_VERB_GET_PIN_SENSE, 0);
3927 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3928 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3929}
3930
3931static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3932{
3933 if ((res >> 26) == ALC880_HP_EVENT)
3934 alc260_hp_automute(codec);
3935}
3936
df694daa 3937static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
3938 {
3939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3940 .name = "Master Playback Switch",
3941 .info = snd_ctl_boolean_mono_info,
3942 .get = alc260_hp_master_sw_get,
3943 .put = alc260_hp_master_sw_put,
3944 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3945 },
df694daa
KY
3946 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3947 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3948 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3949 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3950 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
3952 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3953 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3954 { } /* end */
3955};
3956
bec15c3a
TI
3957static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3958 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3959 {},
3960};
3961
3962static void alc260_hp_3013_automute(struct hda_codec *codec)
3963{
3964 struct alc_spec *spec = codec->spec;
3965 unsigned int present;
3966
3967 present = snd_hda_codec_read(codec, 0x15, 0,
3968 AC_VERB_GET_PIN_SENSE, 0);
3969 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3970 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3971}
3972
3973static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3974 unsigned int res)
3975{
3976 if ((res >> 26) == ALC880_HP_EVENT)
3977 alc260_hp_3013_automute(codec);
3978}
3979
a1e8d2da
JW
3980/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3981 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3982 */
c8b6bf9b 3983static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3984 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3985 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3986 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3987 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3988 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3989 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3990 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 3991 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
3992 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3993 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
3994 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3995 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
3996 { } /* end */
3997};
3998
a1e8d2da
JW
3999/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4000 * versions of the ALC260 don't act on requests to enable mic bias from NID
4001 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4002 * datasheet doesn't mention this restriction. At this stage it's not clear
4003 * whether this behaviour is intentional or is a hardware bug in chip
4004 * revisions available in early 2006. Therefore for now allow the
4005 * "Headphone Jack Mode" control to span all choices, but if it turns out
4006 * that the lack of mic bias for this NID is intentional we could change the
4007 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4008 *
4009 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4010 * don't appear to make the mic bias available from the "line" jack, even
4011 * though the NID used for this jack (0x14) can supply it. The theory is
4012 * that perhaps Acer have included blocking capacitors between the ALC260
4013 * and the output jack. If this turns out to be the case for all such
4014 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4015 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4016 *
4017 * The C20x Tablet series have a mono internal speaker which is controlled
4018 * via the chip's Mono sum widget and pin complex, so include the necessary
4019 * controls for such models. On models without a "mono speaker" the control
4020 * won't do anything.
a1e8d2da 4021 */
0bfc90e9
JW
4022static struct snd_kcontrol_new alc260_acer_mixer[] = {
4023 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4024 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4025 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4026 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4027 HDA_OUTPUT),
31bffaa9 4028 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4029 HDA_INPUT),
0bfc90e9
JW
4030 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4031 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4033 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4034 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4035 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4036 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4037 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4038 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4039 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4040 { } /* end */
4041};
4042
bc9f98a9
KY
4043/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4044 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4045 */
4046static struct snd_kcontrol_new alc260_will_mixer[] = {
4047 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4048 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4049 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4050 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4051 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4052 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4053 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4054 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4055 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4056 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4058 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4059 { } /* end */
4060};
4061
4062/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4063 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4064 */
4065static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4066 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4067 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4069 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4070 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4071 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4072 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4073 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4074 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4075 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4076 { } /* end */
4077};
4078
df694daa
KY
4079/* capture mixer elements */
4080static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4081 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4082 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4083 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4084 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4085 {
4086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4087 /* The multiple "Capture Source" controls confuse alsamixer
4088 * So call somewhat different..
df694daa
KY
4089 */
4090 /* .name = "Capture Source", */
4091 .name = "Input Source",
4092 .count = 2,
4093 .info = alc_mux_enum_info,
4094 .get = alc_mux_enum_get,
4095 .put = alc_mux_enum_put,
4096 },
4097 { } /* end */
4098};
4099
4100static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4101 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4102 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4103 {
4104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4105 /* The multiple "Capture Source" controls confuse alsamixer
4106 * So call somewhat different..
df694daa
KY
4107 */
4108 /* .name = "Capture Source", */
4109 .name = "Input Source",
4110 .count = 1,
a9430dd8
JW
4111 .info = alc_mux_enum_info,
4112 .get = alc_mux_enum_get,
4113 .put = alc_mux_enum_put,
4114 },
4115 { } /* end */
4116};
4117
df694daa
KY
4118/*
4119 * initialization verbs
4120 */
1da177e4
LT
4121static struct hda_verb alc260_init_verbs[] = {
4122 /* Line In pin widget for input */
05acb863 4123 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4124 /* CD pin widget for input */
05acb863 4125 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4126 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4127 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4128 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4129 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4130 /* LINE-2 is used for line-out in rear */
05acb863 4131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4132 /* select line-out */
fd56f2db 4133 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4134 /* LINE-OUT pin */
05acb863 4135 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4136 /* enable HP */
05acb863 4137 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4138 /* enable Mono */
05acb863
TI
4139 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4140 /* mute capture amp left and right */
16ded525 4141 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4142 /* set connection select to line in (default select for this ADC) */
4143 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4144 /* mute capture amp left and right */
4145 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4146 /* set connection select to line in (default select for this ADC) */
4147 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4148 /* set vol=0 Line-Out mixer amp left and right */
4149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4150 /* unmute pin widget amp left and right (no gain on this amp) */
4151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4152 /* set vol=0 HP mixer amp left and right */
4153 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4154 /* unmute pin widget amp left and right (no gain on this amp) */
4155 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4156 /* set vol=0 Mono mixer amp left and right */
4157 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4158 /* unmute pin widget amp left and right (no gain on this amp) */
4159 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4160 /* unmute LINE-2 out pin */
4161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4162 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4163 * Line In 2 = 0x03
4164 */
cb53c626
TI
4165 /* mute analog inputs */
4166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4169 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4170 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4171 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4172 /* mute Front out path */
4173 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4175 /* mute Headphone out path */
4176 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4177 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4178 /* mute Mono out path */
4179 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4180 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4181 { }
4182};
4183
474167d6 4184#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4185static struct hda_verb alc260_hp_init_verbs[] = {
4186 /* Headphone and output */
4187 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4188 /* mono output */
4189 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4190 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4191 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4192 /* Mic2 (front panel) pin widget for input and vref at 80% */
4193 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4194 /* Line In pin widget for input */
4195 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4196 /* Line-2 pin widget for output */
4197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4198 /* CD pin widget for input */
4199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4200 /* unmute amp left and right */
4201 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4202 /* set connection select to line in (default select for this ADC) */
4203 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4204 /* unmute Line-Out mixer amp left and right (volume = 0) */
4205 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4206 /* mute pin widget amp left and right (no gain on this amp) */
4207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4208 /* unmute HP mixer amp left and right (volume = 0) */
4209 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4210 /* mute pin widget amp left and right (no gain on this amp) */
4211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4212 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4213 * Line In 2 = 0x03
4214 */
cb53c626
TI
4215 /* mute analog inputs */
4216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4218 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4220 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4221 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4222 /* Unmute Front out path */
4223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4224 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4225 /* Unmute Headphone out path */
4226 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4227 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4228 /* Unmute Mono out path */
4229 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4230 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4231 { }
4232};
474167d6 4233#endif
df694daa
KY
4234
4235static struct hda_verb alc260_hp_3013_init_verbs[] = {
4236 /* Line out and output */
4237 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4238 /* mono output */
4239 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4240 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4241 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4242 /* Mic2 (front panel) pin widget for input and vref at 80% */
4243 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4244 /* Line In pin widget for input */
4245 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4246 /* Headphone pin widget for output */
4247 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4248 /* CD pin widget for input */
4249 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4250 /* unmute amp left and right */
4251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4252 /* set connection select to line in (default select for this ADC) */
4253 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4254 /* unmute Line-Out mixer amp left and right (volume = 0) */
4255 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4256 /* mute pin widget amp left and right (no gain on this amp) */
4257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4258 /* unmute HP mixer amp left and right (volume = 0) */
4259 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4260 /* mute pin widget amp left and right (no gain on this amp) */
4261 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4262 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4263 * Line In 2 = 0x03
4264 */
cb53c626
TI
4265 /* mute analog inputs */
4266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4271 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4272 /* Unmute Front out path */
4273 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4274 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4275 /* Unmute Headphone out path */
4276 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4277 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4278 /* Unmute Mono out path */
4279 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4280 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4281 { }
4282};
4283
a9430dd8 4284/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4285 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4286 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4287 */
4288static struct hda_verb alc260_fujitsu_init_verbs[] = {
4289 /* Disable all GPIOs */
4290 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4291 /* Internal speaker is connected to headphone pin */
4292 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4293 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4295 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4296 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4297 /* Ensure all other unused pins are disabled and muted. */
4298 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4300 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4301 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4302 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4303 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4304 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4305 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4306
4307 /* Disable digital (SPDIF) pins */
4308 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4309 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4310
f7ace40d
JW
4311 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4312 * when acting as an output.
4313 */
4314 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4315
f7ace40d 4316 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4321 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4323 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4324 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4325 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4326
f7ace40d
JW
4327 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4328 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4329 /* Unmute Line1 pin widget output buffer since it starts as an output.
4330 * If the pin mode is changed by the user the pin mode control will
4331 * take care of enabling the pin's input/output buffers as needed.
4332 * Therefore there's no need to enable the input buffer at this
4333 * stage.
cdcd9268 4334 */
f7ace40d 4335 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4336 /* Unmute input buffer of pin widget used for Line-in (no equiv
4337 * mixer ctrl)
4338 */
f7ace40d
JW
4339 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4340
4341 /* Mute capture amp left and right */
4342 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4343 /* Set ADC connection select to match default mixer setting - line
4344 * in (on mic1 pin)
4345 */
4346 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4347
4348 /* Do the same for the second ADC: mute capture input amp and
4349 * set ADC connection to line in (on mic1 pin)
4350 */
4351 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4352 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4353
4354 /* Mute all inputs to mixer widget (even unconnected ones) */
4355 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4360 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4363
4364 { }
a9430dd8
JW
4365};
4366
0bfc90e9
JW
4367/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4368 * similar laptops (adapted from Fujitsu init verbs).
4369 */
4370static struct hda_verb alc260_acer_init_verbs[] = {
4371 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4372 * the headphone jack. Turn this on and rely on the standard mute
4373 * methods whenever the user wants to turn these outputs off.
4374 */
4375 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4376 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4377 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4378 /* Internal speaker/Headphone jack is connected to Line-out pin */
4379 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4380 /* Internal microphone/Mic jack is connected to Mic1 pin */
4381 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4382 /* Line In jack is connected to Line1 pin */
4383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4384 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4385 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4386 /* Ensure all other unused pins are disabled and muted. */
4387 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4388 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4389 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4390 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4391 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4392 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4393 /* Disable digital (SPDIF) pins */
4394 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4395 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4396
4397 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4398 * bus when acting as outputs.
4399 */
4400 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4401 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4402
4403 /* Start with output sum widgets muted and their output gains at min */
4404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4406 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4408 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4409 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4410 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4411 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4412 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4413
f12ab1e0
TI
4414 /* Unmute Line-out pin widget amp left and right
4415 * (no equiv mixer ctrl)
4416 */
0bfc90e9 4417 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4418 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4419 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4420 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4421 * inputs. If the pin mode is changed by the user the pin mode control
4422 * will take care of enabling the pin's input/output buffers as needed.
4423 * Therefore there's no need to enable the input buffer at this
4424 * stage.
4425 */
4426 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4427 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4428
4429 /* Mute capture amp left and right */
4430 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4431 /* Set ADC connection select to match default mixer setting - mic
4432 * (on mic1 pin)
4433 */
4434 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4435
4436 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4437 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4438 */
4439 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4440 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4441
4442 /* Mute all inputs to mixer widget (even unconnected ones) */
4443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4445 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4447 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4451
4452 { }
4453};
4454
bc9f98a9
KY
4455static struct hda_verb alc260_will_verbs[] = {
4456 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4457 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4458 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4459 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4460 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4461 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4462 {}
4463};
4464
4465static struct hda_verb alc260_replacer_672v_verbs[] = {
4466 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4467 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4468 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4469
4470 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4471 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4472 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4473
4474 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4475 {}
4476};
4477
4478/* toggle speaker-output according to the hp-jack state */
4479static void alc260_replacer_672v_automute(struct hda_codec *codec)
4480{
4481 unsigned int present;
4482
4483 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4484 present = snd_hda_codec_read(codec, 0x0f, 0,
4485 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4486 if (present) {
82beb8fd
TI
4487 snd_hda_codec_write_cache(codec, 0x01, 0,
4488 AC_VERB_SET_GPIO_DATA, 1);
4489 snd_hda_codec_write_cache(codec, 0x0f, 0,
4490 AC_VERB_SET_PIN_WIDGET_CONTROL,
4491 PIN_HP);
bc9f98a9 4492 } else {
82beb8fd
TI
4493 snd_hda_codec_write_cache(codec, 0x01, 0,
4494 AC_VERB_SET_GPIO_DATA, 0);
4495 snd_hda_codec_write_cache(codec, 0x0f, 0,
4496 AC_VERB_SET_PIN_WIDGET_CONTROL,
4497 PIN_OUT);
bc9f98a9
KY
4498 }
4499}
4500
4501static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4502 unsigned int res)
4503{
4504 if ((res >> 26) == ALC880_HP_EVENT)
4505 alc260_replacer_672v_automute(codec);
4506}
4507
7cf51e48
JW
4508/* Test configuration for debugging, modelled after the ALC880 test
4509 * configuration.
4510 */
4511#ifdef CONFIG_SND_DEBUG
4512static hda_nid_t alc260_test_dac_nids[1] = {
4513 0x02,
4514};
4515static hda_nid_t alc260_test_adc_nids[2] = {
4516 0x04, 0x05,
4517};
a1e8d2da
JW
4518/* For testing the ALC260, each input MUX needs its own definition since
4519 * the signal assignments are different. This assumes that the first ADC
4520 * is NID 0x04.
17e7aec6 4521 */
a1e8d2da
JW
4522static struct hda_input_mux alc260_test_capture_sources[2] = {
4523 {
4524 .num_items = 7,
4525 .items = {
4526 { "MIC1 pin", 0x0 },
4527 { "MIC2 pin", 0x1 },
4528 { "LINE1 pin", 0x2 },
4529 { "LINE2 pin", 0x3 },
4530 { "CD pin", 0x4 },
4531 { "LINE-OUT pin", 0x5 },
4532 { "HP-OUT pin", 0x6 },
4533 },
4534 },
4535 {
4536 .num_items = 8,
4537 .items = {
4538 { "MIC1 pin", 0x0 },
4539 { "MIC2 pin", 0x1 },
4540 { "LINE1 pin", 0x2 },
4541 { "LINE2 pin", 0x3 },
4542 { "CD pin", 0x4 },
4543 { "Mixer", 0x5 },
4544 { "LINE-OUT pin", 0x6 },
4545 { "HP-OUT pin", 0x7 },
4546 },
7cf51e48
JW
4547 },
4548};
4549static struct snd_kcontrol_new alc260_test_mixer[] = {
4550 /* Output driver widgets */
4551 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4552 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4553 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4554 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4555 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4556 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4557
a1e8d2da
JW
4558 /* Modes for retasking pin widgets
4559 * Note: the ALC260 doesn't seem to act on requests to enable mic
4560 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4561 * mention this restriction. At this stage it's not clear whether
4562 * this behaviour is intentional or is a hardware bug in chip
4563 * revisions available at least up until early 2006. Therefore for
4564 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4565 * choices, but if it turns out that the lack of mic bias for these
4566 * NIDs is intentional we could change their modes from
4567 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4568 */
7cf51e48
JW
4569 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4570 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4571 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4572 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4573 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4574 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4575
4576 /* Loopback mixer controls */
4577 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4578 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4579 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4580 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4581 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4582 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4583 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4584 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4585 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4586 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4587 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4588 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4589 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4590 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4591 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4592 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4593
4594 /* Controls for GPIO pins, assuming they are configured as outputs */
4595 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4596 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4597 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4598 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4599
92621f13
JW
4600 /* Switches to allow the digital IO pins to be enabled. The datasheet
4601 * is ambigious as to which NID is which; testing on laptops which
4602 * make this output available should provide clarification.
4603 */
4604 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4605 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4606
f8225f6d
JW
4607 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4608 * this output to turn on an external amplifier.
4609 */
4610 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4611 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4612
7cf51e48
JW
4613 { } /* end */
4614};
4615static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4616 /* Enable all GPIOs as outputs with an initial value of 0 */
4617 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4618 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4619 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4620
7cf51e48
JW
4621 /* Enable retasking pins as output, initially without power amp */
4622 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4623 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4626 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4627 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4628
92621f13
JW
4629 /* Disable digital (SPDIF) pins initially, but users can enable
4630 * them via a mixer switch. In the case of SPDIF-out, this initverb
4631 * payload also sets the generation to 0, output to be in "consumer"
4632 * PCM format, copyright asserted, no pre-emphasis and no validity
4633 * control.
4634 */
7cf51e48
JW
4635 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4636 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4637
f7ace40d 4638 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4639 * OUT1 sum bus when acting as an output.
4640 */
4641 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4642 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4643 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4644 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4645
4646 /* Start with output sum widgets muted and their output gains at min */
4647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4648 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4650 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4651 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4652 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4653 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4654 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4655 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4656
cdcd9268
JW
4657 /* Unmute retasking pin widget output buffers since the default
4658 * state appears to be output. As the pin mode is changed by the
4659 * user the pin mode control will take care of enabling the pin's
4660 * input/output buffers as needed.
4661 */
7cf51e48
JW
4662 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4663 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4666 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4667 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4668 /* Also unmute the mono-out pin widget */
4669 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4670
7cf51e48
JW
4671 /* Mute capture amp left and right */
4672 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4673 /* Set ADC connection select to match default mixer setting (mic1
4674 * pin)
7cf51e48
JW
4675 */
4676 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4677
4678 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4679 * set ADC connection to mic1 pin
7cf51e48
JW
4680 */
4681 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4682 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4683
4684 /* Mute all inputs to mixer widget (even unconnected ones) */
4685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4686 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4693
4694 { }
4695};
4696#endif
4697
6330079f
TI
4698#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4699#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4700
a3bcba38
TI
4701#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4702#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4703
df694daa
KY
4704/*
4705 * for BIOS auto-configuration
4706 */
16ded525 4707
df694daa
KY
4708static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4709 const char *pfx)
4710{
4711 hda_nid_t nid_vol;
4712 unsigned long vol_val, sw_val;
4713 char name[32];
4714 int err;
4715
4716 if (nid >= 0x0f && nid < 0x11) {
4717 nid_vol = nid - 0x7;
4718 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4719 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4720 } else if (nid == 0x11) {
4721 nid_vol = nid - 0x7;
4722 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4723 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4724 } else if (nid >= 0x12 && nid <= 0x15) {
4725 nid_vol = 0x08;
4726 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4727 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4728 } else
4729 return 0; /* N/A */
4730
4731 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4732 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4733 if (err < 0)
df694daa
KY
4734 return err;
4735 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4736 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4737 if (err < 0)
df694daa
KY
4738 return err;
4739 return 1;
4740}
4741
4742/* add playback controls from the parsed DAC table */
4743static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4744 const struct auto_pin_cfg *cfg)
4745{
4746 hda_nid_t nid;
4747 int err;
4748
4749 spec->multiout.num_dacs = 1;
4750 spec->multiout.dac_nids = spec->private_dac_nids;
4751 spec->multiout.dac_nids[0] = 0x02;
4752
4753 nid = cfg->line_out_pins[0];
4754 if (nid) {
4755 err = alc260_add_playback_controls(spec, nid, "Front");
4756 if (err < 0)
4757 return err;
4758 }
4759
82bc955f 4760 nid = cfg->speaker_pins[0];
df694daa
KY
4761 if (nid) {
4762 err = alc260_add_playback_controls(spec, nid, "Speaker");
4763 if (err < 0)
4764 return err;
4765 }
4766
eb06ed8f 4767 nid = cfg->hp_pins[0];
df694daa
KY
4768 if (nid) {
4769 err = alc260_add_playback_controls(spec, nid, "Headphone");
4770 if (err < 0)
4771 return err;
4772 }
f12ab1e0 4773 return 0;
df694daa
KY
4774}
4775
4776/* create playback/capture controls for input pins */
4777static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4778 const struct auto_pin_cfg *cfg)
4779{
df694daa
KY
4780 struct hda_input_mux *imux = &spec->private_imux;
4781 int i, err, idx;
4782
4783 for (i = 0; i < AUTO_PIN_LAST; i++) {
4784 if (cfg->input_pins[i] >= 0x12) {
4785 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4786 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4787 auto_pin_cfg_labels[i], idx,
4788 0x07);
df694daa
KY
4789 if (err < 0)
4790 return err;
f12ab1e0
TI
4791 imux->items[imux->num_items].label =
4792 auto_pin_cfg_labels[i];
df694daa
KY
4793 imux->items[imux->num_items].index = idx;
4794 imux->num_items++;
4795 }
f12ab1e0 4796 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4797 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4798 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4799 auto_pin_cfg_labels[i], idx,
4800 0x07);
df694daa
KY
4801 if (err < 0)
4802 return err;
f12ab1e0
TI
4803 imux->items[imux->num_items].label =
4804 auto_pin_cfg_labels[i];
df694daa
KY
4805 imux->items[imux->num_items].index = idx;
4806 imux->num_items++;
4807 }
4808 }
4809 return 0;
4810}
4811
4812static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4813 hda_nid_t nid, int pin_type,
4814 int sel_idx)
4815{
f6c7e546 4816 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
4817 /* need the manual connection? */
4818 if (nid >= 0x12) {
4819 int idx = nid - 0x12;
4820 snd_hda_codec_write(codec, idx + 0x0b, 0,
4821 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4822 }
4823}
4824
4825static void alc260_auto_init_multi_out(struct hda_codec *codec)
4826{
4827 struct alc_spec *spec = codec->spec;
4828 hda_nid_t nid;
4829
bc9f98a9 4830 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4831 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4832 if (nid) {
4833 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4834 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4835 }
df694daa 4836
82bc955f 4837 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4838 if (nid)
4839 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4840
eb06ed8f 4841 nid = spec->autocfg.hp_pins[0];
df694daa 4842 if (nid)
baba8ee9 4843 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4844}
df694daa
KY
4845
4846#define ALC260_PIN_CD_NID 0x16
4847static void alc260_auto_init_analog_input(struct hda_codec *codec)
4848{
4849 struct alc_spec *spec = codec->spec;
4850 int i;
4851
4852 for (i = 0; i < AUTO_PIN_LAST; i++) {
4853 hda_nid_t nid = spec->autocfg.input_pins[i];
4854 if (nid >= 0x12) {
f12ab1e0
TI
4855 snd_hda_codec_write(codec, nid, 0,
4856 AC_VERB_SET_PIN_WIDGET_CONTROL,
4857 i <= AUTO_PIN_FRONT_MIC ?
4858 PIN_VREF80 : PIN_IN);
df694daa 4859 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4860 snd_hda_codec_write(codec, nid, 0,
4861 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4862 AMP_OUT_MUTE);
4863 }
4864 }
4865}
4866
4867/*
4868 * generic initialization of ADC, input mixers and output mixers
4869 */
4870static struct hda_verb alc260_volume_init_verbs[] = {
4871 /*
4872 * Unmute ADC0-1 and set the default input to mic-in
4873 */
4874 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4875 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4876 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4877 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4878
4879 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4880 * mixer widget
f12ab1e0
TI
4881 * Note: PASD motherboards uses the Line In 2 as the input for
4882 * front panel mic (mic 2)
df694daa
KY
4883 */
4884 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4885 /* mute analog inputs */
4886 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4888 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4889 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4890 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4891
4892 /*
4893 * Set up output mixers (0x08 - 0x0a)
4894 */
4895 /* set vol=0 to output mixers */
4896 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4897 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4898 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4899 /* set up input amps for analog loopback */
4900 /* Amp Indices: DAC = 0, mixer = 1 */
4901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4902 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4905 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4906 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4907
4908 { }
4909};
4910
4911static int alc260_parse_auto_config(struct hda_codec *codec)
4912{
4913 struct alc_spec *spec = codec->spec;
4914 unsigned int wcap;
4915 int err;
4916 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4917
f12ab1e0
TI
4918 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4919 alc260_ignore);
4920 if (err < 0)
df694daa 4921 return err;
f12ab1e0
TI
4922 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4923 if (err < 0)
4a471b7d 4924 return err;
f12ab1e0 4925 if (!spec->kctl_alloc)
df694daa 4926 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4927 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4928 if (err < 0)
df694daa
KY
4929 return err;
4930
4931 spec->multiout.max_channels = 2;
4932
4933 if (spec->autocfg.dig_out_pin)
4934 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4935 if (spec->kctl_alloc)
4936 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4937
4938 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4939
a1e8d2da 4940 spec->num_mux_defs = 1;
df694daa
KY
4941 spec->input_mux = &spec->private_imux;
4942
4943 /* check whether NID 0x04 is valid */
4a471b7d 4944 wcap = get_wcaps(codec, 0x04);
df694daa
KY
4945 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4946 if (wcap != AC_WID_AUD_IN) {
4947 spec->adc_nids = alc260_adc_nids_alt;
4948 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4949 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4950 } else {
4951 spec->adc_nids = alc260_adc_nids;
4952 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4953 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4954 }
4a471b7d 4955 spec->num_mixers++;
df694daa
KY
4956
4957 return 1;
4958}
4959
ae6b813a
TI
4960/* additional initialization for auto-configuration model */
4961static void alc260_auto_init(struct hda_codec *codec)
df694daa 4962{
f6c7e546 4963 struct alc_spec *spec = codec->spec;
df694daa
KY
4964 alc260_auto_init_multi_out(codec);
4965 alc260_auto_init_analog_input(codec);
f6c7e546
TI
4966 if (spec->unsol_event)
4967 alc_sku_automute(codec);
df694daa
KY
4968}
4969
cb53c626
TI
4970#ifdef CONFIG_SND_HDA_POWER_SAVE
4971static struct hda_amp_list alc260_loopbacks[] = {
4972 { 0x07, HDA_INPUT, 0 },
4973 { 0x07, HDA_INPUT, 1 },
4974 { 0x07, HDA_INPUT, 2 },
4975 { 0x07, HDA_INPUT, 3 },
4976 { 0x07, HDA_INPUT, 4 },
4977 { } /* end */
4978};
4979#endif
4980
df694daa
KY
4981/*
4982 * ALC260 configurations
4983 */
f5fcc13c
TI
4984static const char *alc260_models[ALC260_MODEL_LAST] = {
4985 [ALC260_BASIC] = "basic",
4986 [ALC260_HP] = "hp",
4987 [ALC260_HP_3013] = "hp-3013",
4988 [ALC260_FUJITSU_S702X] = "fujitsu",
4989 [ALC260_ACER] = "acer",
bc9f98a9
KY
4990 [ALC260_WILL] = "will",
4991 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 4992#ifdef CONFIG_SND_DEBUG
f5fcc13c 4993 [ALC260_TEST] = "test",
7cf51e48 4994#endif
f5fcc13c
TI
4995 [ALC260_AUTO] = "auto",
4996};
4997
4998static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 4999 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5000 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5001 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5002 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
5003 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5004 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5005 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5006 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5007 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5008 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5009 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5010 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5011 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5012 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5013 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5014 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5015 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5016 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5017 {}
5018};
5019
5020static struct alc_config_preset alc260_presets[] = {
5021 [ALC260_BASIC] = {
5022 .mixers = { alc260_base_output_mixer,
5023 alc260_input_mixer,
5024 alc260_pc_beep_mixer,
5025 alc260_capture_mixer },
5026 .init_verbs = { alc260_init_verbs },
5027 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5028 .dac_nids = alc260_dac_nids,
5029 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5030 .adc_nids = alc260_adc_nids,
5031 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5032 .channel_mode = alc260_modes,
5033 .input_mux = &alc260_capture_source,
5034 },
5035 [ALC260_HP] = {
bec15c3a 5036 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5037 alc260_input_mixer,
5038 alc260_capture_alt_mixer },
bec15c3a
TI
5039 .init_verbs = { alc260_init_verbs,
5040 alc260_hp_unsol_verbs },
df694daa
KY
5041 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5042 .dac_nids = alc260_dac_nids,
5043 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5044 .adc_nids = alc260_hp_adc_nids,
5045 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5046 .channel_mode = alc260_modes,
5047 .input_mux = &alc260_capture_source,
bec15c3a
TI
5048 .unsol_event = alc260_hp_unsol_event,
5049 .init_hook = alc260_hp_automute,
df694daa
KY
5050 },
5051 [ALC260_HP_3013] = {
5052 .mixers = { alc260_hp_3013_mixer,
5053 alc260_input_mixer,
5054 alc260_capture_alt_mixer },
bec15c3a
TI
5055 .init_verbs = { alc260_hp_3013_init_verbs,
5056 alc260_hp_3013_unsol_verbs },
df694daa
KY
5057 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5058 .dac_nids = alc260_dac_nids,
5059 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5060 .adc_nids = alc260_hp_adc_nids,
5061 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5062 .channel_mode = alc260_modes,
5063 .input_mux = &alc260_capture_source,
bec15c3a
TI
5064 .unsol_event = alc260_hp_3013_unsol_event,
5065 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5066 },
5067 [ALC260_FUJITSU_S702X] = {
5068 .mixers = { alc260_fujitsu_mixer,
5069 alc260_capture_mixer },
5070 .init_verbs = { alc260_fujitsu_init_verbs },
5071 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5072 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5073 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5074 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5075 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5076 .channel_mode = alc260_modes,
a1e8d2da
JW
5077 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5078 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5079 },
0bfc90e9
JW
5080 [ALC260_ACER] = {
5081 .mixers = { alc260_acer_mixer,
5082 alc260_capture_mixer },
5083 .init_verbs = { alc260_acer_init_verbs },
5084 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5085 .dac_nids = alc260_dac_nids,
5086 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5087 .adc_nids = alc260_dual_adc_nids,
5088 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5089 .channel_mode = alc260_modes,
a1e8d2da
JW
5090 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5091 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5092 },
bc9f98a9
KY
5093 [ALC260_WILL] = {
5094 .mixers = { alc260_will_mixer,
5095 alc260_capture_mixer },
5096 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5097 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5098 .dac_nids = alc260_dac_nids,
5099 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5100 .adc_nids = alc260_adc_nids,
5101 .dig_out_nid = ALC260_DIGOUT_NID,
5102 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5103 .channel_mode = alc260_modes,
5104 .input_mux = &alc260_capture_source,
5105 },
5106 [ALC260_REPLACER_672V] = {
5107 .mixers = { alc260_replacer_672v_mixer,
5108 alc260_capture_mixer },
5109 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5110 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5111 .dac_nids = alc260_dac_nids,
5112 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5113 .adc_nids = alc260_adc_nids,
5114 .dig_out_nid = ALC260_DIGOUT_NID,
5115 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5116 .channel_mode = alc260_modes,
5117 .input_mux = &alc260_capture_source,
5118 .unsol_event = alc260_replacer_672v_unsol_event,
5119 .init_hook = alc260_replacer_672v_automute,
5120 },
7cf51e48
JW
5121#ifdef CONFIG_SND_DEBUG
5122 [ALC260_TEST] = {
5123 .mixers = { alc260_test_mixer,
5124 alc260_capture_mixer },
5125 .init_verbs = { alc260_test_init_verbs },
5126 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5127 .dac_nids = alc260_test_dac_nids,
5128 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5129 .adc_nids = alc260_test_adc_nids,
5130 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5131 .channel_mode = alc260_modes,
a1e8d2da
JW
5132 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5133 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5134 },
5135#endif
df694daa
KY
5136};
5137
5138static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5139{
5140 struct alc_spec *spec;
df694daa 5141 int err, board_config;
1da177e4 5142
e560d8d8 5143 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5144 if (spec == NULL)
5145 return -ENOMEM;
5146
5147 codec->spec = spec;
5148
f5fcc13c
TI
5149 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5150 alc260_models,
5151 alc260_cfg_tbl);
5152 if (board_config < 0) {
9c7f852e
TI
5153 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5154 "trying auto-probe from BIOS...\n");
df694daa 5155 board_config = ALC260_AUTO;
16ded525 5156 }
1da177e4 5157
df694daa
KY
5158 if (board_config == ALC260_AUTO) {
5159 /* automatic parse from the BIOS config */
5160 err = alc260_parse_auto_config(codec);
5161 if (err < 0) {
5162 alc_free(codec);
5163 return err;
f12ab1e0 5164 } else if (!err) {
9c7f852e
TI
5165 printk(KERN_INFO
5166 "hda_codec: Cannot set up configuration "
5167 "from BIOS. Using base mode...\n");
df694daa
KY
5168 board_config = ALC260_BASIC;
5169 }
a9430dd8 5170 }
e9edcee0 5171
df694daa
KY
5172 if (board_config != ALC260_AUTO)
5173 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5174
5175 spec->stream_name_analog = "ALC260 Analog";
5176 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5177 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5178
a3bcba38
TI
5179 spec->stream_name_digital = "ALC260 Digital";
5180 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5181 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5182
2134ea4f
TI
5183 spec->vmaster_nid = 0x08;
5184
1da177e4 5185 codec->patch_ops = alc_patch_ops;
df694daa 5186 if (board_config == ALC260_AUTO)
ae6b813a 5187 spec->init_hook = alc260_auto_init;
cb53c626
TI
5188#ifdef CONFIG_SND_HDA_POWER_SAVE
5189 if (!spec->loopback.amplist)
5190 spec->loopback.amplist = alc260_loopbacks;
5191#endif
1da177e4
LT
5192
5193 return 0;
5194}
5195
e9edcee0 5196
1da177e4
LT
5197/*
5198 * ALC882 support
5199 *
5200 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5201 * configuration. Each pin widget can choose any input DACs and a mixer.
5202 * Each ADC is connected from a mixer of all inputs. This makes possible
5203 * 6-channel independent captures.
5204 *
5205 * In addition, an independent DAC for the multi-playback (not used in this
5206 * driver yet).
5207 */
df694daa
KY
5208#define ALC882_DIGOUT_NID 0x06
5209#define ALC882_DIGIN_NID 0x0a
1da177e4 5210
d2a6d7dc 5211static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5212 { 8, NULL }
5213};
5214
5215static hda_nid_t alc882_dac_nids[4] = {
5216 /* front, rear, clfe, rear_surr */
5217 0x02, 0x03, 0x04, 0x05
5218};
5219
df694daa
KY
5220/* identical with ALC880 */
5221#define alc882_adc_nids alc880_adc_nids
5222#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5223
e1406348
TI
5224static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5225static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5226
1da177e4
LT
5227/* input MUX */
5228/* FIXME: should be a matrix-type input source selection */
5229
5230static struct hda_input_mux alc882_capture_source = {
5231 .num_items = 4,
5232 .items = {
5233 { "Mic", 0x0 },
5234 { "Front Mic", 0x1 },
5235 { "Line", 0x2 },
5236 { "CD", 0x4 },
5237 },
5238};
1da177e4
LT
5239#define alc882_mux_enum_info alc_mux_enum_info
5240#define alc882_mux_enum_get alc_mux_enum_get
5241
f12ab1e0
TI
5242static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5243 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5244{
5245 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5246 struct alc_spec *spec = codec->spec;
5247 const struct hda_input_mux *imux = spec->input_mux;
5248 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
e1406348 5249 hda_nid_t nid = spec->capsrc_nids[adc_idx];
1da177e4
LT
5250 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5251 unsigned int i, idx;
5252
5253 idx = ucontrol->value.enumerated.item[0];
5254 if (idx >= imux->num_items)
5255 idx = imux->num_items - 1;
82beb8fd 5256 if (*cur_val == idx)
1da177e4
LT
5257 return 0;
5258 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5259 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5260 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5261 imux->items[i].index,
47fd830a 5262 HDA_AMP_MUTE, v);
1da177e4
LT
5263 }
5264 *cur_val = idx;
5265 return 1;
5266}
5267
272a527c
KY
5268/*
5269 * 2ch mode
5270 */
5271static struct hda_verb alc882_3ST_ch2_init[] = {
5272 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5273 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5274 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5275 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5276 { } /* end */
5277};
5278
5279/*
5280 * 6ch mode
5281 */
5282static struct hda_verb alc882_3ST_ch6_init[] = {
5283 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5284 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5285 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5286 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5287 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5288 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5289 { } /* end */
5290};
5291
5292static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5293 { 2, alc882_3ST_ch2_init },
5294 { 6, alc882_3ST_ch6_init },
5295};
5296
df694daa
KY
5297/*
5298 * 6ch mode
5299 */
5300static struct hda_verb alc882_sixstack_ch6_init[] = {
5301 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5302 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5303 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5304 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5305 { } /* end */
5306};
5307
5308/*
5309 * 8ch mode
5310 */
5311static struct hda_verb alc882_sixstack_ch8_init[] = {
5312 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5313 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5314 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5315 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5316 { } /* end */
5317};
5318
5319static struct hda_channel_mode alc882_sixstack_modes[2] = {
5320 { 6, alc882_sixstack_ch6_init },
5321 { 8, alc882_sixstack_ch8_init },
5322};
5323
87350ad0
TI
5324/*
5325 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5326 */
5327
5328/*
5329 * 2ch mode
5330 */
5331static struct hda_verb alc885_mbp_ch2_init[] = {
5332 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5333 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5334 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5335 { } /* end */
5336};
5337
5338/*
5339 * 6ch mode
5340 */
5341static struct hda_verb alc885_mbp_ch6_init[] = {
5342 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5343 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5344 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5345 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5346 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5347 { } /* end */
5348};
5349
5350static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5351 { 2, alc885_mbp_ch2_init },
5352 { 6, alc885_mbp_ch6_init },
5353};
5354
5355
1da177e4
LT
5356/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5357 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5358 */
c8b6bf9b 5359static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5360 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5361 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5362 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5363 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5364 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5365 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5366 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5367 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5368 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5369 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5370 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5371 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5372 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5373 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5374 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5376 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5377 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5379 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5380 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5381 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5382 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5383 { } /* end */
5384};
5385
87350ad0 5386static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5387 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5388 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5389 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5390 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5392 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5394 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5395 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5396 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5397 { } /* end */
5398};
bdd148a3
KY
5399static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5400 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5404 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5405 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5407 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5409 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5410 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5411 { } /* end */
5412};
5413
272a527c
KY
5414static struct snd_kcontrol_new alc882_targa_mixer[] = {
5415 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5416 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5417 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5418 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5419 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5424 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5425 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5426 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5427 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5428 { } /* end */
5429};
5430
5431/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5432 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5433 */
5434static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5436 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5438 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5441 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5442 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5443 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5444 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5446 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5447 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5448 { } /* end */
5449};
5450
914759b7
TI
5451static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5453 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5455 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5456 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5460 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5462 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5463 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5464 { } /* end */
5465};
5466
df694daa
KY
5467static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5468 {
5469 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5470 .name = "Channel Mode",
5471 .info = alc_ch_mode_info,
5472 .get = alc_ch_mode_get,
5473 .put = alc_ch_mode_put,
5474 },
5475 { } /* end */
5476};
5477
1da177e4
LT
5478static struct hda_verb alc882_init_verbs[] = {
5479 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5482 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5483 /* Rear mixer */
05acb863
TI
5484 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5487 /* CLFE mixer */
05acb863
TI
5488 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5491 /* Side mixer */
05acb863
TI
5492 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5493 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5494 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5495
e9edcee0 5496 /* Front Pin: output 0 (0x0c) */
05acb863 5497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5499 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5500 /* Rear Pin: output 1 (0x0d) */
05acb863 5501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5502 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5503 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5504 /* CLFE Pin: output 2 (0x0e) */
05acb863 5505 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5507 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5508 /* Side Pin: output 3 (0x0f) */
05acb863 5509 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5510 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5511 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5512 /* Mic (rear) pin: input vref at 80% */
16ded525 5513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5515 /* Front Mic pin: input vref at 80% */
16ded525 5516 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5517 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5518 /* Line In pin: input */
05acb863 5519 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5521 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5522 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5523 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5524 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5525 /* CD pin widget for input */
05acb863 5526 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5527
5528 /* FIXME: use matrix-type input source selection */
5529 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5530 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5533 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5534 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5535 /* Input mixer2 */
05acb863
TI
5536 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5539 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5540 /* Input mixer3 */
05acb863
TI
5541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5544 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5545 /* ADC1: mute amp left and right */
5546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5547 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5548 /* ADC2: mute amp left and right */
5549 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5550 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5551 /* ADC3: mute amp left and right */
5552 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5553 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5554
5555 { }
5556};
5557
4b146cb0
TI
5558static struct hda_verb alc882_eapd_verbs[] = {
5559 /* change to EAPD mode */
5560 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5561 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5562 { }
4b146cb0
TI
5563};
5564
9102cd1c
TD
5565/* Mac Pro test */
5566static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5567 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5568 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5570 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5571 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5572 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5573 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5574 { } /* end */
5575};
5576
5577static struct hda_verb alc882_macpro_init_verbs[] = {
5578 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5582 /* Front Pin: output 0 (0x0c) */
5583 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5586 /* Front Mic pin: input vref at 80% */
5587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5589 /* Speaker: output */
5590 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5592 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5593 /* Headphone output (output 0 - 0x0c) */
5594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5596 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5597
5598 /* FIXME: use matrix-type input source selection */
5599 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5600 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5605 /* Input mixer2 */
5606 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5608 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5609 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5610 /* Input mixer3 */
5611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5614 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5615 /* ADC1: mute amp left and right */
5616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5617 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5618 /* ADC2: mute amp left and right */
5619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5621 /* ADC3: mute amp left and right */
5622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5623 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5624
5625 { }
5626};
f12ab1e0 5627
87350ad0
TI
5628/* Macbook Pro rev3 */
5629static struct hda_verb alc885_mbp3_init_verbs[] = {
5630 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5631 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5634 /* Rear mixer */
5635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5638 /* Front Pin: output 0 (0x0c) */
5639 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5640 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5641 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5642 /* HP Pin: output 0 (0x0d) */
5643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5645 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5646 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5647 /* Mic (rear) pin: input vref at 80% */
5648 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5649 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5650 /* Front Mic pin: input vref at 80% */
5651 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5652 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5653 /* Line In pin: use output 1 when in LineOut mode */
5654 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5655 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5656 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5657
5658 /* FIXME: use matrix-type input source selection */
5659 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5660 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5662 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5665 /* Input mixer2 */
5666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5667 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5670 /* Input mixer3 */
5671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5675 /* ADC1: mute amp left and right */
5676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5677 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5678 /* ADC2: mute amp left and right */
5679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5680 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5681 /* ADC3: mute amp left and right */
5682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5683 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5684
5685 { }
5686};
5687
c54728d8
NF
5688/* iMac 24 mixer. */
5689static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5690 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5691 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5692 { } /* end */
5693};
5694
5695/* iMac 24 init verbs. */
5696static struct hda_verb alc885_imac24_init_verbs[] = {
5697 /* Internal speakers: output 0 (0x0c) */
5698 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5700 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5701 /* Internal speakers: output 0 (0x0c) */
5702 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5703 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5705 /* Headphone: output 0 (0x0c) */
5706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5708 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5709 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5710 /* Front Mic: input vref at 80% */
5711 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5713 { }
5714};
5715
5716/* Toggle speaker-output according to the hp-jack state */
5717static void alc885_imac24_automute(struct hda_codec *codec)
5718{
5719 unsigned int present;
5720
5721 present = snd_hda_codec_read(codec, 0x14, 0,
5722 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5723 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5724 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5725 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5726 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5727}
5728
5729/* Processes unsolicited events. */
5730static void alc885_imac24_unsol_event(struct hda_codec *codec,
5731 unsigned int res)
5732{
5733 /* Headphone insertion or removal. */
5734 if ((res >> 26) == ALC880_HP_EVENT)
5735 alc885_imac24_automute(codec);
5736}
5737
87350ad0
TI
5738static void alc885_mbp3_automute(struct hda_codec *codec)
5739{
5740 unsigned int present;
5741
5742 present = snd_hda_codec_read(codec, 0x15, 0,
5743 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5745 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5746 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5747 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5748
5749}
5750static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5751 unsigned int res)
5752{
5753 /* Headphone insertion or removal. */
5754 if ((res >> 26) == ALC880_HP_EVENT)
5755 alc885_mbp3_automute(codec);
5756}
5757
5758
272a527c
KY
5759static struct hda_verb alc882_targa_verbs[] = {
5760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5762
5763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5765
5766 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5767 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5768 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5769
5770 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5771 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5772 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5773 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5774 { } /* end */
5775};
5776
5777/* toggle speaker-output according to the hp-jack state */
5778static void alc882_targa_automute(struct hda_codec *codec)
5779{
5780 unsigned int present;
5781
5782 present = snd_hda_codec_read(codec, 0x14, 0,
5783 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5784 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5785 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5786 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5787 present ? 1 : 3);
272a527c
KY
5788}
5789
5790static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5791{
5792 /* Looks like the unsol event is incompatible with the standard
5793 * definition. 4bit tag is placed at 26 bit!
5794 */
5795 if (((res >> 26) == ALC880_HP_EVENT)) {
5796 alc882_targa_automute(codec);
5797 }
5798}
5799
5800static struct hda_verb alc882_asus_a7j_verbs[] = {
5801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5803
5804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5806 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5807
5808 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5809 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5810 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5811
5812 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5813 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5814 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5815 { } /* end */
5816};
5817
914759b7
TI
5818static struct hda_verb alc882_asus_a7m_verbs[] = {
5819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5821
5822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5823 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5824 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5825
5826 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5828 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5829
5830 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5831 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5832 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5833 { } /* end */
5834};
5835
9102cd1c
TD
5836static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5837{
5838 unsigned int gpiostate, gpiomask, gpiodir;
5839
5840 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5841 AC_VERB_GET_GPIO_DATA, 0);
5842
5843 if (!muted)
5844 gpiostate |= (1 << pin);
5845 else
5846 gpiostate &= ~(1 << pin);
5847
5848 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5849 AC_VERB_GET_GPIO_MASK, 0);
5850 gpiomask |= (1 << pin);
5851
5852 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5853 AC_VERB_GET_GPIO_DIRECTION, 0);
5854 gpiodir |= (1 << pin);
5855
5856
5857 snd_hda_codec_write(codec, codec->afg, 0,
5858 AC_VERB_SET_GPIO_MASK, gpiomask);
5859 snd_hda_codec_write(codec, codec->afg, 0,
5860 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5861
5862 msleep(1);
5863
5864 snd_hda_codec_write(codec, codec->afg, 0,
5865 AC_VERB_SET_GPIO_DATA, gpiostate);
5866}
5867
7debbe51
TI
5868/* set up GPIO at initialization */
5869static void alc885_macpro_init_hook(struct hda_codec *codec)
5870{
5871 alc882_gpio_mute(codec, 0, 0);
5872 alc882_gpio_mute(codec, 1, 0);
5873}
5874
5875/* set up GPIO and update auto-muting at initialization */
5876static void alc885_imac24_init_hook(struct hda_codec *codec)
5877{
5878 alc885_macpro_init_hook(codec);
5879 alc885_imac24_automute(codec);
5880}
5881
df694daa
KY
5882/*
5883 * generic initialization of ADC, input mixers and output mixers
5884 */
5885static struct hda_verb alc882_auto_init_verbs[] = {
5886 /*
5887 * Unmute ADC0-2 and set the default input to mic-in
5888 */
5889 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5890 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5891 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5893 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5894 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5895
cb53c626 5896 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5897 * mixer widget
f12ab1e0
TI
5898 * Note: PASD motherboards uses the Line In 2 as the input for
5899 * front panel mic (mic 2)
df694daa
KY
5900 */
5901 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5903 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5904 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5905 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5906 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5907
df694daa
KY
5908 /*
5909 * Set up output mixers (0x0c - 0x0f)
5910 */
5911 /* set vol=0 to output mixers */
5912 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5913 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5914 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5915 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5916 /* set up input amps for analog loopback */
5917 /* Amp Indices: DAC = 0, mixer = 1 */
5918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5920 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5921 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5922 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5923 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5925 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5926 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5927 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5928
5929 /* FIXME: use matrix-type input source selection */
5930 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5931 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5932 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5933 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5934 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5935 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5936 /* Input mixer2 */
5937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5940 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5941 /* Input mixer3 */
5942 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5943 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5944 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5946
5947 { }
5948};
5949
5950/* capture mixer elements */
5951static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5952 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5953 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5954 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5955 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5956 {
5957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5958 /* The multiple "Capture Source" controls confuse alsamixer
5959 * So call somewhat different..
df694daa
KY
5960 */
5961 /* .name = "Capture Source", */
5962 .name = "Input Source",
5963 .count = 2,
5964 .info = alc882_mux_enum_info,
5965 .get = alc882_mux_enum_get,
5966 .put = alc882_mux_enum_put,
5967 },
5968 { } /* end */
5969};
5970
5971static struct snd_kcontrol_new alc882_capture_mixer[] = {
5972 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5973 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5974 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5975 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5976 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5977 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5978 {
5979 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5980 /* The multiple "Capture Source" controls confuse alsamixer
5981 * So call somewhat different..
df694daa
KY
5982 */
5983 /* .name = "Capture Source", */
5984 .name = "Input Source",
5985 .count = 3,
5986 .info = alc882_mux_enum_info,
5987 .get = alc882_mux_enum_get,
5988 .put = alc882_mux_enum_put,
5989 },
5990 { } /* end */
5991};
5992
cb53c626
TI
5993#ifdef CONFIG_SND_HDA_POWER_SAVE
5994#define alc882_loopbacks alc880_loopbacks
5995#endif
5996
df694daa
KY
5997/* pcm configuration: identiacal with ALC880 */
5998#define alc882_pcm_analog_playback alc880_pcm_analog_playback
5999#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6000#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6001#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6002
6003/*
6004 * configuration and preset
6005 */
f5fcc13c
TI
6006static const char *alc882_models[ALC882_MODEL_LAST] = {
6007 [ALC882_3ST_DIG] = "3stack-dig",
6008 [ALC882_6ST_DIG] = "6stack-dig",
6009 [ALC882_ARIMA] = "arima",
bdd148a3 6010 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6011 [ALC882_TARGA] = "targa",
6012 [ALC882_ASUS_A7J] = "asus-a7j",
6013 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6014 [ALC885_MACPRO] = "macpro",
87350ad0 6015 [ALC885_MBP3] = "mbp3",
c54728d8 6016 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6017 [ALC882_AUTO] = "auto",
6018};
6019
6020static struct snd_pci_quirk alc882_cfg_tbl[] = {
6021 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6022 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6023 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6024 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6025 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6026 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6027 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6028 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6029 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6030 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6031 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6032 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6033 {}
6034};
6035
6036static struct alc_config_preset alc882_presets[] = {
6037 [ALC882_3ST_DIG] = {
6038 .mixers = { alc882_base_mixer },
6039 .init_verbs = { alc882_init_verbs },
6040 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6041 .dac_nids = alc882_dac_nids,
6042 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6043 .dig_in_nid = ALC882_DIGIN_NID,
6044 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6045 .channel_mode = alc882_ch_modes,
4e195a7b 6046 .need_dac_fix = 1,
df694daa
KY
6047 .input_mux = &alc882_capture_source,
6048 },
6049 [ALC882_6ST_DIG] = {
6050 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6051 .init_verbs = { alc882_init_verbs },
6052 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6053 .dac_nids = alc882_dac_nids,
6054 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6055 .dig_in_nid = ALC882_DIGIN_NID,
6056 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6057 .channel_mode = alc882_sixstack_modes,
6058 .input_mux = &alc882_capture_source,
6059 },
4b146cb0
TI
6060 [ALC882_ARIMA] = {
6061 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6062 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6063 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6064 .dac_nids = alc882_dac_nids,
6065 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6066 .channel_mode = alc882_sixstack_modes,
6067 .input_mux = &alc882_capture_source,
6068 },
bdd148a3
KY
6069 [ALC882_W2JC] = {
6070 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6071 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6072 alc880_gpio1_init_verbs },
6073 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6074 .dac_nids = alc882_dac_nids,
6075 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6076 .channel_mode = alc880_threestack_modes,
6077 .need_dac_fix = 1,
6078 .input_mux = &alc882_capture_source,
6079 .dig_out_nid = ALC882_DIGOUT_NID,
6080 },
87350ad0
TI
6081 [ALC885_MBP3] = {
6082 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6083 .init_verbs = { alc885_mbp3_init_verbs,
6084 alc880_gpio1_init_verbs },
6085 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6086 .dac_nids = alc882_dac_nids,
6087 .channel_mode = alc885_mbp_6ch_modes,
6088 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6089 .input_mux = &alc882_capture_source,
6090 .dig_out_nid = ALC882_DIGOUT_NID,
6091 .dig_in_nid = ALC882_DIGIN_NID,
6092 .unsol_event = alc885_mbp3_unsol_event,
6093 .init_hook = alc885_mbp3_automute,
6094 },
9102cd1c
TD
6095 [ALC885_MACPRO] = {
6096 .mixers = { alc882_macpro_mixer },
6097 .init_verbs = { alc882_macpro_init_verbs },
6098 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6099 .dac_nids = alc882_dac_nids,
6100 .dig_out_nid = ALC882_DIGOUT_NID,
6101 .dig_in_nid = ALC882_DIGIN_NID,
6102 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6103 .channel_mode = alc882_ch_modes,
6104 .input_mux = &alc882_capture_source,
7debbe51 6105 .init_hook = alc885_macpro_init_hook,
9102cd1c 6106 },
c54728d8
NF
6107 [ALC885_IMAC24] = {
6108 .mixers = { alc885_imac24_mixer },
6109 .init_verbs = { alc885_imac24_init_verbs },
6110 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6111 .dac_nids = alc882_dac_nids,
6112 .dig_out_nid = ALC882_DIGOUT_NID,
6113 .dig_in_nid = ALC882_DIGIN_NID,
6114 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6115 .channel_mode = alc882_ch_modes,
6116 .input_mux = &alc882_capture_source,
6117 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6118 .init_hook = alc885_imac24_init_hook,
c54728d8 6119 },
272a527c
KY
6120 [ALC882_TARGA] = {
6121 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6122 alc882_capture_mixer },
6123 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6124 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6125 .dac_nids = alc882_dac_nids,
6126 .dig_out_nid = ALC882_DIGOUT_NID,
6127 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6128 .adc_nids = alc882_adc_nids,
e1406348 6129 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6130 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6131 .channel_mode = alc882_3ST_6ch_modes,
6132 .need_dac_fix = 1,
6133 .input_mux = &alc882_capture_source,
6134 .unsol_event = alc882_targa_unsol_event,
6135 .init_hook = alc882_targa_automute,
6136 },
6137 [ALC882_ASUS_A7J] = {
6138 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6139 alc882_capture_mixer },
6140 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6141 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6142 .dac_nids = alc882_dac_nids,
6143 .dig_out_nid = ALC882_DIGOUT_NID,
6144 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6145 .adc_nids = alc882_adc_nids,
e1406348 6146 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6147 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6148 .channel_mode = alc882_3ST_6ch_modes,
6149 .need_dac_fix = 1,
6150 .input_mux = &alc882_capture_source,
6151 },
914759b7
TI
6152 [ALC882_ASUS_A7M] = {
6153 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6154 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6155 alc880_gpio1_init_verbs,
6156 alc882_asus_a7m_verbs },
6157 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6158 .dac_nids = alc882_dac_nids,
6159 .dig_out_nid = ALC882_DIGOUT_NID,
6160 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6161 .channel_mode = alc880_threestack_modes,
6162 .need_dac_fix = 1,
6163 .input_mux = &alc882_capture_source,
6164 },
df694daa
KY
6165};
6166
6167
f95474ec
TI
6168/*
6169 * Pin config fixes
6170 */
6171enum {
6172 PINFIX_ABIT_AW9D_MAX
6173};
6174
6175static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6176 { 0x15, 0x01080104 }, /* side */
6177 { 0x16, 0x01011012 }, /* rear */
6178 { 0x17, 0x01016011 }, /* clfe */
6179 { }
6180};
6181
6182static const struct alc_pincfg *alc882_pin_fixes[] = {
6183 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6184};
6185
6186static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6187 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6188 {}
6189};
6190
df694daa
KY
6191/*
6192 * BIOS auto configuration
6193 */
6194static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6195 hda_nid_t nid, int pin_type,
6196 int dac_idx)
6197{
6198 /* set as output */
6199 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6200 int idx;
6201
f6c7e546 6202 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6203 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6204 idx = 4;
6205 else
6206 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6207 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6208
6209}
6210
6211static void alc882_auto_init_multi_out(struct hda_codec *codec)
6212{
6213 struct alc_spec *spec = codec->spec;
6214 int i;
6215
bc9f98a9 6216 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6217 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6218 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6219 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6220 if (nid)
baba8ee9 6221 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6222 i);
df694daa
KY
6223 }
6224}
6225
6226static void alc882_auto_init_hp_out(struct hda_codec *codec)
6227{
6228 struct alc_spec *spec = codec->spec;
6229 hda_nid_t pin;
6230
eb06ed8f 6231 pin = spec->autocfg.hp_pins[0];
df694daa 6232 if (pin) /* connect to front */
f12ab1e0
TI
6233 /* use dac 0 */
6234 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6235 pin = spec->autocfg.speaker_pins[0];
6236 if (pin)
6237 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6238}
6239
6240#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6241#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6242
6243static void alc882_auto_init_analog_input(struct hda_codec *codec)
6244{
6245 struct alc_spec *spec = codec->spec;
6246 int i;
6247
6248 for (i = 0; i < AUTO_PIN_LAST; i++) {
6249 hda_nid_t nid = spec->autocfg.input_pins[i];
6250 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6251 snd_hda_codec_write(codec, nid, 0,
6252 AC_VERB_SET_PIN_WIDGET_CONTROL,
6253 i <= AUTO_PIN_FRONT_MIC ?
6254 PIN_VREF80 : PIN_IN);
df694daa 6255 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6256 snd_hda_codec_write(codec, nid, 0,
6257 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6258 AMP_OUT_MUTE);
6259 }
6260 }
6261}
6262
776e184e
TI
6263/* add mic boosts if needed */
6264static int alc_auto_add_mic_boost(struct hda_codec *codec)
6265{
6266 struct alc_spec *spec = codec->spec;
6267 int err;
6268 hda_nid_t nid;
6269
6270 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6271 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6272 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6273 "Mic Boost",
6274 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6275 if (err < 0)
6276 return err;
6277 }
6278 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6279 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6280 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6281 "Front Mic Boost",
6282 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6283 if (err < 0)
6284 return err;
6285 }
6286 return 0;
6287}
6288
df694daa
KY
6289/* almost identical with ALC880 parser... */
6290static int alc882_parse_auto_config(struct hda_codec *codec)
6291{
6292 struct alc_spec *spec = codec->spec;
6293 int err = alc880_parse_auto_config(codec);
6294
6295 if (err < 0)
6296 return err;
776e184e
TI
6297 else if (!err)
6298 return 0; /* no config found */
6299
6300 err = alc_auto_add_mic_boost(codec);
6301 if (err < 0)
6302 return err;
6303
6304 /* hack - override the init verbs */
6305 spec->init_verbs[0] = alc882_auto_init_verbs;
6306
6307 return 1; /* config found */
df694daa
KY
6308}
6309
ae6b813a
TI
6310/* additional initialization for auto-configuration model */
6311static void alc882_auto_init(struct hda_codec *codec)
df694daa 6312{
f6c7e546 6313 struct alc_spec *spec = codec->spec;
df694daa
KY
6314 alc882_auto_init_multi_out(codec);
6315 alc882_auto_init_hp_out(codec);
6316 alc882_auto_init_analog_input(codec);
f6c7e546
TI
6317 if (spec->unsol_event)
6318 alc_sku_automute(codec);
df694daa
KY
6319}
6320
df694daa
KY
6321static int patch_alc882(struct hda_codec *codec)
6322{
6323 struct alc_spec *spec;
6324 int err, board_config;
6325
6326 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6327 if (spec == NULL)
6328 return -ENOMEM;
6329
6330 codec->spec = spec;
6331
f5fcc13c
TI
6332 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6333 alc882_models,
6334 alc882_cfg_tbl);
df694daa
KY
6335
6336 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6337 /* Pick up systems that don't supply PCI SSID */
6338 switch (codec->subsystem_id) {
6339 case 0x106b0c00: /* Mac Pro */
6340 board_config = ALC885_MACPRO;
6341 break;
c54728d8
NF
6342 case 0x106b1000: /* iMac 24 */
6343 board_config = ALC885_IMAC24;
6344 break;
3d5fa2e5 6345 case 0x106b00a1: /* Macbook */
87350ad0
TI
6346 case 0x106b2c00: /* Macbook Pro rev3 */
6347 board_config = ALC885_MBP3;
6348 break;
081d17c4
TD
6349 default:
6350 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6351 "trying auto-probe from BIOS...\n");
6352 board_config = ALC882_AUTO;
6353 }
df694daa
KY
6354 }
6355
f95474ec
TI
6356 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6357
df694daa
KY
6358 if (board_config == ALC882_AUTO) {
6359 /* automatic parse from the BIOS config */
6360 err = alc882_parse_auto_config(codec);
6361 if (err < 0) {
6362 alc_free(codec);
6363 return err;
f12ab1e0 6364 } else if (!err) {
9c7f852e
TI
6365 printk(KERN_INFO
6366 "hda_codec: Cannot set up configuration "
6367 "from BIOS. Using base mode...\n");
df694daa
KY
6368 board_config = ALC882_3ST_DIG;
6369 }
6370 }
6371
6372 if (board_config != ALC882_AUTO)
6373 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6374
6375 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6376 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6377 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6378 /* FIXME: setup DAC5 */
6379 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6380 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
6381
6382 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6383 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6384 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6385
f12ab1e0 6386 if (!spec->adc_nids && spec->input_mux) {
df694daa 6387 /* check whether NID 0x07 is valid */
4a471b7d 6388 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6389 /* get type */
6390 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6391 if (wcap != AC_WID_AUD_IN) {
6392 spec->adc_nids = alc882_adc_nids_alt;
6393 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6394 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6395 spec->mixers[spec->num_mixers] =
6396 alc882_capture_alt_mixer;
df694daa
KY
6397 spec->num_mixers++;
6398 } else {
6399 spec->adc_nids = alc882_adc_nids;
6400 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6401 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6402 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6403 spec->num_mixers++;
6404 }
6405 }
1da177e4 6406
2134ea4f
TI
6407 spec->vmaster_nid = 0x0c;
6408
1da177e4 6409 codec->patch_ops = alc_patch_ops;
df694daa 6410 if (board_config == ALC882_AUTO)
ae6b813a 6411 spec->init_hook = alc882_auto_init;
cb53c626
TI
6412#ifdef CONFIG_SND_HDA_POWER_SAVE
6413 if (!spec->loopback.amplist)
6414 spec->loopback.amplist = alc882_loopbacks;
6415#endif
df694daa
KY
6416
6417 return 0;
6418}
6419
6420/*
9c7f852e
TI
6421 * ALC883 support
6422 *
6423 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6424 * configuration. Each pin widget can choose any input DACs and a mixer.
6425 * Each ADC is connected from a mixer of all inputs. This makes possible
6426 * 6-channel independent captures.
6427 *
6428 * In addition, an independent DAC for the multi-playback (not used in this
6429 * driver yet).
df694daa 6430 */
9c7f852e
TI
6431#define ALC883_DIGOUT_NID 0x06
6432#define ALC883_DIGIN_NID 0x0a
df694daa 6433
9c7f852e
TI
6434static hda_nid_t alc883_dac_nids[4] = {
6435 /* front, rear, clfe, rear_surr */
6436 0x02, 0x04, 0x03, 0x05
6437};
df694daa 6438
9c7f852e
TI
6439static hda_nid_t alc883_adc_nids[2] = {
6440 /* ADC1-2 */
6441 0x08, 0x09,
6442};
f12ab1e0 6443
e1406348
TI
6444static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6445
9c7f852e
TI
6446/* input MUX */
6447/* FIXME: should be a matrix-type input source selection */
df694daa 6448
9c7f852e
TI
6449static struct hda_input_mux alc883_capture_source = {
6450 .num_items = 4,
6451 .items = {
6452 { "Mic", 0x0 },
6453 { "Front Mic", 0x1 },
6454 { "Line", 0x2 },
6455 { "CD", 0x4 },
6456 },
6457};
bc9f98a9
KY
6458
6459static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6460 .num_items = 2,
6461 .items = {
6462 { "Mic", 0x1 },
6463 { "Line", 0x2 },
6464 },
6465};
6466
272a527c
KY
6467static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6468 .num_items = 4,
6469 .items = {
6470 { "Mic", 0x0 },
6471 { "iMic", 0x1 },
6472 { "Line", 0x2 },
6473 { "CD", 0x4 },
6474 },
6475};
6476
9c7f852e
TI
6477#define alc883_mux_enum_info alc_mux_enum_info
6478#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6479/* ALC883 has the ALC882-type input selection */
6480#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6481
9c7f852e
TI
6482/*
6483 * 2ch mode
6484 */
6485static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6486 { 2, NULL }
6487};
6488
6489/*
6490 * 2ch mode
6491 */
6492static struct hda_verb alc883_3ST_ch2_init[] = {
6493 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6494 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6495 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6496 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6497 { } /* end */
6498};
6499
b201131c
TD
6500/*
6501 * 4ch mode
6502 */
6503static struct hda_verb alc883_3ST_ch4_init[] = {
6504 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6505 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6506 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6507 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6508 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6509 { } /* end */
6510};
6511
9c7f852e
TI
6512/*
6513 * 6ch mode
6514 */
6515static struct hda_verb alc883_3ST_ch6_init[] = {
6516 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6517 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6518 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6521 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6522 { } /* end */
6523};
6524
b201131c 6525static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6526 { 2, alc883_3ST_ch2_init },
b201131c 6527 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6528 { 6, alc883_3ST_ch6_init },
6529};
6530
6531/*
6532 * 6ch mode
6533 */
6534static struct hda_verb alc883_sixstack_ch6_init[] = {
6535 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6536 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6537 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6538 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6539 { } /* end */
6540};
6541
6542/*
6543 * 8ch mode
6544 */
6545static struct hda_verb alc883_sixstack_ch8_init[] = {
6546 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6547 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6548 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6549 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6550 { } /* end */
6551};
6552
6553static struct hda_channel_mode alc883_sixstack_modes[2] = {
6554 { 6, alc883_sixstack_ch6_init },
6555 { 8, alc883_sixstack_ch8_init },
6556};
6557
b373bdeb
AN
6558static struct hda_verb alc883_medion_eapd_verbs[] = {
6559 /* eanable EAPD on medion laptop */
6560 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6561 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6562 { }
6563};
6564
9c7f852e
TI
6565/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6566 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6567 */
6568
6569static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6570 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6571 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6572 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6573 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6574 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6575 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6576 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6577 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6578 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6579 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6580 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6586 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6589 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6590 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6591 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6592 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6593 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6594 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6595 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6596 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6597 {
6598 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6599 /* .name = "Capture Source", */
6600 .name = "Input Source",
6601 .count = 2,
6602 .info = alc883_mux_enum_info,
6603 .get = alc883_mux_enum_get,
6604 .put = alc883_mux_enum_put,
6605 },
df694daa 6606 { } /* end */
834be88d
TI
6607};
6608
a8848bd6
AS
6609static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6610 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6611 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6612 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6613 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6614 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6615 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6618 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6619 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6620 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6621 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6622 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6623 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6624 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6625 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6626 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6627 {
6628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6629 /* .name = "Capture Source", */
6630 .name = "Input Source",
6631 .count = 2,
6632 .info = alc883_mux_enum_info,
6633 .get = alc883_mux_enum_get,
6634 .put = alc883_mux_enum_put,
6635 },
6636 { } /* end */
6637};
6638
9c7f852e
TI
6639static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6640 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6641 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6642 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6648 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6651 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6652 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6653 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6654 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6655 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6656 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6657 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6658 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6659 {
6660 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6661 /* .name = "Capture Source", */
6662 .name = "Input Source",
6663 .count = 2,
6664 .info = alc883_mux_enum_info,
6665 .get = alc883_mux_enum_get,
6666 .put = alc883_mux_enum_put,
6667 },
6668 { } /* end */
6669};
df694daa 6670
9c7f852e
TI
6671static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6672 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6673 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6674 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6675 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6676 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6677 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6678 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6679 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6683 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6684 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6689 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6691 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6692 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6693 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6694 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6695 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6696 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6697 {
6698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6699 /* .name = "Capture Source", */
6700 .name = "Input Source",
6701 .count = 2,
6702 .info = alc883_mux_enum_info,
6703 .get = alc883_mux_enum_get,
6704 .put = alc883_mux_enum_put,
6705 },
6706 { } /* end */
6707};
6708
d1d985f0 6709static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6710 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6711 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6712 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6713 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6716 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6717 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6719 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6720 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6724 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6725 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6727 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6728 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6729 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6730 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6731 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6732 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6733
6734 {
6735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6736 /* .name = "Capture Source", */
6737 .name = "Input Source",
6738 .count = 1,
6739 .info = alc883_mux_enum_info,
6740 .get = alc883_mux_enum_get,
6741 .put = alc883_mux_enum_put,
6742 },
6743 { } /* end */
6744};
6745
ccc656ce
KY
6746static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6747 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6748 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6749 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6750 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6751 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6752 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6753 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6754 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6755 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6758 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6759 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6760 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6761 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6762 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6763 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6764 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6765 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6766 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6767 {
6768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6769 /* .name = "Capture Source", */
6770 .name = "Input Source",
6771 .count = 2,
6772 .info = alc883_mux_enum_info,
6773 .get = alc883_mux_enum_get,
6774 .put = alc883_mux_enum_put,
6775 },
6776 { } /* end */
f12ab1e0 6777};
ccc656ce
KY
6778
6779static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6780 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6782 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6783 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6784 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6786 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6787 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6788 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6789 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6790 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6791 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6792 {
6793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6794 /* .name = "Capture Source", */
6795 .name = "Input Source",
6796 .count = 2,
6797 .info = alc883_mux_enum_info,
6798 .get = alc883_mux_enum_get,
6799 .put = alc883_mux_enum_put,
6800 },
6801 { } /* end */
f12ab1e0 6802};
ccc656ce 6803
bc9f98a9
KY
6804static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6805 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6806 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
6807 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6808 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
6809 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6811 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6813 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6814 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6815 {
6816 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6817 /* .name = "Capture Source", */
6818 .name = "Input Source",
6819 .count = 1,
6820 .info = alc883_mux_enum_info,
6821 .get = alc883_mux_enum_get,
6822 .put = alc883_mux_enum_put,
6823 },
6824 { } /* end */
f12ab1e0 6825};
bc9f98a9 6826
272a527c
KY
6827static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6828 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6829 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6830 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6831 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6832 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6835 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6836 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6837 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6838 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6839 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6840 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6841 {
6842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6843 /* .name = "Capture Source", */
6844 .name = "Input Source",
6845 .count = 2,
6846 .info = alc883_mux_enum_info,
6847 .get = alc883_mux_enum_get,
6848 .put = alc883_mux_enum_put,
6849 },
6850 { } /* end */
6851};
6852
6853static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6854 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6856 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6861 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6862 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6863 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6864 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6865 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6866 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6867 {
6868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6869 /* .name = "Capture Source", */
6870 .name = "Input Source",
6871 .count = 2,
6872 .info = alc883_mux_enum_info,
6873 .get = alc883_mux_enum_get,
6874 .put = alc883_mux_enum_put,
6875 },
6876 { } /* end */
6877};
6878
4723c022 6879static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6882 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6883 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6884 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6885 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6886 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6887 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6888 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6889 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6890 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6898 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6899 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6901 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6902 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6903 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6904 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6905 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6906 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6907 {
6908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6909 /* .name = "Capture Source", */
6910 .name = "Input Source",
6911 .count = 2,
6912 .info = alc883_mux_enum_info,
6913 .get = alc883_mux_enum_get,
6914 .put = alc883_mux_enum_put,
6915 },
6916 { } /* end */
6917};
6918
4723c022 6919static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6920 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6921 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6923 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6924 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6925 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6926 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6927 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6930 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6937 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6938 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6939 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6940 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6941 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6942 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6943 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6944 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6945 {
6946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6947 /* .name = "Capture Source", */
6948 .name = "Input Source",
6949 .count = 2,
6950 .info = alc883_mux_enum_info,
6951 .get = alc883_mux_enum_get,
6952 .put = alc883_mux_enum_put,
6953 },
6954 { } /* end */
6955};
6956
5795b9e6
CM
6957static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6958 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6959 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6960 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6961 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6962 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6963 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6964 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6965 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6966 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6967 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6971 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6972 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6974 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6976 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6977 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6978 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6979 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6980 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6982 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6983 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6984 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6985 {
6986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6987 /* .name = "Capture Source", */
6988 .name = "Input Source",
6989 .count = 2,
6990 .info = alc883_mux_enum_info,
6991 .get = alc883_mux_enum_get,
6992 .put = alc883_mux_enum_put,
6993 },
6994 { } /* end */
6995};
6996
2880a867 6997static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
6998 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6999 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7003 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7004 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7006 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7007 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7008 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7009 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7010 {
7011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7012 /* .name = "Capture Source", */
7013 .name = "Input Source",
7014 .count = 2,
7015 .info = alc883_mux_enum_info,
7016 .get = alc883_mux_enum_get,
7017 .put = alc883_mux_enum_put,
7018 },
7019 { } /* end */
d1a991a6 7020};
2880a867 7021
9c7f852e
TI
7022static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7023 {
7024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7025 .name = "Channel Mode",
7026 .info = alc_ch_mode_info,
7027 .get = alc_ch_mode_get,
7028 .put = alc_ch_mode_put,
7029 },
7030 { } /* end */
7031};
7032
7033static struct hda_verb alc883_init_verbs[] = {
7034 /* ADC1: mute amp left and right */
7035 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7036 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7037 /* ADC2: mute amp left and right */
7038 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7039 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7040 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7041 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7044 /* Rear mixer */
7045 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7046 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7048 /* CLFE mixer */
7049 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7050 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7052 /* Side mixer */
7053 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7054 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7055 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7056
cb53c626
TI
7057 /* mute analog input loopbacks */
7058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7063
9c7f852e
TI
7064 /* Front Pin: output 0 (0x0c) */
7065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7066 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7067 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7068 /* Rear Pin: output 1 (0x0d) */
7069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7072 /* CLFE Pin: output 2 (0x0e) */
7073 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7074 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7075 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7076 /* Side Pin: output 3 (0x0f) */
7077 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7078 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7079 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7080 /* Mic (rear) pin: input vref at 80% */
7081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7083 /* Front Mic pin: input vref at 80% */
7084 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7085 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7086 /* Line In pin: input */
7087 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7088 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7089 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7090 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7093 /* CD pin widget for input */
7094 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7095
7096 /* FIXME: use matrix-type input source selection */
7097 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7098 /* Input mixer2 */
7099 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7100 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7101 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7102 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7103 /* Input mixer3 */
7104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7105 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7106 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7108 { }
7109};
7110
a8848bd6
AS
7111/* toggle speaker-output according to the hp-jack state */
7112static void alc883_mitac_hp_automute(struct hda_codec *codec)
7113{
7114 unsigned int present;
7115
7116 present = snd_hda_codec_read(codec, 0x15, 0,
7117 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7118 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7119 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7120 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7121 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7122}
7123
7124/* auto-toggle front mic */
7125/*
7126static void alc883_mitac_mic_automute(struct hda_codec *codec)
7127{
7128 unsigned int present;
7129 unsigned char bits;
7130
7131 present = snd_hda_codec_read(codec, 0x18, 0,
7132 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7133 bits = present ? HDA_AMP_MUTE : 0;
7134 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7135}
7136*/
7137
7138static void alc883_mitac_automute(struct hda_codec *codec)
7139{
7140 alc883_mitac_hp_automute(codec);
7141 /* alc883_mitac_mic_automute(codec); */
7142}
7143
7144static void alc883_mitac_unsol_event(struct hda_codec *codec,
7145 unsigned int res)
7146{
7147 switch (res >> 26) {
7148 case ALC880_HP_EVENT:
7149 alc883_mitac_hp_automute(codec);
7150 break;
7151 case ALC880_MIC_EVENT:
7152 /* alc883_mitac_mic_automute(codec); */
7153 break;
7154 }
7155}
7156
7157static struct hda_verb alc883_mitac_verbs[] = {
7158 /* HP */
7159 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7161 /* Subwoofer */
7162 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7163 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7164
7165 /* enable unsolicited event */
7166 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7167 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7168
7169 { } /* end */
7170};
7171
ccc656ce
KY
7172static struct hda_verb alc883_tagra_verbs[] = {
7173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7175
7176 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7177 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7178
7179 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7180 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7181 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7182
7183 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7184 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7185 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7186 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7187
7188 { } /* end */
7189};
7190
bc9f98a9
KY
7191static struct hda_verb alc883_lenovo_101e_verbs[] = {
7192 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7193 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7194 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7195 { } /* end */
7196};
7197
272a527c
KY
7198static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7199 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7200 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7201 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7203 { } /* end */
7204};
7205
7206static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7209 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7211 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7212 { } /* end */
7213};
7214
189609ae
KY
7215static struct hda_verb alc883_haier_w66_verbs[] = {
7216 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7218
7219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7220
7221 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7222 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7224 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7225 { } /* end */
7226};
7227
4723c022 7228static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
7229 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7230 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7231 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7232 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7233 { }
7234};
7235
4723c022 7236static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
7237 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7238 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7239 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7240 { }
7241};
7242
5795b9e6
CM
7243static struct hda_verb alc888_6st_dell_verbs[] = {
7244 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7245 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7246 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7247 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7248 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7249 { }
7250};
7251
4723c022 7252static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7253 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7254 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7255 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7256 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7257 { }
7258};
7259
4723c022 7260static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7261 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7262 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7263 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7264 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7265 { }
7266};
7267
4723c022
CM
7268static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7269 { 2, alc888_3st_hp_2ch_init },
7270 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7271};
7272
272a527c
KY
7273/* toggle front-jack and RCA according to the hp-jack state */
7274static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7275{
7276 unsigned int present;
7277
7278 present = snd_hda_codec_read(codec, 0x1b, 0,
7279 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7280 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7281 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7282 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7283 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7284}
7285
7286/* toggle RCA according to the front-jack state */
7287static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7288{
7289 unsigned int present;
7290
7291 present = snd_hda_codec_read(codec, 0x14, 0,
7292 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7293 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7294 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7295}
47fd830a 7296
272a527c
KY
7297static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7298 unsigned int res)
7299{
7300 if ((res >> 26) == ALC880_HP_EVENT)
7301 alc888_lenovo_ms7195_front_automute(codec);
7302 if ((res >> 26) == ALC880_FRONT_EVENT)
7303 alc888_lenovo_ms7195_rca_automute(codec);
7304}
7305
7306static struct hda_verb alc883_medion_md2_verbs[] = {
7307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7308 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7309
7310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7311
7312 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7313 { } /* end */
7314};
7315
7316/* toggle speaker-output according to the hp-jack state */
7317static void alc883_medion_md2_automute(struct hda_codec *codec)
7318{
7319 unsigned int present;
7320
7321 present = snd_hda_codec_read(codec, 0x14, 0,
7322 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7323 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7324 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7325}
7326
7327static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7328 unsigned int res)
7329{
7330 if ((res >> 26) == ALC880_HP_EVENT)
7331 alc883_medion_md2_automute(codec);
7332}
7333
ccc656ce
KY
7334/* toggle speaker-output according to the hp-jack state */
7335static void alc883_tagra_automute(struct hda_codec *codec)
7336{
7337 unsigned int present;
f12ab1e0 7338 unsigned char bits;
ccc656ce
KY
7339
7340 present = snd_hda_codec_read(codec, 0x14, 0,
7341 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7342 bits = present ? HDA_AMP_MUTE : 0;
7343 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7344 HDA_AMP_MUTE, bits);
82beb8fd
TI
7345 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7346 present ? 1 : 3);
ccc656ce
KY
7347}
7348
7349static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7350{
7351 if ((res >> 26) == ALC880_HP_EVENT)
7352 alc883_tagra_automute(codec);
7353}
7354
189609ae
KY
7355static void alc883_haier_w66_automute(struct hda_codec *codec)
7356{
7357 unsigned int present;
7358 unsigned char bits;
7359
7360 present = snd_hda_codec_read(codec, 0x1b, 0,
7361 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7362 bits = present ? 0x80 : 0;
7363 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7364 0x80, bits);
7365}
7366
7367static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7368 unsigned int res)
7369{
7370 if ((res >> 26) == ALC880_HP_EVENT)
7371 alc883_haier_w66_automute(codec);
7372}
7373
bc9f98a9
KY
7374static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7375{
7376 unsigned int present;
f12ab1e0 7377 unsigned char bits;
bc9f98a9
KY
7378
7379 present = snd_hda_codec_read(codec, 0x14, 0,
7380 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7381 bits = present ? HDA_AMP_MUTE : 0;
7382 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7383 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7384}
7385
7386static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7387{
7388 unsigned int present;
f12ab1e0 7389 unsigned char bits;
bc9f98a9
KY
7390
7391 present = snd_hda_codec_read(codec, 0x1b, 0,
7392 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7393 bits = present ? HDA_AMP_MUTE : 0;
7394 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7395 HDA_AMP_MUTE, bits);
7396 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7397 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7398}
7399
7400static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7401 unsigned int res)
7402{
7403 if ((res >> 26) == ALC880_HP_EVENT)
7404 alc883_lenovo_101e_all_automute(codec);
7405 if ((res >> 26) == ALC880_FRONT_EVENT)
7406 alc883_lenovo_101e_ispeaker_automute(codec);
7407}
7408
676a9b53
TI
7409/* toggle speaker-output according to the hp-jack state */
7410static void alc883_acer_aspire_automute(struct hda_codec *codec)
7411{
7412 unsigned int present;
7413
7414 present = snd_hda_codec_read(codec, 0x14, 0,
7415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7416 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7417 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7418 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7419 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7420}
7421
7422static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7423 unsigned int res)
7424{
7425 if ((res >> 26) == ALC880_HP_EVENT)
7426 alc883_acer_aspire_automute(codec);
7427}
7428
d1a991a6
KY
7429static struct hda_verb alc883_acer_eapd_verbs[] = {
7430 /* HP Pin: output 0 (0x0c) */
7431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7432 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7433 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7434 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7435 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7436 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7437 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7438 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7439 /* eanable EAPD on medion laptop */
7440 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7441 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7442 /* enable unsolicited event */
7443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7444 { }
7445};
7446
5795b9e6
CM
7447static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7448{
7449 unsigned int present;
7450
7451 present = snd_hda_codec_read(codec, 0x1b, 0,
7452 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7453 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7454 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7455 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7456 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7457 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7458 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7459 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7460 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7461}
7462
7463static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7464 unsigned int res)
7465{
7466 switch (res >> 26) {
7467 case ALC880_HP_EVENT:
7468 printk("hp_event\n");
7469 alc888_6st_dell_front_automute(codec);
7470 break;
7471 }
7472}
7473
9c7f852e
TI
7474/*
7475 * generic initialization of ADC, input mixers and output mixers
7476 */
7477static struct hda_verb alc883_auto_init_verbs[] = {
7478 /*
7479 * Unmute ADC0-2 and set the default input to mic-in
7480 */
7481 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7483 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7485
cb53c626 7486 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7487 * mixer widget
f12ab1e0
TI
7488 * Note: PASD motherboards uses the Line In 2 as the input for
7489 * front panel mic (mic 2)
9c7f852e
TI
7490 */
7491 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7497
7498 /*
7499 * Set up output mixers (0x0c - 0x0f)
7500 */
7501 /* set vol=0 to output mixers */
7502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7504 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7505 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7506 /* set up input amps for analog loopback */
7507 /* Amp Indices: DAC = 0, mixer = 1 */
7508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7512 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7515 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7516 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7517 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7518
7519 /* FIXME: use matrix-type input source selection */
7520 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7521 /* Input mixer1 */
7522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7525 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7527 /* Input mixer2 */
7528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7531 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7533
7534 { }
7535};
7536
7537/* capture mixer elements */
7538static struct snd_kcontrol_new alc883_capture_mixer[] = {
7539 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7540 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7541 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7542 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7543 {
7544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7545 /* The multiple "Capture Source" controls confuse alsamixer
7546 * So call somewhat different..
9c7f852e
TI
7547 */
7548 /* .name = "Capture Source", */
7549 .name = "Input Source",
7550 .count = 2,
7551 .info = alc882_mux_enum_info,
7552 .get = alc882_mux_enum_get,
7553 .put = alc882_mux_enum_put,
7554 },
7555 { } /* end */
7556};
7557
cb53c626
TI
7558#ifdef CONFIG_SND_HDA_POWER_SAVE
7559#define alc883_loopbacks alc880_loopbacks
7560#endif
7561
9c7f852e
TI
7562/* pcm configuration: identiacal with ALC880 */
7563#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7564#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 7565#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
7566#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7567#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7568
7569/*
7570 * configuration and preset
7571 */
f5fcc13c
TI
7572static const char *alc883_models[ALC883_MODEL_LAST] = {
7573 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7574 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7575 [ALC883_3ST_6ch] = "3stack-6ch",
7576 [ALC883_6ST_DIG] = "6stack-dig",
7577 [ALC883_TARGA_DIG] = "targa-dig",
7578 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7579 [ALC883_ACER] = "acer",
2880a867 7580 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7581 [ALC883_MEDION] = "medion",
272a527c 7582 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7583 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7584 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7585 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7586 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7587 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7588 [ALC888_6ST_HP] = "6stack-hp",
7589 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 7590 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 7591 [ALC883_MITAC] = "mitac",
f5fcc13c
TI
7592 [ALC883_AUTO] = "auto",
7593};
7594
7595static struct snd_pci_quirk alc883_cfg_tbl[] = {
7596 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7597 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7598 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7599 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7600 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 7601 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 7602 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7603 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7604 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7605 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7606 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7607 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7608 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7609 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7610 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7611 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7612 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7613 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7614 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7615 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
f5fcc13c 7616 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7617 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7618 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7619 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7620 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7621 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7622 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7623 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7624 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7625 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7626 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7627 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7628 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7629 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7630 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741
TI
7631 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7632 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7633 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7634 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7635 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7636 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7637 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7638 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7639 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 7640 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 7641 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7642 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7643 {}
7644};
7645
7646static struct alc_config_preset alc883_presets[] = {
7647 [ALC883_3ST_2ch_DIG] = {
7648 .mixers = { alc883_3ST_2ch_mixer },
7649 .init_verbs = { alc883_init_verbs },
7650 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7651 .dac_nids = alc883_dac_nids,
7652 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7653 .dig_in_nid = ALC883_DIGIN_NID,
7654 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7655 .channel_mode = alc883_3ST_2ch_modes,
7656 .input_mux = &alc883_capture_source,
7657 },
7658 [ALC883_3ST_6ch_DIG] = {
7659 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7660 .init_verbs = { alc883_init_verbs },
7661 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7662 .dac_nids = alc883_dac_nids,
7663 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7664 .dig_in_nid = ALC883_DIGIN_NID,
7665 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7666 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7667 .need_dac_fix = 1,
9c7f852e 7668 .input_mux = &alc883_capture_source,
f12ab1e0 7669 },
9c7f852e
TI
7670 [ALC883_3ST_6ch] = {
7671 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7672 .init_verbs = { alc883_init_verbs },
7673 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7674 .dac_nids = alc883_dac_nids,
9c7f852e
TI
7675 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7676 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7677 .need_dac_fix = 1,
9c7f852e 7678 .input_mux = &alc883_capture_source,
f12ab1e0 7679 },
9c7f852e
TI
7680 [ALC883_6ST_DIG] = {
7681 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7682 .init_verbs = { alc883_init_verbs },
7683 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7684 .dac_nids = alc883_dac_nids,
7685 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7686 .dig_in_nid = ALC883_DIGIN_NID,
7687 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7688 .channel_mode = alc883_sixstack_modes,
7689 .input_mux = &alc883_capture_source,
7690 },
ccc656ce
KY
7691 [ALC883_TARGA_DIG] = {
7692 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7693 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7694 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7695 .dac_nids = alc883_dac_nids,
7696 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7698 .channel_mode = alc883_3ST_6ch_modes,
7699 .need_dac_fix = 1,
7700 .input_mux = &alc883_capture_source,
7701 .unsol_event = alc883_tagra_unsol_event,
7702 .init_hook = alc883_tagra_automute,
7703 },
7704 [ALC883_TARGA_2ch_DIG] = {
7705 .mixers = { alc883_tagra_2ch_mixer},
7706 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7707 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7708 .dac_nids = alc883_dac_nids,
7709 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7710 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7711 .channel_mode = alc883_3ST_2ch_modes,
7712 .input_mux = &alc883_capture_source,
7713 .unsol_event = alc883_tagra_unsol_event,
7714 .init_hook = alc883_tagra_automute,
7715 },
bab282b9 7716 [ALC883_ACER] = {
676a9b53 7717 .mixers = { alc883_base_mixer },
bab282b9
VA
7718 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7719 * and the headphone jack. Turn this on and rely on the
7720 * standard mute methods whenever the user wants to turn
7721 * these outputs off.
7722 */
7723 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7724 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7725 .dac_nids = alc883_dac_nids,
bab282b9
VA
7726 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7727 .channel_mode = alc883_3ST_2ch_modes,
7728 .input_mux = &alc883_capture_source,
7729 },
2880a867 7730 [ALC883_ACER_ASPIRE] = {
676a9b53 7731 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7732 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7734 .dac_nids = alc883_dac_nids,
7735 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
7736 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7737 .channel_mode = alc883_3ST_2ch_modes,
7738 .input_mux = &alc883_capture_source,
676a9b53
TI
7739 .unsol_event = alc883_acer_aspire_unsol_event,
7740 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7741 },
c07584c8
TD
7742 [ALC883_MEDION] = {
7743 .mixers = { alc883_fivestack_mixer,
7744 alc883_chmode_mixer },
7745 .init_verbs = { alc883_init_verbs,
b373bdeb 7746 alc883_medion_eapd_verbs },
c07584c8
TD
7747 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7748 .dac_nids = alc883_dac_nids,
c07584c8
TD
7749 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7750 .channel_mode = alc883_sixstack_modes,
7751 .input_mux = &alc883_capture_source,
b373bdeb 7752 },
272a527c
KY
7753 [ALC883_MEDION_MD2] = {
7754 .mixers = { alc883_medion_md2_mixer},
7755 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7756 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7757 .dac_nids = alc883_dac_nids,
7758 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7759 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7760 .channel_mode = alc883_3ST_2ch_modes,
7761 .input_mux = &alc883_capture_source,
7762 .unsol_event = alc883_medion_md2_unsol_event,
7763 .init_hook = alc883_medion_md2_automute,
7764 },
b373bdeb 7765 [ALC883_LAPTOP_EAPD] = {
676a9b53 7766 .mixers = { alc883_base_mixer },
b373bdeb
AN
7767 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7768 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7769 .dac_nids = alc883_dac_nids,
b373bdeb
AN
7770 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7771 .channel_mode = alc883_3ST_2ch_modes,
7772 .input_mux = &alc883_capture_source,
7773 },
bc9f98a9
KY
7774 [ALC883_LENOVO_101E_2ch] = {
7775 .mixers = { alc883_lenovo_101e_2ch_mixer},
7776 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7778 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
7779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7780 .channel_mode = alc883_3ST_2ch_modes,
7781 .input_mux = &alc883_lenovo_101e_capture_source,
7782 .unsol_event = alc883_lenovo_101e_unsol_event,
7783 .init_hook = alc883_lenovo_101e_all_automute,
7784 },
272a527c
KY
7785 [ALC883_LENOVO_NB0763] = {
7786 .mixers = { alc883_lenovo_nb0763_mixer },
7787 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7788 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7789 .dac_nids = alc883_dac_nids,
272a527c
KY
7790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7791 .channel_mode = alc883_3ST_2ch_modes,
7792 .need_dac_fix = 1,
7793 .input_mux = &alc883_lenovo_nb0763_capture_source,
7794 .unsol_event = alc883_medion_md2_unsol_event,
7795 .init_hook = alc883_medion_md2_automute,
7796 },
7797 [ALC888_LENOVO_MS7195_DIG] = {
7798 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7799 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7800 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7801 .dac_nids = alc883_dac_nids,
7802 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7803 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7804 .channel_mode = alc883_3ST_6ch_modes,
7805 .need_dac_fix = 1,
7806 .input_mux = &alc883_capture_source,
7807 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7808 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7809 },
7810 [ALC883_HAIER_W66] = {
7811 .mixers = { alc883_tagra_2ch_mixer},
7812 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7813 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7814 .dac_nids = alc883_dac_nids,
7815 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
7816 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7817 .channel_mode = alc883_3ST_2ch_modes,
7818 .input_mux = &alc883_capture_source,
7819 .unsol_event = alc883_haier_w66_unsol_event,
7820 .init_hook = alc883_haier_w66_automute,
272a527c 7821 },
4723c022
CM
7822 [ALC888_6ST_HP] = {
7823 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7824 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7825 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7826 .dac_nids = alc883_dac_nids,
7827 .dig_out_nid = ALC883_DIGOUT_NID,
cd1e3b40
CM
7828 .dig_in_nid = ALC883_DIGIN_NID,
7829 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7830 .channel_mode = alc883_sixstack_modes,
7831 .input_mux = &alc883_capture_source,
7832 },
4723c022
CM
7833 [ALC888_3ST_HP] = {
7834 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7835 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7836 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7837 .dac_nids = alc883_dac_nids,
4723c022
CM
7838 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7839 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7840 .need_dac_fix = 1,
7841 .input_mux = &alc883_capture_source,
7842 },
5795b9e6
CM
7843 [ALC888_6ST_DELL] = {
7844 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7845 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7846 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7847 .dac_nids = alc883_dac_nids,
7848 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
7849 .dig_in_nid = ALC883_DIGIN_NID,
7850 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7851 .channel_mode = alc883_sixstack_modes,
7852 .input_mux = &alc883_capture_source,
7853 .unsol_event = alc888_6st_dell_unsol_event,
7854 .init_hook = alc888_6st_dell_front_automute,
7855 },
a8848bd6
AS
7856 [ALC883_MITAC] = {
7857 .mixers = { alc883_mitac_mixer },
7858 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7859 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7860 .dac_nids = alc883_dac_nids,
a8848bd6
AS
7861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7862 .channel_mode = alc883_3ST_2ch_modes,
7863 .input_mux = &alc883_capture_source,
7864 .unsol_event = alc883_mitac_unsol_event,
7865 .init_hook = alc883_mitac_automute,
7866 },
9c7f852e
TI
7867};
7868
7869
7870/*
7871 * BIOS auto configuration
7872 */
7873static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7874 hda_nid_t nid, int pin_type,
7875 int dac_idx)
7876{
7877 /* set as output */
7878 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7879 int idx;
7880
f6c7e546 7881 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
7882 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7883 idx = 4;
7884 else
7885 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
7886 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7887
7888}
7889
7890static void alc883_auto_init_multi_out(struct hda_codec *codec)
7891{
7892 struct alc_spec *spec = codec->spec;
7893 int i;
7894
bc9f98a9 7895 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7896 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7897 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7898 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7899 if (nid)
baba8ee9 7900 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7901 i);
9c7f852e
TI
7902 }
7903}
7904
7905static void alc883_auto_init_hp_out(struct hda_codec *codec)
7906{
7907 struct alc_spec *spec = codec->spec;
7908 hda_nid_t pin;
7909
eb06ed8f 7910 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7911 if (pin) /* connect to front */
7912 /* use dac 0 */
7913 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7914 pin = spec->autocfg.speaker_pins[0];
7915 if (pin)
7916 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
7917}
7918
7919#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7920#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7921
7922static void alc883_auto_init_analog_input(struct hda_codec *codec)
7923{
7924 struct alc_spec *spec = codec->spec;
7925 int i;
7926
7927 for (i = 0; i < AUTO_PIN_LAST; i++) {
7928 hda_nid_t nid = spec->autocfg.input_pins[i];
7929 if (alc883_is_input_pin(nid)) {
7930 snd_hda_codec_write(codec, nid, 0,
7931 AC_VERB_SET_PIN_WIDGET_CONTROL,
7932 (i <= AUTO_PIN_FRONT_MIC ?
7933 PIN_VREF80 : PIN_IN));
7934 if (nid != ALC883_PIN_CD_NID)
7935 snd_hda_codec_write(codec, nid, 0,
7936 AC_VERB_SET_AMP_GAIN_MUTE,
7937 AMP_OUT_MUTE);
7938 }
7939 }
7940}
7941
7942/* almost identical with ALC880 parser... */
7943static int alc883_parse_auto_config(struct hda_codec *codec)
7944{
7945 struct alc_spec *spec = codec->spec;
7946 int err = alc880_parse_auto_config(codec);
7947
7948 if (err < 0)
7949 return err;
776e184e
TI
7950 else if (!err)
7951 return 0; /* no config found */
7952
7953 err = alc_auto_add_mic_boost(codec);
7954 if (err < 0)
7955 return err;
7956
7957 /* hack - override the init verbs */
7958 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
7959 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7960 spec->num_mixers++;
776e184e
TI
7961
7962 return 1; /* config found */
9c7f852e
TI
7963}
7964
7965/* additional initialization for auto-configuration model */
7966static void alc883_auto_init(struct hda_codec *codec)
7967{
f6c7e546 7968 struct alc_spec *spec = codec->spec;
9c7f852e
TI
7969 alc883_auto_init_multi_out(codec);
7970 alc883_auto_init_hp_out(codec);
7971 alc883_auto_init_analog_input(codec);
f6c7e546
TI
7972 if (spec->unsol_event)
7973 alc_sku_automute(codec);
9c7f852e
TI
7974}
7975
7976static int patch_alc883(struct hda_codec *codec)
7977{
7978 struct alc_spec *spec;
7979 int err, board_config;
7980
7981 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7982 if (spec == NULL)
7983 return -ENOMEM;
7984
7985 codec->spec = spec;
7986
f5fcc13c
TI
7987 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7988 alc883_models,
7989 alc883_cfg_tbl);
7990 if (board_config < 0) {
9c7f852e
TI
7991 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7992 "trying auto-probe from BIOS...\n");
7993 board_config = ALC883_AUTO;
7994 }
7995
7996 if (board_config == ALC883_AUTO) {
7997 /* automatic parse from the BIOS config */
7998 err = alc883_parse_auto_config(codec);
7999 if (err < 0) {
8000 alc_free(codec);
8001 return err;
f12ab1e0 8002 } else if (!err) {
9c7f852e
TI
8003 printk(KERN_INFO
8004 "hda_codec: Cannot set up configuration "
8005 "from BIOS. Using base mode...\n");
8006 board_config = ALC883_3ST_2ch_DIG;
8007 }
8008 }
8009
8010 if (board_config != ALC883_AUTO)
8011 setup_preset(spec, &alc883_presets[board_config]);
8012
8013 spec->stream_name_analog = "ALC883 Analog";
8014 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8015 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8016 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e
TI
8017
8018 spec->stream_name_digital = "ALC883 Digital";
8019 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8020 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8021
e1406348
TI
8022 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8023 spec->adc_nids = alc883_adc_nids;
8024 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8025
2134ea4f
TI
8026 spec->vmaster_nid = 0x0c;
8027
9c7f852e
TI
8028 codec->patch_ops = alc_patch_ops;
8029 if (board_config == ALC883_AUTO)
8030 spec->init_hook = alc883_auto_init;
cb53c626
TI
8031#ifdef CONFIG_SND_HDA_POWER_SAVE
8032 if (!spec->loopback.amplist)
8033 spec->loopback.amplist = alc883_loopbacks;
8034#endif
9c7f852e
TI
8035
8036 return 0;
8037}
8038
8039/*
8040 * ALC262 support
8041 */
8042
8043#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8044#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8045
8046#define alc262_dac_nids alc260_dac_nids
8047#define alc262_adc_nids alc882_adc_nids
8048#define alc262_adc_nids_alt alc882_adc_nids_alt
8049
8050#define alc262_modes alc260_modes
8051#define alc262_capture_source alc882_capture_source
8052
8053static struct snd_kcontrol_new alc262_base_mixer[] = {
8054 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8055 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8059 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8062 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8063 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8064 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8065 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8066 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8067 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8068 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8069 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8070 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8071 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8072 { } /* end */
8073};
8074
ccc656ce
KY
8075static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8076 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8077 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8080 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8081 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8085 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8086 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8087 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8088 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8089 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8090 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8091 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8092 { } /* end */
8093};
8094
ce875f07
TI
8095/* update HP, line and mono-out pins according to the master switch */
8096static void alc262_hp_master_update(struct hda_codec *codec)
8097{
8098 struct alc_spec *spec = codec->spec;
8099 int val = spec->master_sw;
8100
8101 /* HP & line-out */
8102 snd_hda_codec_write_cache(codec, 0x1b, 0,
8103 AC_VERB_SET_PIN_WIDGET_CONTROL,
8104 val ? PIN_HP : 0);
8105 snd_hda_codec_write_cache(codec, 0x15, 0,
8106 AC_VERB_SET_PIN_WIDGET_CONTROL,
8107 val ? PIN_HP : 0);
8108 /* mono (speaker) depending on the HP jack sense */
8109 val = val && !spec->jack_present;
8110 snd_hda_codec_write_cache(codec, 0x16, 0,
8111 AC_VERB_SET_PIN_WIDGET_CONTROL,
8112 val ? PIN_OUT : 0);
8113}
8114
8115static void alc262_hp_bpc_automute(struct hda_codec *codec)
8116{
8117 struct alc_spec *spec = codec->spec;
8118 unsigned int presence;
8119 presence = snd_hda_codec_read(codec, 0x1b, 0,
8120 AC_VERB_GET_PIN_SENSE, 0);
8121 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8122 alc262_hp_master_update(codec);
8123}
8124
8125static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8126{
8127 if ((res >> 26) != ALC880_HP_EVENT)
8128 return;
8129 alc262_hp_bpc_automute(codec);
8130}
8131
8132static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8133{
8134 struct alc_spec *spec = codec->spec;
8135 unsigned int presence;
8136 presence = snd_hda_codec_read(codec, 0x15, 0,
8137 AC_VERB_GET_PIN_SENSE, 0);
8138 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8139 alc262_hp_master_update(codec);
8140}
8141
8142static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8143 unsigned int res)
8144{
8145 if ((res >> 26) != ALC880_HP_EVENT)
8146 return;
8147 alc262_hp_wildwest_automute(codec);
8148}
8149
8150static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8151 struct snd_ctl_elem_value *ucontrol)
8152{
8153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8154 struct alc_spec *spec = codec->spec;
8155 *ucontrol->value.integer.value = spec->master_sw;
8156 return 0;
8157}
8158
8159static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8160 struct snd_ctl_elem_value *ucontrol)
8161{
8162 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8163 struct alc_spec *spec = codec->spec;
8164 int val = !!*ucontrol->value.integer.value;
8165
8166 if (val == spec->master_sw)
8167 return 0;
8168 spec->master_sw = val;
8169 alc262_hp_master_update(codec);
8170 return 1;
8171}
8172
9c7f852e 8173static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8174 {
8175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8176 .name = "Master Playback Switch",
8177 .info = snd_ctl_boolean_mono_info,
8178 .get = alc262_hp_master_sw_get,
8179 .put = alc262_hp_master_sw_put,
8180 },
9c7f852e
TI
8181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8182 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8184 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8185 HDA_OUTPUT),
8186 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8187 HDA_OUTPUT),
9c7f852e
TI
8188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8191 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8192 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8193 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
8194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8196 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8197 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8198 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8199 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8200 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8201 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8202 { } /* end */
8203};
8204
cd7509a4 8205static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
8206 {
8207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8208 .name = "Master Playback Switch",
8209 .info = snd_ctl_boolean_mono_info,
8210 .get = alc262_hp_master_sw_get,
8211 .put = alc262_hp_master_sw_put,
8212 },
cd7509a4
KY
8213 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8214 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8215 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
8217 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8218 HDA_OUTPUT),
8219 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8220 HDA_OUTPUT),
cd7509a4
KY
8221 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8222 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 8223 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
8224 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8225 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8226 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8227 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8228 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8229 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8230 { } /* end */
8231};
8232
8233static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8234 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8235 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8236 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
8237 { } /* end */
8238};
8239
66d2a9d6
KY
8240/* mute/unmute internal speaker according to the hp jack and mute state */
8241static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8242{
8243 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
8244
8245 if (force || !spec->sense_updated) {
8246 unsigned int present;
8247 present = snd_hda_codec_read(codec, 0x15, 0,
8248 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 8249 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
8250 spec->sense_updated = 1;
8251 }
4bb26130
TI
8252 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8253 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
8254}
8255
8256static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8257 unsigned int res)
8258{
8259 if ((res >> 26) != ALC880_HP_EVENT)
8260 return;
8261 alc262_hp_t5735_automute(codec, 1);
8262}
8263
8264static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8265{
8266 alc262_hp_t5735_automute(codec, 1);
8267}
8268
8269static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
8270 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8271 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
8272 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8277 { } /* end */
8278};
8279
8280static struct hda_verb alc262_hp_t5735_verbs[] = {
8281 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8283
8284 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8285 { }
8286};
8287
8c427226 8288static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
8289 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8290 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
8291 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8292 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
8293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8294 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8295 { } /* end */
8296};
8297
8298static struct hda_verb alc262_hp_rp5700_verbs[] = {
8299 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8300 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8303 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8304 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8309 {}
8310};
8311
8312static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8313 .num_items = 1,
8314 .items = {
8315 { "Line", 0x1 },
8316 },
8317};
8318
0724ea2a
TI
8319/* bind hp and internal speaker mute (with plug check) */
8320static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8321 struct snd_ctl_elem_value *ucontrol)
8322{
8323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8324 long *valp = ucontrol->value.integer.value;
8325 int change;
8326
8327 /* change hp mute */
8328 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8329 HDA_AMP_MUTE,
8330 valp[0] ? 0 : HDA_AMP_MUTE);
8331 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8332 HDA_AMP_MUTE,
8333 valp[1] ? 0 : HDA_AMP_MUTE);
8334 if (change) {
8335 /* change speaker according to HP jack state */
8336 struct alc_spec *spec = codec->spec;
8337 unsigned int mute;
8338 if (spec->jack_present)
8339 mute = HDA_AMP_MUTE;
8340 else
8341 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8342 HDA_OUTPUT, 0);
8343 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8344 HDA_AMP_MUTE, mute);
8345 }
8346 return change;
8347}
5b31954e 8348
272a527c 8349static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
8350 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8351 {
8352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8353 .name = "Master Playback Switch",
8354 .info = snd_hda_mixer_amp_switch_info,
8355 .get = snd_hda_mixer_amp_switch_get,
8356 .put = alc262_sony_master_sw_put,
8357 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8358 },
272a527c
KY
8359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8361 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8362 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8363 { } /* end */
8364};
8365
83c34218
KY
8366static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8368 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8369 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8372 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8373 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8374 { } /* end */
8375};
272a527c 8376
9c7f852e
TI
8377#define alc262_capture_mixer alc882_capture_mixer
8378#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8379
8380/*
8381 * generic initialization of ADC, input mixers and output mixers
8382 */
8383static struct hda_verb alc262_init_verbs[] = {
8384 /*
8385 * Unmute ADC0-2 and set the default input to mic-in
8386 */
8387 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8388 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8389 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8391 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8393
cb53c626 8394 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8395 * mixer widget
f12ab1e0
TI
8396 * Note: PASD motherboards uses the Line In 2 as the input for
8397 * front panel mic (mic 2)
9c7f852e
TI
8398 */
8399 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8405
8406 /*
df694daa
KY
8407 * Set up output mixers (0x0c - 0x0e)
8408 */
8409 /* set vol=0 to output mixers */
8410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8413 /* set up input amps for analog loopback */
8414 /* Amp Indices: DAC = 0, mixer = 1 */
8415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8421
8422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8425 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8427 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8428
8429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8431 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8433 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8434
8435 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8437
8438 /* FIXME: use matrix-type input source selection */
8439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8440 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8441 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8445 /* Input mixer2 */
8446 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8448 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8450 /* Input mixer3 */
8451 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8454 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8455
8456 { }
8457};
1da177e4 8458
ccc656ce
KY
8459static struct hda_verb alc262_hippo_unsol_verbs[] = {
8460 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8462 {}
8463};
8464
8465static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8467 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8468 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8469
8470 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8471 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8472 {}
8473};
8474
272a527c
KY
8475static struct hda_verb alc262_sony_unsol_verbs[] = {
8476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8479
8480 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8482};
8483
ccc656ce 8484/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8485static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8486{
8487 struct alc_spec *spec = codec->spec;
8488 unsigned int mute;
5b31954e 8489 unsigned int present;
ccc656ce 8490
5b31954e
TI
8491 /* need to execute and sync at first */
8492 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8493 present = snd_hda_codec_read(codec, 0x15, 0,
8494 AC_VERB_GET_PIN_SENSE, 0);
8495 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8496 if (spec->jack_present) {
8497 /* mute internal speaker */
47fd830a
TI
8498 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8499 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8500 } else {
8501 /* unmute internal speaker if necessary */
8502 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8503 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8504 HDA_AMP_MUTE, mute);
ccc656ce
KY
8505 }
8506}
8507
8508/* unsolicited event for HP jack sensing */
8509static void alc262_hippo_unsol_event(struct hda_codec *codec,
8510 unsigned int res)
8511{
8512 if ((res >> 26) != ALC880_HP_EVENT)
8513 return;
5b31954e 8514 alc262_hippo_automute(codec);
ccc656ce
KY
8515}
8516
5b31954e 8517static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8518{
ccc656ce 8519 unsigned int mute;
5b31954e 8520 unsigned int present;
ccc656ce 8521
5b31954e
TI
8522 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8523 present = snd_hda_codec_read(codec, 0x1b, 0,
8524 AC_VERB_GET_PIN_SENSE, 0);
8525 present = (present & 0x80000000) != 0;
8526 if (present) {
ccc656ce 8527 /* mute internal speaker */
47fd830a
TI
8528 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8529 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8530 } else {
8531 /* unmute internal speaker if necessary */
8532 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8533 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8534 HDA_AMP_MUTE, mute);
ccc656ce
KY
8535 }
8536}
8537
8538/* unsolicited event for HP jack sensing */
8539static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8540 unsigned int res)
8541{
8542 if ((res >> 26) != ALC880_HP_EVENT)
8543 return;
5b31954e 8544 alc262_hippo1_automute(codec);
ccc656ce
KY
8545}
8546
834be88d
TI
8547/*
8548 * fujitsu model
8549 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8550 */
8551
8552#define ALC_HP_EVENT 0x37
8553
8554static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8555 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8557 {}
8558};
8559
8560static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8561 .num_items = 3,
834be88d
TI
8562 .items = {
8563 { "Mic", 0x0 },
39d3ed38 8564 { "Int Mic", 0x1 },
834be88d
TI
8565 { "CD", 0x4 },
8566 },
8567};
8568
9c7f852e
TI
8569static struct hda_input_mux alc262_HP_capture_source = {
8570 .num_items = 5,
8571 .items = {
8572 { "Mic", 0x0 },
accbe498 8573 { "Front Mic", 0x1 },
9c7f852e
TI
8574 { "Line", 0x2 },
8575 { "CD", 0x4 },
8576 { "AUX IN", 0x6 },
8577 },
8578};
8579
accbe498 8580static struct hda_input_mux alc262_HP_D7000_capture_source = {
8581 .num_items = 4,
8582 .items = {
8583 { "Mic", 0x0 },
8584 { "Front Mic", 0x2 },
8585 { "Line", 0x1 },
8586 { "CD", 0x4 },
8587 },
8588};
8589
834be88d
TI
8590/* mute/unmute internal speaker according to the hp jack and mute state */
8591static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8592{
8593 struct alc_spec *spec = codec->spec;
8594 unsigned int mute;
8595
f12ab1e0 8596 if (force || !spec->sense_updated) {
834be88d
TI
8597 unsigned int present;
8598 /* need to execute and sync at first */
8599 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8600 present = snd_hda_codec_read(codec, 0x14, 0,
8601 AC_VERB_GET_PIN_SENSE, 0);
8602 spec->jack_present = (present & 0x80000000) != 0;
8603 spec->sense_updated = 1;
8604 }
8605 if (spec->jack_present) {
8606 /* mute internal speaker */
47fd830a
TI
8607 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8608 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8609 } else {
8610 /* unmute internal speaker if necessary */
8611 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8612 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8613 HDA_AMP_MUTE, mute);
834be88d
TI
8614 }
8615}
8616
8617/* unsolicited event for HP jack sensing */
8618static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8619 unsigned int res)
8620{
8621 if ((res >> 26) != ALC_HP_EVENT)
8622 return;
8623 alc262_fujitsu_automute(codec, 1);
8624}
8625
8626/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8627static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8628 .ops = &snd_hda_bind_vol,
8629 .values = {
8630 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8631 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8632 0
8633 },
8634};
834be88d
TI
8635
8636/* bind hp and internal speaker mute (with plug check) */
8637static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8638 struct snd_ctl_elem_value *ucontrol)
8639{
8640 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8641 long *valp = ucontrol->value.integer.value;
8642 int change;
8643
8644 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8645 HDA_AMP_MUTE,
8646 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8647 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8648 HDA_AMP_MUTE,
8649 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8650 if (change)
8651 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8652 return change;
8653}
8654
8655static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8656 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8657 {
8658 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8659 .name = "Master Playback Switch",
8660 .info = snd_hda_mixer_amp_switch_info,
8661 .get = snd_hda_mixer_amp_switch_get,
8662 .put = alc262_fujitsu_master_sw_put,
8663 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8664 },
8665 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8666 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8670 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8671 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8672 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8673 { } /* end */
8674};
8675
304dcaac
TI
8676/* additional init verbs for Benq laptops */
8677static struct hda_verb alc262_EAPD_verbs[] = {
8678 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8679 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8680 {}
8681};
8682
83c34218
KY
8683static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8685 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8686
8687 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8688 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8689 {}
8690};
8691
f651b50b
TD
8692/* Samsung Q1 Ultra Vista model setup */
8693static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8694 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8695 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8696 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8698 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8699 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8700 { } /* end */
8701};
8702
8703static struct hda_verb alc262_ultra_verbs[] = {
8704 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8705 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8707 /* Mic is on Node 0x19 */
8708 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8709 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8711 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8713 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8714 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8715 {}
8716};
8717
8718static struct hda_input_mux alc262_ultra_capture_source = {
8719 .num_items = 1,
8720 .items = {
8721 { "Mic", 0x1 },
8722 },
8723};
8724
8725/* mute/unmute internal speaker according to the hp jack and mute state */
8726static void alc262_ultra_automute(struct hda_codec *codec)
8727{
8728 struct alc_spec *spec = codec->spec;
8729 unsigned int mute;
8730 unsigned int present;
8731
8732 /* need to execute and sync at first */
8733 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8734 present = snd_hda_codec_read(codec, 0x15, 0,
8735 AC_VERB_GET_PIN_SENSE, 0);
8736 spec->jack_present = (present & 0x80000000) != 0;
8737 if (spec->jack_present) {
8738 /* mute internal speaker */
8739 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8740 HDA_AMP_MUTE, HDA_AMP_MUTE);
8741 } else {
8742 /* unmute internal speaker if necessary */
8743 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8745 HDA_AMP_MUTE, mute);
8746 }
8747}
8748
8749/* unsolicited event for HP jack sensing */
8750static void alc262_ultra_unsol_event(struct hda_codec *codec,
8751 unsigned int res)
8752{
8753 if ((res >> 26) != ALC880_HP_EVENT)
8754 return;
8755 alc262_ultra_automute(codec);
8756}
8757
df694daa 8758/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8759static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8760 const struct auto_pin_cfg *cfg)
df694daa
KY
8761{
8762 hda_nid_t nid;
8763 int err;
8764
8765 spec->multiout.num_dacs = 1; /* only use one dac */
8766 spec->multiout.dac_nids = spec->private_dac_nids;
8767 spec->multiout.dac_nids[0] = 2;
8768
8769 nid = cfg->line_out_pins[0];
8770 if (nid) {
f12ab1e0
TI
8771 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8772 "Front Playback Volume",
8773 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8774 if (err < 0)
df694daa 8775 return err;
f12ab1e0
TI
8776 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8777 "Front Playback Switch",
8778 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8779 if (err < 0)
df694daa
KY
8780 return err;
8781 }
8782
82bc955f 8783 nid = cfg->speaker_pins[0];
df694daa
KY
8784 if (nid) {
8785 if (nid == 0x16) {
f12ab1e0
TI
8786 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8787 "Speaker Playback Volume",
8788 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8789 HDA_OUTPUT));
8790 if (err < 0)
df694daa 8791 return err;
f12ab1e0
TI
8792 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8793 "Speaker Playback Switch",
8794 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8795 HDA_OUTPUT));
8796 if (err < 0)
df694daa
KY
8797 return err;
8798 } else {
f12ab1e0
TI
8799 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8800 "Speaker Playback Switch",
8801 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8802 HDA_OUTPUT));
8803 if (err < 0)
df694daa
KY
8804 return err;
8805 }
8806 }
eb06ed8f 8807 nid = cfg->hp_pins[0];
df694daa
KY
8808 if (nid) {
8809 /* spec->multiout.hp_nid = 2; */
8810 if (nid == 0x16) {
f12ab1e0
TI
8811 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8812 "Headphone Playback Volume",
8813 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8814 HDA_OUTPUT));
8815 if (err < 0)
df694daa 8816 return err;
f12ab1e0
TI
8817 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8818 "Headphone Playback Switch",
8819 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8820 HDA_OUTPUT));
8821 if (err < 0)
df694daa
KY
8822 return err;
8823 } else {
f12ab1e0
TI
8824 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8825 "Headphone Playback Switch",
8826 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8827 HDA_OUTPUT));
8828 if (err < 0)
df694daa
KY
8829 return err;
8830 }
8831 }
f12ab1e0 8832 return 0;
df694daa
KY
8833}
8834
8835/* identical with ALC880 */
f12ab1e0
TI
8836#define alc262_auto_create_analog_input_ctls \
8837 alc880_auto_create_analog_input_ctls
df694daa
KY
8838
8839/*
8840 * generic initialization of ADC, input mixers and output mixers
8841 */
8842static struct hda_verb alc262_volume_init_verbs[] = {
8843 /*
8844 * Unmute ADC0-2 and set the default input to mic-in
8845 */
8846 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8847 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8848 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8849 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8850 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8851 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8852
cb53c626 8853 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8854 * mixer widget
f12ab1e0
TI
8855 * Note: PASD motherboards uses the Line In 2 as the input for
8856 * front panel mic (mic 2)
df694daa
KY
8857 */
8858 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8861 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8862 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8863 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8864
8865 /*
8866 * Set up output mixers (0x0c - 0x0f)
8867 */
8868 /* set vol=0 to output mixers */
8869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8871 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8872
8873 /* set up input amps for analog loopback */
8874 /* Amp Indices: DAC = 0, mixer = 1 */
8875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8879 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8880 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8881
8882 /* FIXME: use matrix-type input source selection */
8883 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8884 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8885 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8886 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8887 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8888 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8889 /* Input mixer2 */
8890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8891 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8892 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8893 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8894 /* Input mixer3 */
8895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8896 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8897 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8898 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8899
8900 { }
8901};
8902
9c7f852e
TI
8903static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8904 /*
8905 * Unmute ADC0-2 and set the default input to mic-in
8906 */
8907 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8909 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8910 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8911 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8912 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8913
cb53c626 8914 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8915 * mixer widget
f12ab1e0
TI
8916 * Note: PASD motherboards uses the Line In 2 as the input for
8917 * front panel mic (mic 2)
9c7f852e
TI
8918 */
8919 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
8927
8928 /*
8929 * Set up output mixers (0x0c - 0x0e)
8930 */
8931 /* set vol=0 to output mixers */
8932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8934 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8935
8936 /* set up input amps for analog loopback */
8937 /* Amp Indices: DAC = 0, mixer = 1 */
8938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8939 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8940 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8941 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8942 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8943 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8944
ce875f07 8945 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
8946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8948
8949 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8951
8952 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8953 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8954
8955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8956 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8957 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8958 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8959 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8960
8961 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8962 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8963 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8964 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8965 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8966 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8967
8968
8969 /* FIXME: use matrix-type input source selection */
8970 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8971 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8976 /* Input mixer2 */
8977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8978 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8981 /* Input mixer3 */
8982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8986
ce875f07
TI
8987 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8988
9c7f852e
TI
8989 { }
8990};
8991
cd7509a4
KY
8992static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8993 /*
8994 * Unmute ADC0-2 and set the default input to mic-in
8995 */
8996 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8998 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9000 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9001 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9002
cb53c626 9003 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
9004 * mixer widget
9005 * Note: PASD motherboards uses the Line In 2 as the input for front
9006 * panel mic (mic 2)
9007 */
9008 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9014 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9015 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
9017 /*
9018 * Set up output mixers (0x0c - 0x0e)
9019 */
9020 /* set vol=0 to output mixers */
9021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9022 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9023 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9024
9025 /* set up input amps for analog loopback */
9026 /* Amp Indices: DAC = 0, mixer = 1 */
9027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9033
9034
9035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9036 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9037 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9038 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9039 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9041 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9042
9043 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9044 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9045
9046 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9048
9049 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9050 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9051 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9052 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9053 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9054 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9055
9056 /* FIXME: use matrix-type input source selection */
9057 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9058 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9064 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9066 /* Input mixer2 */
9067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9072 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9074 /* Input mixer3 */
9075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9080 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9081 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9082
ce875f07
TI
9083 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9084
cd7509a4
KY
9085 { }
9086};
9087
cb53c626
TI
9088#ifdef CONFIG_SND_HDA_POWER_SAVE
9089#define alc262_loopbacks alc880_loopbacks
9090#endif
9091
df694daa
KY
9092/* pcm configuration: identiacal with ALC880 */
9093#define alc262_pcm_analog_playback alc880_pcm_analog_playback
9094#define alc262_pcm_analog_capture alc880_pcm_analog_capture
9095#define alc262_pcm_digital_playback alc880_pcm_digital_playback
9096#define alc262_pcm_digital_capture alc880_pcm_digital_capture
9097
9098/*
9099 * BIOS auto configuration
9100 */
9101static int alc262_parse_auto_config(struct hda_codec *codec)
9102{
9103 struct alc_spec *spec = codec->spec;
9104 int err;
9105 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9106
f12ab1e0
TI
9107 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9108 alc262_ignore);
9109 if (err < 0)
df694daa 9110 return err;
f12ab1e0 9111 if (!spec->autocfg.line_outs)
df694daa 9112 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
9113 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9114 if (err < 0)
9115 return err;
9116 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9117 if (err < 0)
df694daa
KY
9118 return err;
9119
9120 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9121
9122 if (spec->autocfg.dig_out_pin)
9123 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9124 if (spec->autocfg.dig_in_pin)
9125 spec->dig_in_nid = ALC262_DIGIN_NID;
9126
9127 if (spec->kctl_alloc)
9128 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9129
9130 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 9131 spec->num_mux_defs = 1;
df694daa
KY
9132 spec->input_mux = &spec->private_imux;
9133
776e184e
TI
9134 err = alc_auto_add_mic_boost(codec);
9135 if (err < 0)
9136 return err;
9137
df694daa
KY
9138 return 1;
9139}
9140
9141#define alc262_auto_init_multi_out alc882_auto_init_multi_out
9142#define alc262_auto_init_hp_out alc882_auto_init_hp_out
9143#define alc262_auto_init_analog_input alc882_auto_init_analog_input
9144
9145
9146/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 9147static void alc262_auto_init(struct hda_codec *codec)
df694daa 9148{
f6c7e546 9149 struct alc_spec *spec = codec->spec;
df694daa
KY
9150 alc262_auto_init_multi_out(codec);
9151 alc262_auto_init_hp_out(codec);
9152 alc262_auto_init_analog_input(codec);
f6c7e546
TI
9153 if (spec->unsol_event)
9154 alc_sku_automute(codec);
df694daa
KY
9155}
9156
9157/*
9158 * configuration and preset
9159 */
f5fcc13c
TI
9160static const char *alc262_models[ALC262_MODEL_LAST] = {
9161 [ALC262_BASIC] = "basic",
9162 [ALC262_HIPPO] = "hippo",
9163 [ALC262_HIPPO_1] = "hippo_1",
9164 [ALC262_FUJITSU] = "fujitsu",
9165 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 9166 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 9167 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 9168 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 9169 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
9170 [ALC262_BENQ_T31] = "benq-t31",
9171 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 9172 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
9173 [ALC262_AUTO] = "auto",
9174};
9175
9176static struct snd_pci_quirk alc262_cfg_tbl[] = {
9177 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9178 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 9179 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
9180 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9181 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 9182 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 9183 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 9184 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 9185 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 9186 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9187 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9188 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9189 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9190 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9191 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9192 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9193 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
9194 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9195 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9196 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
9197 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9198 ALC262_HP_TC_T5735),
8c427226 9199 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 9200 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 9201 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 9202 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 9203 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
9204 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9205 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 9206 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 9207 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
9208 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9209 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9210 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
9211 {}
9212};
9213
9214static struct alc_config_preset alc262_presets[] = {
9215 [ALC262_BASIC] = {
9216 .mixers = { alc262_base_mixer },
9217 .init_verbs = { alc262_init_verbs },
9218 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9219 .dac_nids = alc262_dac_nids,
9220 .hp_nid = 0x03,
9221 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9222 .channel_mode = alc262_modes,
a3bcba38 9223 .input_mux = &alc262_capture_source,
df694daa 9224 },
ccc656ce
KY
9225 [ALC262_HIPPO] = {
9226 .mixers = { alc262_base_mixer },
9227 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9228 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9229 .dac_nids = alc262_dac_nids,
9230 .hp_nid = 0x03,
9231 .dig_out_nid = ALC262_DIGOUT_NID,
9232 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9233 .channel_mode = alc262_modes,
9234 .input_mux = &alc262_capture_source,
9235 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9236 .init_hook = alc262_hippo_automute,
ccc656ce
KY
9237 },
9238 [ALC262_HIPPO_1] = {
9239 .mixers = { alc262_hippo1_mixer },
9240 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9241 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9242 .dac_nids = alc262_dac_nids,
9243 .hp_nid = 0x02,
9244 .dig_out_nid = ALC262_DIGOUT_NID,
9245 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9246 .channel_mode = alc262_modes,
9247 .input_mux = &alc262_capture_source,
9248 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 9249 .init_hook = alc262_hippo1_automute,
ccc656ce 9250 },
834be88d
TI
9251 [ALC262_FUJITSU] = {
9252 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
9253 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9254 alc262_fujitsu_unsol_verbs },
834be88d
TI
9255 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9256 .dac_nids = alc262_dac_nids,
9257 .hp_nid = 0x03,
9258 .dig_out_nid = ALC262_DIGOUT_NID,
9259 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9260 .channel_mode = alc262_modes,
9261 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 9262 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 9263 },
9c7f852e
TI
9264 [ALC262_HP_BPC] = {
9265 .mixers = { alc262_HP_BPC_mixer },
9266 .init_verbs = { alc262_HP_BPC_init_verbs },
9267 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9268 .dac_nids = alc262_dac_nids,
9269 .hp_nid = 0x03,
9270 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9271 .channel_mode = alc262_modes,
9272 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
9273 .unsol_event = alc262_hp_bpc_unsol_event,
9274 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 9275 },
cd7509a4
KY
9276 [ALC262_HP_BPC_D7000_WF] = {
9277 .mixers = { alc262_HP_BPC_WildWest_mixer },
9278 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9279 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9280 .dac_nids = alc262_dac_nids,
9281 .hp_nid = 0x03,
9282 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9283 .channel_mode = alc262_modes,
accbe498 9284 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9285 .unsol_event = alc262_hp_wildwest_unsol_event,
9286 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9287 },
cd7509a4
KY
9288 [ALC262_HP_BPC_D7000_WL] = {
9289 .mixers = { alc262_HP_BPC_WildWest_mixer,
9290 alc262_HP_BPC_WildWest_option_mixer },
9291 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9292 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9293 .dac_nids = alc262_dac_nids,
9294 .hp_nid = 0x03,
9295 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9296 .channel_mode = alc262_modes,
accbe498 9297 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9298 .unsol_event = alc262_hp_wildwest_unsol_event,
9299 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9300 },
66d2a9d6
KY
9301 [ALC262_HP_TC_T5735] = {
9302 .mixers = { alc262_hp_t5735_mixer },
9303 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9304 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9305 .dac_nids = alc262_dac_nids,
9306 .hp_nid = 0x03,
9307 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9308 .channel_mode = alc262_modes,
9309 .input_mux = &alc262_capture_source,
9310 .unsol_event = alc262_hp_t5735_unsol_event,
9311 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
9312 },
9313 [ALC262_HP_RP5700] = {
9314 .mixers = { alc262_hp_rp5700_mixer },
9315 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9316 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9317 .dac_nids = alc262_dac_nids,
9318 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9319 .channel_mode = alc262_modes,
9320 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 9321 },
304dcaac
TI
9322 [ALC262_BENQ_ED8] = {
9323 .mixers = { alc262_base_mixer },
9324 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9325 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9326 .dac_nids = alc262_dac_nids,
9327 .hp_nid = 0x03,
9328 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9329 .channel_mode = alc262_modes,
9330 .input_mux = &alc262_capture_source,
f12ab1e0 9331 },
272a527c
KY
9332 [ALC262_SONY_ASSAMD] = {
9333 .mixers = { alc262_sony_mixer },
9334 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9335 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9336 .dac_nids = alc262_dac_nids,
9337 .hp_nid = 0x02,
9338 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9339 .channel_mode = alc262_modes,
9340 .input_mux = &alc262_capture_source,
9341 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9342 .init_hook = alc262_hippo_automute,
83c34218
KY
9343 },
9344 [ALC262_BENQ_T31] = {
9345 .mixers = { alc262_benq_t31_mixer },
9346 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9347 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9348 .dac_nids = alc262_dac_nids,
9349 .hp_nid = 0x03,
9350 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9351 .channel_mode = alc262_modes,
9352 .input_mux = &alc262_capture_source,
9353 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9354 .init_hook = alc262_hippo_automute,
272a527c 9355 },
f651b50b
TD
9356 [ALC262_ULTRA] = {
9357 .mixers = { alc262_ultra_mixer },
9358 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9359 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9360 .dac_nids = alc262_dac_nids,
9361 .hp_nid = 0x03,
9362 .dig_out_nid = ALC262_DIGOUT_NID,
9363 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9364 .channel_mode = alc262_modes,
9365 .input_mux = &alc262_ultra_capture_source,
9366 .unsol_event = alc262_ultra_unsol_event,
9367 .init_hook = alc262_ultra_automute,
9368 },
df694daa
KY
9369};
9370
9371static int patch_alc262(struct hda_codec *codec)
9372{
9373 struct alc_spec *spec;
9374 int board_config;
9375 int err;
9376
dc041e0b 9377 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
9378 if (spec == NULL)
9379 return -ENOMEM;
9380
9381 codec->spec = spec;
9382#if 0
f12ab1e0
TI
9383 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9384 * under-run
9385 */
df694daa
KY
9386 {
9387 int tmp;
9388 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9389 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9390 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9391 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9392 }
9393#endif
9394
f5fcc13c
TI
9395 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9396 alc262_models,
9397 alc262_cfg_tbl);
cd7509a4 9398
f5fcc13c 9399 if (board_config < 0) {
9c7f852e
TI
9400 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9401 "trying auto-probe from BIOS...\n");
df694daa
KY
9402 board_config = ALC262_AUTO;
9403 }
9404
9405 if (board_config == ALC262_AUTO) {
9406 /* automatic parse from the BIOS config */
9407 err = alc262_parse_auto_config(codec);
9408 if (err < 0) {
9409 alc_free(codec);
9410 return err;
f12ab1e0 9411 } else if (!err) {
9c7f852e
TI
9412 printk(KERN_INFO
9413 "hda_codec: Cannot set up configuration "
9414 "from BIOS. Using base mode...\n");
df694daa
KY
9415 board_config = ALC262_BASIC;
9416 }
9417 }
9418
9419 if (board_config != ALC262_AUTO)
9420 setup_preset(spec, &alc262_presets[board_config]);
9421
9422 spec->stream_name_analog = "ALC262 Analog";
9423 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9424 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9425
9426 spec->stream_name_digital = "ALC262 Digital";
9427 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9428 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9429
f12ab1e0 9430 if (!spec->adc_nids && spec->input_mux) {
df694daa 9431 /* check whether NID 0x07 is valid */
4a471b7d
TI
9432 unsigned int wcap = get_wcaps(codec, 0x07);
9433
f12ab1e0
TI
9434 /* get type */
9435 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9436 if (wcap != AC_WID_AUD_IN) {
9437 spec->adc_nids = alc262_adc_nids_alt;
9438 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
f12ab1e0
TI
9439 spec->mixers[spec->num_mixers] =
9440 alc262_capture_alt_mixer;
df694daa
KY
9441 spec->num_mixers++;
9442 } else {
9443 spec->adc_nids = alc262_adc_nids;
9444 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9445 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9446 spec->num_mixers++;
9447 }
9448 }
9449
2134ea4f
TI
9450 spec->vmaster_nid = 0x0c;
9451
df694daa
KY
9452 codec->patch_ops = alc_patch_ops;
9453 if (board_config == ALC262_AUTO)
ae6b813a 9454 spec->init_hook = alc262_auto_init;
cb53c626
TI
9455#ifdef CONFIG_SND_HDA_POWER_SAVE
9456 if (!spec->loopback.amplist)
9457 spec->loopback.amplist = alc262_loopbacks;
9458#endif
834be88d 9459
df694daa
KY
9460 return 0;
9461}
9462
a361d84b
KY
9463/*
9464 * ALC268 channel source setting (2 channel)
9465 */
9466#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9467#define alc268_modes alc260_modes
9468
9469static hda_nid_t alc268_dac_nids[2] = {
9470 /* front, hp */
9471 0x02, 0x03
9472};
9473
9474static hda_nid_t alc268_adc_nids[2] = {
9475 /* ADC0-1 */
9476 0x08, 0x07
9477};
9478
9479static hda_nid_t alc268_adc_nids_alt[1] = {
9480 /* ADC0 */
9481 0x08
9482};
9483
e1406348
TI
9484static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9485
a361d84b
KY
9486static struct snd_kcontrol_new alc268_base_mixer[] = {
9487 /* output mixer control */
9488 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9489 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9490 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9492 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9493 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9494 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9495 { }
9496};
9497
d1a991a6
KY
9498static struct hda_verb alc268_eapd_verbs[] = {
9499 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9500 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9501 { }
9502};
9503
d273809e
TI
9504/* Toshiba specific */
9505#define alc268_toshiba_automute alc262_hippo_automute
9506
9507static struct hda_verb alc268_toshiba_verbs[] = {
9508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9509 { } /* end */
9510};
9511
9512/* Acer specific */
889c4395 9513/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9514static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9515 .ops = &snd_hda_bind_vol,
9516 .values = {
9517 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9518 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9519 0
9520 },
9521};
9522
889c4395
TI
9523/* mute/unmute internal speaker according to the hp jack and mute state */
9524static void alc268_acer_automute(struct hda_codec *codec, int force)
9525{
9526 struct alc_spec *spec = codec->spec;
9527 unsigned int mute;
9528
9529 if (force || !spec->sense_updated) {
9530 unsigned int present;
9531 present = snd_hda_codec_read(codec, 0x14, 0,
9532 AC_VERB_GET_PIN_SENSE, 0);
9533 spec->jack_present = (present & 0x80000000) != 0;
9534 spec->sense_updated = 1;
9535 }
9536 if (spec->jack_present)
9537 mute = HDA_AMP_MUTE; /* mute internal speaker */
9538 else /* unmute internal speaker if necessary */
9539 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9540 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9541 HDA_AMP_MUTE, mute);
9542}
9543
9544
9545/* bind hp and internal speaker mute (with plug check) */
9546static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9547 struct snd_ctl_elem_value *ucontrol)
9548{
9549 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9550 long *valp = ucontrol->value.integer.value;
9551 int change;
9552
9553 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9554 HDA_AMP_MUTE,
9555 valp[0] ? 0 : HDA_AMP_MUTE);
9556 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9557 HDA_AMP_MUTE,
9558 valp[1] ? 0 : HDA_AMP_MUTE);
9559 if (change)
9560 alc268_acer_automute(codec, 0);
9561 return change;
9562}
d273809e
TI
9563
9564static struct snd_kcontrol_new alc268_acer_mixer[] = {
9565 /* output mixer control */
9566 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9567 {
9568 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9569 .name = "Master Playback Switch",
9570 .info = snd_hda_mixer_amp_switch_info,
9571 .get = snd_hda_mixer_amp_switch_get,
9572 .put = alc268_acer_master_sw_put,
9573 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9574 },
33bf17ab
TI
9575 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9576 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9577 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9578 { }
9579};
9580
9581static struct hda_verb alc268_acer_verbs[] = {
9582 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9583 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584
9585 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9586 { }
9587};
9588
9589/* unsolicited event for HP jack sensing */
9590static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9591 unsigned int res)
9592{
889c4395 9593 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9594 return;
9595 alc268_toshiba_automute(codec);
9596}
9597
9598static void alc268_acer_unsol_event(struct hda_codec *codec,
9599 unsigned int res)
9600{
889c4395 9601 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9602 return;
9603 alc268_acer_automute(codec, 1);
9604}
9605
889c4395
TI
9606static void alc268_acer_init_hook(struct hda_codec *codec)
9607{
9608 alc268_acer_automute(codec, 1);
9609}
9610
3866f0b0
TI
9611static struct snd_kcontrol_new alc268_dell_mixer[] = {
9612 /* output mixer control */
9613 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9614 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9615 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9617 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9618 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9619 { }
9620};
9621
9622static struct hda_verb alc268_dell_verbs[] = {
9623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9624 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9626 { }
9627};
9628
9629/* mute/unmute internal speaker according to the hp jack and mute state */
9630static void alc268_dell_automute(struct hda_codec *codec)
9631{
9632 unsigned int present;
9633 unsigned int mute;
9634
9635 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9636 if (present & 0x80000000)
9637 mute = HDA_AMP_MUTE;
9638 else
9639 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9640 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9641 HDA_AMP_MUTE, mute);
9642}
9643
9644static void alc268_dell_unsol_event(struct hda_codec *codec,
9645 unsigned int res)
9646{
9647 if ((res >> 26) != ALC880_HP_EVENT)
9648 return;
9649 alc268_dell_automute(codec);
9650}
9651
9652#define alc268_dell_init_hook alc268_dell_automute
9653
a361d84b
KY
9654/*
9655 * generic initialization of ADC, input mixers and output mixers
9656 */
9657static struct hda_verb alc268_base_init_verbs[] = {
9658 /* Unmute DAC0-1 and set vol = 0 */
9659 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9660 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9661 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9662 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9663 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9664 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9665
9666 /*
9667 * Set up output mixers (0x0c - 0x0e)
9668 */
9669 /* set vol=0 to output mixers */
9670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9671 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9672 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9673 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9674
9675 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9676 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9677
9678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9679 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9680 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9681 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9682 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9683 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9684 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9685 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9686
9687 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9689 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9691 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9692 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9693 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9694 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9695
a9b3aa8a
JZ
9696 /* Unmute Selector 23h,24h and set the default input to mic-in */
9697
9698 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9699 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9700 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9701 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9702
a361d84b
KY
9703 { }
9704};
9705
9706/*
9707 * generic initialization of ADC, input mixers and output mixers
9708 */
9709static struct hda_verb alc268_volume_init_verbs[] = {
9710 /* set output DAC */
9711 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9712 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9713 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9714 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9715
9716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9718 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9719 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9720 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9721
9722 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9726 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9727
9728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9730 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9731 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9732
9733 /* set PCBEEP vol = 0 */
9734 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9735
9736 { }
9737};
9738
9739#define alc268_mux_enum_info alc_mux_enum_info
9740#define alc268_mux_enum_get alc_mux_enum_get
e1406348 9741#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
9742
9743static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9744 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9745 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9746 {
9747 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9748 /* The multiple "Capture Source" controls confuse alsamixer
9749 * So call somewhat different..
a361d84b
KY
9750 */
9751 /* .name = "Capture Source", */
9752 .name = "Input Source",
9753 .count = 1,
9754 .info = alc268_mux_enum_info,
9755 .get = alc268_mux_enum_get,
9756 .put = alc268_mux_enum_put,
9757 },
9758 { } /* end */
9759};
9760
9761static struct snd_kcontrol_new alc268_capture_mixer[] = {
9762 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9763 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9764 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9765 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9766 {
9767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9768 /* The multiple "Capture Source" controls confuse alsamixer
9769 * So call somewhat different..
a361d84b
KY
9770 */
9771 /* .name = "Capture Source", */
9772 .name = "Input Source",
9773 .count = 2,
9774 .info = alc268_mux_enum_info,
9775 .get = alc268_mux_enum_get,
9776 .put = alc268_mux_enum_put,
9777 },
9778 { } /* end */
9779};
9780
9781static struct hda_input_mux alc268_capture_source = {
9782 .num_items = 4,
9783 .items = {
9784 { "Mic", 0x0 },
9785 { "Front Mic", 0x1 },
9786 { "Line", 0x2 },
9787 { "CD", 0x3 },
9788 },
9789};
9790
86c53bd2
JW
9791#ifdef CONFIG_SND_DEBUG
9792static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
9793 /* Volume widgets */
9794 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9795 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9796 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9797 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9798 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9799 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9800 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9801 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9802 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9803 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9804 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9805 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9806 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
9807 /* The below appears problematic on some hardwares */
9808 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
9809 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9810 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9811 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9812 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9813
9814 /* Modes for retasking pin widgets */
9815 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9816 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9817 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9818 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9819
9820 /* Controls for GPIO pins, assuming they are configured as outputs */
9821 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9822 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9823 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9824 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9825
9826 /* Switches to allow the digital SPDIF output pin to be enabled.
9827 * The ALC268 does not have an SPDIF input.
9828 */
9829 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9830
9831 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9832 * this output to turn on an external amplifier.
9833 */
9834 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9835 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9836
9837 { } /* end */
9838};
9839#endif
9840
a361d84b
KY
9841/* create input playback/capture controls for the given pin */
9842static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9843 const char *ctlname, int idx)
9844{
9845 char name[32];
9846 int err;
9847
9848 sprintf(name, "%s Playback Volume", ctlname);
9849 if (nid == 0x14) {
9850 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9851 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9852 HDA_OUTPUT));
9853 if (err < 0)
9854 return err;
9855 } else if (nid == 0x15) {
9856 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9857 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9858 HDA_OUTPUT));
9859 if (err < 0)
9860 return err;
9861 } else
9862 return -1;
9863 sprintf(name, "%s Playback Switch", ctlname);
9864 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9865 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9866 if (err < 0)
9867 return err;
9868 return 0;
9869}
9870
9871/* add playback controls from the parsed DAC table */
9872static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9873 const struct auto_pin_cfg *cfg)
9874{
9875 hda_nid_t nid;
9876 int err;
9877
9878 spec->multiout.num_dacs = 2; /* only use one dac */
9879 spec->multiout.dac_nids = spec->private_dac_nids;
9880 spec->multiout.dac_nids[0] = 2;
9881 spec->multiout.dac_nids[1] = 3;
9882
9883 nid = cfg->line_out_pins[0];
9884 if (nid)
9885 alc268_new_analog_output(spec, nid, "Front", 0);
9886
9887 nid = cfg->speaker_pins[0];
9888 if (nid == 0x1d) {
9889 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9890 "Speaker Playback Volume",
9891 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9892 if (err < 0)
9893 return err;
9894 }
9895 nid = cfg->hp_pins[0];
9896 if (nid)
9897 alc268_new_analog_output(spec, nid, "Headphone", 0);
9898
9899 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9900 if (nid == 0x16) {
9901 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9902 "Mono Playback Switch",
9903 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9904 if (err < 0)
9905 return err;
9906 }
9907 return 0;
9908}
9909
9910/* create playback/capture controls for input pins */
9911static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9912 const struct auto_pin_cfg *cfg)
9913{
9914 struct hda_input_mux *imux = &spec->private_imux;
9915 int i, idx1;
9916
9917 for (i = 0; i < AUTO_PIN_LAST; i++) {
9918 switch(cfg->input_pins[i]) {
9919 case 0x18:
9920 idx1 = 0; /* Mic 1 */
9921 break;
9922 case 0x19:
9923 idx1 = 1; /* Mic 2 */
9924 break;
9925 case 0x1a:
9926 idx1 = 2; /* Line In */
9927 break;
9928 case 0x1c:
9929 idx1 = 3; /* CD */
9930 break;
9931 default:
9932 continue;
9933 }
9934 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9935 imux->items[imux->num_items].index = idx1;
9936 imux->num_items++;
9937 }
9938 return 0;
9939}
9940
9941static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9942{
9943 struct alc_spec *spec = codec->spec;
9944 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9945 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9946 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9947 unsigned int dac_vol1, dac_vol2;
9948
9949 if (speaker_nid) {
9950 snd_hda_codec_write(codec, speaker_nid, 0,
9951 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9952 snd_hda_codec_write(codec, 0x0f, 0,
9953 AC_VERB_SET_AMP_GAIN_MUTE,
9954 AMP_IN_UNMUTE(1));
9955 snd_hda_codec_write(codec, 0x10, 0,
9956 AC_VERB_SET_AMP_GAIN_MUTE,
9957 AMP_IN_UNMUTE(1));
9958 } else {
9959 snd_hda_codec_write(codec, 0x0f, 0,
9960 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9961 snd_hda_codec_write(codec, 0x10, 0,
9962 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9963 }
9964
9965 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9966 if (line_nid == 0x14)
9967 dac_vol2 = AMP_OUT_ZERO;
9968 else if (line_nid == 0x15)
9969 dac_vol1 = AMP_OUT_ZERO;
9970 if (hp_nid == 0x14)
9971 dac_vol2 = AMP_OUT_ZERO;
9972 else if (hp_nid == 0x15)
9973 dac_vol1 = AMP_OUT_ZERO;
9974 if (line_nid != 0x16 || hp_nid != 0x16 ||
9975 spec->autocfg.line_out_pins[1] != 0x16 ||
9976 spec->autocfg.line_out_pins[2] != 0x16)
9977 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9978
9979 snd_hda_codec_write(codec, 0x02, 0,
9980 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9981 snd_hda_codec_write(codec, 0x03, 0,
9982 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9983}
9984
9985/* pcm configuration: identiacal with ALC880 */
9986#define alc268_pcm_analog_playback alc880_pcm_analog_playback
9987#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 9988#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
9989#define alc268_pcm_digital_playback alc880_pcm_digital_playback
9990
9991/*
9992 * BIOS auto configuration
9993 */
9994static int alc268_parse_auto_config(struct hda_codec *codec)
9995{
9996 struct alc_spec *spec = codec->spec;
9997 int err;
9998 static hda_nid_t alc268_ignore[] = { 0 };
9999
10000 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10001 alc268_ignore);
10002 if (err < 0)
10003 return err;
10004 if (!spec->autocfg.line_outs)
10005 return 0; /* can't find valid BIOS pin config */
10006
10007 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10008 if (err < 0)
10009 return err;
10010 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10011 if (err < 0)
10012 return err;
10013
10014 spec->multiout.max_channels = 2;
10015
10016 /* digital only support output */
10017 if (spec->autocfg.dig_out_pin)
10018 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10019
10020 if (spec->kctl_alloc)
10021 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10022
10023 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10024 spec->num_mux_defs = 1;
10025 spec->input_mux = &spec->private_imux;
10026
776e184e
TI
10027 err = alc_auto_add_mic_boost(codec);
10028 if (err < 0)
10029 return err;
10030
a361d84b
KY
10031 return 1;
10032}
10033
10034#define alc268_auto_init_multi_out alc882_auto_init_multi_out
10035#define alc268_auto_init_hp_out alc882_auto_init_hp_out
10036#define alc268_auto_init_analog_input alc882_auto_init_analog_input
10037
10038/* init callback for auto-configuration model -- overriding the default init */
10039static void alc268_auto_init(struct hda_codec *codec)
10040{
f6c7e546 10041 struct alc_spec *spec = codec->spec;
a361d84b
KY
10042 alc268_auto_init_multi_out(codec);
10043 alc268_auto_init_hp_out(codec);
10044 alc268_auto_init_mono_speaker_out(codec);
10045 alc268_auto_init_analog_input(codec);
f6c7e546
TI
10046 if (spec->unsol_event)
10047 alc_sku_automute(codec);
a361d84b
KY
10048}
10049
10050/*
10051 * configuration and preset
10052 */
10053static const char *alc268_models[ALC268_MODEL_LAST] = {
10054 [ALC268_3ST] = "3stack",
983f8ae4 10055 [ALC268_TOSHIBA] = "toshiba",
d273809e 10056 [ALC268_ACER] = "acer",
3866f0b0 10057 [ALC268_DELL] = "dell",
f12462c5 10058 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
10059#ifdef CONFIG_SND_DEBUG
10060 [ALC268_TEST] = "test",
10061#endif
a361d84b
KY
10062 [ALC268_AUTO] = "auto",
10063};
10064
10065static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741 10066 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 10067 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 10068 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 10069 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
3866f0b0 10070 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 10071 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 10072 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 10073 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 10074 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 10075 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
f12462c5 10076 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
10077 {}
10078};
10079
10080static struct alc_config_preset alc268_presets[] = {
10081 [ALC268_3ST] = {
10082 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10083 .init_verbs = { alc268_base_init_verbs },
10084 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10085 .dac_nids = alc268_dac_nids,
10086 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10087 .adc_nids = alc268_adc_nids_alt,
e1406348 10088 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
10089 .hp_nid = 0x03,
10090 .dig_out_nid = ALC268_DIGOUT_NID,
10091 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10092 .channel_mode = alc268_modes,
10093 .input_mux = &alc268_capture_source,
10094 },
d1a991a6
KY
10095 [ALC268_TOSHIBA] = {
10096 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
d273809e
TI
10097 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10098 alc268_toshiba_verbs },
d1a991a6
KY
10099 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10100 .dac_nids = alc268_dac_nids,
10101 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10102 .adc_nids = alc268_adc_nids_alt,
e1406348 10103 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
10104 .hp_nid = 0x03,
10105 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10106 .channel_mode = alc268_modes,
10107 .input_mux = &alc268_capture_source,
d273809e
TI
10108 .unsol_event = alc268_toshiba_unsol_event,
10109 .init_hook = alc268_toshiba_automute,
10110 },
10111 [ALC268_ACER] = {
10112 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
10113 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10114 alc268_acer_verbs },
10115 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10116 .dac_nids = alc268_dac_nids,
10117 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10118 .adc_nids = alc268_adc_nids_alt,
e1406348 10119 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
10120 .hp_nid = 0x02,
10121 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10122 .channel_mode = alc268_modes,
10123 .input_mux = &alc268_capture_source,
10124 .unsol_event = alc268_acer_unsol_event,
889c4395 10125 .init_hook = alc268_acer_init_hook,
d1a991a6 10126 },
3866f0b0
TI
10127 [ALC268_DELL] = {
10128 .mixers = { alc268_dell_mixer },
10129 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10130 alc268_dell_verbs },
10131 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10132 .dac_nids = alc268_dac_nids,
10133 .hp_nid = 0x02,
10134 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10135 .channel_mode = alc268_modes,
10136 .unsol_event = alc268_dell_unsol_event,
10137 .init_hook = alc268_dell_init_hook,
10138 .input_mux = &alc268_capture_source,
10139 },
f12462c5
MT
10140 [ALC268_ZEPTO] = {
10141 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10142 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10143 alc268_toshiba_verbs },
10144 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10145 .dac_nids = alc268_dac_nids,
10146 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10147 .adc_nids = alc268_adc_nids_alt,
e1406348 10148 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
10149 .hp_nid = 0x03,
10150 .dig_out_nid = ALC268_DIGOUT_NID,
10151 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10152 .channel_mode = alc268_modes,
10153 .input_mux = &alc268_capture_source,
10154 .unsol_event = alc268_toshiba_unsol_event,
10155 .init_hook = alc268_toshiba_automute
10156 },
86c53bd2
JW
10157#ifdef CONFIG_SND_DEBUG
10158 [ALC268_TEST] = {
10159 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10160 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10161 alc268_volume_init_verbs },
10162 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10163 .dac_nids = alc268_dac_nids,
10164 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10165 .adc_nids = alc268_adc_nids_alt,
e1406348 10166 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
10167 .hp_nid = 0x03,
10168 .dig_out_nid = ALC268_DIGOUT_NID,
10169 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10170 .channel_mode = alc268_modes,
10171 .input_mux = &alc268_capture_source,
10172 },
10173#endif
a361d84b
KY
10174};
10175
10176static int patch_alc268(struct hda_codec *codec)
10177{
10178 struct alc_spec *spec;
10179 int board_config;
10180 int err;
10181
10182 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10183 if (spec == NULL)
10184 return -ENOMEM;
10185
10186 codec->spec = spec;
10187
10188 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10189 alc268_models,
10190 alc268_cfg_tbl);
10191
10192 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10193 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10194 "trying auto-probe from BIOS...\n");
10195 board_config = ALC268_AUTO;
10196 }
10197
10198 if (board_config == ALC268_AUTO) {
10199 /* automatic parse from the BIOS config */
10200 err = alc268_parse_auto_config(codec);
10201 if (err < 0) {
10202 alc_free(codec);
10203 return err;
10204 } else if (!err) {
10205 printk(KERN_INFO
10206 "hda_codec: Cannot set up configuration "
10207 "from BIOS. Using base mode...\n");
10208 board_config = ALC268_3ST;
10209 }
10210 }
10211
10212 if (board_config != ALC268_AUTO)
10213 setup_preset(spec, &alc268_presets[board_config]);
10214
10215 spec->stream_name_analog = "ALC268 Analog";
10216 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10217 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 10218 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b
KY
10219
10220 spec->stream_name_digital = "ALC268 Digital";
10221 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10222
3866f0b0
TI
10223 if (!spec->adc_nids && spec->input_mux) {
10224 /* check whether NID 0x07 is valid */
10225 unsigned int wcap = get_wcaps(codec, 0x07);
10226
10227 /* get type */
10228 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10229 if (wcap != AC_WID_AUD_IN) {
10230 spec->adc_nids = alc268_adc_nids_alt;
10231 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10232 spec->mixers[spec->num_mixers] =
a361d84b 10233 alc268_capture_alt_mixer;
3866f0b0
TI
10234 spec->num_mixers++;
10235 } else {
10236 spec->adc_nids = alc268_adc_nids;
10237 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10238 spec->mixers[spec->num_mixers] =
10239 alc268_capture_mixer;
10240 spec->num_mixers++;
a361d84b 10241 }
e1406348 10242 spec->capsrc_nids = alc268_capsrc_nids;
a361d84b 10243 }
2134ea4f
TI
10244
10245 spec->vmaster_nid = 0x02;
10246
a361d84b
KY
10247 codec->patch_ops = alc_patch_ops;
10248 if (board_config == ALC268_AUTO)
10249 spec->init_hook = alc268_auto_init;
10250
10251 return 0;
10252}
10253
f6a92248
KY
10254/*
10255 * ALC269 channel source setting (2 channel)
10256 */
10257#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10258
10259#define alc269_dac_nids alc260_dac_nids
10260
10261static hda_nid_t alc269_adc_nids[1] = {
10262 /* ADC1 */
10263 0x07,
10264};
10265
10266#define alc269_modes alc260_modes
10267#define alc269_capture_source alc880_lg_lw_capture_source
10268
10269static struct snd_kcontrol_new alc269_base_mixer[] = {
10270 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10271 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10272 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10273 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10277 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10278 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10279 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10280 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10281 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10282 { } /* end */
10283};
10284
10285/* capture mixer elements */
10286static struct snd_kcontrol_new alc269_capture_mixer[] = {
10287 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10288 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10289 {
10290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10291 /* The multiple "Capture Source" controls confuse alsamixer
10292 * So call somewhat different..
f6a92248
KY
10293 */
10294 /* .name = "Capture Source", */
10295 .name = "Input Source",
10296 .count = 1,
10297 .info = alc_mux_enum_info,
10298 .get = alc_mux_enum_get,
10299 .put = alc_mux_enum_put,
10300 },
10301 { } /* end */
10302};
10303
10304/*
10305 * generic initialization of ADC, input mixers and output mixers
10306 */
10307static struct hda_verb alc269_init_verbs[] = {
10308 /*
10309 * Unmute ADC0 and set the default input to mic-in
10310 */
10311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10312
10313 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10314 * analog-loopback mixer widget
10315 * Note: PASD motherboards uses the Line In 2 as the input for
10316 * front panel mic (mic 2)
10317 */
10318 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10319 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10320 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10322 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10323 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10324
10325 /*
10326 * Set up output mixers (0x0c - 0x0e)
10327 */
10328 /* set vol=0 to output mixers */
10329 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10330 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10331
10332 /* set up input amps for analog loopback */
10333 /* Amp Indices: DAC = 0, mixer = 1 */
10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10336 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10337 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10338 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10339 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10340
10341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10343 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10344 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10345 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10346 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10348
10349 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10350 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10351 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10353 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10354 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10355 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10356
10357 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10358 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10359
10360 /* FIXME: use matrix-type input source selection */
10361 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10362 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10365 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10366 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10367
10368 /* set EAPD */
10369 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10370 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10371 { }
10372};
10373
10374/* add playback controls from the parsed DAC table */
10375static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10376 const struct auto_pin_cfg *cfg)
10377{
10378 hda_nid_t nid;
10379 int err;
10380
10381 spec->multiout.num_dacs = 1; /* only use one dac */
10382 spec->multiout.dac_nids = spec->private_dac_nids;
10383 spec->multiout.dac_nids[0] = 2;
10384
10385 nid = cfg->line_out_pins[0];
10386 if (nid) {
10387 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10388 "Front Playback Volume",
10389 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10390 if (err < 0)
10391 return err;
10392 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10393 "Front Playback Switch",
10394 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10395 if (err < 0)
10396 return err;
10397 }
10398
10399 nid = cfg->speaker_pins[0];
10400 if (nid) {
10401 if (!cfg->line_out_pins[0]) {
10402 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10403 "Speaker Playback Volume",
10404 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10405 HDA_OUTPUT));
10406 if (err < 0)
10407 return err;
10408 }
10409 if (nid == 0x16) {
10410 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10411 "Speaker Playback Switch",
10412 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10413 HDA_OUTPUT));
10414 if (err < 0)
10415 return err;
10416 } else {
10417 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10418 "Speaker Playback Switch",
10419 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10420 HDA_OUTPUT));
10421 if (err < 0)
10422 return err;
10423 }
10424 }
10425 nid = cfg->hp_pins[0];
10426 if (nid) {
10427 /* spec->multiout.hp_nid = 2; */
10428 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10429 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10430 "Headphone Playback Volume",
10431 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10432 HDA_OUTPUT));
10433 if (err < 0)
10434 return err;
10435 }
10436 if (nid == 0x16) {
10437 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10438 "Headphone Playback Switch",
10439 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10440 HDA_OUTPUT));
10441 if (err < 0)
10442 return err;
10443 } else {
10444 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10445 "Headphone Playback Switch",
10446 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10447 HDA_OUTPUT));
10448 if (err < 0)
10449 return err;
10450 }
10451 }
10452 return 0;
10453}
10454
10455#define alc269_auto_create_analog_input_ctls \
10456 alc880_auto_create_analog_input_ctls
10457
10458#ifdef CONFIG_SND_HDA_POWER_SAVE
10459#define alc269_loopbacks alc880_loopbacks
10460#endif
10461
10462/* pcm configuration: identiacal with ALC880 */
10463#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10464#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10465#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10466#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10467
10468/*
10469 * BIOS auto configuration
10470 */
10471static int alc269_parse_auto_config(struct hda_codec *codec)
10472{
10473 struct alc_spec *spec = codec->spec;
10474 int err;
10475 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10476
10477 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10478 alc269_ignore);
10479 if (err < 0)
10480 return err;
10481
10482 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10483 if (err < 0)
10484 return err;
10485 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10486 if (err < 0)
10487 return err;
10488
10489 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10490
10491 if (spec->autocfg.dig_out_pin)
10492 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10493
10494 if (spec->kctl_alloc)
10495 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10496
10497 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10498 spec->num_mux_defs = 1;
10499 spec->input_mux = &spec->private_imux;
10500
10501 err = alc_auto_add_mic_boost(codec);
10502 if (err < 0)
10503 return err;
10504
10505 return 1;
10506}
10507
10508#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10509#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10510#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10511
10512
10513/* init callback for auto-configuration model -- overriding the default init */
10514static void alc269_auto_init(struct hda_codec *codec)
10515{
f6c7e546 10516 struct alc_spec *spec = codec->spec;
f6a92248
KY
10517 alc269_auto_init_multi_out(codec);
10518 alc269_auto_init_hp_out(codec);
10519 alc269_auto_init_analog_input(codec);
f6c7e546
TI
10520 if (spec->unsol_event)
10521 alc_sku_automute(codec);
f6a92248
KY
10522}
10523
10524/*
10525 * configuration and preset
10526 */
10527static const char *alc269_models[ALC269_MODEL_LAST] = {
10528 [ALC269_BASIC] = "basic",
10529};
10530
10531static struct snd_pci_quirk alc269_cfg_tbl[] = {
10532 {}
10533};
10534
10535static struct alc_config_preset alc269_presets[] = {
10536 [ALC269_BASIC] = {
10537 .mixers = { alc269_base_mixer },
10538 .init_verbs = { alc269_init_verbs },
10539 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10540 .dac_nids = alc269_dac_nids,
10541 .hp_nid = 0x03,
10542 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10543 .channel_mode = alc269_modes,
10544 .input_mux = &alc269_capture_source,
10545 },
10546};
10547
10548static int patch_alc269(struct hda_codec *codec)
10549{
10550 struct alc_spec *spec;
10551 int board_config;
10552 int err;
10553
10554 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10555 if (spec == NULL)
10556 return -ENOMEM;
10557
10558 codec->spec = spec;
10559
10560 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10561 alc269_models,
10562 alc269_cfg_tbl);
10563
10564 if (board_config < 0) {
10565 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10566 "trying auto-probe from BIOS...\n");
10567 board_config = ALC269_AUTO;
10568 }
10569
10570 if (board_config == ALC269_AUTO) {
10571 /* automatic parse from the BIOS config */
10572 err = alc269_parse_auto_config(codec);
10573 if (err < 0) {
10574 alc_free(codec);
10575 return err;
10576 } else if (!err) {
10577 printk(KERN_INFO
10578 "hda_codec: Cannot set up configuration "
10579 "from BIOS. Using base mode...\n");
10580 board_config = ALC269_BASIC;
10581 }
10582 }
10583
10584 if (board_config != ALC269_AUTO)
10585 setup_preset(spec, &alc269_presets[board_config]);
10586
10587 spec->stream_name_analog = "ALC269 Analog";
10588 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10589 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10590
10591 spec->stream_name_digital = "ALC269 Digital";
10592 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10593 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10594
10595 spec->adc_nids = alc269_adc_nids;
10596 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10597 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10598 spec->num_mixers++;
10599
10600 codec->patch_ops = alc_patch_ops;
10601 if (board_config == ALC269_AUTO)
10602 spec->init_hook = alc269_auto_init;
10603#ifdef CONFIG_SND_HDA_POWER_SAVE
10604 if (!spec->loopback.amplist)
10605 spec->loopback.amplist = alc269_loopbacks;
10606#endif
10607
10608 return 0;
10609}
10610
df694daa
KY
10611/*
10612 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10613 */
10614
10615/*
10616 * set the path ways for 2 channel output
10617 * need to set the codec line out and mic 1 pin widgets to inputs
10618 */
10619static struct hda_verb alc861_threestack_ch2_init[] = {
10620 /* set pin widget 1Ah (line in) for input */
10621 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10622 /* set pin widget 18h (mic1/2) for input, for mic also enable
10623 * the vref
10624 */
df694daa
KY
10625 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10626
9c7f852e
TI
10627 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10628#if 0
10629 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10630 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10631#endif
df694daa
KY
10632 { } /* end */
10633};
10634/*
10635 * 6ch mode
10636 * need to set the codec line out and mic 1 pin widgets to outputs
10637 */
10638static struct hda_verb alc861_threestack_ch6_init[] = {
10639 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10640 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10641 /* set pin widget 18h (mic1) for output (CLFE)*/
10642 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10643
10644 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10645 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10646
9c7f852e
TI
10647 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10648#if 0
10649 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10650 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10651#endif
df694daa
KY
10652 { } /* end */
10653};
10654
10655static struct hda_channel_mode alc861_threestack_modes[2] = {
10656 { 2, alc861_threestack_ch2_init },
10657 { 6, alc861_threestack_ch6_init },
10658};
22309c3e
TI
10659/* Set mic1 as input and unmute the mixer */
10660static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10661 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10662 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10663 { } /* end */
10664};
10665/* Set mic1 as output and mute mixer */
10666static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10667 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10668 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10669 { } /* end */
10670};
10671
10672static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10673 { 2, alc861_uniwill_m31_ch2_init },
10674 { 4, alc861_uniwill_m31_ch4_init },
10675};
df694daa 10676
7cdbff94
MD
10677/* Set mic1 and line-in as input and unmute the mixer */
10678static struct hda_verb alc861_asus_ch2_init[] = {
10679 /* set pin widget 1Ah (line in) for input */
10680 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10681 /* set pin widget 18h (mic1/2) for input, for mic also enable
10682 * the vref
10683 */
7cdbff94
MD
10684 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10685
10686 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10687#if 0
10688 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10689 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10690#endif
10691 { } /* end */
10692};
10693/* Set mic1 nad line-in as output and mute mixer */
10694static struct hda_verb alc861_asus_ch6_init[] = {
10695 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10696 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10697 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10698 /* set pin widget 18h (mic1) for output (CLFE)*/
10699 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10700 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10701 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10702 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10703
10704 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10705#if 0
10706 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10707 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10708#endif
10709 { } /* end */
10710};
10711
10712static struct hda_channel_mode alc861_asus_modes[2] = {
10713 { 2, alc861_asus_ch2_init },
10714 { 6, alc861_asus_ch6_init },
10715};
10716
df694daa
KY
10717/* patch-ALC861 */
10718
10719static struct snd_kcontrol_new alc861_base_mixer[] = {
10720 /* output mixer control */
10721 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10722 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10723 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10724 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10725 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10726
10727 /*Input mixer control */
10728 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10729 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10730 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10731 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10732 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10733 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10735 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10736 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10738
df694daa
KY
10739 /* Capture mixer control */
10740 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10741 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10742 {
10743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10744 .name = "Capture Source",
10745 .count = 1,
10746 .info = alc_mux_enum_info,
10747 .get = alc_mux_enum_get,
10748 .put = alc_mux_enum_put,
10749 },
10750 { } /* end */
10751};
10752
10753static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10754 /* output mixer control */
10755 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10756 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10757 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10758 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10759 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10760
10761 /* Input mixer control */
10762 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10763 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10764 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10765 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10766 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10767 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10768 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10769 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10770 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10772
df694daa
KY
10773 /* Capture mixer control */
10774 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10775 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10776 {
10777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10778 .name = "Capture Source",
10779 .count = 1,
10780 .info = alc_mux_enum_info,
10781 .get = alc_mux_enum_get,
10782 .put = alc_mux_enum_put,
10783 },
10784 {
10785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10786 .name = "Channel Mode",
10787 .info = alc_ch_mode_info,
10788 .get = alc_ch_mode_get,
10789 .put = alc_ch_mode_put,
10790 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10791 },
10792 { } /* end */
a53d1aec
TD
10793};
10794
d1d985f0 10795static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10796 /* output mixer control */
10797 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10799 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10800
10801 /*Capture mixer control */
10802 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10803 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10804 {
10805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10806 .name = "Capture Source",
10807 .count = 1,
10808 .info = alc_mux_enum_info,
10809 .get = alc_mux_enum_get,
10810 .put = alc_mux_enum_put,
10811 },
10812
10813 { } /* end */
f12ab1e0 10814};
a53d1aec 10815
22309c3e
TI
10816static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10817 /* output mixer control */
10818 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10819 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10820 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10821 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10822 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10823
10824 /* Input mixer control */
10825 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10826 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10827 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10828 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10829 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10830 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10832 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10833 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10835
22309c3e
TI
10836 /* Capture mixer control */
10837 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10838 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10839 {
10840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10841 .name = "Capture Source",
10842 .count = 1,
10843 .info = alc_mux_enum_info,
10844 .get = alc_mux_enum_get,
10845 .put = alc_mux_enum_put,
10846 },
10847 {
10848 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10849 .name = "Channel Mode",
10850 .info = alc_ch_mode_info,
10851 .get = alc_ch_mode_get,
10852 .put = alc_ch_mode_put,
10853 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10854 },
10855 { } /* end */
f12ab1e0 10856};
7cdbff94
MD
10857
10858static struct snd_kcontrol_new alc861_asus_mixer[] = {
10859 /* output mixer control */
10860 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10861 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10862 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10863 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10864 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10865
10866 /* Input mixer control */
10867 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10868 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10869 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10870 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10871 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10872 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10874 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10875 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
10876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10877
7cdbff94
MD
10878 /* Capture mixer control */
10879 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10880 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10881 {
10882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10883 .name = "Capture Source",
10884 .count = 1,
10885 .info = alc_mux_enum_info,
10886 .get = alc_mux_enum_get,
10887 .put = alc_mux_enum_put,
10888 },
10889 {
10890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10891 .name = "Channel Mode",
10892 .info = alc_ch_mode_info,
10893 .get = alc_ch_mode_get,
10894 .put = alc_ch_mode_put,
10895 .private_value = ARRAY_SIZE(alc861_asus_modes),
10896 },
10897 { }
56bb0cab
TI
10898};
10899
10900/* additional mixer */
d1d985f0 10901static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
10902 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10903 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10904 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10905 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10906 { }
10907};
7cdbff94 10908
df694daa
KY
10909/*
10910 * generic initialization of ADC, input mixers and output mixers
10911 */
10912static struct hda_verb alc861_base_init_verbs[] = {
10913 /*
10914 * Unmute ADC0 and set the default input to mic-in
10915 */
10916 /* port-A for surround (rear panel) */
10917 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10918 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10919 /* port-B for mic-in (rear panel) with vref */
10920 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10921 /* port-C for line-in (rear panel) */
10922 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10923 /* port-D for Front */
10924 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10925 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10926 /* port-E for HP out (front panel) */
10927 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10928 /* route front PCM to HP */
9dece1d7 10929 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10930 /* port-F for mic-in (front panel) with vref */
10931 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10932 /* port-G for CLFE (rear panel) */
10933 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10934 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10935 /* port-H for side (rear panel) */
10936 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10937 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10938 /* CD-in */
10939 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10940 /* route front mic to ADC1*/
10941 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10942 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10943
10944 /* Unmute DAC0~3 & spdif out*/
10945 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10946 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10947 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10948 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10949 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10950
10951 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10952 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10953 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10954 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10955 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10956
10957 /* Unmute Stereo Mixer 15 */
10958 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10959 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10960 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10962
10963 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10964 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10965 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10967 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10968 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10969 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10971 /* hp used DAC 3 (Front) */
10972 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10973 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10974
10975 { }
10976};
10977
10978static struct hda_verb alc861_threestack_init_verbs[] = {
10979 /*
10980 * Unmute ADC0 and set the default input to mic-in
10981 */
10982 /* port-A for surround (rear panel) */
10983 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10984 /* port-B for mic-in (rear panel) with vref */
10985 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10986 /* port-C for line-in (rear panel) */
10987 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10988 /* port-D for Front */
10989 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10990 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10991 /* port-E for HP out (front panel) */
10992 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10993 /* route front PCM to HP */
9dece1d7 10994 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10995 /* port-F for mic-in (front panel) with vref */
10996 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10997 /* port-G for CLFE (rear panel) */
10998 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10999 /* port-H for side (rear panel) */
11000 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11001 /* CD-in */
11002 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11003 /* route front mic to ADC1*/
11004 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11005 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11006 /* Unmute DAC0~3 & spdif out*/
11007 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11008 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11009 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11010 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11012
11013 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11014 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11015 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11016 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11017 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11018
11019 /* Unmute Stereo Mixer 15 */
11020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11021 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11022 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11023 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11024
11025 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11026 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11027 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11028 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11029 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11030 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11031 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11033 /* hp used DAC 3 (Front) */
11034 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11035 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11036 { }
11037};
22309c3e
TI
11038
11039static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11040 /*
11041 * Unmute ADC0 and set the default input to mic-in
11042 */
11043 /* port-A for surround (rear panel) */
11044 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11045 /* port-B for mic-in (rear panel) with vref */
11046 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11047 /* port-C for line-in (rear panel) */
11048 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11049 /* port-D for Front */
11050 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11051 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11052 /* port-E for HP out (front panel) */
f12ab1e0
TI
11053 /* this has to be set to VREF80 */
11054 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 11055 /* route front PCM to HP */
9dece1d7 11056 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
11057 /* port-F for mic-in (front panel) with vref */
11058 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11059 /* port-G for CLFE (rear panel) */
11060 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11061 /* port-H for side (rear panel) */
11062 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11063 /* CD-in */
11064 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11065 /* route front mic to ADC1*/
11066 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11068 /* Unmute DAC0~3 & spdif out*/
11069 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11070 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11071 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11072 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11074
11075 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11076 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11077 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11078 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11079 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11080
11081 /* Unmute Stereo Mixer 15 */
11082 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11083 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
11086
11087 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11088 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11089 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11090 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11093 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11095 /* hp used DAC 3 (Front) */
11096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
11097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11098 { }
11099};
11100
7cdbff94
MD
11101static struct hda_verb alc861_asus_init_verbs[] = {
11102 /*
11103 * Unmute ADC0 and set the default input to mic-in
11104 */
f12ab1e0
TI
11105 /* port-A for surround (rear panel)
11106 * according to codec#0 this is the HP jack
11107 */
7cdbff94
MD
11108 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11109 /* route front PCM to HP */
11110 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11111 /* port-B for mic-in (rear panel) with vref */
11112 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11113 /* port-C for line-in (rear panel) */
11114 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11115 /* port-D for Front */
11116 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11117 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11118 /* port-E for HP out (front panel) */
f12ab1e0
TI
11119 /* this has to be set to VREF80 */
11120 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 11121 /* route front PCM to HP */
9dece1d7 11122 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
11123 /* port-F for mic-in (front panel) with vref */
11124 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11125 /* port-G for CLFE (rear panel) */
11126 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11127 /* port-H for side (rear panel) */
11128 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11129 /* CD-in */
11130 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11131 /* route front mic to ADC1*/
11132 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11133 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11134 /* Unmute DAC0~3 & spdif out*/
11135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11136 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11137 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11138 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11139 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11140 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11141 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11144 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11145
11146 /* Unmute Stereo Mixer 15 */
11147 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11149 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11150 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
11151
11152 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11153 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11154 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11155 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11156 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11157 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11158 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11159 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11160 /* hp used DAC 3 (Front) */
11161 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
11162 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11163 { }
11164};
11165
56bb0cab
TI
11166/* additional init verbs for ASUS laptops */
11167static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11168 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11169 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11170 { }
11171};
7cdbff94 11172
df694daa
KY
11173/*
11174 * generic initialization of ADC, input mixers and output mixers
11175 */
11176static struct hda_verb alc861_auto_init_verbs[] = {
11177 /*
11178 * Unmute ADC0 and set the default input to mic-in
11179 */
f12ab1e0 11180 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
11181 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11182
11183 /* Unmute DAC0~3 & spdif out*/
11184 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11185 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11186 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11187 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11189
11190 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11191 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11192 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11193 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11194 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11195
11196 /* Unmute Stereo Mixer 15 */
11197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11198 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11199 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11201
11202 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11203 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11204 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11205 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11206 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11207 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11208 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11209 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11210
11211 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11212 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11213 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11214 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11215 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11216 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11217 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11218 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 11219
f12ab1e0 11220 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
11221
11222 { }
11223};
11224
a53d1aec
TD
11225static struct hda_verb alc861_toshiba_init_verbs[] = {
11226 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 11227
a53d1aec
TD
11228 { }
11229};
11230
11231/* toggle speaker-output according to the hp-jack state */
11232static void alc861_toshiba_automute(struct hda_codec *codec)
11233{
11234 unsigned int present;
11235
11236 present = snd_hda_codec_read(codec, 0x0f, 0,
11237 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11238 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11239 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11240 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11241 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
11242}
11243
11244static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11245 unsigned int res)
11246{
a53d1aec
TD
11247 if ((res >> 26) == ALC880_HP_EVENT)
11248 alc861_toshiba_automute(codec);
11249}
11250
df694daa
KY
11251/* pcm configuration: identiacal with ALC880 */
11252#define alc861_pcm_analog_playback alc880_pcm_analog_playback
11253#define alc861_pcm_analog_capture alc880_pcm_analog_capture
11254#define alc861_pcm_digital_playback alc880_pcm_digital_playback
11255#define alc861_pcm_digital_capture alc880_pcm_digital_capture
11256
11257
11258#define ALC861_DIGOUT_NID 0x07
11259
11260static struct hda_channel_mode alc861_8ch_modes[1] = {
11261 { 8, NULL }
11262};
11263
11264static hda_nid_t alc861_dac_nids[4] = {
11265 /* front, surround, clfe, side */
11266 0x03, 0x06, 0x05, 0x04
11267};
11268
9c7f852e
TI
11269static hda_nid_t alc660_dac_nids[3] = {
11270 /* front, clfe, surround */
11271 0x03, 0x05, 0x06
11272};
11273
df694daa
KY
11274static hda_nid_t alc861_adc_nids[1] = {
11275 /* ADC0-2 */
11276 0x08,
11277};
11278
11279static struct hda_input_mux alc861_capture_source = {
11280 .num_items = 5,
11281 .items = {
11282 { "Mic", 0x0 },
11283 { "Front Mic", 0x3 },
11284 { "Line", 0x1 },
11285 { "CD", 0x4 },
11286 { "Mixer", 0x5 },
11287 },
11288};
11289
11290/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
11291static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11292 const struct auto_pin_cfg *cfg)
df694daa
KY
11293{
11294 int i;
11295 hda_nid_t nid;
11296
11297 spec->multiout.dac_nids = spec->private_dac_nids;
11298 for (i = 0; i < cfg->line_outs; i++) {
11299 nid = cfg->line_out_pins[i];
11300 if (nid) {
11301 if (i >= ARRAY_SIZE(alc861_dac_nids))
11302 continue;
11303 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11304 }
11305 }
11306 spec->multiout.num_dacs = cfg->line_outs;
11307 return 0;
11308}
11309
11310/* add playback controls from the parsed DAC table */
11311static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11312 const struct auto_pin_cfg *cfg)
11313{
11314 char name[32];
f12ab1e0
TI
11315 static const char *chname[4] = {
11316 "Front", "Surround", NULL /*CLFE*/, "Side"
11317 };
df694daa
KY
11318 hda_nid_t nid;
11319 int i, idx, err;
11320
11321 for (i = 0; i < cfg->line_outs; i++) {
11322 nid = spec->multiout.dac_nids[i];
f12ab1e0 11323 if (!nid)
df694daa
KY
11324 continue;
11325 if (nid == 0x05) {
11326 /* Center/LFE */
f12ab1e0
TI
11327 err = add_control(spec, ALC_CTL_BIND_MUTE,
11328 "Center Playback Switch",
11329 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11330 HDA_OUTPUT));
11331 if (err < 0)
df694daa 11332 return err;
f12ab1e0
TI
11333 err = add_control(spec, ALC_CTL_BIND_MUTE,
11334 "LFE Playback Switch",
11335 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11336 HDA_OUTPUT));
11337 if (err < 0)
df694daa
KY
11338 return err;
11339 } else {
f12ab1e0
TI
11340 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11341 idx++)
df694daa
KY
11342 if (nid == alc861_dac_nids[idx])
11343 break;
11344 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
11345 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11346 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11347 HDA_OUTPUT));
11348 if (err < 0)
df694daa
KY
11349 return err;
11350 }
11351 }
11352 return 0;
11353}
11354
11355static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11356{
11357 int err;
11358 hda_nid_t nid;
11359
f12ab1e0 11360 if (!pin)
df694daa
KY
11361 return 0;
11362
11363 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11364 nid = 0x03;
f12ab1e0
TI
11365 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11366 "Headphone Playback Switch",
11367 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11368 if (err < 0)
df694daa
KY
11369 return err;
11370 spec->multiout.hp_nid = nid;
11371 }
11372 return 0;
11373}
11374
11375/* create playback/capture controls for input pins */
f12ab1e0
TI
11376static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11377 const struct auto_pin_cfg *cfg)
df694daa 11378{
df694daa
KY
11379 struct hda_input_mux *imux = &spec->private_imux;
11380 int i, err, idx, idx1;
11381
11382 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 11383 switch (cfg->input_pins[i]) {
df694daa
KY
11384 case 0x0c:
11385 idx1 = 1;
f12ab1e0 11386 idx = 2; /* Line In */
df694daa
KY
11387 break;
11388 case 0x0f:
11389 idx1 = 2;
f12ab1e0 11390 idx = 2; /* Line In */
df694daa
KY
11391 break;
11392 case 0x0d:
11393 idx1 = 0;
f12ab1e0 11394 idx = 1; /* Mic In */
df694daa 11395 break;
f12ab1e0 11396 case 0x10:
df694daa 11397 idx1 = 3;
f12ab1e0 11398 idx = 1; /* Mic In */
df694daa
KY
11399 break;
11400 case 0x11:
11401 idx1 = 4;
f12ab1e0 11402 idx = 0; /* CD */
df694daa
KY
11403 break;
11404 default:
11405 continue;
11406 }
11407
4a471b7d
TI
11408 err = new_analog_input(spec, cfg->input_pins[i],
11409 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
11410 if (err < 0)
11411 return err;
11412
4a471b7d 11413 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 11414 imux->items[imux->num_items].index = idx1;
f12ab1e0 11415 imux->num_items++;
df694daa
KY
11416 }
11417 return 0;
11418}
11419
11420static struct snd_kcontrol_new alc861_capture_mixer[] = {
11421 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11422 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11423
11424 {
11425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11426 /* The multiple "Capture Source" controls confuse alsamixer
11427 * So call somewhat different..
df694daa
KY
11428 */
11429 /* .name = "Capture Source", */
11430 .name = "Input Source",
11431 .count = 1,
11432 .info = alc_mux_enum_info,
11433 .get = alc_mux_enum_get,
11434 .put = alc_mux_enum_put,
11435 },
11436 { } /* end */
11437};
11438
f12ab1e0
TI
11439static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11440 hda_nid_t nid,
df694daa
KY
11441 int pin_type, int dac_idx)
11442{
f6c7e546 11443 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
11444}
11445
11446static void alc861_auto_init_multi_out(struct hda_codec *codec)
11447{
11448 struct alc_spec *spec = codec->spec;
11449 int i;
11450
bc9f98a9 11451 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
11452 for (i = 0; i < spec->autocfg.line_outs; i++) {
11453 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11454 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 11455 if (nid)
baba8ee9 11456 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11457 spec->multiout.dac_nids[i]);
df694daa
KY
11458 }
11459}
11460
11461static void alc861_auto_init_hp_out(struct hda_codec *codec)
11462{
11463 struct alc_spec *spec = codec->spec;
11464 hda_nid_t pin;
11465
eb06ed8f 11466 pin = spec->autocfg.hp_pins[0];
df694daa 11467 if (pin) /* connect to front */
f12ab1e0
TI
11468 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11469 spec->multiout.dac_nids[0]);
f6c7e546
TI
11470 pin = spec->autocfg.speaker_pins[0];
11471 if (pin)
11472 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
11473}
11474
11475static void alc861_auto_init_analog_input(struct hda_codec *codec)
11476{
11477 struct alc_spec *spec = codec->spec;
11478 int i;
11479
11480 for (i = 0; i < AUTO_PIN_LAST; i++) {
11481 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11482 if (nid >= 0x0c && nid <= 0x11) {
11483 snd_hda_codec_write(codec, nid, 0,
11484 AC_VERB_SET_PIN_WIDGET_CONTROL,
11485 i <= AUTO_PIN_FRONT_MIC ?
11486 PIN_VREF80 : PIN_IN);
df694daa
KY
11487 }
11488 }
11489}
11490
11491/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11492/* return 1 if successful, 0 if the proper config is not found,
11493 * or a negative error code
11494 */
df694daa
KY
11495static int alc861_parse_auto_config(struct hda_codec *codec)
11496{
11497 struct alc_spec *spec = codec->spec;
11498 int err;
11499 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11500
f12ab1e0
TI
11501 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11502 alc861_ignore);
11503 if (err < 0)
df694daa 11504 return err;
f12ab1e0 11505 if (!spec->autocfg.line_outs)
df694daa
KY
11506 return 0; /* can't find valid BIOS pin config */
11507
f12ab1e0
TI
11508 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11509 if (err < 0)
11510 return err;
11511 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11512 if (err < 0)
11513 return err;
11514 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11515 if (err < 0)
11516 return err;
11517 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11518 if (err < 0)
df694daa
KY
11519 return err;
11520
11521 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11522
11523 if (spec->autocfg.dig_out_pin)
11524 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11525
11526 if (spec->kctl_alloc)
11527 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11528
11529 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11530
a1e8d2da 11531 spec->num_mux_defs = 1;
df694daa
KY
11532 spec->input_mux = &spec->private_imux;
11533
11534 spec->adc_nids = alc861_adc_nids;
11535 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11536 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11537 spec->num_mixers++;
11538
11539 return 1;
11540}
11541
ae6b813a
TI
11542/* additional initialization for auto-configuration model */
11543static void alc861_auto_init(struct hda_codec *codec)
df694daa 11544{
f6c7e546 11545 struct alc_spec *spec = codec->spec;
df694daa
KY
11546 alc861_auto_init_multi_out(codec);
11547 alc861_auto_init_hp_out(codec);
11548 alc861_auto_init_analog_input(codec);
f6c7e546
TI
11549 if (spec->unsol_event)
11550 alc_sku_automute(codec);
df694daa
KY
11551}
11552
cb53c626
TI
11553#ifdef CONFIG_SND_HDA_POWER_SAVE
11554static struct hda_amp_list alc861_loopbacks[] = {
11555 { 0x15, HDA_INPUT, 0 },
11556 { 0x15, HDA_INPUT, 1 },
11557 { 0x15, HDA_INPUT, 2 },
11558 { 0x15, HDA_INPUT, 3 },
11559 { } /* end */
11560};
11561#endif
11562
df694daa
KY
11563
11564/*
11565 * configuration and preset
11566 */
f5fcc13c
TI
11567static const char *alc861_models[ALC861_MODEL_LAST] = {
11568 [ALC861_3ST] = "3stack",
11569 [ALC660_3ST] = "3stack-660",
11570 [ALC861_3ST_DIG] = "3stack-dig",
11571 [ALC861_6ST_DIG] = "6stack-dig",
11572 [ALC861_UNIWILL_M31] = "uniwill-m31",
11573 [ALC861_TOSHIBA] = "toshiba",
11574 [ALC861_ASUS] = "asus",
11575 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11576 [ALC861_AUTO] = "auto",
11577};
11578
11579static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11580 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11581 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11582 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11583 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11584 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11585 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11586 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11587 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11588 * Any other models that need this preset?
11589 */
11590 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11591 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11592 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11593 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11594 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11595 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11596 /* FIXME: the below seems conflict */
11597 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11598 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11599 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11600 {}
11601};
11602
11603static struct alc_config_preset alc861_presets[] = {
11604 [ALC861_3ST] = {
11605 .mixers = { alc861_3ST_mixer },
11606 .init_verbs = { alc861_threestack_init_verbs },
11607 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11608 .dac_nids = alc861_dac_nids,
11609 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11610 .channel_mode = alc861_threestack_modes,
4e195a7b 11611 .need_dac_fix = 1,
df694daa
KY
11612 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11613 .adc_nids = alc861_adc_nids,
11614 .input_mux = &alc861_capture_source,
11615 },
11616 [ALC861_3ST_DIG] = {
11617 .mixers = { alc861_base_mixer },
11618 .init_verbs = { alc861_threestack_init_verbs },
11619 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11620 .dac_nids = alc861_dac_nids,
11621 .dig_out_nid = ALC861_DIGOUT_NID,
11622 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11623 .channel_mode = alc861_threestack_modes,
4e195a7b 11624 .need_dac_fix = 1,
df694daa
KY
11625 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11626 .adc_nids = alc861_adc_nids,
11627 .input_mux = &alc861_capture_source,
11628 },
11629 [ALC861_6ST_DIG] = {
11630 .mixers = { alc861_base_mixer },
11631 .init_verbs = { alc861_base_init_verbs },
11632 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11633 .dac_nids = alc861_dac_nids,
11634 .dig_out_nid = ALC861_DIGOUT_NID,
11635 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11636 .channel_mode = alc861_8ch_modes,
11637 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11638 .adc_nids = alc861_adc_nids,
11639 .input_mux = &alc861_capture_source,
11640 },
9c7f852e
TI
11641 [ALC660_3ST] = {
11642 .mixers = { alc861_3ST_mixer },
11643 .init_verbs = { alc861_threestack_init_verbs },
11644 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11645 .dac_nids = alc660_dac_nids,
11646 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11647 .channel_mode = alc861_threestack_modes,
4e195a7b 11648 .need_dac_fix = 1,
9c7f852e
TI
11649 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11650 .adc_nids = alc861_adc_nids,
11651 .input_mux = &alc861_capture_source,
11652 },
22309c3e
TI
11653 [ALC861_UNIWILL_M31] = {
11654 .mixers = { alc861_uniwill_m31_mixer },
11655 .init_verbs = { alc861_uniwill_m31_init_verbs },
11656 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11657 .dac_nids = alc861_dac_nids,
11658 .dig_out_nid = ALC861_DIGOUT_NID,
11659 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11660 .channel_mode = alc861_uniwill_m31_modes,
11661 .need_dac_fix = 1,
11662 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11663 .adc_nids = alc861_adc_nids,
11664 .input_mux = &alc861_capture_source,
11665 },
a53d1aec
TD
11666 [ALC861_TOSHIBA] = {
11667 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11668 .init_verbs = { alc861_base_init_verbs,
11669 alc861_toshiba_init_verbs },
a53d1aec
TD
11670 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11671 .dac_nids = alc861_dac_nids,
11672 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11673 .channel_mode = alc883_3ST_2ch_modes,
11674 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11675 .adc_nids = alc861_adc_nids,
11676 .input_mux = &alc861_capture_source,
11677 .unsol_event = alc861_toshiba_unsol_event,
11678 .init_hook = alc861_toshiba_automute,
11679 },
7cdbff94
MD
11680 [ALC861_ASUS] = {
11681 .mixers = { alc861_asus_mixer },
11682 .init_verbs = { alc861_asus_init_verbs },
11683 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11684 .dac_nids = alc861_dac_nids,
11685 .dig_out_nid = ALC861_DIGOUT_NID,
11686 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11687 .channel_mode = alc861_asus_modes,
11688 .need_dac_fix = 1,
11689 .hp_nid = 0x06,
11690 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11691 .adc_nids = alc861_adc_nids,
11692 .input_mux = &alc861_capture_source,
11693 },
56bb0cab
TI
11694 [ALC861_ASUS_LAPTOP] = {
11695 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11696 .init_verbs = { alc861_asus_init_verbs,
11697 alc861_asus_laptop_init_verbs },
11698 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11699 .dac_nids = alc861_dac_nids,
11700 .dig_out_nid = ALC861_DIGOUT_NID,
11701 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11702 .channel_mode = alc883_3ST_2ch_modes,
11703 .need_dac_fix = 1,
11704 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11705 .adc_nids = alc861_adc_nids,
11706 .input_mux = &alc861_capture_source,
11707 },
11708};
df694daa
KY
11709
11710
11711static int patch_alc861(struct hda_codec *codec)
11712{
11713 struct alc_spec *spec;
11714 int board_config;
11715 int err;
11716
dc041e0b 11717 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11718 if (spec == NULL)
11719 return -ENOMEM;
11720
f12ab1e0 11721 codec->spec = spec;
df694daa 11722
f5fcc13c
TI
11723 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11724 alc861_models,
11725 alc861_cfg_tbl);
9c7f852e 11726
f5fcc13c 11727 if (board_config < 0) {
9c7f852e
TI
11728 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11729 "trying auto-probe from BIOS...\n");
df694daa
KY
11730 board_config = ALC861_AUTO;
11731 }
11732
11733 if (board_config == ALC861_AUTO) {
11734 /* automatic parse from the BIOS config */
11735 err = alc861_parse_auto_config(codec);
11736 if (err < 0) {
11737 alc_free(codec);
11738 return err;
f12ab1e0 11739 } else if (!err) {
9c7f852e
TI
11740 printk(KERN_INFO
11741 "hda_codec: Cannot set up configuration "
11742 "from BIOS. Using base mode...\n");
df694daa
KY
11743 board_config = ALC861_3ST_DIG;
11744 }
11745 }
11746
11747 if (board_config != ALC861_AUTO)
11748 setup_preset(spec, &alc861_presets[board_config]);
11749
11750 spec->stream_name_analog = "ALC861 Analog";
11751 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11752 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11753
11754 spec->stream_name_digital = "ALC861 Digital";
11755 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11756 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11757
2134ea4f
TI
11758 spec->vmaster_nid = 0x03;
11759
df694daa
KY
11760 codec->patch_ops = alc_patch_ops;
11761 if (board_config == ALC861_AUTO)
ae6b813a 11762 spec->init_hook = alc861_auto_init;
cb53c626
TI
11763#ifdef CONFIG_SND_HDA_POWER_SAVE
11764 if (!spec->loopback.amplist)
11765 spec->loopback.amplist = alc861_loopbacks;
11766#endif
df694daa 11767
1da177e4
LT
11768 return 0;
11769}
11770
f32610ed
JS
11771/*
11772 * ALC861-VD support
11773 *
11774 * Based on ALC882
11775 *
11776 * In addition, an independent DAC
11777 */
11778#define ALC861VD_DIGOUT_NID 0x06
11779
11780static hda_nid_t alc861vd_dac_nids[4] = {
11781 /* front, surr, clfe, side surr */
11782 0x02, 0x03, 0x04, 0x05
11783};
11784
11785/* dac_nids for ALC660vd are in a different order - according to
11786 * Realtek's driver.
11787 * This should probably tesult in a different mixer for 6stack models
11788 * of ALC660vd codecs, but for now there is only 3stack mixer
11789 * - and it is the same as in 861vd.
11790 * adc_nids in ALC660vd are (is) the same as in 861vd
11791 */
11792static hda_nid_t alc660vd_dac_nids[3] = {
11793 /* front, rear, clfe, rear_surr */
11794 0x02, 0x04, 0x03
11795};
11796
11797static hda_nid_t alc861vd_adc_nids[1] = {
11798 /* ADC0 */
11799 0x09,
11800};
11801
e1406348
TI
11802static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
11803
f32610ed
JS
11804/* input MUX */
11805/* FIXME: should be a matrix-type input source selection */
11806static struct hda_input_mux alc861vd_capture_source = {
11807 .num_items = 4,
11808 .items = {
11809 { "Mic", 0x0 },
11810 { "Front Mic", 0x1 },
11811 { "Line", 0x2 },
11812 { "CD", 0x4 },
11813 },
11814};
11815
272a527c
KY
11816static struct hda_input_mux alc861vd_dallas_capture_source = {
11817 .num_items = 3,
11818 .items = {
11819 { "Front Mic", 0x0 },
11820 { "ATAPI Mic", 0x1 },
11821 { "Line In", 0x5 },
11822 },
11823};
11824
d1a991a6
KY
11825static struct hda_input_mux alc861vd_hp_capture_source = {
11826 .num_items = 2,
11827 .items = {
11828 { "Front Mic", 0x0 },
11829 { "ATAPI Mic", 0x1 },
11830 },
11831};
11832
f32610ed
JS
11833#define alc861vd_mux_enum_info alc_mux_enum_info
11834#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
11835/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
11836#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
11837
11838/*
11839 * 2ch mode
11840 */
11841static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11842 { 2, NULL }
11843};
11844
11845/*
11846 * 6ch mode
11847 */
11848static struct hda_verb alc861vd_6stack_ch6_init[] = {
11849 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11850 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11851 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11852 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11853 { } /* end */
11854};
11855
11856/*
11857 * 8ch mode
11858 */
11859static struct hda_verb alc861vd_6stack_ch8_init[] = {
11860 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11861 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11862 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11863 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11864 { } /* end */
11865};
11866
11867static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11868 { 6, alc861vd_6stack_ch6_init },
11869 { 8, alc861vd_6stack_ch8_init },
11870};
11871
11872static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11873 {
11874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11875 .name = "Channel Mode",
11876 .info = alc_ch_mode_info,
11877 .get = alc_ch_mode_get,
11878 .put = alc_ch_mode_put,
11879 },
11880 { } /* end */
11881};
11882
11883static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11884 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11885 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11886
11887 {
11888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11889 /* The multiple "Capture Source" controls confuse alsamixer
11890 * So call somewhat different..
f32610ed
JS
11891 */
11892 /* .name = "Capture Source", */
11893 .name = "Input Source",
11894 .count = 1,
11895 .info = alc861vd_mux_enum_info,
11896 .get = alc861vd_mux_enum_get,
11897 .put = alc861vd_mux_enum_put,
11898 },
11899 { } /* end */
11900};
11901
11902/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11903 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11904 */
11905static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11906 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11907 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11908
11909 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11910 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11911
11912 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11913 HDA_OUTPUT),
11914 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11915 HDA_OUTPUT),
11916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11918
11919 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11920 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11921
11922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11923
11924 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11927
11928 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11929 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11930 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11931
11932 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11933 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11934
11935 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11936 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11937
11938 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11939 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11940
11941 { } /* end */
11942};
11943
11944static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11945 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11946 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11947
11948 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11949
11950 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11952 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11953
11954 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11955 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11956 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11957
11958 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11959 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11960
11961 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11962 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11963
11964 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11965 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11966
11967 { } /* end */
11968};
11969
bdd148a3
KY
11970static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11971 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11972 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11973 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11974
11975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11976
11977 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11978 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11979 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11980
11981 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11982 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11983 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11984
11985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11987
11988 { } /* end */
11989};
11990
272a527c
KY
11991/* Pin assignment: Front=0x14, HP = 0x15,
11992 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
11993 */
11994static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
11995 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11996 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11997 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11998 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
11999 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12000 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12001 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12002 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
12005 { } /* end */
12006};
12007
d1a991a6
KY
12008/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12009 * Front Mic=0x18, ATAPI Mic = 0x19,
12010 */
12011static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12012 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12013 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12014 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12015 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12016 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12017 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12018 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12019 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12020
12021 { } /* end */
12022};
12023
f32610ed
JS
12024/*
12025 * generic initialization of ADC, input mixers and output mixers
12026 */
12027static struct hda_verb alc861vd_volume_init_verbs[] = {
12028 /*
12029 * Unmute ADC0 and set the default input to mic-in
12030 */
12031 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12033
12034 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12035 * the analog-loopback mixer widget
12036 */
12037 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12039 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12041 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12042 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
12043
12044 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
12045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 12048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
12049
12050 /*
12051 * Set up output mixers (0x02 - 0x05)
12052 */
12053 /* set vol=0 to output mixers */
12054 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12055 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12057 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12058
12059 /* set up input amps for analog loopback */
12060 /* Amp Indices: DAC = 0, mixer = 1 */
12061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12069
12070 { }
12071};
12072
12073/*
12074 * 3-stack pin configuration:
12075 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12076 */
12077static struct hda_verb alc861vd_3stack_init_verbs[] = {
12078 /*
12079 * Set pin mode and muting
12080 */
12081 /* set front pin widgets 0x14 for output */
12082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12084 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12085
12086 /* Mic (rear) pin: input vref at 80% */
12087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12088 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12089 /* Front Mic pin: input vref at 80% */
12090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12092 /* Line In pin: input */
12093 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12094 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12095 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12097 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12098 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12099 /* CD pin widget for input */
12100 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12101
12102 { }
12103};
12104
12105/*
12106 * 6-stack pin configuration:
12107 */
12108static struct hda_verb alc861vd_6stack_init_verbs[] = {
12109 /*
12110 * Set pin mode and muting
12111 */
12112 /* set front pin widgets 0x14 for output */
12113 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12114 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12115 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12116
12117 /* Rear Pin: output 1 (0x0d) */
12118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12120 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12121 /* CLFE Pin: output 2 (0x0e) */
12122 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12123 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12124 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12125 /* Side Pin: output 3 (0x0f) */
12126 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12128 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12129
12130 /* Mic (rear) pin: input vref at 80% */
12131 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12133 /* Front Mic pin: input vref at 80% */
12134 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12136 /* Line In pin: input */
12137 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12139 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12140 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12141 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12142 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12143 /* CD pin widget for input */
12144 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12145
12146 { }
12147};
12148
bdd148a3
KY
12149static struct hda_verb alc861vd_eapd_verbs[] = {
12150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12151 { }
12152};
12153
12154static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12160 {}
12161};
12162
12163/* toggle speaker-output according to the hp-jack state */
12164static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12165{
12166 unsigned int present;
12167 unsigned char bits;
12168
12169 present = snd_hda_codec_read(codec, 0x1b, 0,
12170 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12171 bits = present ? HDA_AMP_MUTE : 0;
12172 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12173 HDA_AMP_MUTE, bits);
bdd148a3
KY
12174}
12175
12176static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12177{
12178 unsigned int present;
12179 unsigned char bits;
12180
12181 present = snd_hda_codec_read(codec, 0x18, 0,
12182 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12183 bits = present ? HDA_AMP_MUTE : 0;
12184 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12185 HDA_AMP_MUTE, bits);
bdd148a3
KY
12186}
12187
12188static void alc861vd_lenovo_automute(struct hda_codec *codec)
12189{
12190 alc861vd_lenovo_hp_automute(codec);
12191 alc861vd_lenovo_mic_automute(codec);
12192}
12193
12194static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12195 unsigned int res)
12196{
12197 switch (res >> 26) {
12198 case ALC880_HP_EVENT:
12199 alc861vd_lenovo_hp_automute(codec);
12200 break;
12201 case ALC880_MIC_EVENT:
12202 alc861vd_lenovo_mic_automute(codec);
12203 break;
12204 }
12205}
12206
272a527c
KY
12207static struct hda_verb alc861vd_dallas_verbs[] = {
12208 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12210 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12211 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12212
12213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12216 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12217 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12218 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12219 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12220 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12221
12222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12227 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12228 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12229 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12230
12231 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12232 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12237 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12238 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12239
12240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12243 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12244
12245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12246 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12247 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12248
12249 { } /* end */
12250};
12251
12252/* toggle speaker-output according to the hp-jack state */
12253static void alc861vd_dallas_automute(struct hda_codec *codec)
12254{
12255 unsigned int present;
12256
12257 present = snd_hda_codec_read(codec, 0x15, 0,
12258 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12259 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12260 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
12261}
12262
12263static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12264{
12265 if ((res >> 26) == ALC880_HP_EVENT)
12266 alc861vd_dallas_automute(codec);
12267}
12268
cb53c626
TI
12269#ifdef CONFIG_SND_HDA_POWER_SAVE
12270#define alc861vd_loopbacks alc880_loopbacks
12271#endif
12272
f32610ed
JS
12273/* pcm configuration: identiacal with ALC880 */
12274#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12275#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12276#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12277#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12278
12279/*
12280 * configuration and preset
12281 */
12282static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12283 [ALC660VD_3ST] = "3stack-660",
983f8ae4 12284 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
12285 [ALC861VD_3ST] = "3stack",
12286 [ALC861VD_3ST_DIG] = "3stack-digout",
12287 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 12288 [ALC861VD_LENOVO] = "lenovo",
272a527c 12289 [ALC861VD_DALLAS] = "dallas",
983f8ae4 12290 [ALC861VD_HP] = "hp",
f32610ed
JS
12291 [ALC861VD_AUTO] = "auto",
12292};
12293
12294static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
12295 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12296 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 12297 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 12298 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 12299 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 12300 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 12301 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 12302 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 12303 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 12304 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 12305 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
12306 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12307 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 12308 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
12309 {}
12310};
12311
12312static struct alc_config_preset alc861vd_presets[] = {
12313 [ALC660VD_3ST] = {
12314 .mixers = { alc861vd_3st_mixer },
12315 .init_verbs = { alc861vd_volume_init_verbs,
12316 alc861vd_3stack_init_verbs },
12317 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12318 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
12319 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12320 .channel_mode = alc861vd_3stack_2ch_modes,
12321 .input_mux = &alc861vd_capture_source,
12322 },
6963f84c
MC
12323 [ALC660VD_3ST_DIG] = {
12324 .mixers = { alc861vd_3st_mixer },
12325 .init_verbs = { alc861vd_volume_init_verbs,
12326 alc861vd_3stack_init_verbs },
12327 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12328 .dac_nids = alc660vd_dac_nids,
12329 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
12330 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12331 .channel_mode = alc861vd_3stack_2ch_modes,
12332 .input_mux = &alc861vd_capture_source,
12333 },
f32610ed
JS
12334 [ALC861VD_3ST] = {
12335 .mixers = { alc861vd_3st_mixer },
12336 .init_verbs = { alc861vd_volume_init_verbs,
12337 alc861vd_3stack_init_verbs },
12338 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12339 .dac_nids = alc861vd_dac_nids,
12340 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12341 .channel_mode = alc861vd_3stack_2ch_modes,
12342 .input_mux = &alc861vd_capture_source,
12343 },
12344 [ALC861VD_3ST_DIG] = {
12345 .mixers = { alc861vd_3st_mixer },
12346 .init_verbs = { alc861vd_volume_init_verbs,
12347 alc861vd_3stack_init_verbs },
12348 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12349 .dac_nids = alc861vd_dac_nids,
12350 .dig_out_nid = ALC861VD_DIGOUT_NID,
12351 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12352 .channel_mode = alc861vd_3stack_2ch_modes,
12353 .input_mux = &alc861vd_capture_source,
12354 },
12355 [ALC861VD_6ST_DIG] = {
12356 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12357 .init_verbs = { alc861vd_volume_init_verbs,
12358 alc861vd_6stack_init_verbs },
12359 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12360 .dac_nids = alc861vd_dac_nids,
12361 .dig_out_nid = ALC861VD_DIGOUT_NID,
12362 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12363 .channel_mode = alc861vd_6stack_modes,
12364 .input_mux = &alc861vd_capture_source,
12365 },
bdd148a3
KY
12366 [ALC861VD_LENOVO] = {
12367 .mixers = { alc861vd_lenovo_mixer },
12368 .init_verbs = { alc861vd_volume_init_verbs,
12369 alc861vd_3stack_init_verbs,
12370 alc861vd_eapd_verbs,
12371 alc861vd_lenovo_unsol_verbs },
12372 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12373 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
12374 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12375 .channel_mode = alc861vd_3stack_2ch_modes,
12376 .input_mux = &alc861vd_capture_source,
12377 .unsol_event = alc861vd_lenovo_unsol_event,
12378 .init_hook = alc861vd_lenovo_automute,
12379 },
272a527c
KY
12380 [ALC861VD_DALLAS] = {
12381 .mixers = { alc861vd_dallas_mixer },
12382 .init_verbs = { alc861vd_dallas_verbs },
12383 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12384 .dac_nids = alc861vd_dac_nids,
272a527c
KY
12385 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12386 .channel_mode = alc861vd_3stack_2ch_modes,
12387 .input_mux = &alc861vd_dallas_capture_source,
12388 .unsol_event = alc861vd_dallas_unsol_event,
12389 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
12390 },
12391 [ALC861VD_HP] = {
12392 .mixers = { alc861vd_hp_mixer },
12393 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12394 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12395 .dac_nids = alc861vd_dac_nids,
d1a991a6 12396 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
12397 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12398 .channel_mode = alc861vd_3stack_2ch_modes,
12399 .input_mux = &alc861vd_hp_capture_source,
12400 .unsol_event = alc861vd_dallas_unsol_event,
12401 .init_hook = alc861vd_dallas_automute,
12402 },
f32610ed
JS
12403};
12404
12405/*
12406 * BIOS auto configuration
12407 */
12408static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12409 hda_nid_t nid, int pin_type, int dac_idx)
12410{
f6c7e546 12411 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
12412}
12413
12414static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12415{
12416 struct alc_spec *spec = codec->spec;
12417 int i;
12418
bc9f98a9 12419 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
12420 for (i = 0; i <= HDA_SIDE; i++) {
12421 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12422 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
12423 if (nid)
12424 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 12425 pin_type, i);
f32610ed
JS
12426 }
12427}
12428
12429
12430static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12431{
12432 struct alc_spec *spec = codec->spec;
12433 hda_nid_t pin;
12434
12435 pin = spec->autocfg.hp_pins[0];
12436 if (pin) /* connect to front and use dac 0 */
12437 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
12438 pin = spec->autocfg.speaker_pins[0];
12439 if (pin)
12440 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
12441}
12442
12443#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12444#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12445
12446static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12447{
12448 struct alc_spec *spec = codec->spec;
12449 int i;
12450
12451 for (i = 0; i < AUTO_PIN_LAST; i++) {
12452 hda_nid_t nid = spec->autocfg.input_pins[i];
12453 if (alc861vd_is_input_pin(nid)) {
12454 snd_hda_codec_write(codec, nid, 0,
12455 AC_VERB_SET_PIN_WIDGET_CONTROL,
12456 i <= AUTO_PIN_FRONT_MIC ?
12457 PIN_VREF80 : PIN_IN);
12458 if (nid != ALC861VD_PIN_CD_NID)
12459 snd_hda_codec_write(codec, nid, 0,
12460 AC_VERB_SET_AMP_GAIN_MUTE,
12461 AMP_OUT_MUTE);
12462 }
12463 }
12464}
12465
12466#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12467#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12468
12469/* add playback controls from the parsed DAC table */
12470/* Based on ALC880 version. But ALC861VD has separate,
12471 * different NIDs for mute/unmute switch and volume control */
12472static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12473 const struct auto_pin_cfg *cfg)
12474{
12475 char name[32];
12476 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12477 hda_nid_t nid_v, nid_s;
12478 int i, err;
12479
12480 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12481 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12482 continue;
12483 nid_v = alc861vd_idx_to_mixer_vol(
12484 alc880_dac_to_idx(
12485 spec->multiout.dac_nids[i]));
12486 nid_s = alc861vd_idx_to_mixer_switch(
12487 alc880_dac_to_idx(
12488 spec->multiout.dac_nids[i]));
12489
12490 if (i == 2) {
12491 /* Center/LFE */
f12ab1e0
TI
12492 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12493 "Center Playback Volume",
12494 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12495 HDA_OUTPUT));
12496 if (err < 0)
f32610ed 12497 return err;
f12ab1e0
TI
12498 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12499 "LFE Playback Volume",
12500 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12501 HDA_OUTPUT));
12502 if (err < 0)
f32610ed 12503 return err;
f12ab1e0
TI
12504 err = add_control(spec, ALC_CTL_BIND_MUTE,
12505 "Center Playback Switch",
12506 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12507 HDA_INPUT));
12508 if (err < 0)
f32610ed 12509 return err;
f12ab1e0
TI
12510 err = add_control(spec, ALC_CTL_BIND_MUTE,
12511 "LFE Playback Switch",
12512 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12513 HDA_INPUT));
12514 if (err < 0)
f32610ed
JS
12515 return err;
12516 } else {
12517 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12518 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12519 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12520 HDA_OUTPUT));
12521 if (err < 0)
f32610ed
JS
12522 return err;
12523 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12524 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12525 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12526 HDA_INPUT));
12527 if (err < 0)
f32610ed
JS
12528 return err;
12529 }
12530 }
12531 return 0;
12532}
12533
12534/* add playback controls for speaker and HP outputs */
12535/* Based on ALC880 version. But ALC861VD has separate,
12536 * different NIDs for mute/unmute switch and volume control */
12537static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12538 hda_nid_t pin, const char *pfx)
12539{
12540 hda_nid_t nid_v, nid_s;
12541 int err;
12542 char name[32];
12543
f12ab1e0 12544 if (!pin)
f32610ed
JS
12545 return 0;
12546
12547 if (alc880_is_fixed_pin(pin)) {
12548 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12549 /* specify the DAC as the extra output */
f12ab1e0 12550 if (!spec->multiout.hp_nid)
f32610ed
JS
12551 spec->multiout.hp_nid = nid_v;
12552 else
12553 spec->multiout.extra_out_nid[0] = nid_v;
12554 /* control HP volume/switch on the output mixer amp */
12555 nid_v = alc861vd_idx_to_mixer_vol(
12556 alc880_fixed_pin_idx(pin));
12557 nid_s = alc861vd_idx_to_mixer_switch(
12558 alc880_fixed_pin_idx(pin));
12559
12560 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12561 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12562 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12563 if (err < 0)
f32610ed
JS
12564 return err;
12565 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12566 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12567 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12568 if (err < 0)
f32610ed
JS
12569 return err;
12570 } else if (alc880_is_multi_pin(pin)) {
12571 /* set manual connection */
12572 /* we have only a switch on HP-out PIN */
12573 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12574 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12575 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12576 if (err < 0)
f32610ed
JS
12577 return err;
12578 }
12579 return 0;
12580}
12581
12582/* parse the BIOS configuration and set up the alc_spec
12583 * return 1 if successful, 0 if the proper config is not found,
12584 * or a negative error code
12585 * Based on ALC880 version - had to change it to override
12586 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12587static int alc861vd_parse_auto_config(struct hda_codec *codec)
12588{
12589 struct alc_spec *spec = codec->spec;
12590 int err;
12591 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12592
f12ab1e0
TI
12593 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12594 alc861vd_ignore);
12595 if (err < 0)
f32610ed 12596 return err;
f12ab1e0 12597 if (!spec->autocfg.line_outs)
f32610ed
JS
12598 return 0; /* can't find valid BIOS pin config */
12599
f12ab1e0
TI
12600 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12601 if (err < 0)
12602 return err;
12603 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12604 if (err < 0)
12605 return err;
12606 err = alc861vd_auto_create_extra_out(spec,
12607 spec->autocfg.speaker_pins[0],
12608 "Speaker");
12609 if (err < 0)
12610 return err;
12611 err = alc861vd_auto_create_extra_out(spec,
12612 spec->autocfg.hp_pins[0],
12613 "Headphone");
12614 if (err < 0)
12615 return err;
12616 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12617 if (err < 0)
f32610ed
JS
12618 return err;
12619
12620 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12621
12622 if (spec->autocfg.dig_out_pin)
12623 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12624
12625 if (spec->kctl_alloc)
12626 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12627
12628 spec->init_verbs[spec->num_init_verbs++]
12629 = alc861vd_volume_init_verbs;
12630
12631 spec->num_mux_defs = 1;
12632 spec->input_mux = &spec->private_imux;
12633
776e184e
TI
12634 err = alc_auto_add_mic_boost(codec);
12635 if (err < 0)
12636 return err;
12637
f32610ed
JS
12638 return 1;
12639}
12640
12641/* additional initialization for auto-configuration model */
12642static void alc861vd_auto_init(struct hda_codec *codec)
12643{
f6c7e546 12644 struct alc_spec *spec = codec->spec;
f32610ed
JS
12645 alc861vd_auto_init_multi_out(codec);
12646 alc861vd_auto_init_hp_out(codec);
12647 alc861vd_auto_init_analog_input(codec);
f6c7e546
TI
12648 if (spec->unsol_event)
12649 alc_sku_automute(codec);
f32610ed
JS
12650}
12651
12652static int patch_alc861vd(struct hda_codec *codec)
12653{
12654 struct alc_spec *spec;
12655 int err, board_config;
12656
12657 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12658 if (spec == NULL)
12659 return -ENOMEM;
12660
12661 codec->spec = spec;
12662
12663 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12664 alc861vd_models,
12665 alc861vd_cfg_tbl);
12666
12667 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12668 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12669 "ALC861VD, trying auto-probe from BIOS...\n");
12670 board_config = ALC861VD_AUTO;
12671 }
12672
12673 if (board_config == ALC861VD_AUTO) {
12674 /* automatic parse from the BIOS config */
12675 err = alc861vd_parse_auto_config(codec);
12676 if (err < 0) {
12677 alc_free(codec);
12678 return err;
f12ab1e0 12679 } else if (!err) {
f32610ed
JS
12680 printk(KERN_INFO
12681 "hda_codec: Cannot set up configuration "
12682 "from BIOS. Using base mode...\n");
12683 board_config = ALC861VD_3ST;
12684 }
12685 }
12686
12687 if (board_config != ALC861VD_AUTO)
12688 setup_preset(spec, &alc861vd_presets[board_config]);
12689
12690 spec->stream_name_analog = "ALC861VD Analog";
12691 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12692 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12693
12694 spec->stream_name_digital = "ALC861VD Digital";
12695 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12696 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12697
12698 spec->adc_nids = alc861vd_adc_nids;
12699 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 12700 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
12701
12702 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12703 spec->num_mixers++;
12704
2134ea4f
TI
12705 spec->vmaster_nid = 0x02;
12706
f32610ed
JS
12707 codec->patch_ops = alc_patch_ops;
12708
12709 if (board_config == ALC861VD_AUTO)
12710 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12711#ifdef CONFIG_SND_HDA_POWER_SAVE
12712 if (!spec->loopback.amplist)
12713 spec->loopback.amplist = alc861vd_loopbacks;
12714#endif
f32610ed
JS
12715
12716 return 0;
12717}
12718
bc9f98a9
KY
12719/*
12720 * ALC662 support
12721 *
12722 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12723 * configuration. Each pin widget can choose any input DACs and a mixer.
12724 * Each ADC is connected from a mixer of all inputs. This makes possible
12725 * 6-channel independent captures.
12726 *
12727 * In addition, an independent DAC for the multi-playback (not used in this
12728 * driver yet).
12729 */
12730#define ALC662_DIGOUT_NID 0x06
12731#define ALC662_DIGIN_NID 0x0a
12732
12733static hda_nid_t alc662_dac_nids[4] = {
12734 /* front, rear, clfe, rear_surr */
12735 0x02, 0x03, 0x04
12736};
12737
12738static hda_nid_t alc662_adc_nids[1] = {
12739 /* ADC1-2 */
12740 0x09,
12741};
e1406348
TI
12742
12743static hda_nid_t alc662_capsrc_nids[1] = { 0x23 };
12744
bc9f98a9
KY
12745/* input MUX */
12746/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
12747static struct hda_input_mux alc662_capture_source = {
12748 .num_items = 4,
12749 .items = {
12750 { "Mic", 0x0 },
12751 { "Front Mic", 0x1 },
12752 { "Line", 0x2 },
12753 { "CD", 0x4 },
12754 },
12755};
12756
12757static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12758 .num_items = 2,
12759 .items = {
12760 { "Mic", 0x1 },
12761 { "Line", 0x2 },
12762 },
12763};
291702f0
KY
12764
12765static struct hda_input_mux alc662_eeepc_capture_source = {
12766 .num_items = 2,
12767 .items = {
12768 { "i-Mic", 0x1 },
12769 { "e-Mic", 0x0 },
12770 },
12771};
12772
bc9f98a9
KY
12773#define alc662_mux_enum_info alc_mux_enum_info
12774#define alc662_mux_enum_get alc_mux_enum_get
e1406348 12775#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 12776
bc9f98a9
KY
12777/*
12778 * 2ch mode
12779 */
12780static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12781 { 2, NULL }
12782};
12783
12784/*
12785 * 2ch mode
12786 */
12787static struct hda_verb alc662_3ST_ch2_init[] = {
12788 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12789 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12790 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12791 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12792 { } /* end */
12793};
12794
12795/*
12796 * 6ch mode
12797 */
12798static struct hda_verb alc662_3ST_ch6_init[] = {
12799 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12800 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12801 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12804 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12805 { } /* end */
12806};
12807
12808static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12809 { 2, alc662_3ST_ch2_init },
12810 { 6, alc662_3ST_ch6_init },
12811};
12812
12813/*
12814 * 2ch mode
12815 */
12816static struct hda_verb alc662_sixstack_ch6_init[] = {
12817 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12818 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12819 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12820 { } /* end */
12821};
12822
12823/*
12824 * 6ch mode
12825 */
12826static struct hda_verb alc662_sixstack_ch8_init[] = {
12827 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12828 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12829 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12830 { } /* end */
12831};
12832
12833static struct hda_channel_mode alc662_5stack_modes[2] = {
12834 { 2, alc662_sixstack_ch6_init },
12835 { 6, alc662_sixstack_ch8_init },
12836};
12837
12838/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12839 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12840 */
12841
12842static struct snd_kcontrol_new alc662_base_mixer[] = {
12843 /* output mixer control */
12844 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12845 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12846 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12847 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12848 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12849 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12850 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12851 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12852 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12853
12854 /*Input mixer control */
12855 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12856 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12857 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12858 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12859 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12860 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12861 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12862 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12863 { } /* end */
12864};
12865
12866static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12867 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12868 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12870 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12871 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12877 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12878 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12879 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12880 { } /* end */
12881};
12882
12883static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12884 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12885 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12887 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12892 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12893 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12894 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12895 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12896 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12899 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12901 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12902 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12903 { } /* end */
12904};
12905
12906static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12907 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12908 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
12909 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12910 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
12911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12913 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12914 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12915 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
12916 { } /* end */
12917};
12918
291702f0 12919static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 12920 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 12921
b4818494
HRK
12922 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12923 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
12924
12925 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12926 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12927 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12928
12929 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12930 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12931 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12932 { } /* end */
12933};
12934
8c427226 12935static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
12936 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12937 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
12938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12939 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12940 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12941 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12942 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12943 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 12944 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
12945 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
12946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12950 { } /* end */
12951};
12952
bc9f98a9
KY
12953static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12954 {
12955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12956 .name = "Channel Mode",
12957 .info = alc_ch_mode_info,
12958 .get = alc_ch_mode_get,
12959 .put = alc_ch_mode_put,
12960 },
12961 { } /* end */
12962};
12963
12964static struct hda_verb alc662_init_verbs[] = {
12965 /* ADC: mute amp left and right */
12966 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12967 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12968 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12969
cb53c626
TI
12970 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 12975
b60dd394
KY
12976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12978 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12979 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12980 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12981 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12982
12983 /* Front Pin: output 0 (0x0c) */
12984 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12985 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12986
12987 /* Rear Pin: output 1 (0x0d) */
12988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12990
12991 /* CLFE Pin: output 2 (0x0e) */
12992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12994
12995 /* Mic (rear) pin: input vref at 80% */
12996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12997 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12998 /* Front Mic pin: input vref at 80% */
12999 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13000 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13001 /* Line In pin: input */
13002 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13003 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13004 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13005 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13006 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13007 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13008 /* CD pin widget for input */
13009 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13010
13011 /* FIXME: use matrix-type input source selection */
13012 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13013 /* Input mixer */
13014 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
13018
13019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
13023 { }
13024};
13025
13026static struct hda_verb alc662_sue_init_verbs[] = {
13027 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13028 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
13029 {}
13030};
13031
13032static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13035 {}
bc9f98a9
KY
13036};
13037
8c427226
KY
13038/* Set Unsolicited Event*/
13039static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13042 {}
13043};
13044
bc9f98a9
KY
13045/*
13046 * generic initialization of ADC, input mixers and output mixers
13047 */
13048static struct hda_verb alc662_auto_init_verbs[] = {
13049 /*
13050 * Unmute ADC and set the default input to mic-in
13051 */
13052 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13053 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13054
13055 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13056 * mixer widget
13057 * Note: PASD motherboards uses the Line In 2 as the input for front
13058 * panel mic (mic 2)
13059 */
13060 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
13066
13067 /*
13068 * Set up output mixers (0x0c - 0x0f)
13069 */
13070 /* set vol=0 to output mixers */
13071 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13072 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13073 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13074
13075 /* set up input amps for analog loopback */
13076 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
13077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13079 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13080 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13081 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13082 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13083
13084
13085 /* FIXME: use matrix-type input source selection */
13086 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13087 /* Input mixer */
13088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 13089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
13090 { }
13091};
13092
13093/* capture mixer elements */
13094static struct snd_kcontrol_new alc662_capture_mixer[] = {
13095 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13096 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13097 {
13098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13099 /* The multiple "Capture Source" controls confuse alsamixer
13100 * So call somewhat different..
bc9f98a9
KY
13101 */
13102 /* .name = "Capture Source", */
13103 .name = "Input Source",
13104 .count = 1,
6e7939bb
HRK
13105 .info = alc662_mux_enum_info,
13106 .get = alc662_mux_enum_get,
13107 .put = alc662_mux_enum_put,
bc9f98a9
KY
13108 },
13109 { } /* end */
13110};
13111
13112static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13113{
13114 unsigned int present;
f12ab1e0 13115 unsigned char bits;
bc9f98a9
KY
13116
13117 present = snd_hda_codec_read(codec, 0x14, 0,
13118 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13119 bits = present ? HDA_AMP_MUTE : 0;
13120 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13121 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13122}
13123
13124static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13125{
13126 unsigned int present;
f12ab1e0 13127 unsigned char bits;
bc9f98a9
KY
13128
13129 present = snd_hda_codec_read(codec, 0x1b, 0,
13130 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13131 bits = present ? HDA_AMP_MUTE : 0;
13132 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13133 HDA_AMP_MUTE, bits);
13134 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13135 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13136}
13137
13138static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13139 unsigned int res)
13140{
13141 if ((res >> 26) == ALC880_HP_EVENT)
13142 alc662_lenovo_101e_all_automute(codec);
13143 if ((res >> 26) == ALC880_FRONT_EVENT)
13144 alc662_lenovo_101e_ispeaker_automute(codec);
13145}
13146
291702f0
KY
13147static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13148{
13149 unsigned int present;
13150
13151 present = snd_hda_codec_read(codec, 0x18, 0,
13152 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13153 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13154 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13155 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13156 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13157 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13158 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13159 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13160 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13161}
13162
13163/* unsolicited event for HP jack sensing */
13164static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13165 unsigned int res)
13166{
13167 if ((res >> 26) == ALC880_HP_EVENT)
13168 alc262_hippo1_automute( codec );
13169
13170 if ((res >> 26) == ALC880_MIC_EVENT)
13171 alc662_eeepc_mic_automute(codec);
13172}
13173
13174static void alc662_eeepc_inithook(struct hda_codec *codec)
13175{
13176 alc262_hippo1_automute( codec );
13177 alc662_eeepc_mic_automute(codec);
13178}
13179
8c427226
KY
13180static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13181{
13182 unsigned int mute;
13183 unsigned int present;
13184
13185 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13186 present = snd_hda_codec_read(codec, 0x14, 0,
13187 AC_VERB_GET_PIN_SENSE, 0);
13188 present = (present & 0x80000000) != 0;
13189 if (present) {
13190 /* mute internal speaker */
13191 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13192 HDA_AMP_MUTE, HDA_AMP_MUTE);
13193 } else {
13194 /* unmute internal speaker if necessary */
13195 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13196 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13197 HDA_AMP_MUTE, mute);
13198 }
13199}
13200
13201/* unsolicited event for HP jack sensing */
13202static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13203 unsigned int res)
13204{
13205 if ((res >> 26) == ALC880_HP_EVENT)
13206 alc662_eeepc_ep20_automute(codec);
13207}
13208
13209static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13210{
13211 alc662_eeepc_ep20_automute(codec);
13212}
13213
cb53c626
TI
13214#ifdef CONFIG_SND_HDA_POWER_SAVE
13215#define alc662_loopbacks alc880_loopbacks
13216#endif
13217
bc9f98a9
KY
13218
13219/* pcm configuration: identiacal with ALC880 */
13220#define alc662_pcm_analog_playback alc880_pcm_analog_playback
13221#define alc662_pcm_analog_capture alc880_pcm_analog_capture
13222#define alc662_pcm_digital_playback alc880_pcm_digital_playback
13223#define alc662_pcm_digital_capture alc880_pcm_digital_capture
13224
13225/*
13226 * configuration and preset
13227 */
13228static const char *alc662_models[ALC662_MODEL_LAST] = {
13229 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13230 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13231 [ALC662_3ST_6ch] = "3stack-6ch",
13232 [ALC662_5ST_DIG] = "6stack-dig",
13233 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 13234 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 13235 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
bc9f98a9
KY
13236 [ALC662_AUTO] = "auto",
13237};
13238
13239static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 13240 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 13241 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
ac3e3741 13242 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
13243 {}
13244};
13245
13246static struct alc_config_preset alc662_presets[] = {
13247 [ALC662_3ST_2ch_DIG] = {
291702f0 13248 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
13249 .init_verbs = { alc662_init_verbs },
13250 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13251 .dac_nids = alc662_dac_nids,
13252 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13253 .dig_in_nid = ALC662_DIGIN_NID,
13254 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13255 .channel_mode = alc662_3ST_2ch_modes,
13256 .input_mux = &alc662_capture_source,
13257 },
13258 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
13259 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13260 alc662_capture_mixer },
bc9f98a9
KY
13261 .init_verbs = { alc662_init_verbs },
13262 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13263 .dac_nids = alc662_dac_nids,
13264 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13265 .dig_in_nid = ALC662_DIGIN_NID,
13266 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13267 .channel_mode = alc662_3ST_6ch_modes,
13268 .need_dac_fix = 1,
13269 .input_mux = &alc662_capture_source,
f12ab1e0 13270 },
bc9f98a9 13271 [ALC662_3ST_6ch] = {
291702f0
KY
13272 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13273 alc662_capture_mixer },
bc9f98a9
KY
13274 .init_verbs = { alc662_init_verbs },
13275 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13276 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13277 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13278 .channel_mode = alc662_3ST_6ch_modes,
13279 .need_dac_fix = 1,
13280 .input_mux = &alc662_capture_source,
f12ab1e0 13281 },
bc9f98a9 13282 [ALC662_5ST_DIG] = {
291702f0
KY
13283 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13284 alc662_capture_mixer },
bc9f98a9
KY
13285 .init_verbs = { alc662_init_verbs },
13286 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13287 .dac_nids = alc662_dac_nids,
13288 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13289 .dig_in_nid = ALC662_DIGIN_NID,
13290 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13291 .channel_mode = alc662_5stack_modes,
13292 .input_mux = &alc662_capture_source,
13293 },
13294 [ALC662_LENOVO_101E] = {
291702f0 13295 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
13296 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13297 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13298 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13299 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13300 .channel_mode = alc662_3ST_2ch_modes,
13301 .input_mux = &alc662_lenovo_101e_capture_source,
13302 .unsol_event = alc662_lenovo_101e_unsol_event,
13303 .init_hook = alc662_lenovo_101e_all_automute,
13304 },
291702f0
KY
13305 [ALC662_ASUS_EEEPC_P701] = {
13306 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13307 .init_verbs = { alc662_init_verbs,
13308 alc662_eeepc_sue_init_verbs },
13309 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13310 .dac_nids = alc662_dac_nids,
291702f0
KY
13311 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13312 .channel_mode = alc662_3ST_2ch_modes,
13313 .input_mux = &alc662_eeepc_capture_source,
13314 .unsol_event = alc662_eeepc_unsol_event,
13315 .init_hook = alc662_eeepc_inithook,
13316 },
8c427226
KY
13317 [ALC662_ASUS_EEEPC_EP20] = {
13318 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13319 alc662_chmode_mixer },
13320 .init_verbs = { alc662_init_verbs,
13321 alc662_eeepc_ep20_sue_init_verbs },
13322 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13323 .dac_nids = alc662_dac_nids,
8c427226
KY
13324 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13325 .channel_mode = alc662_3ST_6ch_modes,
13326 .input_mux = &alc662_lenovo_101e_capture_source,
13327 .unsol_event = alc662_eeepc_ep20_unsol_event,
13328 .init_hook = alc662_eeepc_ep20_inithook,
13329 },
bc9f98a9
KY
13330
13331};
13332
13333
13334/*
13335 * BIOS auto configuration
13336 */
13337
13338/* add playback controls from the parsed DAC table */
13339static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13340 const struct auto_pin_cfg *cfg)
13341{
13342 char name[32];
13343 static const char *chname[4] = {
13344 "Front", "Surround", NULL /*CLFE*/, "Side"
13345 };
13346 hda_nid_t nid;
13347 int i, err;
13348
13349 for (i = 0; i < cfg->line_outs; i++) {
13350 if (!spec->multiout.dac_nids[i])
13351 continue;
b60dd394 13352 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
13353 if (i == 2) {
13354 /* Center/LFE */
13355 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13356 "Center Playback Volume",
f12ab1e0
TI
13357 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13358 HDA_OUTPUT));
bc9f98a9
KY
13359 if (err < 0)
13360 return err;
13361 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13362 "LFE Playback Volume",
f12ab1e0
TI
13363 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13364 HDA_OUTPUT));
bc9f98a9
KY
13365 if (err < 0)
13366 return err;
13367 err = add_control(spec, ALC_CTL_BIND_MUTE,
13368 "Center Playback Switch",
f12ab1e0
TI
13369 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13370 HDA_INPUT));
bc9f98a9
KY
13371 if (err < 0)
13372 return err;
13373 err = add_control(spec, ALC_CTL_BIND_MUTE,
13374 "LFE Playback Switch",
f12ab1e0
TI
13375 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13376 HDA_INPUT));
bc9f98a9
KY
13377 if (err < 0)
13378 return err;
13379 } else {
13380 sprintf(name, "%s Playback Volume", chname[i]);
13381 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
13382 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13383 HDA_OUTPUT));
bc9f98a9
KY
13384 if (err < 0)
13385 return err;
13386 sprintf(name, "%s Playback Switch", chname[i]);
13387 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
13388 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13389 HDA_INPUT));
bc9f98a9
KY
13390 if (err < 0)
13391 return err;
13392 }
13393 }
13394 return 0;
13395}
13396
13397/* add playback controls for speaker and HP outputs */
13398static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13399 const char *pfx)
13400{
13401 hda_nid_t nid;
13402 int err;
13403 char name[32];
13404
13405 if (!pin)
13406 return 0;
13407
13408 if (alc880_is_fixed_pin(pin)) {
13409 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13410 /* printk("DAC nid=%x\n",nid); */
13411 /* specify the DAC as the extra output */
13412 if (!spec->multiout.hp_nid)
13413 spec->multiout.hp_nid = nid;
13414 else
13415 spec->multiout.extra_out_nid[0] = nid;
13416 /* control HP volume/switch on the output mixer amp */
13417 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13418 sprintf(name, "%s Playback Volume", pfx);
13419 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13420 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13421 if (err < 0)
13422 return err;
13423 sprintf(name, "%s Playback Switch", pfx);
13424 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13425 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13426 if (err < 0)
13427 return err;
13428 } else if (alc880_is_multi_pin(pin)) {
13429 /* set manual connection */
13430 /* we have only a switch on HP-out PIN */
13431 sprintf(name, "%s Playback Switch", pfx);
13432 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13433 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13434 if (err < 0)
13435 return err;
13436 }
13437 return 0;
13438}
13439
13440/* create playback/capture controls for input pins */
13441static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13442 const struct auto_pin_cfg *cfg)
13443{
13444 struct hda_input_mux *imux = &spec->private_imux;
13445 int i, err, idx;
13446
13447 for (i = 0; i < AUTO_PIN_LAST; i++) {
13448 if (alc880_is_input_pin(cfg->input_pins[i])) {
13449 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13450 err = new_analog_input(spec, cfg->input_pins[i],
13451 auto_pin_cfg_labels[i],
13452 idx, 0x0b);
13453 if (err < 0)
13454 return err;
13455 imux->items[imux->num_items].label =
13456 auto_pin_cfg_labels[i];
13457 imux->items[imux->num_items].index =
13458 alc880_input_pin_idx(cfg->input_pins[i]);
13459 imux->num_items++;
13460 }
13461 }
13462 return 0;
13463}
13464
13465static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13466 hda_nid_t nid, int pin_type,
13467 int dac_idx)
13468{
f6c7e546 13469 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
13470 /* need the manual connection? */
13471 if (alc880_is_multi_pin(nid)) {
13472 struct alc_spec *spec = codec->spec;
13473 int idx = alc880_multi_pin_idx(nid);
13474 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13475 AC_VERB_SET_CONNECT_SEL,
13476 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13477 }
13478}
13479
13480static void alc662_auto_init_multi_out(struct hda_codec *codec)
13481{
13482 struct alc_spec *spec = codec->spec;
13483 int i;
13484
8c427226 13485 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
13486 for (i = 0; i <= HDA_SIDE; i++) {
13487 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13488 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 13489 if (nid)
baba8ee9 13490 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
13491 i);
13492 }
13493}
13494
13495static void alc662_auto_init_hp_out(struct hda_codec *codec)
13496{
13497 struct alc_spec *spec = codec->spec;
13498 hda_nid_t pin;
13499
13500 pin = spec->autocfg.hp_pins[0];
13501 if (pin) /* connect to front */
13502 /* use dac 0 */
13503 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
13504 pin = spec->autocfg.speaker_pins[0];
13505 if (pin)
13506 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
13507}
13508
13509#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13510#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13511
13512static void alc662_auto_init_analog_input(struct hda_codec *codec)
13513{
13514 struct alc_spec *spec = codec->spec;
13515 int i;
13516
13517 for (i = 0; i < AUTO_PIN_LAST; i++) {
13518 hda_nid_t nid = spec->autocfg.input_pins[i];
13519 if (alc662_is_input_pin(nid)) {
13520 snd_hda_codec_write(codec, nid, 0,
13521 AC_VERB_SET_PIN_WIDGET_CONTROL,
13522 (i <= AUTO_PIN_FRONT_MIC ?
13523 PIN_VREF80 : PIN_IN));
13524 if (nid != ALC662_PIN_CD_NID)
13525 snd_hda_codec_write(codec, nid, 0,
13526 AC_VERB_SET_AMP_GAIN_MUTE,
13527 AMP_OUT_MUTE);
13528 }
13529 }
13530}
13531
13532static int alc662_parse_auto_config(struct hda_codec *codec)
13533{
13534 struct alc_spec *spec = codec->spec;
13535 int err;
13536 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13537
13538 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13539 alc662_ignore);
13540 if (err < 0)
13541 return err;
13542 if (!spec->autocfg.line_outs)
13543 return 0; /* can't find valid BIOS pin config */
13544
f12ab1e0
TI
13545 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13546 if (err < 0)
13547 return err;
13548 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13549 if (err < 0)
13550 return err;
13551 err = alc662_auto_create_extra_out(spec,
13552 spec->autocfg.speaker_pins[0],
13553 "Speaker");
13554 if (err < 0)
13555 return err;
13556 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13557 "Headphone");
13558 if (err < 0)
13559 return err;
13560 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13561 if (err < 0)
bc9f98a9
KY
13562 return err;
13563
13564 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13565
13566 if (spec->autocfg.dig_out_pin)
13567 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13568
13569 if (spec->kctl_alloc)
13570 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13571
13572 spec->num_mux_defs = 1;
13573 spec->input_mux = &spec->private_imux;
13574
8c87286f 13575 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13576 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13577 spec->num_mixers++;
8c87286f 13578 return 1;
bc9f98a9
KY
13579}
13580
13581/* additional initialization for auto-configuration model */
13582static void alc662_auto_init(struct hda_codec *codec)
13583{
f6c7e546 13584 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
13585 alc662_auto_init_multi_out(codec);
13586 alc662_auto_init_hp_out(codec);
13587 alc662_auto_init_analog_input(codec);
f6c7e546
TI
13588 if (spec->unsol_event)
13589 alc_sku_automute(codec);
bc9f98a9
KY
13590}
13591
13592static int patch_alc662(struct hda_codec *codec)
13593{
13594 struct alc_spec *spec;
13595 int err, board_config;
13596
13597 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13598 if (!spec)
13599 return -ENOMEM;
13600
13601 codec->spec = spec;
13602
13603 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13604 alc662_models,
13605 alc662_cfg_tbl);
13606 if (board_config < 0) {
13607 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13608 "trying auto-probe from BIOS...\n");
13609 board_config = ALC662_AUTO;
13610 }
13611
13612 if (board_config == ALC662_AUTO) {
13613 /* automatic parse from the BIOS config */
13614 err = alc662_parse_auto_config(codec);
13615 if (err < 0) {
13616 alc_free(codec);
13617 return err;
8c87286f 13618 } else if (!err) {
bc9f98a9
KY
13619 printk(KERN_INFO
13620 "hda_codec: Cannot set up configuration "
13621 "from BIOS. Using base mode...\n");
13622 board_config = ALC662_3ST_2ch_DIG;
13623 }
13624 }
13625
13626 if (board_config != ALC662_AUTO)
13627 setup_preset(spec, &alc662_presets[board_config]);
13628
13629 spec->stream_name_analog = "ALC662 Analog";
13630 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13631 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13632
13633 spec->stream_name_digital = "ALC662 Digital";
13634 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13635 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13636
e1406348
TI
13637 spec->adc_nids = alc662_adc_nids;
13638 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13639 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 13640
2134ea4f
TI
13641 spec->vmaster_nid = 0x02;
13642
bc9f98a9
KY
13643 codec->patch_ops = alc_patch_ops;
13644 if (board_config == ALC662_AUTO)
13645 spec->init_hook = alc662_auto_init;
cb53c626
TI
13646#ifdef CONFIG_SND_HDA_POWER_SAVE
13647 if (!spec->loopback.amplist)
13648 spec->loopback.amplist = alc662_loopbacks;
13649#endif
bc9f98a9
KY
13650
13651 return 0;
13652}
13653
1da177e4
LT
13654/*
13655 * patch entries
13656 */
13657struct hda_codec_preset snd_hda_preset_realtek[] = {
13658 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13659 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13660 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13661 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13662 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13663 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13664 .patch = patch_alc861 },
f32610ed
JS
13665 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13666 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13667 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13668 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13669 .patch = patch_alc883 },
13670 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13671 .patch = patch_alc662 },
f32610ed 13672 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13673 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13674 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13675 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13676 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13677 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13678 {} /* terminator */
13679};