]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] HDA-Intel - Patch to support RV7xx HDMI Audio
[thirdparty/linux.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;
9a08160b
TI
1523 err = snd_hda_create_spdif_share_sw(codec,
1524 &spec->multiout);
1525 if (err < 0)
1526 return err;
1527 spec->multiout.share_spdif = 1;
1da177e4
LT
1528 }
1529 if (spec->dig_in_nid) {
1530 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1531 if (err < 0)
1532 return err;
1533 }
2134ea4f
TI
1534
1535 /* if we have no master control, let's create it */
1536 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1537 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1538 HDA_OUTPUT, spec->vmaster_tlv);
1539 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1540 spec->vmaster_tlv, alc_slave_vols);
1541 if (err < 0)
1542 return err;
1543 }
1544 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1545 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1546 NULL, alc_slave_sws);
1547 if (err < 0)
1548 return err;
1549 }
1550
1da177e4
LT
1551 return 0;
1552}
1553
e9edcee0 1554
1da177e4
LT
1555/*
1556 * initialize the codec volumes, etc
1557 */
1558
e9edcee0
TI
1559/*
1560 * generic initialization of ADC, input mixers and output mixers
1561 */
1562static struct hda_verb alc880_volume_init_verbs[] = {
1563 /*
1564 * Unmute ADC0-2 and set the default input to mic-in
1565 */
71fe7b82 1566 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1570 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1571 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1572
e9edcee0
TI
1573 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1574 * mixer widget
9c7f852e
TI
1575 * Note: PASD motherboards uses the Line In 2 as the input for front
1576 * panel mic (mic 2)
1da177e4 1577 */
e9edcee0 1578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1586
e9edcee0
TI
1587 /*
1588 * Set up output mixers (0x0c - 0x0f)
1da177e4 1589 */
e9edcee0
TI
1590 /* set vol=0 to output mixers */
1591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1595 /* set up input amps for analog loopback */
1596 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1597 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1601 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1603 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1605
1606 { }
1607};
1608
e9edcee0
TI
1609/*
1610 * 3-stack pin configuration:
1611 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1612 */
1613static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1614 /*
1615 * preset connection lists of input pins
1616 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1617 */
1618 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1619 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1620 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1621
1622 /*
1623 * Set pin mode and muting
1624 */
1625 /* set front pin widgets 0x14 for output */
05acb863 1626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1627 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1629 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1630 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1631 /* Mic2 (as headphone out) for HP output */
1632 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1633 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1634 /* Line In pin widget for input */
05acb863 1635 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1637 /* Line2 (as front mic) pin widget for input and vref at 80% */
1638 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1639 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1640 /* CD pin widget for input */
05acb863 1641 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1642
e9edcee0
TI
1643 { }
1644};
1da177e4 1645
e9edcee0
TI
1646/*
1647 * 5-stack pin configuration:
1648 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1649 * line-in/side = 0x1a, f-mic = 0x1b
1650 */
1651static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1652 /*
1653 * preset connection lists of input pins
1654 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1655 */
e9edcee0
TI
1656 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1657 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1658
e9edcee0
TI
1659 /*
1660 * Set pin mode and muting
1da177e4 1661 */
e9edcee0
TI
1662 /* set pin widgets 0x14-0x17 for output */
1663 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1665 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1666 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1667 /* unmute pins for output (no gain on this amp) */
1668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1669 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1670 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672
1673 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1674 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1675 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1676 /* Mic2 (as headphone out) for HP output */
1677 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1678 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1679 /* Line In pin widget for input */
1680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1682 /* Line2 (as front mic) pin widget for input and vref at 80% */
1683 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1684 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1685 /* CD pin widget for input */
1686 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1687
1688 { }
1689};
1690
e9edcee0
TI
1691/*
1692 * W810 pin configuration:
1693 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1694 */
1695static struct hda_verb alc880_pin_w810_init_verbs[] = {
1696 /* hphone/speaker input selector: front DAC */
1697 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1698
05acb863 1699 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1700 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1701 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1703 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1705
e9edcee0 1706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1708
1da177e4
LT
1709 { }
1710};
1711
e9edcee0
TI
1712/*
1713 * Z71V pin configuration:
1714 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1715 */
1716static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1717 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1718 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1719 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1720 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1721
16ded525 1722 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1723 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1724 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1725 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1726
1727 { }
1728};
1729
e9edcee0
TI
1730/*
1731 * 6-stack pin configuration:
9c7f852e
TI
1732 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1733 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1734 */
1735static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1736 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1737
16ded525 1738 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1742 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1743 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1744 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1745 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1746
16ded525 1747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1753 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1754 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1755 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1756
e9edcee0
TI
1757 { }
1758};
1759
ccc656ce
KY
1760/*
1761 * Uniwill pin configuration:
1762 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1763 * line = 0x1a
1764 */
1765static struct hda_verb alc880_uniwill_init_verbs[] = {
1766 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1767
1768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1772 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1774 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1775 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1778 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1780 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1781 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1782
1783 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1784 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1787 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1788 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1789 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1790 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1792
1793 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1795
1796 { }
1797};
1798
1799/*
1800* Uniwill P53
1801* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1802 */
1803static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1804 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1805
1806 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1807 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1810 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1811 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1814 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1815 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1816 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1817 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1818
1819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1820 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1823 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1824 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1825
1826 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1827 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1828
1829 { }
1830};
1831
2cf9f0fc
TD
1832static struct hda_verb alc880_beep_init_verbs[] = {
1833 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1834 { }
1835};
1836
ccc656ce 1837/* toggle speaker-output according to the hp-jack state */
458a4fab 1838static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1839{
1840 unsigned int present;
f12ab1e0 1841 unsigned char bits;
ccc656ce
KY
1842
1843 present = snd_hda_codec_read(codec, 0x14, 0,
1844 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1845 bits = present ? HDA_AMP_MUTE : 0;
1846 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1847 HDA_AMP_MUTE, bits);
1848 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1849 HDA_AMP_MUTE, bits);
458a4fab
TI
1850}
1851
1852/* auto-toggle front mic */
1853static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1854{
1855 unsigned int present;
1856 unsigned char bits;
ccc656ce
KY
1857
1858 present = snd_hda_codec_read(codec, 0x18, 0,
1859 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1860 bits = present ? HDA_AMP_MUTE : 0;
1861 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1862}
1863
1864static void alc880_uniwill_automute(struct hda_codec *codec)
1865{
1866 alc880_uniwill_hp_automute(codec);
1867 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1868}
1869
1870static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1871 unsigned int res)
1872{
1873 /* Looks like the unsol event is incompatible with the standard
1874 * definition. 4bit tag is placed at 28 bit!
1875 */
458a4fab
TI
1876 switch (res >> 28) {
1877 case ALC880_HP_EVENT:
1878 alc880_uniwill_hp_automute(codec);
1879 break;
1880 case ALC880_MIC_EVENT:
1881 alc880_uniwill_mic_automute(codec);
1882 break;
1883 }
ccc656ce
KY
1884}
1885
1886static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1887{
1888 unsigned int present;
f12ab1e0 1889 unsigned char bits;
ccc656ce
KY
1890
1891 present = snd_hda_codec_read(codec, 0x14, 0,
1892 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1893 bits = present ? HDA_AMP_MUTE : 0;
1894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1895}
1896
1897static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1898{
1899 unsigned int present;
1900
1901 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1902 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1903 present &= HDA_AMP_VOLMASK;
1904 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1905 HDA_AMP_VOLMASK, present);
1906 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1907 HDA_AMP_VOLMASK, present);
ccc656ce 1908}
47fd830a 1909
ccc656ce
KY
1910static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1911 unsigned int res)
1912{
1913 /* Looks like the unsol event is incompatible with the standard
1914 * definition. 4bit tag is placed at 28 bit!
1915 */
1916 if ((res >> 28) == ALC880_HP_EVENT)
1917 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1918 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1919 alc880_uniwill_p53_dcvol_automute(codec);
1920}
1921
e9edcee0
TI
1922/*
1923 * F1734 pin configuration:
1924 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1925 */
1926static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1927 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1928 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1929 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1930 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1931
e9edcee0 1932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1933 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1936
e9edcee0
TI
1937 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1938 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1939 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1940 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1941 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1942 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1943 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1944 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1945 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 1946
937b4160
TI
1947 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1948 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1949
dfc0ff62
TI
1950 { }
1951};
1952
e9edcee0
TI
1953/*
1954 * ASUS pin configuration:
1955 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1956 */
1957static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1958 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1959 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1960 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1961 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1962
1963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1965 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1967 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1969 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1971
1972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1973 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1974 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1980 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1981
e9edcee0
TI
1982 { }
1983};
16ded525 1984
e9edcee0 1985/* Enable GPIO mask and set output */
bc9f98a9
KY
1986#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1987#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1988
1989/* Clevo m520g init */
1990static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1991 /* headphone output */
1992 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1993 /* line-out */
1994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1995 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1996 /* Line-in */
1997 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999 /* CD */
2000 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2001 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2002 /* Mic1 (rear panel) */
2003 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2004 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2005 /* Mic2 (front panel) */
2006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 /* headphone */
2009 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2010 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011 /* change to EAPD mode */
2012 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2013 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2014
2015 { }
16ded525
TI
2016};
2017
df694daa 2018static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2019 /* change to EAPD mode */
2020 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2021 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2022
df694daa
KY
2023 /* Headphone output */
2024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2025 /* Front output*/
2026 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2027 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2028
2029 /* Line In pin widget for input */
2030 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2031 /* CD pin widget for input */
2032 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2033 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2035
2036 /* change to EAPD mode */
2037 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2038 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2039
2040 { }
2041};
16ded525 2042
e9edcee0 2043/*
ae6b813a
TI
2044 * LG m1 express dual
2045 *
2046 * Pin assignment:
2047 * Rear Line-In/Out (blue): 0x14
2048 * Build-in Mic-In: 0x15
2049 * Speaker-out: 0x17
2050 * HP-Out (green): 0x1b
2051 * Mic-In/Out (red): 0x19
2052 * SPDIF-Out: 0x1e
2053 */
2054
2055/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2056static hda_nid_t alc880_lg_dac_nids[3] = {
2057 0x05, 0x02, 0x03
2058};
2059
2060/* seems analog CD is not working */
2061static struct hda_input_mux alc880_lg_capture_source = {
2062 .num_items = 3,
2063 .items = {
2064 { "Mic", 0x1 },
2065 { "Line", 0x5 },
2066 { "Internal Mic", 0x6 },
2067 },
2068};
2069
2070/* 2,4,6 channel modes */
2071static struct hda_verb alc880_lg_ch2_init[] = {
2072 /* set line-in and mic-in to input */
2073 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2074 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2075 { }
2076};
2077
2078static struct hda_verb alc880_lg_ch4_init[] = {
2079 /* set line-in to out and mic-in to input */
2080 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2081 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2082 { }
2083};
2084
2085static struct hda_verb alc880_lg_ch6_init[] = {
2086 /* set line-in and mic-in to output */
2087 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2088 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2089 { }
2090};
2091
2092static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2093 { 2, alc880_lg_ch2_init },
2094 { 4, alc880_lg_ch4_init },
2095 { 6, alc880_lg_ch6_init },
2096};
2097
2098static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2100 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2112 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2113 {
2114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2115 .name = "Channel Mode",
2116 .info = alc_ch_mode_info,
2117 .get = alc_ch_mode_get,
2118 .put = alc_ch_mode_put,
2119 },
2120 { } /* end */
2121};
2122
2123static struct hda_verb alc880_lg_init_verbs[] = {
2124 /* set capture source to mic-in */
2125 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2126 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2128 /* mute all amp mixer inputs */
2129 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2130 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2132 /* line-in to input */
2133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2135 /* built-in mic */
2136 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2137 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2138 /* speaker-out */
2139 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2140 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2141 /* mic-in to input */
2142 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2144 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2145 /* HP-out */
2146 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2147 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2148 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2149 /* jack sense */
2150 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2151 { }
2152};
2153
2154/* toggle speaker-output according to the hp-jack state */
2155static void alc880_lg_automute(struct hda_codec *codec)
2156{
2157 unsigned int present;
f12ab1e0 2158 unsigned char bits;
ae6b813a
TI
2159
2160 present = snd_hda_codec_read(codec, 0x1b, 0,
2161 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2162 bits = present ? HDA_AMP_MUTE : 0;
2163 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2164 HDA_AMP_MUTE, bits);
ae6b813a
TI
2165}
2166
2167static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2168{
2169 /* Looks like the unsol event is incompatible with the standard
2170 * definition. 4bit tag is placed at 28 bit!
2171 */
2172 if ((res >> 28) == 0x01)
2173 alc880_lg_automute(codec);
2174}
2175
d681518a
TI
2176/*
2177 * LG LW20
2178 *
2179 * Pin assignment:
2180 * Speaker-out: 0x14
2181 * Mic-In: 0x18
e4f41da9
CM
2182 * Built-in Mic-In: 0x19
2183 * Line-In: 0x1b
2184 * HP-Out: 0x1a
d681518a
TI
2185 * SPDIF-Out: 0x1e
2186 */
2187
d681518a 2188static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2189 .num_items = 3,
d681518a
TI
2190 .items = {
2191 { "Mic", 0x0 },
2192 { "Internal Mic", 0x1 },
e4f41da9 2193 { "Line In", 0x2 },
d681518a
TI
2194 },
2195};
2196
0a8c5da3
CM
2197#define alc880_lg_lw_modes alc880_threestack_modes
2198
d681518a 2199static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2200 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2201 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2202 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2203 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2204 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2205 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2206 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2207 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2212 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2213 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2214 {
2215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2216 .name = "Channel Mode",
2217 .info = alc_ch_mode_info,
2218 .get = alc_ch_mode_get,
2219 .put = alc_ch_mode_put,
2220 },
d681518a
TI
2221 { } /* end */
2222};
2223
2224static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2225 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2226 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2227 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2228
d681518a
TI
2229 /* set capture source to mic-in */
2230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2233 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2234 /* speaker-out */
2235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2236 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2237 /* HP-out */
d681518a
TI
2238 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2239 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2240 /* mic-in to input */
2241 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2242 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2243 /* built-in mic */
2244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2245 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2246 /* jack sense */
2247 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2248 { }
2249};
2250
2251/* toggle speaker-output according to the hp-jack state */
2252static void alc880_lg_lw_automute(struct hda_codec *codec)
2253{
2254 unsigned int present;
f12ab1e0 2255 unsigned char bits;
d681518a
TI
2256
2257 present = snd_hda_codec_read(codec, 0x1b, 0,
2258 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2259 bits = present ? HDA_AMP_MUTE : 0;
2260 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2261 HDA_AMP_MUTE, bits);
d681518a
TI
2262}
2263
2264static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2265{
2266 /* Looks like the unsol event is incompatible with the standard
2267 * definition. 4bit tag is placed at 28 bit!
2268 */
2269 if ((res >> 28) == 0x01)
2270 alc880_lg_lw_automute(codec);
2271}
2272
cb53c626
TI
2273#ifdef CONFIG_SND_HDA_POWER_SAVE
2274static struct hda_amp_list alc880_loopbacks[] = {
2275 { 0x0b, HDA_INPUT, 0 },
2276 { 0x0b, HDA_INPUT, 1 },
2277 { 0x0b, HDA_INPUT, 2 },
2278 { 0x0b, HDA_INPUT, 3 },
2279 { 0x0b, HDA_INPUT, 4 },
2280 { } /* end */
2281};
2282
2283static struct hda_amp_list alc880_lg_loopbacks[] = {
2284 { 0x0b, HDA_INPUT, 1 },
2285 { 0x0b, HDA_INPUT, 6 },
2286 { 0x0b, HDA_INPUT, 7 },
2287 { } /* end */
2288};
2289#endif
2290
ae6b813a
TI
2291/*
2292 * Common callbacks
e9edcee0
TI
2293 */
2294
1da177e4
LT
2295static int alc_init(struct hda_codec *codec)
2296{
2297 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2298 unsigned int i;
2299
2300 for (i = 0; i < spec->num_init_verbs; i++)
2301 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2302
2303 if (spec->init_hook)
2304 spec->init_hook(codec);
2305
1da177e4
LT
2306 return 0;
2307}
2308
ae6b813a
TI
2309static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2310{
2311 struct alc_spec *spec = codec->spec;
2312
2313 if (spec->unsol_event)
2314 spec->unsol_event(codec, res);
2315}
2316
cb53c626
TI
2317#ifdef CONFIG_SND_HDA_POWER_SAVE
2318static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2319{
2320 struct alc_spec *spec = codec->spec;
2321 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2322}
2323#endif
2324
1da177e4
LT
2325/*
2326 * Analog playback callbacks
2327 */
2328static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2329 struct hda_codec *codec,
c8b6bf9b 2330 struct snd_pcm_substream *substream)
1da177e4
LT
2331{
2332 struct alc_spec *spec = codec->spec;
9a08160b
TI
2333 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2334 hinfo);
1da177e4
LT
2335}
2336
2337static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2338 struct hda_codec *codec,
2339 unsigned int stream_tag,
2340 unsigned int format,
c8b6bf9b 2341 struct snd_pcm_substream *substream)
1da177e4
LT
2342{
2343 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2344 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2345 stream_tag, format, substream);
1da177e4
LT
2346}
2347
2348static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2349 struct hda_codec *codec,
c8b6bf9b 2350 struct snd_pcm_substream *substream)
1da177e4
LT
2351{
2352 struct alc_spec *spec = codec->spec;
2353 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2354}
2355
2356/*
2357 * Digital out
2358 */
2359static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2360 struct hda_codec *codec,
c8b6bf9b 2361 struct snd_pcm_substream *substream)
1da177e4
LT
2362{
2363 struct alc_spec *spec = codec->spec;
2364 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2365}
2366
6b97eb45
TI
2367static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2368 struct hda_codec *codec,
2369 unsigned int stream_tag,
2370 unsigned int format,
2371 struct snd_pcm_substream *substream)
2372{
2373 struct alc_spec *spec = codec->spec;
2374 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2375 stream_tag, format, substream);
2376}
2377
1da177e4
LT
2378static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2379 struct hda_codec *codec,
c8b6bf9b 2380 struct snd_pcm_substream *substream)
1da177e4
LT
2381{
2382 struct alc_spec *spec = codec->spec;
2383 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2384}
2385
2386/*
2387 * Analog capture
2388 */
6330079f 2389static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2390 struct hda_codec *codec,
2391 unsigned int stream_tag,
2392 unsigned int format,
c8b6bf9b 2393 struct snd_pcm_substream *substream)
1da177e4
LT
2394{
2395 struct alc_spec *spec = codec->spec;
2396
6330079f 2397 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2398 stream_tag, 0, format);
2399 return 0;
2400}
2401
6330079f 2402static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2403 struct hda_codec *codec,
c8b6bf9b 2404 struct snd_pcm_substream *substream)
1da177e4
LT
2405{
2406 struct alc_spec *spec = codec->spec;
2407
6330079f 2408 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
9c7f852e 2409 0, 0, 0);
1da177e4
LT
2410 return 0;
2411}
2412
2413
2414/*
2415 */
2416static struct hda_pcm_stream alc880_pcm_analog_playback = {
2417 .substreams = 1,
2418 .channels_min = 2,
2419 .channels_max = 8,
e9edcee0 2420 /* NID is set in alc_build_pcms */
1da177e4
LT
2421 .ops = {
2422 .open = alc880_playback_pcm_open,
2423 .prepare = alc880_playback_pcm_prepare,
2424 .cleanup = alc880_playback_pcm_cleanup
2425 },
2426};
2427
2428static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2429 .substreams = 1,
2430 .channels_min = 2,
2431 .channels_max = 2,
2432 /* NID is set in alc_build_pcms */
2433};
2434
2435static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2436 .substreams = 1,
2437 .channels_min = 2,
2438 .channels_max = 2,
2439 /* NID is set in alc_build_pcms */
2440};
2441
2442static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2443 .substreams = 2, /* can be overridden */
1da177e4
LT
2444 .channels_min = 2,
2445 .channels_max = 2,
e9edcee0 2446 /* NID is set in alc_build_pcms */
1da177e4 2447 .ops = {
6330079f
TI
2448 .prepare = alc880_alt_capture_pcm_prepare,
2449 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2450 },
2451};
2452
2453static struct hda_pcm_stream alc880_pcm_digital_playback = {
2454 .substreams = 1,
2455 .channels_min = 2,
2456 .channels_max = 2,
2457 /* NID is set in alc_build_pcms */
2458 .ops = {
2459 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2460 .close = alc880_dig_playback_pcm_close,
2461 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2462 },
2463};
2464
2465static struct hda_pcm_stream alc880_pcm_digital_capture = {
2466 .substreams = 1,
2467 .channels_min = 2,
2468 .channels_max = 2,
2469 /* NID is set in alc_build_pcms */
2470};
2471
4c5186ed 2472/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2473static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2474 .substreams = 0,
2475 .channels_min = 0,
2476 .channels_max = 0,
2477};
2478
1da177e4
LT
2479static int alc_build_pcms(struct hda_codec *codec)
2480{
2481 struct alc_spec *spec = codec->spec;
2482 struct hda_pcm *info = spec->pcm_rec;
2483 int i;
2484
2485 codec->num_pcms = 1;
2486 codec->pcm_info = info;
2487
2488 info->name = spec->stream_name_analog;
4a471b7d
TI
2489 if (spec->stream_analog_playback) {
2490 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2491 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2492 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2493 }
2494 if (spec->stream_analog_capture) {
2495 snd_assert(spec->adc_nids, return -EINVAL);
2496 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2497 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2498 }
2499
2500 if (spec->channel_mode) {
2501 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2502 for (i = 0; i < spec->num_channel_mode; i++) {
2503 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2504 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2505 }
1da177e4
LT
2506 }
2507 }
2508
e08a007d 2509 /* SPDIF for stream index #1 */
1da177e4 2510 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2511 codec->num_pcms = 2;
c06134d7 2512 info = spec->pcm_rec + 1;
1da177e4 2513 info->name = spec->stream_name_digital;
7ba72ba1 2514 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2515 if (spec->multiout.dig_out_nid &&
2516 spec->stream_digital_playback) {
1da177e4
LT
2517 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2518 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2519 }
4a471b7d
TI
2520 if (spec->dig_in_nid &&
2521 spec->stream_digital_capture) {
1da177e4
LT
2522 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2523 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2524 }
2525 }
2526
e08a007d
TI
2527 /* If the use of more than one ADC is requested for the current
2528 * model, configure a second analog capture-only PCM.
2529 */
2530 /* Additional Analaog capture for index #2 */
6330079f
TI
2531 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2532 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2533 codec->num_pcms = 3;
c06134d7 2534 info = spec->pcm_rec + 2;
e08a007d 2535 info->name = spec->stream_name_analog;
6330079f
TI
2536 if (spec->alt_dac_nid) {
2537 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2538 *spec->stream_analog_alt_playback;
2539 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2540 spec->alt_dac_nid;
2541 } else {
2542 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2543 alc_pcm_null_stream;
2544 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2545 }
2546 if (spec->num_adc_nids > 1) {
2547 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2548 *spec->stream_analog_alt_capture;
2549 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2550 spec->adc_nids[1];
2551 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2552 spec->num_adc_nids - 1;
2553 } else {
2554 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2555 alc_pcm_null_stream;
2556 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2557 }
2558 }
2559
1da177e4
LT
2560 return 0;
2561}
2562
2563static void alc_free(struct hda_codec *codec)
2564{
e9edcee0
TI
2565 struct alc_spec *spec = codec->spec;
2566 unsigned int i;
2567
f12ab1e0 2568 if (!spec)
e9edcee0
TI
2569 return;
2570
2571 if (spec->kctl_alloc) {
2572 for (i = 0; i < spec->num_kctl_used; i++)
2573 kfree(spec->kctl_alloc[i].name);
2574 kfree(spec->kctl_alloc);
2575 }
2576 kfree(spec);
1da177e4
LT
2577}
2578
2579/*
2580 */
2581static struct hda_codec_ops alc_patch_ops = {
2582 .build_controls = alc_build_controls,
2583 .build_pcms = alc_build_pcms,
2584 .init = alc_init,
2585 .free = alc_free,
ae6b813a 2586 .unsol_event = alc_unsol_event,
cb53c626
TI
2587#ifdef CONFIG_SND_HDA_POWER_SAVE
2588 .check_power_status = alc_check_power_status,
2589#endif
1da177e4
LT
2590};
2591
2fa522be
TI
2592
2593/*
2594 * Test configuration for debugging
2595 *
2596 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2597 * enum controls.
2598 */
2599#ifdef CONFIG_SND_DEBUG
2600static hda_nid_t alc880_test_dac_nids[4] = {
2601 0x02, 0x03, 0x04, 0x05
2602};
2603
2604static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2605 .num_items = 7,
2fa522be
TI
2606 .items = {
2607 { "In-1", 0x0 },
2608 { "In-2", 0x1 },
2609 { "In-3", 0x2 },
2610 { "In-4", 0x3 },
2611 { "CD", 0x4 },
ae6b813a
TI
2612 { "Front", 0x5 },
2613 { "Surround", 0x6 },
2fa522be
TI
2614 },
2615};
2616
d2a6d7dc 2617static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2618 { 2, NULL },
fd2c326d 2619 { 4, NULL },
2fa522be 2620 { 6, NULL },
fd2c326d 2621 { 8, NULL },
2fa522be
TI
2622};
2623
9c7f852e
TI
2624static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2625 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2626{
2627 static char *texts[] = {
2628 "N/A", "Line Out", "HP Out",
2629 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2630 };
2631 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2632 uinfo->count = 1;
2633 uinfo->value.enumerated.items = 8;
2634 if (uinfo->value.enumerated.item >= 8)
2635 uinfo->value.enumerated.item = 7;
2636 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2637 return 0;
2638}
2639
9c7f852e
TI
2640static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2641 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2642{
2643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2644 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2645 unsigned int pin_ctl, item = 0;
2646
2647 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2648 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2649 if (pin_ctl & AC_PINCTL_OUT_EN) {
2650 if (pin_ctl & AC_PINCTL_HP_EN)
2651 item = 2;
2652 else
2653 item = 1;
2654 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2655 switch (pin_ctl & AC_PINCTL_VREFEN) {
2656 case AC_PINCTL_VREF_HIZ: item = 3; break;
2657 case AC_PINCTL_VREF_50: item = 4; break;
2658 case AC_PINCTL_VREF_GRD: item = 5; break;
2659 case AC_PINCTL_VREF_80: item = 6; break;
2660 case AC_PINCTL_VREF_100: item = 7; break;
2661 }
2662 }
2663 ucontrol->value.enumerated.item[0] = item;
2664 return 0;
2665}
2666
9c7f852e
TI
2667static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2668 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2669{
2670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2671 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2672 static unsigned int ctls[] = {
2673 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2674 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2675 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2676 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2677 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2678 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2679 };
2680 unsigned int old_ctl, new_ctl;
2681
2682 old_ctl = snd_hda_codec_read(codec, nid, 0,
2683 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2684 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2685 if (old_ctl != new_ctl) {
82beb8fd
TI
2686 int val;
2687 snd_hda_codec_write_cache(codec, nid, 0,
2688 AC_VERB_SET_PIN_WIDGET_CONTROL,
2689 new_ctl);
47fd830a
TI
2690 val = ucontrol->value.enumerated.item[0] >= 3 ?
2691 HDA_AMP_MUTE : 0;
2692 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2693 HDA_AMP_MUTE, val);
2fa522be
TI
2694 return 1;
2695 }
2696 return 0;
2697}
2698
9c7f852e
TI
2699static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2700 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2701{
2702 static char *texts[] = {
2703 "Front", "Surround", "CLFE", "Side"
2704 };
2705 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2706 uinfo->count = 1;
2707 uinfo->value.enumerated.items = 4;
2708 if (uinfo->value.enumerated.item >= 4)
2709 uinfo->value.enumerated.item = 3;
2710 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2711 return 0;
2712}
2713
9c7f852e
TI
2714static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2715 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2716{
2717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2718 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2719 unsigned int sel;
2720
2721 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2722 ucontrol->value.enumerated.item[0] = sel & 3;
2723 return 0;
2724}
2725
9c7f852e
TI
2726static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2728{
2729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2730 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2731 unsigned int sel;
2732
2733 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2734 if (ucontrol->value.enumerated.item[0] != sel) {
2735 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2736 snd_hda_codec_write_cache(codec, nid, 0,
2737 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2738 return 1;
2739 }
2740 return 0;
2741}
2742
2743#define PIN_CTL_TEST(xname,nid) { \
2744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2745 .name = xname, \
2746 .info = alc_test_pin_ctl_info, \
2747 .get = alc_test_pin_ctl_get, \
2748 .put = alc_test_pin_ctl_put, \
2749 .private_value = nid \
2750 }
2751
2752#define PIN_SRC_TEST(xname,nid) { \
2753 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2754 .name = xname, \
2755 .info = alc_test_pin_src_info, \
2756 .get = alc_test_pin_src_get, \
2757 .put = alc_test_pin_src_put, \
2758 .private_value = nid \
2759 }
2760
c8b6bf9b 2761static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2762 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2763 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2764 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2765 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2766 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2767 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2768 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2769 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2770 PIN_CTL_TEST("Front Pin Mode", 0x14),
2771 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2772 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2773 PIN_CTL_TEST("Side Pin Mode", 0x17),
2774 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2775 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2776 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2777 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2778 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2779 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2780 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2781 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2782 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2783 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2784 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2785 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2786 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2787 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2788 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2789 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2790 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2791 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2792 {
2793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2794 .name = "Channel Mode",
df694daa
KY
2795 .info = alc_ch_mode_info,
2796 .get = alc_ch_mode_get,
2797 .put = alc_ch_mode_put,
2fa522be
TI
2798 },
2799 { } /* end */
2800};
2801
2802static struct hda_verb alc880_test_init_verbs[] = {
2803 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2810 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2812 /* Vol output for 0x0c-0x0f */
05acb863
TI
2813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2814 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2816 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2817 /* Set output pins 0x14-0x17 */
05acb863
TI
2818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2820 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2821 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2822 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2825 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2826 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2827 /* Set input pins 0x18-0x1c */
16ded525
TI
2828 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2829 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2830 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2832 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2833 /* Mute input pins 0x18-0x1b */
05acb863
TI
2834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2836 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2838 /* ADC set up */
05acb863 2839 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2840 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2841 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2842 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2843 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2844 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2845 /* Analog input/passthru */
2846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2851 { }
2852};
2853#endif
2854
1da177e4
LT
2855/*
2856 */
2857
f5fcc13c
TI
2858static const char *alc880_models[ALC880_MODEL_LAST] = {
2859 [ALC880_3ST] = "3stack",
2860 [ALC880_TCL_S700] = "tcl",
2861 [ALC880_3ST_DIG] = "3stack-digout",
2862 [ALC880_CLEVO] = "clevo",
2863 [ALC880_5ST] = "5stack",
2864 [ALC880_5ST_DIG] = "5stack-digout",
2865 [ALC880_W810] = "w810",
2866 [ALC880_Z71V] = "z71v",
2867 [ALC880_6ST] = "6stack",
2868 [ALC880_6ST_DIG] = "6stack-digout",
2869 [ALC880_ASUS] = "asus",
2870 [ALC880_ASUS_W1V] = "asus-w1v",
2871 [ALC880_ASUS_DIG] = "asus-dig",
2872 [ALC880_ASUS_DIG2] = "asus-dig2",
2873 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2874 [ALC880_UNIWILL_P53] = "uniwill-p53",
2875 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2876 [ALC880_F1734] = "F1734",
2877 [ALC880_LG] = "lg",
2878 [ALC880_LG_LW] = "lg-lw",
2fa522be 2879#ifdef CONFIG_SND_DEBUG
f5fcc13c 2880 [ALC880_TEST] = "test",
2fa522be 2881#endif
f5fcc13c
TI
2882 [ALC880_AUTO] = "auto",
2883};
2884
2885static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2886 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2887 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2888 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2889 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2890 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2891 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2892 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2893 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2894 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2895 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2896 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2897 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2898 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2899 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2900 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2901 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2902 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2903 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2904 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2905 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2906 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2907 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2908 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2909 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2910 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2911 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2912 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2913 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2914 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2915 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2916 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2917 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2918 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2919 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2920 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2921 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2922 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2923 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2924 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2925 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2926 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2927 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2928 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2929 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2930 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2931 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2932 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2933 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2934 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2935 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2936 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2937 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2938 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2939 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2940 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2941 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2942 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2943 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2944 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2945 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2946 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2947 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2948 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2949 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2950 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2951 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2952 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2953 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2954 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2955 {}
2956};
2957
16ded525 2958/*
df694daa 2959 * ALC880 codec presets
16ded525 2960 */
16ded525
TI
2961static struct alc_config_preset alc880_presets[] = {
2962 [ALC880_3ST] = {
e9edcee0 2963 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2964 .init_verbs = { alc880_volume_init_verbs,
2965 alc880_pin_3stack_init_verbs },
16ded525 2966 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2967 .dac_nids = alc880_dac_nids,
16ded525
TI
2968 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2969 .channel_mode = alc880_threestack_modes,
4e195a7b 2970 .need_dac_fix = 1,
16ded525
TI
2971 .input_mux = &alc880_capture_source,
2972 },
2973 [ALC880_3ST_DIG] = {
e9edcee0 2974 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2975 .init_verbs = { alc880_volume_init_verbs,
2976 alc880_pin_3stack_init_verbs },
16ded525 2977 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2978 .dac_nids = alc880_dac_nids,
2979 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2980 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2981 .channel_mode = alc880_threestack_modes,
4e195a7b 2982 .need_dac_fix = 1,
16ded525
TI
2983 .input_mux = &alc880_capture_source,
2984 },
df694daa
KY
2985 [ALC880_TCL_S700] = {
2986 .mixers = { alc880_tcl_s700_mixer },
2987 .init_verbs = { alc880_volume_init_verbs,
2988 alc880_pin_tcl_S700_init_verbs,
2989 alc880_gpio2_init_verbs },
2990 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2991 .dac_nids = alc880_dac_nids,
2992 .hp_nid = 0x03,
2993 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2994 .channel_mode = alc880_2_jack_modes,
2995 .input_mux = &alc880_capture_source,
2996 },
16ded525 2997 [ALC880_5ST] = {
f12ab1e0
TI
2998 .mixers = { alc880_three_stack_mixer,
2999 alc880_five_stack_mixer},
3000 .init_verbs = { alc880_volume_init_verbs,
3001 alc880_pin_5stack_init_verbs },
16ded525
TI
3002 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3003 .dac_nids = alc880_dac_nids,
16ded525
TI
3004 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3005 .channel_mode = alc880_fivestack_modes,
3006 .input_mux = &alc880_capture_source,
3007 },
3008 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3009 .mixers = { alc880_three_stack_mixer,
3010 alc880_five_stack_mixer },
3011 .init_verbs = { alc880_volume_init_verbs,
3012 alc880_pin_5stack_init_verbs },
16ded525
TI
3013 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3014 .dac_nids = alc880_dac_nids,
3015 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3016 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3017 .channel_mode = alc880_fivestack_modes,
3018 .input_mux = &alc880_capture_source,
3019 },
b6482d48
TI
3020 [ALC880_6ST] = {
3021 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3022 .init_verbs = { alc880_volume_init_verbs,
3023 alc880_pin_6stack_init_verbs },
b6482d48
TI
3024 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3025 .dac_nids = alc880_6st_dac_nids,
3026 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3027 .channel_mode = alc880_sixstack_modes,
3028 .input_mux = &alc880_6stack_capture_source,
3029 },
16ded525 3030 [ALC880_6ST_DIG] = {
e9edcee0 3031 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3032 .init_verbs = { alc880_volume_init_verbs,
3033 alc880_pin_6stack_init_verbs },
16ded525
TI
3034 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3035 .dac_nids = alc880_6st_dac_nids,
3036 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3037 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3038 .channel_mode = alc880_sixstack_modes,
3039 .input_mux = &alc880_6stack_capture_source,
3040 },
3041 [ALC880_W810] = {
e9edcee0 3042 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3043 .init_verbs = { alc880_volume_init_verbs,
3044 alc880_pin_w810_init_verbs,
b0af0de5 3045 alc880_gpio2_init_verbs },
16ded525
TI
3046 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3047 .dac_nids = alc880_w810_dac_nids,
3048 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3049 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3050 .channel_mode = alc880_w810_modes,
3051 .input_mux = &alc880_capture_source,
3052 },
3053 [ALC880_Z71V] = {
e9edcee0 3054 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3055 .init_verbs = { alc880_volume_init_verbs,
3056 alc880_pin_z71v_init_verbs },
16ded525
TI
3057 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3058 .dac_nids = alc880_z71v_dac_nids,
3059 .dig_out_nid = ALC880_DIGOUT_NID,
3060 .hp_nid = 0x03,
e9edcee0
TI
3061 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3062 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3063 .input_mux = &alc880_capture_source,
3064 },
3065 [ALC880_F1734] = {
e9edcee0 3066 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3067 .init_verbs = { alc880_volume_init_verbs,
3068 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3069 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3070 .dac_nids = alc880_f1734_dac_nids,
3071 .hp_nid = 0x02,
3072 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3073 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3074 .input_mux = &alc880_f1734_capture_source,
3075 .unsol_event = alc880_uniwill_p53_unsol_event,
3076 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3077 },
3078 [ALC880_ASUS] = {
e9edcee0 3079 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3080 .init_verbs = { alc880_volume_init_verbs,
3081 alc880_pin_asus_init_verbs,
e9edcee0
TI
3082 alc880_gpio1_init_verbs },
3083 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3084 .dac_nids = alc880_asus_dac_nids,
3085 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3086 .channel_mode = alc880_asus_modes,
4e195a7b 3087 .need_dac_fix = 1,
16ded525
TI
3088 .input_mux = &alc880_capture_source,
3089 },
3090 [ALC880_ASUS_DIG] = {
e9edcee0 3091 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3092 .init_verbs = { alc880_volume_init_verbs,
3093 alc880_pin_asus_init_verbs,
e9edcee0
TI
3094 alc880_gpio1_init_verbs },
3095 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3096 .dac_nids = alc880_asus_dac_nids,
16ded525 3097 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3098 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3099 .channel_mode = alc880_asus_modes,
4e195a7b 3100 .need_dac_fix = 1,
16ded525
TI
3101 .input_mux = &alc880_capture_source,
3102 },
df694daa
KY
3103 [ALC880_ASUS_DIG2] = {
3104 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3105 .init_verbs = { alc880_volume_init_verbs,
3106 alc880_pin_asus_init_verbs,
df694daa
KY
3107 alc880_gpio2_init_verbs }, /* use GPIO2 */
3108 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3109 .dac_nids = alc880_asus_dac_nids,
3110 .dig_out_nid = ALC880_DIGOUT_NID,
3111 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3112 .channel_mode = alc880_asus_modes,
4e195a7b 3113 .need_dac_fix = 1,
df694daa
KY
3114 .input_mux = &alc880_capture_source,
3115 },
16ded525 3116 [ALC880_ASUS_W1V] = {
e9edcee0 3117 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3118 .init_verbs = { alc880_volume_init_verbs,
3119 alc880_pin_asus_init_verbs,
e9edcee0
TI
3120 alc880_gpio1_init_verbs },
3121 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3122 .dac_nids = alc880_asus_dac_nids,
16ded525 3123 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3124 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3125 .channel_mode = alc880_asus_modes,
4e195a7b 3126 .need_dac_fix = 1,
16ded525
TI
3127 .input_mux = &alc880_capture_source,
3128 },
3129 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3130 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3131 .init_verbs = { alc880_volume_init_verbs,
3132 alc880_pin_asus_init_verbs },
e9edcee0
TI
3133 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3134 .dac_nids = alc880_asus_dac_nids,
16ded525 3135 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3136 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3137 .channel_mode = alc880_asus_modes,
4e195a7b 3138 .need_dac_fix = 1,
16ded525
TI
3139 .input_mux = &alc880_capture_source,
3140 },
ccc656ce
KY
3141 [ALC880_UNIWILL] = {
3142 .mixers = { alc880_uniwill_mixer },
3143 .init_verbs = { alc880_volume_init_verbs,
3144 alc880_uniwill_init_verbs },
3145 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3146 .dac_nids = alc880_asus_dac_nids,
3147 .dig_out_nid = ALC880_DIGOUT_NID,
3148 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3149 .channel_mode = alc880_threestack_modes,
3150 .need_dac_fix = 1,
3151 .input_mux = &alc880_capture_source,
3152 .unsol_event = alc880_uniwill_unsol_event,
3153 .init_hook = alc880_uniwill_automute,
3154 },
3155 [ALC880_UNIWILL_P53] = {
3156 .mixers = { alc880_uniwill_p53_mixer },
3157 .init_verbs = { alc880_volume_init_verbs,
3158 alc880_uniwill_p53_init_verbs },
3159 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3160 .dac_nids = alc880_asus_dac_nids,
3161 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3162 .channel_mode = alc880_threestack_modes,
3163 .input_mux = &alc880_capture_source,
3164 .unsol_event = alc880_uniwill_p53_unsol_event,
3165 .init_hook = alc880_uniwill_p53_hp_automute,
3166 },
3167 [ALC880_FUJITSU] = {
f12ab1e0 3168 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3169 alc880_pcbeep_mixer, },
3170 .init_verbs = { alc880_volume_init_verbs,
3171 alc880_uniwill_p53_init_verbs,
3172 alc880_beep_init_verbs },
3173 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3174 .dac_nids = alc880_dac_nids,
d53d7d9e 3175 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3176 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3177 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3178 .input_mux = &alc880_capture_source,
3179 .unsol_event = alc880_uniwill_p53_unsol_event,
3180 .init_hook = alc880_uniwill_p53_hp_automute,
3181 },
df694daa
KY
3182 [ALC880_CLEVO] = {
3183 .mixers = { alc880_three_stack_mixer },
3184 .init_verbs = { alc880_volume_init_verbs,
3185 alc880_pin_clevo_init_verbs },
3186 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3187 .dac_nids = alc880_dac_nids,
3188 .hp_nid = 0x03,
3189 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3190 .channel_mode = alc880_threestack_modes,
4e195a7b 3191 .need_dac_fix = 1,
df694daa
KY
3192 .input_mux = &alc880_capture_source,
3193 },
ae6b813a
TI
3194 [ALC880_LG] = {
3195 .mixers = { alc880_lg_mixer },
3196 .init_verbs = { alc880_volume_init_verbs,
3197 alc880_lg_init_verbs },
3198 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3199 .dac_nids = alc880_lg_dac_nids,
3200 .dig_out_nid = ALC880_DIGOUT_NID,
3201 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3202 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3203 .need_dac_fix = 1,
ae6b813a
TI
3204 .input_mux = &alc880_lg_capture_source,
3205 .unsol_event = alc880_lg_unsol_event,
3206 .init_hook = alc880_lg_automute,
cb53c626
TI
3207#ifdef CONFIG_SND_HDA_POWER_SAVE
3208 .loopbacks = alc880_lg_loopbacks,
3209#endif
ae6b813a 3210 },
d681518a
TI
3211 [ALC880_LG_LW] = {
3212 .mixers = { alc880_lg_lw_mixer },
3213 .init_verbs = { alc880_volume_init_verbs,
3214 alc880_lg_lw_init_verbs },
0a8c5da3 3215 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3216 .dac_nids = alc880_dac_nids,
3217 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3218 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3219 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3220 .input_mux = &alc880_lg_lw_capture_source,
3221 .unsol_event = alc880_lg_lw_unsol_event,
3222 .init_hook = alc880_lg_lw_automute,
3223 },
16ded525
TI
3224#ifdef CONFIG_SND_DEBUG
3225 [ALC880_TEST] = {
e9edcee0
TI
3226 .mixers = { alc880_test_mixer },
3227 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3228 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3229 .dac_nids = alc880_test_dac_nids,
3230 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3231 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3232 .channel_mode = alc880_test_modes,
3233 .input_mux = &alc880_test_capture_source,
3234 },
3235#endif
3236};
3237
e9edcee0
TI
3238/*
3239 * Automatic parse of I/O pins from the BIOS configuration
3240 */
3241
3242#define NUM_CONTROL_ALLOC 32
3243#define NUM_VERB_ALLOC 32
3244
3245enum {
3246 ALC_CTL_WIDGET_VOL,
3247 ALC_CTL_WIDGET_MUTE,
3248 ALC_CTL_BIND_MUTE,
3249};
c8b6bf9b 3250static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3251 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3252 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3253 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3254};
3255
3256/* add dynamic controls */
f12ab1e0
TI
3257static int add_control(struct alc_spec *spec, int type, const char *name,
3258 unsigned long val)
e9edcee0 3259{
c8b6bf9b 3260 struct snd_kcontrol_new *knew;
e9edcee0
TI
3261
3262 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3263 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3264
f12ab1e0
TI
3265 /* array + terminator */
3266 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3267 if (!knew)
e9edcee0
TI
3268 return -ENOMEM;
3269 if (spec->kctl_alloc) {
f12ab1e0
TI
3270 memcpy(knew, spec->kctl_alloc,
3271 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3272 kfree(spec->kctl_alloc);
3273 }
3274 spec->kctl_alloc = knew;
3275 spec->num_kctl_alloc = num;
3276 }
3277
3278 knew = &spec->kctl_alloc[spec->num_kctl_used];
3279 *knew = alc880_control_templates[type];
543537bd 3280 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3281 if (!knew->name)
e9edcee0
TI
3282 return -ENOMEM;
3283 knew->private_value = val;
3284 spec->num_kctl_used++;
3285 return 0;
3286}
3287
3288#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3289#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3290#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3291#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3292#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3293#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3294#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3295#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3296#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3297#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3298#define ALC880_PIN_CD_NID 0x1c
3299
3300/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3301static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3302 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3303{
3304 hda_nid_t nid;
3305 int assigned[4];
3306 int i, j;
3307
3308 memset(assigned, 0, sizeof(assigned));
b0af0de5 3309 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3310
3311 /* check the pins hardwired to audio widget */
3312 for (i = 0; i < cfg->line_outs; i++) {
3313 nid = cfg->line_out_pins[i];
3314 if (alc880_is_fixed_pin(nid)) {
3315 int idx = alc880_fixed_pin_idx(nid);
5014f193 3316 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3317 assigned[idx] = 1;
3318 }
3319 }
3320 /* left pins can be connect to any audio widget */
3321 for (i = 0; i < cfg->line_outs; i++) {
3322 nid = cfg->line_out_pins[i];
3323 if (alc880_is_fixed_pin(nid))
3324 continue;
3325 /* search for an empty channel */
3326 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3327 if (!assigned[j]) {
3328 spec->multiout.dac_nids[i] =
3329 alc880_idx_to_dac(j);
e9edcee0
TI
3330 assigned[j] = 1;
3331 break;
3332 }
3333 }
3334 }
3335 spec->multiout.num_dacs = cfg->line_outs;
3336 return 0;
3337}
3338
3339/* add playback controls from the parsed DAC table */
df694daa
KY
3340static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3341 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3342{
3343 char name[32];
f12ab1e0
TI
3344 static const char *chname[4] = {
3345 "Front", "Surround", NULL /*CLFE*/, "Side"
3346 };
e9edcee0
TI
3347 hda_nid_t nid;
3348 int i, err;
3349
3350 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3351 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3352 continue;
3353 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3354 if (i == 2) {
3355 /* Center/LFE */
f12ab1e0
TI
3356 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3357 "Center Playback Volume",
3358 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3359 HDA_OUTPUT));
3360 if (err < 0)
e9edcee0 3361 return err;
f12ab1e0
TI
3362 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3363 "LFE Playback Volume",
3364 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3365 HDA_OUTPUT));
3366 if (err < 0)
e9edcee0 3367 return err;
f12ab1e0
TI
3368 err = add_control(spec, ALC_CTL_BIND_MUTE,
3369 "Center Playback Switch",
3370 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3371 HDA_INPUT));
3372 if (err < 0)
e9edcee0 3373 return err;
f12ab1e0
TI
3374 err = add_control(spec, ALC_CTL_BIND_MUTE,
3375 "LFE Playback Switch",
3376 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3377 HDA_INPUT));
3378 if (err < 0)
e9edcee0
TI
3379 return err;
3380 } else {
3381 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3382 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3383 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3384 HDA_OUTPUT));
3385 if (err < 0)
e9edcee0
TI
3386 return err;
3387 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3388 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3389 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3390 HDA_INPUT));
3391 if (err < 0)
e9edcee0
TI
3392 return err;
3393 }
3394 }
e9edcee0
TI
3395 return 0;
3396}
3397
8d88bc3d
TI
3398/* add playback controls for speaker and HP outputs */
3399static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3400 const char *pfx)
e9edcee0
TI
3401{
3402 hda_nid_t nid;
3403 int err;
8d88bc3d 3404 char name[32];
e9edcee0 3405
f12ab1e0 3406 if (!pin)
e9edcee0
TI
3407 return 0;
3408
3409 if (alc880_is_fixed_pin(pin)) {
3410 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3411 /* specify the DAC as the extra output */
f12ab1e0 3412 if (!spec->multiout.hp_nid)
e9edcee0 3413 spec->multiout.hp_nid = nid;
82bc955f
TI
3414 else
3415 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3416 /* control HP volume/switch on the output mixer amp */
3417 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3418 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3419 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3420 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3421 if (err < 0)
e9edcee0 3422 return err;
8d88bc3d 3423 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3424 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3425 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3426 if (err < 0)
e9edcee0
TI
3427 return err;
3428 } else if (alc880_is_multi_pin(pin)) {
3429 /* set manual connection */
e9edcee0 3430 /* we have only a switch on HP-out PIN */
8d88bc3d 3431 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3432 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3433 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3434 if (err < 0)
e9edcee0
TI
3435 return err;
3436 }
3437 return 0;
3438}
3439
3440/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3441static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3442 const char *ctlname,
df694daa 3443 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3444{
3445 char name[32];
df694daa 3446 int err;
e9edcee0
TI
3447
3448 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3449 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3450 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3451 if (err < 0)
e9edcee0
TI
3452 return err;
3453 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3454 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3455 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3456 if (err < 0)
e9edcee0
TI
3457 return err;
3458 return 0;
3459}
3460
3461/* create playback/capture controls for input pins */
df694daa
KY
3462static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3463 const struct auto_pin_cfg *cfg)
e9edcee0 3464{
e9edcee0 3465 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3466 int i, err, idx;
e9edcee0
TI
3467
3468 for (i = 0; i < AUTO_PIN_LAST; i++) {
3469 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3470 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3471 err = new_analog_input(spec, cfg->input_pins[i],
3472 auto_pin_cfg_labels[i],
df694daa 3473 idx, 0x0b);
e9edcee0
TI
3474 if (err < 0)
3475 return err;
f12ab1e0
TI
3476 imux->items[imux->num_items].label =
3477 auto_pin_cfg_labels[i];
3478 imux->items[imux->num_items].index =
3479 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3480 imux->num_items++;
3481 }
3482 }
3483 return 0;
3484}
3485
f6c7e546
TI
3486static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3487 unsigned int pin_type)
3488{
3489 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3490 pin_type);
3491 /* unmute pin */
d260cdf6
TI
3492 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3493 AMP_OUT_UNMUTE);
f6c7e546
TI
3494}
3495
df694daa
KY
3496static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3497 hda_nid_t nid, int pin_type,
e9edcee0
TI
3498 int dac_idx)
3499{
f6c7e546 3500 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3501 /* need the manual connection? */
3502 if (alc880_is_multi_pin(nid)) {
3503 struct alc_spec *spec = codec->spec;
3504 int idx = alc880_multi_pin_idx(nid);
3505 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3506 AC_VERB_SET_CONNECT_SEL,
3507 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3508 }
3509}
3510
baba8ee9
TI
3511static int get_pin_type(int line_out_type)
3512{
3513 if (line_out_type == AUTO_PIN_HP_OUT)
3514 return PIN_HP;
3515 else
3516 return PIN_OUT;
3517}
3518
e9edcee0
TI
3519static void alc880_auto_init_multi_out(struct hda_codec *codec)
3520{
3521 struct alc_spec *spec = codec->spec;
3522 int i;
bc9f98a9
KY
3523
3524 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3525 for (i = 0; i < spec->autocfg.line_outs; i++) {
3526 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3527 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3528 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3529 }
3530}
3531
8d88bc3d 3532static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3533{
3534 struct alc_spec *spec = codec->spec;
3535 hda_nid_t pin;
3536
82bc955f 3537 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3538 if (pin) /* connect to front */
3539 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3540 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3541 if (pin) /* connect to front */
3542 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3543}
3544
3545static void alc880_auto_init_analog_input(struct hda_codec *codec)
3546{
3547 struct alc_spec *spec = codec->spec;
3548 int i;
3549
3550 for (i = 0; i < AUTO_PIN_LAST; i++) {
3551 hda_nid_t nid = spec->autocfg.input_pins[i];
3552 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3553 snd_hda_codec_write(codec, nid, 0,
3554 AC_VERB_SET_PIN_WIDGET_CONTROL,
3555 i <= AUTO_PIN_FRONT_MIC ?
3556 PIN_VREF80 : PIN_IN);
e9edcee0 3557 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3558 snd_hda_codec_write(codec, nid, 0,
3559 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3560 AMP_OUT_MUTE);
3561 }
3562 }
3563}
3564
3565/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3566/* return 1 if successful, 0 if the proper config is not found,
3567 * or a negative error code
3568 */
e9edcee0
TI
3569static int alc880_parse_auto_config(struct hda_codec *codec)
3570{
3571 struct alc_spec *spec = codec->spec;
3572 int err;
df694daa 3573 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3574
f12ab1e0
TI
3575 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3576 alc880_ignore);
3577 if (err < 0)
e9edcee0 3578 return err;
f12ab1e0 3579 if (!spec->autocfg.line_outs)
e9edcee0 3580 return 0; /* can't find valid BIOS pin config */
df694daa 3581
f12ab1e0
TI
3582 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3583 if (err < 0)
3584 return err;
3585 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3586 if (err < 0)
3587 return err;
3588 err = alc880_auto_create_extra_out(spec,
3589 spec->autocfg.speaker_pins[0],
3590 "Speaker");
3591 if (err < 0)
3592 return err;
3593 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3594 "Headphone");
3595 if (err < 0)
3596 return err;
3597 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3598 if (err < 0)
e9edcee0
TI
3599 return err;
3600
3601 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3602
3603 if (spec->autocfg.dig_out_pin)
3604 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3605 if (spec->autocfg.dig_in_pin)
3606 spec->dig_in_nid = ALC880_DIGIN_NID;
3607
3608 if (spec->kctl_alloc)
3609 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3610
3611 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3612
a1e8d2da 3613 spec->num_mux_defs = 1;
e9edcee0
TI
3614 spec->input_mux = &spec->private_imux;
3615
3616 return 1;
3617}
3618
ae6b813a
TI
3619/* additional initialization for auto-configuration model */
3620static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3621{
f6c7e546 3622 struct alc_spec *spec = codec->spec;
e9edcee0 3623 alc880_auto_init_multi_out(codec);
8d88bc3d 3624 alc880_auto_init_extra_out(codec);
e9edcee0 3625 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3626 if (spec->unsol_event)
3627 alc_sku_automute(codec);
e9edcee0
TI
3628}
3629
3630/*
3631 * OK, here we have finally the patch for ALC880
3632 */
3633
1da177e4
LT
3634static int patch_alc880(struct hda_codec *codec)
3635{
3636 struct alc_spec *spec;
3637 int board_config;
df694daa 3638 int err;
1da177e4 3639
e560d8d8 3640 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3641 if (spec == NULL)
3642 return -ENOMEM;
3643
3644 codec->spec = spec;
3645
f5fcc13c
TI
3646 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3647 alc880_models,
3648 alc880_cfg_tbl);
3649 if (board_config < 0) {
9c7f852e
TI
3650 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3651 "trying auto-probe from BIOS...\n");
e9edcee0 3652 board_config = ALC880_AUTO;
1da177e4 3653 }
1da177e4 3654
e9edcee0
TI
3655 if (board_config == ALC880_AUTO) {
3656 /* automatic parse from the BIOS config */
3657 err = alc880_parse_auto_config(codec);
3658 if (err < 0) {
3659 alc_free(codec);
3660 return err;
f12ab1e0 3661 } else if (!err) {
9c7f852e
TI
3662 printk(KERN_INFO
3663 "hda_codec: Cannot set up configuration "
3664 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3665 board_config = ALC880_3ST;
3666 }
1da177e4
LT
3667 }
3668
df694daa
KY
3669 if (board_config != ALC880_AUTO)
3670 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3671
3672 spec->stream_name_analog = "ALC880 Analog";
3673 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3674 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3675 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3676
3677 spec->stream_name_digital = "ALC880 Digital";
3678 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3679 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3680
f12ab1e0 3681 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3682 /* check whether NID 0x07 is valid */
54d17403 3683 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3684 /* get type */
3685 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3686 if (wcap != AC_WID_AUD_IN) {
3687 spec->adc_nids = alc880_adc_nids_alt;
3688 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3689 spec->mixers[spec->num_mixers] =
3690 alc880_capture_alt_mixer;
e9edcee0
TI
3691 spec->num_mixers++;
3692 } else {
3693 spec->adc_nids = alc880_adc_nids;
3694 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3695 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3696 spec->num_mixers++;
3697 }
3698 }
1da177e4 3699
2134ea4f
TI
3700 spec->vmaster_nid = 0x0c;
3701
1da177e4 3702 codec->patch_ops = alc_patch_ops;
e9edcee0 3703 if (board_config == ALC880_AUTO)
ae6b813a 3704 spec->init_hook = alc880_auto_init;
cb53c626
TI
3705#ifdef CONFIG_SND_HDA_POWER_SAVE
3706 if (!spec->loopback.amplist)
3707 spec->loopback.amplist = alc880_loopbacks;
3708#endif
1da177e4
LT
3709
3710 return 0;
3711}
3712
e9edcee0 3713
1da177e4
LT
3714/*
3715 * ALC260 support
3716 */
3717
e9edcee0
TI
3718static hda_nid_t alc260_dac_nids[1] = {
3719 /* front */
3720 0x02,
3721};
3722
3723static hda_nid_t alc260_adc_nids[1] = {
3724 /* ADC0 */
3725 0x04,
3726};
3727
df694daa 3728static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3729 /* ADC1 */
3730 0x05,
3731};
3732
df694daa
KY
3733static hda_nid_t alc260_hp_adc_nids[2] = {
3734 /* ADC1, 0 */
3735 0x05, 0x04
3736};
3737
d57fdac0
JW
3738/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3739 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3740 */
3741static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3742 /* ADC0, ADC1 */
3743 0x04, 0x05
3744};
3745
e9edcee0
TI
3746#define ALC260_DIGOUT_NID 0x03
3747#define ALC260_DIGIN_NID 0x06
3748
3749static struct hda_input_mux alc260_capture_source = {
3750 .num_items = 4,
3751 .items = {
3752 { "Mic", 0x0 },
3753 { "Front Mic", 0x1 },
3754 { "Line", 0x2 },
3755 { "CD", 0x4 },
3756 },
3757};
3758
17e7aec6 3759/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3760 * headphone jack and the internal CD lines since these are the only pins at
3761 * which audio can appear. For flexibility, also allow the option of
3762 * recording the mixer output on the second ADC (ADC0 doesn't have a
3763 * connection to the mixer output).
a9430dd8 3764 */
a1e8d2da
JW
3765static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3766 {
3767 .num_items = 3,
3768 .items = {
3769 { "Mic/Line", 0x0 },
3770 { "CD", 0x4 },
3771 { "Headphone", 0x2 },
3772 },
a9430dd8 3773 },
a1e8d2da
JW
3774 {
3775 .num_items = 4,
3776 .items = {
3777 { "Mic/Line", 0x0 },
3778 { "CD", 0x4 },
3779 { "Headphone", 0x2 },
3780 { "Mixer", 0x5 },
3781 },
3782 },
3783
a9430dd8
JW
3784};
3785
a1e8d2da
JW
3786/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3787 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3788 */
a1e8d2da
JW
3789static struct hda_input_mux alc260_acer_capture_sources[2] = {
3790 {
3791 .num_items = 4,
3792 .items = {
3793 { "Mic", 0x0 },
3794 { "Line", 0x2 },
3795 { "CD", 0x4 },
3796 { "Headphone", 0x5 },
3797 },
3798 },
3799 {
3800 .num_items = 5,
3801 .items = {
3802 { "Mic", 0x0 },
3803 { "Line", 0x2 },
3804 { "CD", 0x4 },
3805 { "Headphone", 0x6 },
3806 { "Mixer", 0x5 },
3807 },
0bfc90e9
JW
3808 },
3809};
1da177e4
LT
3810/*
3811 * This is just place-holder, so there's something for alc_build_pcms to look
3812 * at when it calculates the maximum number of channels. ALC260 has no mixer
3813 * element which allows changing the channel mode, so the verb list is
3814 * never used.
3815 */
d2a6d7dc 3816static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3817 { 2, NULL },
3818};
3819
df694daa
KY
3820
3821/* Mixer combinations
3822 *
3823 * basic: base_output + input + pc_beep + capture
3824 * HP: base_output + input + capture_alt
3825 * HP_3013: hp_3013 + input + capture
3826 * fujitsu: fujitsu + capture
0bfc90e9 3827 * acer: acer + capture
df694daa
KY
3828 */
3829
3830static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3831 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3832 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3833 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3834 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3835 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3836 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3837 { } /* end */
f12ab1e0 3838};
1da177e4 3839
df694daa 3840static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3841 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3842 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3843 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3844 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3846 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3848 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3849 { } /* end */
3850};
3851
3852static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3853 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3854 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3855 { } /* end */
3856};
3857
bec15c3a
TI
3858/* update HP, line and mono out pins according to the master switch */
3859static void alc260_hp_master_update(struct hda_codec *codec,
3860 hda_nid_t hp, hda_nid_t line,
3861 hda_nid_t mono)
3862{
3863 struct alc_spec *spec = codec->spec;
3864 unsigned int val = spec->master_sw ? PIN_HP : 0;
3865 /* change HP and line-out pins */
3866 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3867 val);
3868 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3869 val);
3870 /* mono (speaker) depending on the HP jack sense */
3871 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3872 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3873 val);
3874}
3875
3876static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3877 struct snd_ctl_elem_value *ucontrol)
3878{
3879 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3880 struct alc_spec *spec = codec->spec;
3881 *ucontrol->value.integer.value = spec->master_sw;
3882 return 0;
3883}
3884
3885static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3886 struct snd_ctl_elem_value *ucontrol)
3887{
3888 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3889 struct alc_spec *spec = codec->spec;
3890 int val = !!*ucontrol->value.integer.value;
3891 hda_nid_t hp, line, mono;
3892
3893 if (val == spec->master_sw)
3894 return 0;
3895 spec->master_sw = val;
3896 hp = (kcontrol->private_value >> 16) & 0xff;
3897 line = (kcontrol->private_value >> 8) & 0xff;
3898 mono = kcontrol->private_value & 0xff;
3899 alc260_hp_master_update(codec, hp, line, mono);
3900 return 1;
3901}
3902
3903static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3904 {
3905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3906 .name = "Master Playback Switch",
3907 .info = snd_ctl_boolean_mono_info,
3908 .get = alc260_hp_master_sw_get,
3909 .put = alc260_hp_master_sw_put,
3910 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3911 },
3912 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3913 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3914 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3915 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3916 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3917 HDA_OUTPUT),
3918 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3919 { } /* end */
3920};
3921
3922static struct hda_verb alc260_hp_unsol_verbs[] = {
3923 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3924 {},
3925};
3926
3927static void alc260_hp_automute(struct hda_codec *codec)
3928{
3929 struct alc_spec *spec = codec->spec;
3930 unsigned int present;
3931
3932 present = snd_hda_codec_read(codec, 0x10, 0,
3933 AC_VERB_GET_PIN_SENSE, 0);
3934 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3935 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3936}
3937
3938static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3939{
3940 if ((res >> 26) == ALC880_HP_EVENT)
3941 alc260_hp_automute(codec);
3942}
3943
df694daa 3944static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
3945 {
3946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3947 .name = "Master Playback Switch",
3948 .info = snd_ctl_boolean_mono_info,
3949 .get = alc260_hp_master_sw_get,
3950 .put = alc260_hp_master_sw_put,
3951 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3952 },
df694daa
KY
3953 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3954 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3955 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3956 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3957 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3958 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
3959 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3960 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3961 { } /* end */
3962};
3963
bec15c3a
TI
3964static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3965 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3966 {},
3967};
3968
3969static void alc260_hp_3013_automute(struct hda_codec *codec)
3970{
3971 struct alc_spec *spec = codec->spec;
3972 unsigned int present;
3973
3974 present = snd_hda_codec_read(codec, 0x15, 0,
3975 AC_VERB_GET_PIN_SENSE, 0);
3976 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3977 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3978}
3979
3980static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3981 unsigned int res)
3982{
3983 if ((res >> 26) == ALC880_HP_EVENT)
3984 alc260_hp_3013_automute(codec);
3985}
3986
a1e8d2da
JW
3987/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3988 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3989 */
c8b6bf9b 3990static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3991 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3992 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3993 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3994 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3995 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3996 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3997 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 3998 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
3999 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4000 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4001 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4002 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4003 { } /* end */
4004};
4005
a1e8d2da
JW
4006/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4007 * versions of the ALC260 don't act on requests to enable mic bias from NID
4008 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4009 * datasheet doesn't mention this restriction. At this stage it's not clear
4010 * whether this behaviour is intentional or is a hardware bug in chip
4011 * revisions available in early 2006. Therefore for now allow the
4012 * "Headphone Jack Mode" control to span all choices, but if it turns out
4013 * that the lack of mic bias for this NID is intentional we could change the
4014 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4015 *
4016 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4017 * don't appear to make the mic bias available from the "line" jack, even
4018 * though the NID used for this jack (0x14) can supply it. The theory is
4019 * that perhaps Acer have included blocking capacitors between the ALC260
4020 * and the output jack. If this turns out to be the case for all such
4021 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4022 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4023 *
4024 * The C20x Tablet series have a mono internal speaker which is controlled
4025 * via the chip's Mono sum widget and pin complex, so include the necessary
4026 * controls for such models. On models without a "mono speaker" the control
4027 * won't do anything.
a1e8d2da 4028 */
0bfc90e9
JW
4029static struct snd_kcontrol_new alc260_acer_mixer[] = {
4030 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4031 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4032 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4033 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4034 HDA_OUTPUT),
31bffaa9 4035 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4036 HDA_INPUT),
0bfc90e9
JW
4037 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4038 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4040 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4041 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4042 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4043 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4044 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4045 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4046 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4047 { } /* end */
4048};
4049
bc9f98a9
KY
4050/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4051 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4052 */
4053static struct snd_kcontrol_new alc260_will_mixer[] = {
4054 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4055 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4057 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4058 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4059 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4060 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4061 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4062 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4063 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4064 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4065 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4066 { } /* end */
4067};
4068
4069/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4070 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4071 */
4072static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4073 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4074 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4076 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4077 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4078 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4079 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4080 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4081 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4082 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4083 { } /* end */
4084};
4085
df694daa
KY
4086/* capture mixer elements */
4087static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4088 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4089 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4090 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4091 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4092 {
4093 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4094 /* The multiple "Capture Source" controls confuse alsamixer
4095 * So call somewhat different..
df694daa
KY
4096 */
4097 /* .name = "Capture Source", */
4098 .name = "Input Source",
4099 .count = 2,
4100 .info = alc_mux_enum_info,
4101 .get = alc_mux_enum_get,
4102 .put = alc_mux_enum_put,
4103 },
4104 { } /* end */
4105};
4106
4107static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4108 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4109 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4110 {
4111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4112 /* The multiple "Capture Source" controls confuse alsamixer
4113 * So call somewhat different..
df694daa
KY
4114 */
4115 /* .name = "Capture Source", */
4116 .name = "Input Source",
4117 .count = 1,
a9430dd8
JW
4118 .info = alc_mux_enum_info,
4119 .get = alc_mux_enum_get,
4120 .put = alc_mux_enum_put,
4121 },
4122 { } /* end */
4123};
4124
df694daa
KY
4125/*
4126 * initialization verbs
4127 */
1da177e4
LT
4128static struct hda_verb alc260_init_verbs[] = {
4129 /* Line In pin widget for input */
05acb863 4130 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4131 /* CD pin widget for input */
05acb863 4132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4133 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4134 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4135 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4136 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4137 /* LINE-2 is used for line-out in rear */
05acb863 4138 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4139 /* select line-out */
fd56f2db 4140 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4141 /* LINE-OUT pin */
05acb863 4142 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4143 /* enable HP */
05acb863 4144 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4145 /* enable Mono */
05acb863
TI
4146 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4147 /* mute capture amp left and right */
16ded525 4148 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4149 /* set connection select to line in (default select for this ADC) */
4150 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4151 /* mute capture amp left and right */
4152 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4153 /* set connection select to line in (default select for this ADC) */
4154 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4155 /* set vol=0 Line-Out mixer amp left and right */
4156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4157 /* unmute pin widget amp left and right (no gain on this amp) */
4158 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4159 /* set vol=0 HP mixer amp left and right */
4160 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4161 /* unmute pin widget amp left and right (no gain on this amp) */
4162 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4163 /* set vol=0 Mono mixer amp left and right */
4164 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4165 /* unmute pin widget amp left and right (no gain on this amp) */
4166 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4167 /* unmute LINE-2 out pin */
4168 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4169 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4170 * Line In 2 = 0x03
4171 */
cb53c626
TI
4172 /* mute analog inputs */
4173 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4177 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4178 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4179 /* mute Front out path */
4180 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4181 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4182 /* mute Headphone out path */
4183 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4184 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4185 /* mute Mono out path */
4186 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4187 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4188 { }
4189};
4190
474167d6 4191#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4192static struct hda_verb alc260_hp_init_verbs[] = {
4193 /* Headphone and output */
4194 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4195 /* mono output */
4196 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4197 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4198 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4199 /* Mic2 (front panel) pin widget for input and vref at 80% */
4200 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4201 /* Line In pin widget for input */
4202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4203 /* Line-2 pin widget for output */
4204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4205 /* CD pin widget for input */
4206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4207 /* unmute amp left and right */
4208 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4209 /* set connection select to line in (default select for this ADC) */
4210 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4211 /* unmute Line-Out mixer amp left and right (volume = 0) */
4212 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4213 /* mute pin widget amp left and right (no gain on this amp) */
4214 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4215 /* unmute HP mixer amp left and right (volume = 0) */
4216 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4217 /* mute pin widget amp left and right (no gain on this amp) */
4218 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4219 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4220 * Line In 2 = 0x03
4221 */
cb53c626
TI
4222 /* mute analog inputs */
4223 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4228 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4229 /* Unmute Front out path */
4230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4232 /* Unmute Headphone out path */
4233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4234 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4235 /* Unmute Mono out path */
4236 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4237 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4238 { }
4239};
474167d6 4240#endif
df694daa
KY
4241
4242static struct hda_verb alc260_hp_3013_init_verbs[] = {
4243 /* Line out and output */
4244 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4245 /* mono output */
4246 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4247 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4248 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4249 /* Mic2 (front panel) pin widget for input and vref at 80% */
4250 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4251 /* Line In pin widget for input */
4252 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4253 /* Headphone pin widget for output */
4254 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4255 /* CD pin widget for input */
4256 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4257 /* unmute amp left and right */
4258 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4259 /* set connection select to line in (default select for this ADC) */
4260 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4261 /* unmute Line-Out mixer amp left and right (volume = 0) */
4262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4263 /* mute pin widget amp left and right (no gain on this amp) */
4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4265 /* unmute HP mixer amp left and right (volume = 0) */
4266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4267 /* mute pin widget amp left and right (no gain on this amp) */
4268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4269 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4270 * Line In 2 = 0x03
4271 */
cb53c626
TI
4272 /* mute analog inputs */
4273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4278 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4279 /* Unmute Front out path */
4280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4282 /* Unmute Headphone out path */
4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4284 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4285 /* Unmute Mono out path */
4286 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4287 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4288 { }
4289};
4290
a9430dd8 4291/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4292 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4293 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4294 */
4295static struct hda_verb alc260_fujitsu_init_verbs[] = {
4296 /* Disable all GPIOs */
4297 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4298 /* Internal speaker is connected to headphone pin */
4299 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4300 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4302 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4303 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4304 /* Ensure all other unused pins are disabled and muted. */
4305 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4307 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4308 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4309 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4310 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4311 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4313
4314 /* Disable digital (SPDIF) pins */
4315 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4316 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4317
f7ace40d
JW
4318 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4319 * when acting as an output.
4320 */
4321 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4322
f7ace40d 4323 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4324 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4329 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4330 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4331 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4332 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4333
f7ace40d
JW
4334 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4335 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4336 /* Unmute Line1 pin widget output buffer since it starts as an output.
4337 * If the pin mode is changed by the user the pin mode control will
4338 * take care of enabling the pin's input/output buffers as needed.
4339 * Therefore there's no need to enable the input buffer at this
4340 * stage.
cdcd9268 4341 */
f7ace40d 4342 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4343 /* Unmute input buffer of pin widget used for Line-in (no equiv
4344 * mixer ctrl)
4345 */
f7ace40d
JW
4346 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4347
4348 /* Mute capture amp left and right */
4349 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4350 /* Set ADC connection select to match default mixer setting - line
4351 * in (on mic1 pin)
4352 */
4353 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4354
4355 /* Do the same for the second ADC: mute capture input amp and
4356 * set ADC connection to line in (on mic1 pin)
4357 */
4358 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4359 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4360
4361 /* Mute all inputs to mixer widget (even unconnected ones) */
4362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4363 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4364 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4366 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4370
4371 { }
a9430dd8
JW
4372};
4373
0bfc90e9
JW
4374/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4375 * similar laptops (adapted from Fujitsu init verbs).
4376 */
4377static struct hda_verb alc260_acer_init_verbs[] = {
4378 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4379 * the headphone jack. Turn this on and rely on the standard mute
4380 * methods whenever the user wants to turn these outputs off.
4381 */
4382 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4383 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4384 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4385 /* Internal speaker/Headphone jack is connected to Line-out pin */
4386 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4387 /* Internal microphone/Mic jack is connected to Mic1 pin */
4388 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4389 /* Line In jack is connected to Line1 pin */
4390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4391 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4392 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4393 /* Ensure all other unused pins are disabled and muted. */
4394 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4395 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4396 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4397 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4399 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4400 /* Disable digital (SPDIF) pins */
4401 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4402 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4403
4404 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4405 * bus when acting as outputs.
4406 */
4407 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4408 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4409
4410 /* Start with output sum widgets muted and their output gains at min */
4411 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4412 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4417 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4420
f12ab1e0
TI
4421 /* Unmute Line-out pin widget amp left and right
4422 * (no equiv mixer ctrl)
4423 */
0bfc90e9 4424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4425 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4426 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4427 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4428 * inputs. If the pin mode is changed by the user the pin mode control
4429 * will take care of enabling the pin's input/output buffers as needed.
4430 * Therefore there's no need to enable the input buffer at this
4431 * stage.
4432 */
4433 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4434 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4435
4436 /* Mute capture amp left and right */
4437 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4438 /* Set ADC connection select to match default mixer setting - mic
4439 * (on mic1 pin)
4440 */
4441 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4442
4443 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4444 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4445 */
4446 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4447 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4448
4449 /* Mute all inputs to mixer widget (even unconnected ones) */
4450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4458
4459 { }
4460};
4461
bc9f98a9
KY
4462static struct hda_verb alc260_will_verbs[] = {
4463 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4464 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4465 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4466 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4467 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4468 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4469 {}
4470};
4471
4472static struct hda_verb alc260_replacer_672v_verbs[] = {
4473 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4474 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4475 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4476
4477 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4478 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4479 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4480
4481 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4482 {}
4483};
4484
4485/* toggle speaker-output according to the hp-jack state */
4486static void alc260_replacer_672v_automute(struct hda_codec *codec)
4487{
4488 unsigned int present;
4489
4490 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4491 present = snd_hda_codec_read(codec, 0x0f, 0,
4492 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4493 if (present) {
82beb8fd
TI
4494 snd_hda_codec_write_cache(codec, 0x01, 0,
4495 AC_VERB_SET_GPIO_DATA, 1);
4496 snd_hda_codec_write_cache(codec, 0x0f, 0,
4497 AC_VERB_SET_PIN_WIDGET_CONTROL,
4498 PIN_HP);
bc9f98a9 4499 } else {
82beb8fd
TI
4500 snd_hda_codec_write_cache(codec, 0x01, 0,
4501 AC_VERB_SET_GPIO_DATA, 0);
4502 snd_hda_codec_write_cache(codec, 0x0f, 0,
4503 AC_VERB_SET_PIN_WIDGET_CONTROL,
4504 PIN_OUT);
bc9f98a9
KY
4505 }
4506}
4507
4508static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4509 unsigned int res)
4510{
4511 if ((res >> 26) == ALC880_HP_EVENT)
4512 alc260_replacer_672v_automute(codec);
4513}
4514
7cf51e48
JW
4515/* Test configuration for debugging, modelled after the ALC880 test
4516 * configuration.
4517 */
4518#ifdef CONFIG_SND_DEBUG
4519static hda_nid_t alc260_test_dac_nids[1] = {
4520 0x02,
4521};
4522static hda_nid_t alc260_test_adc_nids[2] = {
4523 0x04, 0x05,
4524};
a1e8d2da
JW
4525/* For testing the ALC260, each input MUX needs its own definition since
4526 * the signal assignments are different. This assumes that the first ADC
4527 * is NID 0x04.
17e7aec6 4528 */
a1e8d2da
JW
4529static struct hda_input_mux alc260_test_capture_sources[2] = {
4530 {
4531 .num_items = 7,
4532 .items = {
4533 { "MIC1 pin", 0x0 },
4534 { "MIC2 pin", 0x1 },
4535 { "LINE1 pin", 0x2 },
4536 { "LINE2 pin", 0x3 },
4537 { "CD pin", 0x4 },
4538 { "LINE-OUT pin", 0x5 },
4539 { "HP-OUT pin", 0x6 },
4540 },
4541 },
4542 {
4543 .num_items = 8,
4544 .items = {
4545 { "MIC1 pin", 0x0 },
4546 { "MIC2 pin", 0x1 },
4547 { "LINE1 pin", 0x2 },
4548 { "LINE2 pin", 0x3 },
4549 { "CD pin", 0x4 },
4550 { "Mixer", 0x5 },
4551 { "LINE-OUT pin", 0x6 },
4552 { "HP-OUT pin", 0x7 },
4553 },
7cf51e48
JW
4554 },
4555};
4556static struct snd_kcontrol_new alc260_test_mixer[] = {
4557 /* Output driver widgets */
4558 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4559 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4560 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4561 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4562 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4563 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4564
a1e8d2da
JW
4565 /* Modes for retasking pin widgets
4566 * Note: the ALC260 doesn't seem to act on requests to enable mic
4567 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4568 * mention this restriction. At this stage it's not clear whether
4569 * this behaviour is intentional or is a hardware bug in chip
4570 * revisions available at least up until early 2006. Therefore for
4571 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4572 * choices, but if it turns out that the lack of mic bias for these
4573 * NIDs is intentional we could change their modes from
4574 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4575 */
7cf51e48
JW
4576 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4577 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4578 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4579 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4580 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4581 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4582
4583 /* Loopback mixer controls */
4584 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4585 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4586 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4587 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4588 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4589 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4590 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4591 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4592 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4593 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4594 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4595 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4596 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4597 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4598 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4599 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4600
4601 /* Controls for GPIO pins, assuming they are configured as outputs */
4602 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4603 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4604 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4605 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4606
92621f13
JW
4607 /* Switches to allow the digital IO pins to be enabled. The datasheet
4608 * is ambigious as to which NID is which; testing on laptops which
4609 * make this output available should provide clarification.
4610 */
4611 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4612 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4613
f8225f6d
JW
4614 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4615 * this output to turn on an external amplifier.
4616 */
4617 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4618 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4619
7cf51e48
JW
4620 { } /* end */
4621};
4622static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4623 /* Enable all GPIOs as outputs with an initial value of 0 */
4624 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4625 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4626 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4627
7cf51e48
JW
4628 /* Enable retasking pins as output, initially without power amp */
4629 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4630 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4632 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4633 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4634 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4635
92621f13
JW
4636 /* Disable digital (SPDIF) pins initially, but users can enable
4637 * them via a mixer switch. In the case of SPDIF-out, this initverb
4638 * payload also sets the generation to 0, output to be in "consumer"
4639 * PCM format, copyright asserted, no pre-emphasis and no validity
4640 * control.
4641 */
7cf51e48
JW
4642 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4643 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4644
f7ace40d 4645 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4646 * OUT1 sum bus when acting as an output.
4647 */
4648 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4649 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4650 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4651 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4652
4653 /* Start with output sum widgets muted and their output gains at min */
4654 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4657 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4660 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4663
cdcd9268
JW
4664 /* Unmute retasking pin widget output buffers since the default
4665 * state appears to be output. As the pin mode is changed by the
4666 * user the pin mode control will take care of enabling the pin's
4667 * input/output buffers as needed.
4668 */
7cf51e48
JW
4669 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4670 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4671 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4672 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4673 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4674 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4675 /* Also unmute the mono-out pin widget */
4676 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4677
7cf51e48
JW
4678 /* Mute capture amp left and right */
4679 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4680 /* Set ADC connection select to match default mixer setting (mic1
4681 * pin)
7cf51e48
JW
4682 */
4683 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4684
4685 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4686 * set ADC connection to mic1 pin
7cf51e48
JW
4687 */
4688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4689 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4690
4691 /* Mute all inputs to mixer widget (even unconnected ones) */
4692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4700
4701 { }
4702};
4703#endif
4704
6330079f
TI
4705#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4706#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4707
a3bcba38
TI
4708#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4709#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4710
df694daa
KY
4711/*
4712 * for BIOS auto-configuration
4713 */
16ded525 4714
df694daa
KY
4715static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4716 const char *pfx)
4717{
4718 hda_nid_t nid_vol;
4719 unsigned long vol_val, sw_val;
4720 char name[32];
4721 int err;
4722
4723 if (nid >= 0x0f && nid < 0x11) {
4724 nid_vol = nid - 0x7;
4725 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4726 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4727 } else if (nid == 0x11) {
4728 nid_vol = nid - 0x7;
4729 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4730 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4731 } else if (nid >= 0x12 && nid <= 0x15) {
4732 nid_vol = 0x08;
4733 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4734 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4735 } else
4736 return 0; /* N/A */
4737
4738 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4739 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4740 if (err < 0)
df694daa
KY
4741 return err;
4742 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4743 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4744 if (err < 0)
df694daa
KY
4745 return err;
4746 return 1;
4747}
4748
4749/* add playback controls from the parsed DAC table */
4750static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4751 const struct auto_pin_cfg *cfg)
4752{
4753 hda_nid_t nid;
4754 int err;
4755
4756 spec->multiout.num_dacs = 1;
4757 spec->multiout.dac_nids = spec->private_dac_nids;
4758 spec->multiout.dac_nids[0] = 0x02;
4759
4760 nid = cfg->line_out_pins[0];
4761 if (nid) {
4762 err = alc260_add_playback_controls(spec, nid, "Front");
4763 if (err < 0)
4764 return err;
4765 }
4766
82bc955f 4767 nid = cfg->speaker_pins[0];
df694daa
KY
4768 if (nid) {
4769 err = alc260_add_playback_controls(spec, nid, "Speaker");
4770 if (err < 0)
4771 return err;
4772 }
4773
eb06ed8f 4774 nid = cfg->hp_pins[0];
df694daa
KY
4775 if (nid) {
4776 err = alc260_add_playback_controls(spec, nid, "Headphone");
4777 if (err < 0)
4778 return err;
4779 }
f12ab1e0 4780 return 0;
df694daa
KY
4781}
4782
4783/* create playback/capture controls for input pins */
4784static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4785 const struct auto_pin_cfg *cfg)
4786{
df694daa
KY
4787 struct hda_input_mux *imux = &spec->private_imux;
4788 int i, err, idx;
4789
4790 for (i = 0; i < AUTO_PIN_LAST; i++) {
4791 if (cfg->input_pins[i] >= 0x12) {
4792 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4793 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4794 auto_pin_cfg_labels[i], idx,
4795 0x07);
df694daa
KY
4796 if (err < 0)
4797 return err;
f12ab1e0
TI
4798 imux->items[imux->num_items].label =
4799 auto_pin_cfg_labels[i];
df694daa
KY
4800 imux->items[imux->num_items].index = idx;
4801 imux->num_items++;
4802 }
f12ab1e0 4803 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4804 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4805 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4806 auto_pin_cfg_labels[i], idx,
4807 0x07);
df694daa
KY
4808 if (err < 0)
4809 return err;
f12ab1e0
TI
4810 imux->items[imux->num_items].label =
4811 auto_pin_cfg_labels[i];
df694daa
KY
4812 imux->items[imux->num_items].index = idx;
4813 imux->num_items++;
4814 }
4815 }
4816 return 0;
4817}
4818
4819static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4820 hda_nid_t nid, int pin_type,
4821 int sel_idx)
4822{
f6c7e546 4823 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
4824 /* need the manual connection? */
4825 if (nid >= 0x12) {
4826 int idx = nid - 0x12;
4827 snd_hda_codec_write(codec, idx + 0x0b, 0,
4828 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4829 }
4830}
4831
4832static void alc260_auto_init_multi_out(struct hda_codec *codec)
4833{
4834 struct alc_spec *spec = codec->spec;
4835 hda_nid_t nid;
4836
bc9f98a9 4837 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4838 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4839 if (nid) {
4840 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4841 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4842 }
df694daa 4843
82bc955f 4844 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4845 if (nid)
4846 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4847
eb06ed8f 4848 nid = spec->autocfg.hp_pins[0];
df694daa 4849 if (nid)
baba8ee9 4850 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4851}
df694daa
KY
4852
4853#define ALC260_PIN_CD_NID 0x16
4854static void alc260_auto_init_analog_input(struct hda_codec *codec)
4855{
4856 struct alc_spec *spec = codec->spec;
4857 int i;
4858
4859 for (i = 0; i < AUTO_PIN_LAST; i++) {
4860 hda_nid_t nid = spec->autocfg.input_pins[i];
4861 if (nid >= 0x12) {
f12ab1e0
TI
4862 snd_hda_codec_write(codec, nid, 0,
4863 AC_VERB_SET_PIN_WIDGET_CONTROL,
4864 i <= AUTO_PIN_FRONT_MIC ?
4865 PIN_VREF80 : PIN_IN);
df694daa 4866 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4867 snd_hda_codec_write(codec, nid, 0,
4868 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4869 AMP_OUT_MUTE);
4870 }
4871 }
4872}
4873
4874/*
4875 * generic initialization of ADC, input mixers and output mixers
4876 */
4877static struct hda_verb alc260_volume_init_verbs[] = {
4878 /*
4879 * Unmute ADC0-1 and set the default input to mic-in
4880 */
4881 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4882 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4883 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4885
4886 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4887 * mixer widget
f12ab1e0
TI
4888 * Note: PASD motherboards uses the Line In 2 as the input for
4889 * front panel mic (mic 2)
df694daa
KY
4890 */
4891 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4892 /* mute analog inputs */
4893 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4894 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4895 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4898
4899 /*
4900 * Set up output mixers (0x08 - 0x0a)
4901 */
4902 /* set vol=0 to output mixers */
4903 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4905 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4906 /* set up input amps for analog loopback */
4907 /* Amp Indices: DAC = 0, mixer = 1 */
4908 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4909 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4910 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4911 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4912 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4913 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4914
4915 { }
4916};
4917
4918static int alc260_parse_auto_config(struct hda_codec *codec)
4919{
4920 struct alc_spec *spec = codec->spec;
4921 unsigned int wcap;
4922 int err;
4923 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4924
f12ab1e0
TI
4925 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4926 alc260_ignore);
4927 if (err < 0)
df694daa 4928 return err;
f12ab1e0
TI
4929 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4930 if (err < 0)
4a471b7d 4931 return err;
f12ab1e0 4932 if (!spec->kctl_alloc)
df694daa 4933 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4934 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4935 if (err < 0)
df694daa
KY
4936 return err;
4937
4938 spec->multiout.max_channels = 2;
4939
4940 if (spec->autocfg.dig_out_pin)
4941 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4942 if (spec->kctl_alloc)
4943 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4944
4945 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4946
a1e8d2da 4947 spec->num_mux_defs = 1;
df694daa
KY
4948 spec->input_mux = &spec->private_imux;
4949
4950 /* check whether NID 0x04 is valid */
4a471b7d 4951 wcap = get_wcaps(codec, 0x04);
df694daa
KY
4952 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4953 if (wcap != AC_WID_AUD_IN) {
4954 spec->adc_nids = alc260_adc_nids_alt;
4955 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4956 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4957 } else {
4958 spec->adc_nids = alc260_adc_nids;
4959 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4960 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4961 }
4a471b7d 4962 spec->num_mixers++;
df694daa
KY
4963
4964 return 1;
4965}
4966
ae6b813a
TI
4967/* additional initialization for auto-configuration model */
4968static void alc260_auto_init(struct hda_codec *codec)
df694daa 4969{
f6c7e546 4970 struct alc_spec *spec = codec->spec;
df694daa
KY
4971 alc260_auto_init_multi_out(codec);
4972 alc260_auto_init_analog_input(codec);
f6c7e546
TI
4973 if (spec->unsol_event)
4974 alc_sku_automute(codec);
df694daa
KY
4975}
4976
cb53c626
TI
4977#ifdef CONFIG_SND_HDA_POWER_SAVE
4978static struct hda_amp_list alc260_loopbacks[] = {
4979 { 0x07, HDA_INPUT, 0 },
4980 { 0x07, HDA_INPUT, 1 },
4981 { 0x07, HDA_INPUT, 2 },
4982 { 0x07, HDA_INPUT, 3 },
4983 { 0x07, HDA_INPUT, 4 },
4984 { } /* end */
4985};
4986#endif
4987
df694daa
KY
4988/*
4989 * ALC260 configurations
4990 */
f5fcc13c
TI
4991static const char *alc260_models[ALC260_MODEL_LAST] = {
4992 [ALC260_BASIC] = "basic",
4993 [ALC260_HP] = "hp",
4994 [ALC260_HP_3013] = "hp-3013",
4995 [ALC260_FUJITSU_S702X] = "fujitsu",
4996 [ALC260_ACER] = "acer",
bc9f98a9
KY
4997 [ALC260_WILL] = "will",
4998 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 4999#ifdef CONFIG_SND_DEBUG
f5fcc13c 5000 [ALC260_TEST] = "test",
7cf51e48 5001#endif
f5fcc13c
TI
5002 [ALC260_AUTO] = "auto",
5003};
5004
5005static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5006 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5007 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5008 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5009 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
5010 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5011 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5012 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5013 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5014 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5015 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5016 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5017 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5018 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5019 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5020 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5021 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5022 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5023 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5024 {}
5025};
5026
5027static struct alc_config_preset alc260_presets[] = {
5028 [ALC260_BASIC] = {
5029 .mixers = { alc260_base_output_mixer,
5030 alc260_input_mixer,
5031 alc260_pc_beep_mixer,
5032 alc260_capture_mixer },
5033 .init_verbs = { alc260_init_verbs },
5034 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5035 .dac_nids = alc260_dac_nids,
5036 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5037 .adc_nids = alc260_adc_nids,
5038 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5039 .channel_mode = alc260_modes,
5040 .input_mux = &alc260_capture_source,
5041 },
5042 [ALC260_HP] = {
bec15c3a 5043 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5044 alc260_input_mixer,
5045 alc260_capture_alt_mixer },
bec15c3a
TI
5046 .init_verbs = { alc260_init_verbs,
5047 alc260_hp_unsol_verbs },
df694daa
KY
5048 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5049 .dac_nids = alc260_dac_nids,
5050 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5051 .adc_nids = alc260_hp_adc_nids,
5052 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5053 .channel_mode = alc260_modes,
5054 .input_mux = &alc260_capture_source,
bec15c3a
TI
5055 .unsol_event = alc260_hp_unsol_event,
5056 .init_hook = alc260_hp_automute,
df694daa
KY
5057 },
5058 [ALC260_HP_3013] = {
5059 .mixers = { alc260_hp_3013_mixer,
5060 alc260_input_mixer,
5061 alc260_capture_alt_mixer },
bec15c3a
TI
5062 .init_verbs = { alc260_hp_3013_init_verbs,
5063 alc260_hp_3013_unsol_verbs },
df694daa
KY
5064 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5065 .dac_nids = alc260_dac_nids,
5066 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5067 .adc_nids = alc260_hp_adc_nids,
5068 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5069 .channel_mode = alc260_modes,
5070 .input_mux = &alc260_capture_source,
bec15c3a
TI
5071 .unsol_event = alc260_hp_3013_unsol_event,
5072 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5073 },
5074 [ALC260_FUJITSU_S702X] = {
5075 .mixers = { alc260_fujitsu_mixer,
5076 alc260_capture_mixer },
5077 .init_verbs = { alc260_fujitsu_init_verbs },
5078 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5079 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5080 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5081 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5082 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5083 .channel_mode = alc260_modes,
a1e8d2da
JW
5084 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5085 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5086 },
0bfc90e9
JW
5087 [ALC260_ACER] = {
5088 .mixers = { alc260_acer_mixer,
5089 alc260_capture_mixer },
5090 .init_verbs = { alc260_acer_init_verbs },
5091 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5092 .dac_nids = alc260_dac_nids,
5093 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5094 .adc_nids = alc260_dual_adc_nids,
5095 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5096 .channel_mode = alc260_modes,
a1e8d2da
JW
5097 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5098 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5099 },
bc9f98a9
KY
5100 [ALC260_WILL] = {
5101 .mixers = { alc260_will_mixer,
5102 alc260_capture_mixer },
5103 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5104 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5105 .dac_nids = alc260_dac_nids,
5106 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5107 .adc_nids = alc260_adc_nids,
5108 .dig_out_nid = ALC260_DIGOUT_NID,
5109 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5110 .channel_mode = alc260_modes,
5111 .input_mux = &alc260_capture_source,
5112 },
5113 [ALC260_REPLACER_672V] = {
5114 .mixers = { alc260_replacer_672v_mixer,
5115 alc260_capture_mixer },
5116 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5117 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5118 .dac_nids = alc260_dac_nids,
5119 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5120 .adc_nids = alc260_adc_nids,
5121 .dig_out_nid = ALC260_DIGOUT_NID,
5122 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5123 .channel_mode = alc260_modes,
5124 .input_mux = &alc260_capture_source,
5125 .unsol_event = alc260_replacer_672v_unsol_event,
5126 .init_hook = alc260_replacer_672v_automute,
5127 },
7cf51e48
JW
5128#ifdef CONFIG_SND_DEBUG
5129 [ALC260_TEST] = {
5130 .mixers = { alc260_test_mixer,
5131 alc260_capture_mixer },
5132 .init_verbs = { alc260_test_init_verbs },
5133 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5134 .dac_nids = alc260_test_dac_nids,
5135 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5136 .adc_nids = alc260_test_adc_nids,
5137 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5138 .channel_mode = alc260_modes,
a1e8d2da
JW
5139 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5140 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5141 },
5142#endif
df694daa
KY
5143};
5144
5145static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5146{
5147 struct alc_spec *spec;
df694daa 5148 int err, board_config;
1da177e4 5149
e560d8d8 5150 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5151 if (spec == NULL)
5152 return -ENOMEM;
5153
5154 codec->spec = spec;
5155
f5fcc13c
TI
5156 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5157 alc260_models,
5158 alc260_cfg_tbl);
5159 if (board_config < 0) {
9c7f852e
TI
5160 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5161 "trying auto-probe from BIOS...\n");
df694daa 5162 board_config = ALC260_AUTO;
16ded525 5163 }
1da177e4 5164
df694daa
KY
5165 if (board_config == ALC260_AUTO) {
5166 /* automatic parse from the BIOS config */
5167 err = alc260_parse_auto_config(codec);
5168 if (err < 0) {
5169 alc_free(codec);
5170 return err;
f12ab1e0 5171 } else if (!err) {
9c7f852e
TI
5172 printk(KERN_INFO
5173 "hda_codec: Cannot set up configuration "
5174 "from BIOS. Using base mode...\n");
df694daa
KY
5175 board_config = ALC260_BASIC;
5176 }
a9430dd8 5177 }
e9edcee0 5178
df694daa
KY
5179 if (board_config != ALC260_AUTO)
5180 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5181
5182 spec->stream_name_analog = "ALC260 Analog";
5183 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5184 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5185
a3bcba38
TI
5186 spec->stream_name_digital = "ALC260 Digital";
5187 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5188 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5189
2134ea4f
TI
5190 spec->vmaster_nid = 0x08;
5191
1da177e4 5192 codec->patch_ops = alc_patch_ops;
df694daa 5193 if (board_config == ALC260_AUTO)
ae6b813a 5194 spec->init_hook = alc260_auto_init;
cb53c626
TI
5195#ifdef CONFIG_SND_HDA_POWER_SAVE
5196 if (!spec->loopback.amplist)
5197 spec->loopback.amplist = alc260_loopbacks;
5198#endif
1da177e4
LT
5199
5200 return 0;
5201}
5202
e9edcee0 5203
1da177e4
LT
5204/*
5205 * ALC882 support
5206 *
5207 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5208 * configuration. Each pin widget can choose any input DACs and a mixer.
5209 * Each ADC is connected from a mixer of all inputs. This makes possible
5210 * 6-channel independent captures.
5211 *
5212 * In addition, an independent DAC for the multi-playback (not used in this
5213 * driver yet).
5214 */
df694daa
KY
5215#define ALC882_DIGOUT_NID 0x06
5216#define ALC882_DIGIN_NID 0x0a
1da177e4 5217
d2a6d7dc 5218static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5219 { 8, NULL }
5220};
5221
5222static hda_nid_t alc882_dac_nids[4] = {
5223 /* front, rear, clfe, rear_surr */
5224 0x02, 0x03, 0x04, 0x05
5225};
5226
df694daa
KY
5227/* identical with ALC880 */
5228#define alc882_adc_nids alc880_adc_nids
5229#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5230
e1406348
TI
5231static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5232static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5233
1da177e4
LT
5234/* input MUX */
5235/* FIXME: should be a matrix-type input source selection */
5236
5237static struct hda_input_mux alc882_capture_source = {
5238 .num_items = 4,
5239 .items = {
5240 { "Mic", 0x0 },
5241 { "Front Mic", 0x1 },
5242 { "Line", 0x2 },
5243 { "CD", 0x4 },
5244 },
5245};
1da177e4
LT
5246#define alc882_mux_enum_info alc_mux_enum_info
5247#define alc882_mux_enum_get alc_mux_enum_get
5248
f12ab1e0
TI
5249static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5250 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5251{
5252 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5253 struct alc_spec *spec = codec->spec;
5254 const struct hda_input_mux *imux = spec->input_mux;
5255 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
e1406348 5256 hda_nid_t nid = spec->capsrc_nids[adc_idx];
1da177e4
LT
5257 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5258 unsigned int i, idx;
5259
5260 idx = ucontrol->value.enumerated.item[0];
5261 if (idx >= imux->num_items)
5262 idx = imux->num_items - 1;
82beb8fd 5263 if (*cur_val == idx)
1da177e4
LT
5264 return 0;
5265 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5266 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5267 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5268 imux->items[i].index,
47fd830a 5269 HDA_AMP_MUTE, v);
1da177e4
LT
5270 }
5271 *cur_val = idx;
5272 return 1;
5273}
5274
272a527c
KY
5275/*
5276 * 2ch mode
5277 */
5278static struct hda_verb alc882_3ST_ch2_init[] = {
5279 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5280 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5281 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5282 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5283 { } /* end */
5284};
5285
5286/*
5287 * 6ch mode
5288 */
5289static struct hda_verb alc882_3ST_ch6_init[] = {
5290 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5291 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5292 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5293 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5294 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5295 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5296 { } /* end */
5297};
5298
5299static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5300 { 2, alc882_3ST_ch2_init },
5301 { 6, alc882_3ST_ch6_init },
5302};
5303
df694daa
KY
5304/*
5305 * 6ch mode
5306 */
5307static struct hda_verb alc882_sixstack_ch6_init[] = {
5308 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5309 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5310 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5311 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5312 { } /* end */
5313};
5314
5315/*
5316 * 8ch mode
5317 */
5318static struct hda_verb alc882_sixstack_ch8_init[] = {
5319 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5320 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5321 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5322 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5323 { } /* end */
5324};
5325
5326static struct hda_channel_mode alc882_sixstack_modes[2] = {
5327 { 6, alc882_sixstack_ch6_init },
5328 { 8, alc882_sixstack_ch8_init },
5329};
5330
87350ad0
TI
5331/*
5332 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5333 */
5334
5335/*
5336 * 2ch mode
5337 */
5338static struct hda_verb alc885_mbp_ch2_init[] = {
5339 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5340 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5341 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5342 { } /* end */
5343};
5344
5345/*
5346 * 6ch mode
5347 */
5348static struct hda_verb alc885_mbp_ch6_init[] = {
5349 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5350 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5351 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5352 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5353 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5354 { } /* end */
5355};
5356
5357static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5358 { 2, alc885_mbp_ch2_init },
5359 { 6, alc885_mbp_ch6_init },
5360};
5361
5362
1da177e4
LT
5363/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5364 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5365 */
c8b6bf9b 5366static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5367 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5368 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5369 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5370 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5371 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5372 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5373 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5374 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5375 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5376 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5388 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5389 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5390 { } /* end */
5391};
5392
87350ad0 5393static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5394 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5395 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5396 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5397 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5398 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5399 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5400 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5401 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5402 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5404 { } /* end */
5405};
bdd148a3
KY
5406static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5407 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5408 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5409 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5410 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5411 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5412 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5413 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5414 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5415 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5416 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5417 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5418 { } /* end */
5419};
5420
272a527c
KY
5421static struct snd_kcontrol_new alc882_targa_mixer[] = {
5422 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5423 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5424 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5428 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5430 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5434 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5435 { } /* end */
5436};
5437
5438/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5439 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5440 */
5441static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5442 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5443 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5445 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5446 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5447 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5448 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5449 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5450 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5451 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5455 { } /* end */
5456};
5457
914759b7
TI
5458static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5459 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5460 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5462 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5463 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5464 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5465 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5467 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5469 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5470 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5471 { } /* end */
5472};
5473
df694daa
KY
5474static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5475 {
5476 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5477 .name = "Channel Mode",
5478 .info = alc_ch_mode_info,
5479 .get = alc_ch_mode_get,
5480 .put = alc_ch_mode_put,
5481 },
5482 { } /* end */
5483};
5484
1da177e4
LT
5485static struct hda_verb alc882_init_verbs[] = {
5486 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5489 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5490 /* Rear mixer */
05acb863
TI
5491 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5492 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5493 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5494 /* CLFE mixer */
05acb863
TI
5495 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5496 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5497 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5498 /* Side mixer */
05acb863
TI
5499 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5502
e9edcee0 5503 /* Front Pin: output 0 (0x0c) */
05acb863 5504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5506 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5507 /* Rear Pin: output 1 (0x0d) */
05acb863 5508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5509 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5510 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5511 /* CLFE Pin: output 2 (0x0e) */
05acb863 5512 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5513 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5514 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5515 /* Side Pin: output 3 (0x0f) */
05acb863 5516 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5517 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5518 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5519 /* Mic (rear) pin: input vref at 80% */
16ded525 5520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5522 /* Front Mic pin: input vref at 80% */
16ded525 5523 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5524 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5525 /* Line In pin: input */
05acb863 5526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5527 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5528 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5530 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5531 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5532 /* CD pin widget for input */
05acb863 5533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5534
5535 /* FIXME: use matrix-type input source selection */
5536 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5537 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5538 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5539 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5542 /* Input mixer2 */
05acb863
TI
5543 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5547 /* Input mixer3 */
05acb863
TI
5548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5552 /* ADC1: mute amp left and right */
5553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5554 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5555 /* ADC2: mute amp left and right */
5556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5557 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5558 /* ADC3: mute amp left and right */
5559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5560 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5561
5562 { }
5563};
5564
4b146cb0
TI
5565static struct hda_verb alc882_eapd_verbs[] = {
5566 /* change to EAPD mode */
5567 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5568 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5569 { }
4b146cb0
TI
5570};
5571
9102cd1c
TD
5572/* Mac Pro test */
5573static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5574 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5575 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5576 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5579 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5580 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5581 { } /* end */
5582};
5583
5584static struct hda_verb alc882_macpro_init_verbs[] = {
5585 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5589 /* Front Pin: output 0 (0x0c) */
5590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5591 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5592 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5593 /* Front Mic pin: input vref at 80% */
5594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5596 /* Speaker: output */
5597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5599 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5600 /* Headphone output (output 0 - 0x0c) */
5601 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5602 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5603 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5604
5605 /* FIXME: use matrix-type input source selection */
5606 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5612 /* Input mixer2 */
5613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5617 /* Input mixer3 */
5618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5622 /* ADC1: mute amp left and right */
5623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5624 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5625 /* ADC2: mute amp left and right */
5626 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5627 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5628 /* ADC3: mute amp left and right */
5629 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5630 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5631
5632 { }
5633};
f12ab1e0 5634
87350ad0
TI
5635/* Macbook Pro rev3 */
5636static struct hda_verb alc885_mbp3_init_verbs[] = {
5637 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5641 /* Rear mixer */
5642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5645 /* Front Pin: output 0 (0x0c) */
5646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5648 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5649 /* HP Pin: output 0 (0x0d) */
5650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5651 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5653 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5654 /* Mic (rear) pin: input vref at 80% */
5655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5657 /* Front Mic pin: input vref at 80% */
5658 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5659 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5660 /* Line In pin: use output 1 when in LineOut mode */
5661 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5662 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5663 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5664
5665 /* FIXME: use matrix-type input source selection */
5666 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5667 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5672 /* Input mixer2 */
5673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5674 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5675 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5676 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5677 /* Input mixer3 */
5678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5682 /* ADC1: mute amp left and right */
5683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5684 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5685 /* ADC2: mute amp left and right */
5686 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5687 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5688 /* ADC3: mute amp left and right */
5689 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5690 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5691
5692 { }
5693};
5694
c54728d8
NF
5695/* iMac 24 mixer. */
5696static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5697 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5698 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5699 { } /* end */
5700};
5701
5702/* iMac 24 init verbs. */
5703static struct hda_verb alc885_imac24_init_verbs[] = {
5704 /* Internal speakers: output 0 (0x0c) */
5705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5707 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5708 /* Internal speakers: output 0 (0x0c) */
5709 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5710 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5711 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5712 /* Headphone: output 0 (0x0c) */
5713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5715 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5716 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5717 /* Front Mic: input vref at 80% */
5718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5720 { }
5721};
5722
5723/* Toggle speaker-output according to the hp-jack state */
5724static void alc885_imac24_automute(struct hda_codec *codec)
5725{
5726 unsigned int present;
5727
5728 present = snd_hda_codec_read(codec, 0x14, 0,
5729 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5730 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5731 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5732 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5733 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5734}
5735
5736/* Processes unsolicited events. */
5737static void alc885_imac24_unsol_event(struct hda_codec *codec,
5738 unsigned int res)
5739{
5740 /* Headphone insertion or removal. */
5741 if ((res >> 26) == ALC880_HP_EVENT)
5742 alc885_imac24_automute(codec);
5743}
5744
87350ad0
TI
5745static void alc885_mbp3_automute(struct hda_codec *codec)
5746{
5747 unsigned int present;
5748
5749 present = snd_hda_codec_read(codec, 0x15, 0,
5750 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5751 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5752 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5753 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5754 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5755
5756}
5757static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5758 unsigned int res)
5759{
5760 /* Headphone insertion or removal. */
5761 if ((res >> 26) == ALC880_HP_EVENT)
5762 alc885_mbp3_automute(codec);
5763}
5764
5765
272a527c
KY
5766static struct hda_verb alc882_targa_verbs[] = {
5767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5769
5770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5772
5773 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5776
5777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5778 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5779 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5780 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5781 { } /* end */
5782};
5783
5784/* toggle speaker-output according to the hp-jack state */
5785static void alc882_targa_automute(struct hda_codec *codec)
5786{
5787 unsigned int present;
5788
5789 present = snd_hda_codec_read(codec, 0x14, 0,
5790 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5791 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5792 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5793 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5794 present ? 1 : 3);
272a527c
KY
5795}
5796
5797static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5798{
5799 /* Looks like the unsol event is incompatible with the standard
5800 * definition. 4bit tag is placed at 26 bit!
5801 */
5802 if (((res >> 26) == ALC880_HP_EVENT)) {
5803 alc882_targa_automute(codec);
5804 }
5805}
5806
5807static struct hda_verb alc882_asus_a7j_verbs[] = {
5808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5810
5811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5813 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5814
5815 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5816 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5817 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5818
5819 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5820 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5821 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5822 { } /* end */
5823};
5824
914759b7
TI
5825static struct hda_verb alc882_asus_a7m_verbs[] = {
5826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5827 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5828
5829 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5831 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5832
5833 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5834 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5835 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5836
5837 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5838 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5839 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5840 { } /* end */
5841};
5842
9102cd1c
TD
5843static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5844{
5845 unsigned int gpiostate, gpiomask, gpiodir;
5846
5847 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5848 AC_VERB_GET_GPIO_DATA, 0);
5849
5850 if (!muted)
5851 gpiostate |= (1 << pin);
5852 else
5853 gpiostate &= ~(1 << pin);
5854
5855 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5856 AC_VERB_GET_GPIO_MASK, 0);
5857 gpiomask |= (1 << pin);
5858
5859 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5860 AC_VERB_GET_GPIO_DIRECTION, 0);
5861 gpiodir |= (1 << pin);
5862
5863
5864 snd_hda_codec_write(codec, codec->afg, 0,
5865 AC_VERB_SET_GPIO_MASK, gpiomask);
5866 snd_hda_codec_write(codec, codec->afg, 0,
5867 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5868
5869 msleep(1);
5870
5871 snd_hda_codec_write(codec, codec->afg, 0,
5872 AC_VERB_SET_GPIO_DATA, gpiostate);
5873}
5874
7debbe51
TI
5875/* set up GPIO at initialization */
5876static void alc885_macpro_init_hook(struct hda_codec *codec)
5877{
5878 alc882_gpio_mute(codec, 0, 0);
5879 alc882_gpio_mute(codec, 1, 0);
5880}
5881
5882/* set up GPIO and update auto-muting at initialization */
5883static void alc885_imac24_init_hook(struct hda_codec *codec)
5884{
5885 alc885_macpro_init_hook(codec);
5886 alc885_imac24_automute(codec);
5887}
5888
df694daa
KY
5889/*
5890 * generic initialization of ADC, input mixers and output mixers
5891 */
5892static struct hda_verb alc882_auto_init_verbs[] = {
5893 /*
5894 * Unmute ADC0-2 and set the default input to mic-in
5895 */
5896 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5898 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5899 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5900 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5901 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5902
cb53c626 5903 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5904 * mixer widget
f12ab1e0
TI
5905 * Note: PASD motherboards uses the Line In 2 as the input for
5906 * front panel mic (mic 2)
df694daa
KY
5907 */
5908 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5909 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5913 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5914
df694daa
KY
5915 /*
5916 * Set up output mixers (0x0c - 0x0f)
5917 */
5918 /* set vol=0 to output mixers */
5919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5920 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5921 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5922 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5923 /* set up input amps for analog loopback */
5924 /* Amp Indices: DAC = 0, mixer = 1 */
5925 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5927 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5928 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5929 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5930 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5933 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5934 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5935
5936 /* FIXME: use matrix-type input source selection */
5937 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5938 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5940 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5941 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5943 /* Input mixer2 */
5944 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5945 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5948 /* Input mixer3 */
5949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5950 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5953
5954 { }
5955};
5956
5957/* capture mixer elements */
5958static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5959 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5960 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5961 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5962 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5963 {
5964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5965 /* The multiple "Capture Source" controls confuse alsamixer
5966 * So call somewhat different..
df694daa
KY
5967 */
5968 /* .name = "Capture Source", */
5969 .name = "Input Source",
5970 .count = 2,
5971 .info = alc882_mux_enum_info,
5972 .get = alc882_mux_enum_get,
5973 .put = alc882_mux_enum_put,
5974 },
5975 { } /* end */
5976};
5977
5978static struct snd_kcontrol_new alc882_capture_mixer[] = {
5979 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5980 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5981 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5982 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5983 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5984 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5985 {
5986 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5987 /* The multiple "Capture Source" controls confuse alsamixer
5988 * So call somewhat different..
df694daa
KY
5989 */
5990 /* .name = "Capture Source", */
5991 .name = "Input Source",
5992 .count = 3,
5993 .info = alc882_mux_enum_info,
5994 .get = alc882_mux_enum_get,
5995 .put = alc882_mux_enum_put,
5996 },
5997 { } /* end */
5998};
5999
cb53c626
TI
6000#ifdef CONFIG_SND_HDA_POWER_SAVE
6001#define alc882_loopbacks alc880_loopbacks
6002#endif
6003
df694daa
KY
6004/* pcm configuration: identiacal with ALC880 */
6005#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6006#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6007#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6008#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6009
6010/*
6011 * configuration and preset
6012 */
f5fcc13c
TI
6013static const char *alc882_models[ALC882_MODEL_LAST] = {
6014 [ALC882_3ST_DIG] = "3stack-dig",
6015 [ALC882_6ST_DIG] = "6stack-dig",
6016 [ALC882_ARIMA] = "arima",
bdd148a3 6017 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6018 [ALC882_TARGA] = "targa",
6019 [ALC882_ASUS_A7J] = "asus-a7j",
6020 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6021 [ALC885_MACPRO] = "macpro",
87350ad0 6022 [ALC885_MBP3] = "mbp3",
c54728d8 6023 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6024 [ALC882_AUTO] = "auto",
6025};
6026
6027static struct snd_pci_quirk alc882_cfg_tbl[] = {
6028 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6029 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6030 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6031 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6032 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6033 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6034 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6035 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6036 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6037 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6038 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6039 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6040 {}
6041};
6042
6043static struct alc_config_preset alc882_presets[] = {
6044 [ALC882_3ST_DIG] = {
6045 .mixers = { alc882_base_mixer },
6046 .init_verbs = { alc882_init_verbs },
6047 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6048 .dac_nids = alc882_dac_nids,
6049 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6050 .dig_in_nid = ALC882_DIGIN_NID,
6051 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6052 .channel_mode = alc882_ch_modes,
4e195a7b 6053 .need_dac_fix = 1,
df694daa
KY
6054 .input_mux = &alc882_capture_source,
6055 },
6056 [ALC882_6ST_DIG] = {
6057 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6058 .init_verbs = { alc882_init_verbs },
6059 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6060 .dac_nids = alc882_dac_nids,
6061 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6062 .dig_in_nid = ALC882_DIGIN_NID,
6063 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6064 .channel_mode = alc882_sixstack_modes,
6065 .input_mux = &alc882_capture_source,
6066 },
4b146cb0
TI
6067 [ALC882_ARIMA] = {
6068 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6069 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6070 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6071 .dac_nids = alc882_dac_nids,
6072 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6073 .channel_mode = alc882_sixstack_modes,
6074 .input_mux = &alc882_capture_source,
6075 },
bdd148a3
KY
6076 [ALC882_W2JC] = {
6077 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6078 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6079 alc880_gpio1_init_verbs },
6080 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6081 .dac_nids = alc882_dac_nids,
6082 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6083 .channel_mode = alc880_threestack_modes,
6084 .need_dac_fix = 1,
6085 .input_mux = &alc882_capture_source,
6086 .dig_out_nid = ALC882_DIGOUT_NID,
6087 },
87350ad0
TI
6088 [ALC885_MBP3] = {
6089 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6090 .init_verbs = { alc885_mbp3_init_verbs,
6091 alc880_gpio1_init_verbs },
6092 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6093 .dac_nids = alc882_dac_nids,
6094 .channel_mode = alc885_mbp_6ch_modes,
6095 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6096 .input_mux = &alc882_capture_source,
6097 .dig_out_nid = ALC882_DIGOUT_NID,
6098 .dig_in_nid = ALC882_DIGIN_NID,
6099 .unsol_event = alc885_mbp3_unsol_event,
6100 .init_hook = alc885_mbp3_automute,
6101 },
9102cd1c
TD
6102 [ALC885_MACPRO] = {
6103 .mixers = { alc882_macpro_mixer },
6104 .init_verbs = { alc882_macpro_init_verbs },
6105 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6106 .dac_nids = alc882_dac_nids,
6107 .dig_out_nid = ALC882_DIGOUT_NID,
6108 .dig_in_nid = ALC882_DIGIN_NID,
6109 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6110 .channel_mode = alc882_ch_modes,
6111 .input_mux = &alc882_capture_source,
7debbe51 6112 .init_hook = alc885_macpro_init_hook,
9102cd1c 6113 },
c54728d8
NF
6114 [ALC885_IMAC24] = {
6115 .mixers = { alc885_imac24_mixer },
6116 .init_verbs = { alc885_imac24_init_verbs },
6117 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6118 .dac_nids = alc882_dac_nids,
6119 .dig_out_nid = ALC882_DIGOUT_NID,
6120 .dig_in_nid = ALC882_DIGIN_NID,
6121 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6122 .channel_mode = alc882_ch_modes,
6123 .input_mux = &alc882_capture_source,
6124 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6125 .init_hook = alc885_imac24_init_hook,
c54728d8 6126 },
272a527c
KY
6127 [ALC882_TARGA] = {
6128 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6129 alc882_capture_mixer },
6130 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6132 .dac_nids = alc882_dac_nids,
6133 .dig_out_nid = ALC882_DIGOUT_NID,
6134 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6135 .adc_nids = alc882_adc_nids,
e1406348 6136 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6137 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6138 .channel_mode = alc882_3ST_6ch_modes,
6139 .need_dac_fix = 1,
6140 .input_mux = &alc882_capture_source,
6141 .unsol_event = alc882_targa_unsol_event,
6142 .init_hook = alc882_targa_automute,
6143 },
6144 [ALC882_ASUS_A7J] = {
6145 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6146 alc882_capture_mixer },
6147 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6148 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6149 .dac_nids = alc882_dac_nids,
6150 .dig_out_nid = ALC882_DIGOUT_NID,
6151 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6152 .adc_nids = alc882_adc_nids,
e1406348 6153 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6154 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6155 .channel_mode = alc882_3ST_6ch_modes,
6156 .need_dac_fix = 1,
6157 .input_mux = &alc882_capture_source,
6158 },
914759b7
TI
6159 [ALC882_ASUS_A7M] = {
6160 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6161 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6162 alc880_gpio1_init_verbs,
6163 alc882_asus_a7m_verbs },
6164 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6165 .dac_nids = alc882_dac_nids,
6166 .dig_out_nid = ALC882_DIGOUT_NID,
6167 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6168 .channel_mode = alc880_threestack_modes,
6169 .need_dac_fix = 1,
6170 .input_mux = &alc882_capture_source,
6171 },
df694daa
KY
6172};
6173
6174
f95474ec
TI
6175/*
6176 * Pin config fixes
6177 */
6178enum {
6179 PINFIX_ABIT_AW9D_MAX
6180};
6181
6182static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6183 { 0x15, 0x01080104 }, /* side */
6184 { 0x16, 0x01011012 }, /* rear */
6185 { 0x17, 0x01016011 }, /* clfe */
6186 { }
6187};
6188
6189static const struct alc_pincfg *alc882_pin_fixes[] = {
6190 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6191};
6192
6193static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6194 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6195 {}
6196};
6197
df694daa
KY
6198/*
6199 * BIOS auto configuration
6200 */
6201static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6202 hda_nid_t nid, int pin_type,
6203 int dac_idx)
6204{
6205 /* set as output */
6206 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6207 int idx;
6208
f6c7e546 6209 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6210 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6211 idx = 4;
6212 else
6213 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6214 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6215
6216}
6217
6218static void alc882_auto_init_multi_out(struct hda_codec *codec)
6219{
6220 struct alc_spec *spec = codec->spec;
6221 int i;
6222
bc9f98a9 6223 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6224 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6225 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6226 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6227 if (nid)
baba8ee9 6228 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6229 i);
df694daa
KY
6230 }
6231}
6232
6233static void alc882_auto_init_hp_out(struct hda_codec *codec)
6234{
6235 struct alc_spec *spec = codec->spec;
6236 hda_nid_t pin;
6237
eb06ed8f 6238 pin = spec->autocfg.hp_pins[0];
df694daa 6239 if (pin) /* connect to front */
f12ab1e0
TI
6240 /* use dac 0 */
6241 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6242 pin = spec->autocfg.speaker_pins[0];
6243 if (pin)
6244 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6245}
6246
6247#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6248#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6249
6250static void alc882_auto_init_analog_input(struct hda_codec *codec)
6251{
6252 struct alc_spec *spec = codec->spec;
6253 int i;
6254
6255 for (i = 0; i < AUTO_PIN_LAST; i++) {
6256 hda_nid_t nid = spec->autocfg.input_pins[i];
6257 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6258 snd_hda_codec_write(codec, nid, 0,
6259 AC_VERB_SET_PIN_WIDGET_CONTROL,
6260 i <= AUTO_PIN_FRONT_MIC ?
6261 PIN_VREF80 : PIN_IN);
df694daa 6262 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6263 snd_hda_codec_write(codec, nid, 0,
6264 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6265 AMP_OUT_MUTE);
6266 }
6267 }
6268}
6269
776e184e
TI
6270/* add mic boosts if needed */
6271static int alc_auto_add_mic_boost(struct hda_codec *codec)
6272{
6273 struct alc_spec *spec = codec->spec;
6274 int err;
6275 hda_nid_t nid;
6276
6277 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6278 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6279 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6280 "Mic Boost",
6281 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6282 if (err < 0)
6283 return err;
6284 }
6285 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6286 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6287 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6288 "Front Mic Boost",
6289 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6290 if (err < 0)
6291 return err;
6292 }
6293 return 0;
6294}
6295
df694daa
KY
6296/* almost identical with ALC880 parser... */
6297static int alc882_parse_auto_config(struct hda_codec *codec)
6298{
6299 struct alc_spec *spec = codec->spec;
6300 int err = alc880_parse_auto_config(codec);
6301
6302 if (err < 0)
6303 return err;
776e184e
TI
6304 else if (!err)
6305 return 0; /* no config found */
6306
6307 err = alc_auto_add_mic_boost(codec);
6308 if (err < 0)
6309 return err;
6310
6311 /* hack - override the init verbs */
6312 spec->init_verbs[0] = alc882_auto_init_verbs;
6313
6314 return 1; /* config found */
df694daa
KY
6315}
6316
ae6b813a
TI
6317/* additional initialization for auto-configuration model */
6318static void alc882_auto_init(struct hda_codec *codec)
df694daa 6319{
f6c7e546 6320 struct alc_spec *spec = codec->spec;
df694daa
KY
6321 alc882_auto_init_multi_out(codec);
6322 alc882_auto_init_hp_out(codec);
6323 alc882_auto_init_analog_input(codec);
f6c7e546
TI
6324 if (spec->unsol_event)
6325 alc_sku_automute(codec);
df694daa
KY
6326}
6327
df694daa
KY
6328static int patch_alc882(struct hda_codec *codec)
6329{
6330 struct alc_spec *spec;
6331 int err, board_config;
6332
6333 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6334 if (spec == NULL)
6335 return -ENOMEM;
6336
6337 codec->spec = spec;
6338
f5fcc13c
TI
6339 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6340 alc882_models,
6341 alc882_cfg_tbl);
df694daa
KY
6342
6343 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6344 /* Pick up systems that don't supply PCI SSID */
6345 switch (codec->subsystem_id) {
6346 case 0x106b0c00: /* Mac Pro */
6347 board_config = ALC885_MACPRO;
6348 break;
c54728d8
NF
6349 case 0x106b1000: /* iMac 24 */
6350 board_config = ALC885_IMAC24;
6351 break;
3d5fa2e5 6352 case 0x106b00a1: /* Macbook */
87350ad0
TI
6353 case 0x106b2c00: /* Macbook Pro rev3 */
6354 board_config = ALC885_MBP3;
6355 break;
081d17c4
TD
6356 default:
6357 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6358 "trying auto-probe from BIOS...\n");
6359 board_config = ALC882_AUTO;
6360 }
df694daa
KY
6361 }
6362
f95474ec
TI
6363 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6364
df694daa
KY
6365 if (board_config == ALC882_AUTO) {
6366 /* automatic parse from the BIOS config */
6367 err = alc882_parse_auto_config(codec);
6368 if (err < 0) {
6369 alc_free(codec);
6370 return err;
f12ab1e0 6371 } else if (!err) {
9c7f852e
TI
6372 printk(KERN_INFO
6373 "hda_codec: Cannot set up configuration "
6374 "from BIOS. Using base mode...\n");
df694daa
KY
6375 board_config = ALC882_3ST_DIG;
6376 }
6377 }
6378
6379 if (board_config != ALC882_AUTO)
6380 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6381
6382 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6383 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6384 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6385 /* FIXME: setup DAC5 */
6386 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6387 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
6388
6389 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6390 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6391 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6392
f12ab1e0 6393 if (!spec->adc_nids && spec->input_mux) {
df694daa 6394 /* check whether NID 0x07 is valid */
4a471b7d 6395 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6396 /* get type */
6397 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6398 if (wcap != AC_WID_AUD_IN) {
6399 spec->adc_nids = alc882_adc_nids_alt;
6400 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6401 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6402 spec->mixers[spec->num_mixers] =
6403 alc882_capture_alt_mixer;
df694daa
KY
6404 spec->num_mixers++;
6405 } else {
6406 spec->adc_nids = alc882_adc_nids;
6407 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6408 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6409 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6410 spec->num_mixers++;
6411 }
6412 }
1da177e4 6413
2134ea4f
TI
6414 spec->vmaster_nid = 0x0c;
6415
1da177e4 6416 codec->patch_ops = alc_patch_ops;
df694daa 6417 if (board_config == ALC882_AUTO)
ae6b813a 6418 spec->init_hook = alc882_auto_init;
cb53c626
TI
6419#ifdef CONFIG_SND_HDA_POWER_SAVE
6420 if (!spec->loopback.amplist)
6421 spec->loopback.amplist = alc882_loopbacks;
6422#endif
df694daa
KY
6423
6424 return 0;
6425}
6426
6427/*
9c7f852e
TI
6428 * ALC883 support
6429 *
6430 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6431 * configuration. Each pin widget can choose any input DACs and a mixer.
6432 * Each ADC is connected from a mixer of all inputs. This makes possible
6433 * 6-channel independent captures.
6434 *
6435 * In addition, an independent DAC for the multi-playback (not used in this
6436 * driver yet).
df694daa 6437 */
9c7f852e
TI
6438#define ALC883_DIGOUT_NID 0x06
6439#define ALC883_DIGIN_NID 0x0a
df694daa 6440
9c7f852e
TI
6441static hda_nid_t alc883_dac_nids[4] = {
6442 /* front, rear, clfe, rear_surr */
6443 0x02, 0x04, 0x03, 0x05
6444};
df694daa 6445
9c7f852e
TI
6446static hda_nid_t alc883_adc_nids[2] = {
6447 /* ADC1-2 */
6448 0x08, 0x09,
6449};
f12ab1e0 6450
e1406348
TI
6451static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6452
9c7f852e
TI
6453/* input MUX */
6454/* FIXME: should be a matrix-type input source selection */
df694daa 6455
9c7f852e
TI
6456static struct hda_input_mux alc883_capture_source = {
6457 .num_items = 4,
6458 .items = {
6459 { "Mic", 0x0 },
6460 { "Front Mic", 0x1 },
6461 { "Line", 0x2 },
6462 { "CD", 0x4 },
6463 },
6464};
bc9f98a9
KY
6465
6466static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6467 .num_items = 2,
6468 .items = {
6469 { "Mic", 0x1 },
6470 { "Line", 0x2 },
6471 },
6472};
6473
272a527c
KY
6474static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6475 .num_items = 4,
6476 .items = {
6477 { "Mic", 0x0 },
6478 { "iMic", 0x1 },
6479 { "Line", 0x2 },
6480 { "CD", 0x4 },
6481 },
6482};
6483
9c7f852e
TI
6484#define alc883_mux_enum_info alc_mux_enum_info
6485#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6486/* ALC883 has the ALC882-type input selection */
6487#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6488
9c7f852e
TI
6489/*
6490 * 2ch mode
6491 */
6492static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6493 { 2, NULL }
6494};
6495
6496/*
6497 * 2ch mode
6498 */
6499static struct hda_verb alc883_3ST_ch2_init[] = {
6500 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6501 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6502 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6503 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6504 { } /* end */
6505};
6506
b201131c
TD
6507/*
6508 * 4ch mode
6509 */
6510static struct hda_verb alc883_3ST_ch4_init[] = {
6511 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6512 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6513 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6514 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6515 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6516 { } /* end */
6517};
6518
9c7f852e
TI
6519/*
6520 * 6ch mode
6521 */
6522static struct hda_verb alc883_3ST_ch6_init[] = {
6523 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6524 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6525 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6526 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6527 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6528 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6529 { } /* end */
6530};
6531
b201131c 6532static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6533 { 2, alc883_3ST_ch2_init },
b201131c 6534 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6535 { 6, alc883_3ST_ch6_init },
6536};
6537
6538/*
6539 * 6ch mode
6540 */
6541static struct hda_verb alc883_sixstack_ch6_init[] = {
6542 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6543 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6544 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6545 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6546 { } /* end */
6547};
6548
6549/*
6550 * 8ch mode
6551 */
6552static struct hda_verb alc883_sixstack_ch8_init[] = {
6553 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6554 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6555 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6556 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6557 { } /* end */
6558};
6559
6560static struct hda_channel_mode alc883_sixstack_modes[2] = {
6561 { 6, alc883_sixstack_ch6_init },
6562 { 8, alc883_sixstack_ch8_init },
6563};
6564
b373bdeb
AN
6565static struct hda_verb alc883_medion_eapd_verbs[] = {
6566 /* eanable EAPD on medion laptop */
6567 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6568 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6569 { }
6570};
6571
9c7f852e
TI
6572/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6573 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6574 */
6575
6576static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6577 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6578 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6579 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6580 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6581 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6582 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6583 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6584 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6585 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6586 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6587 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6588 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6589 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6595 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6596 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6597 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6598 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6599 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6600 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6601 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6602 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6603 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6604 {
6605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6606 /* .name = "Capture Source", */
6607 .name = "Input Source",
6608 .count = 2,
6609 .info = alc883_mux_enum_info,
6610 .get = alc883_mux_enum_get,
6611 .put = alc883_mux_enum_put,
6612 },
df694daa 6613 { } /* end */
834be88d
TI
6614};
6615
a8848bd6
AS
6616static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6617 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6618 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6619 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6620 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6621 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6622 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6625 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6627 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6628 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6629 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6630 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6631 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6632 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6634 {
6635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6636 /* .name = "Capture Source", */
6637 .name = "Input Source",
6638 .count = 2,
6639 .info = alc883_mux_enum_info,
6640 .get = alc883_mux_enum_get,
6641 .put = alc883_mux_enum_put,
6642 },
6643 { } /* end */
6644};
6645
9c7f852e
TI
6646static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6648 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6651 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6652 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6653 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6658 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6659 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6660 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6661 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6662 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6663 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6664 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6665 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6666 {
6667 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6668 /* .name = "Capture Source", */
6669 .name = "Input Source",
6670 .count = 2,
6671 .info = alc883_mux_enum_info,
6672 .get = alc883_mux_enum_get,
6673 .put = alc883_mux_enum_put,
6674 },
6675 { } /* end */
6676};
df694daa 6677
9c7f852e
TI
6678static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6679 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6680 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6681 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6682 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6683 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6684 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6685 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6686 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6687 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6688 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6689 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6690 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6691 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6693 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6696 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6698 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6699 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6700 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6701 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6702 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6703 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6704 {
6705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6706 /* .name = "Capture Source", */
6707 .name = "Input Source",
6708 .count = 2,
6709 .info = alc883_mux_enum_info,
6710 .get = alc883_mux_enum_get,
6711 .put = alc883_mux_enum_put,
6712 },
6713 { } /* end */
6714};
6715
d1d985f0 6716static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6723 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6724 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6725 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6726 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6727 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6728 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6729 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6732 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6733 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6734 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6735 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6736 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6737 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6738 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6739 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6740
6741 {
6742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6743 /* .name = "Capture Source", */
6744 .name = "Input Source",
6745 .count = 1,
6746 .info = alc883_mux_enum_info,
6747 .get = alc883_mux_enum_get,
6748 .put = alc883_mux_enum_put,
6749 },
6750 { } /* end */
6751};
6752
ccc656ce
KY
6753static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6756 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6757 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6758 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6759 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6760 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6761 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6762 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6763 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6764 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6765 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6766 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6768 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6770 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6771 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6772 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6773 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6774 {
6775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6776 /* .name = "Capture Source", */
6777 .name = "Input Source",
6778 .count = 2,
6779 .info = alc883_mux_enum_info,
6780 .get = alc883_mux_enum_get,
6781 .put = alc883_mux_enum_put,
6782 },
6783 { } /* end */
f12ab1e0 6784};
ccc656ce
KY
6785
6786static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6787 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6788 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6789 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6790 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6791 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6795 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6796 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6797 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6798 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6799 {
6800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6801 /* .name = "Capture Source", */
6802 .name = "Input Source",
6803 .count = 2,
6804 .info = alc883_mux_enum_info,
6805 .get = alc883_mux_enum_get,
6806 .put = alc883_mux_enum_put,
6807 },
6808 { } /* end */
f12ab1e0 6809};
ccc656ce 6810
bc9f98a9
KY
6811static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6812 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6813 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
6814 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6815 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
6816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6820 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6821 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6822 {
6823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6824 /* .name = "Capture Source", */
6825 .name = "Input Source",
6826 .count = 1,
6827 .info = alc883_mux_enum_info,
6828 .get = alc883_mux_enum_get,
6829 .put = alc883_mux_enum_put,
6830 },
6831 { } /* end */
f12ab1e0 6832};
bc9f98a9 6833
272a527c
KY
6834static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6835 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6836 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6837 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6838 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6839 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6842 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6843 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6844 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6845 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6846 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6847 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6848 {
6849 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6850 /* .name = "Capture Source", */
6851 .name = "Input Source",
6852 .count = 2,
6853 .info = alc883_mux_enum_info,
6854 .get = alc883_mux_enum_get,
6855 .put = alc883_mux_enum_put,
6856 },
6857 { } /* end */
6858};
6859
6860static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6861 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6862 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6863 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6866 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6868 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6869 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6870 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6871 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6872 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6873 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6874 {
6875 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6876 /* .name = "Capture Source", */
6877 .name = "Input Source",
6878 .count = 2,
6879 .info = alc883_mux_enum_info,
6880 .get = alc883_mux_enum_get,
6881 .put = alc883_mux_enum_put,
6882 },
6883 { } /* end */
6884};
6885
4723c022 6886static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6887 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6888 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6889 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6890 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6891 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6892 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6893 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6894 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6895 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6896 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6903 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6905 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6906 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6908 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6909 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6910 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6911 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6912 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6913 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6914 {
6915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6916 /* .name = "Capture Source", */
6917 .name = "Input Source",
6918 .count = 2,
6919 .info = alc883_mux_enum_info,
6920 .get = alc883_mux_enum_get,
6921 .put = alc883_mux_enum_put,
6922 },
6923 { } /* end */
6924};
6925
4723c022 6926static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6927 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6928 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6930 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6931 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6932 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6933 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6934 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6935 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6936 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6937 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6938 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6939 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6940 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6941 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6943 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6944 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6945 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6946 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6947 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6948 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6949 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6950 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6951 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6952 {
6953 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6954 /* .name = "Capture Source", */
6955 .name = "Input Source",
6956 .count = 2,
6957 .info = alc883_mux_enum_info,
6958 .get = alc883_mux_enum_get,
6959 .put = alc883_mux_enum_put,
6960 },
6961 { } /* end */
6962};
6963
5795b9e6
CM
6964static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6965 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6966 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6967 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6968 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6969 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6970 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6971 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6972 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6973 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6974 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6981 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6983 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6984 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6985 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6986 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6987 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6988 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6989 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6990 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6991 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6992 {
6993 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6994 /* .name = "Capture Source", */
6995 .name = "Input Source",
6996 .count = 2,
6997 .info = alc883_mux_enum_info,
6998 .get = alc883_mux_enum_get,
6999 .put = alc883_mux_enum_put,
7000 },
7001 { } /* end */
7002};
7003
2880a867 7004static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7011 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7013 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7014 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7015 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7016 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7017 {
7018 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7019 /* .name = "Capture Source", */
7020 .name = "Input Source",
7021 .count = 2,
7022 .info = alc883_mux_enum_info,
7023 .get = alc883_mux_enum_get,
7024 .put = alc883_mux_enum_put,
7025 },
7026 { } /* end */
d1a991a6 7027};
2880a867 7028
9c7f852e
TI
7029static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7030 {
7031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7032 .name = "Channel Mode",
7033 .info = alc_ch_mode_info,
7034 .get = alc_ch_mode_get,
7035 .put = alc_ch_mode_put,
7036 },
7037 { } /* end */
7038};
7039
7040static struct hda_verb alc883_init_verbs[] = {
7041 /* ADC1: mute amp left and right */
7042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7043 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7044 /* ADC2: mute amp left and right */
7045 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7046 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7047 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7048 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7049 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7050 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7051 /* Rear mixer */
7052 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7053 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7054 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7055 /* CLFE mixer */
7056 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7058 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7059 /* Side mixer */
7060 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7061 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7062 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7063
cb53c626
TI
7064 /* mute analog input loopbacks */
7065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7070
9c7f852e
TI
7071 /* Front Pin: output 0 (0x0c) */
7072 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7073 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7074 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7075 /* Rear Pin: output 1 (0x0d) */
7076 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7078 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7079 /* CLFE Pin: output 2 (0x0e) */
7080 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7081 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7082 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7083 /* Side Pin: output 3 (0x0f) */
7084 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7085 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7086 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7087 /* Mic (rear) pin: input vref at 80% */
7088 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7089 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7090 /* Front Mic pin: input vref at 80% */
7091 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7092 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7093 /* Line In pin: input */
7094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7096 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7099 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7100 /* CD pin widget for input */
7101 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7102
7103 /* FIXME: use matrix-type input source selection */
7104 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7105 /* Input mixer2 */
7106 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7107 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7109 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7110 /* Input mixer3 */
7111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7114 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7115 { }
7116};
7117
a8848bd6
AS
7118/* toggle speaker-output according to the hp-jack state */
7119static void alc883_mitac_hp_automute(struct hda_codec *codec)
7120{
7121 unsigned int present;
7122
7123 present = snd_hda_codec_read(codec, 0x15, 0,
7124 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7125 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7126 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7127 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7128 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7129}
7130
7131/* auto-toggle front mic */
7132/*
7133static void alc883_mitac_mic_automute(struct hda_codec *codec)
7134{
7135 unsigned int present;
7136 unsigned char bits;
7137
7138 present = snd_hda_codec_read(codec, 0x18, 0,
7139 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7140 bits = present ? HDA_AMP_MUTE : 0;
7141 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7142}
7143*/
7144
7145static void alc883_mitac_automute(struct hda_codec *codec)
7146{
7147 alc883_mitac_hp_automute(codec);
7148 /* alc883_mitac_mic_automute(codec); */
7149}
7150
7151static void alc883_mitac_unsol_event(struct hda_codec *codec,
7152 unsigned int res)
7153{
7154 switch (res >> 26) {
7155 case ALC880_HP_EVENT:
7156 alc883_mitac_hp_automute(codec);
7157 break;
7158 case ALC880_MIC_EVENT:
7159 /* alc883_mitac_mic_automute(codec); */
7160 break;
7161 }
7162}
7163
7164static struct hda_verb alc883_mitac_verbs[] = {
7165 /* HP */
7166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7168 /* Subwoofer */
7169 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7170 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7171
7172 /* enable unsolicited event */
7173 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7174 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7175
7176 { } /* end */
7177};
7178
ccc656ce
KY
7179static struct hda_verb alc883_tagra_verbs[] = {
7180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7182
7183 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7184 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7185
7186 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7187 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7189
7190 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7191 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7192 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7193 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7194
7195 { } /* end */
7196};
7197
bc9f98a9
KY
7198static struct hda_verb alc883_lenovo_101e_verbs[] = {
7199 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7200 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7201 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7202 { } /* end */
7203};
7204
272a527c
KY
7205static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7206 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7207 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7208 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7209 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7210 { } /* end */
7211};
7212
7213static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7215 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7217 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7218 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7219 { } /* end */
7220};
7221
189609ae
KY
7222static struct hda_verb alc883_haier_w66_verbs[] = {
7223 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7225
7226 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7227
7228 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7229 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7230 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7232 { } /* end */
7233};
7234
4723c022 7235static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
7236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7237 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7238 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7239 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7240 { }
7241};
7242
4723c022 7243static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
7244 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7245 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7246 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7247 { }
7248};
7249
5795b9e6
CM
7250static struct hda_verb alc888_6st_dell_verbs[] = {
7251 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7252 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7253 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7254 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7255 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7256 { }
7257};
7258
4723c022 7259static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7260 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7261 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7262 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7263 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7264 { }
7265};
7266
4723c022 7267static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7268 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7269 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7270 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7271 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7272 { }
7273};
7274
4723c022
CM
7275static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7276 { 2, alc888_3st_hp_2ch_init },
7277 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7278};
7279
272a527c
KY
7280/* toggle front-jack and RCA according to the hp-jack state */
7281static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7282{
7283 unsigned int present;
7284
7285 present = snd_hda_codec_read(codec, 0x1b, 0,
7286 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7287 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7288 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7289 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7290 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7291}
7292
7293/* toggle RCA according to the front-jack state */
7294static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7295{
7296 unsigned int present;
7297
7298 present = snd_hda_codec_read(codec, 0x14, 0,
7299 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7300 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7301 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7302}
47fd830a 7303
272a527c
KY
7304static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7305 unsigned int res)
7306{
7307 if ((res >> 26) == ALC880_HP_EVENT)
7308 alc888_lenovo_ms7195_front_automute(codec);
7309 if ((res >> 26) == ALC880_FRONT_EVENT)
7310 alc888_lenovo_ms7195_rca_automute(codec);
7311}
7312
7313static struct hda_verb alc883_medion_md2_verbs[] = {
7314 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7315 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7316
7317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7318
7319 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7320 { } /* end */
7321};
7322
7323/* toggle speaker-output according to the hp-jack state */
7324static void alc883_medion_md2_automute(struct hda_codec *codec)
7325{
7326 unsigned int present;
7327
7328 present = snd_hda_codec_read(codec, 0x14, 0,
7329 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7330 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7331 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7332}
7333
7334static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7335 unsigned int res)
7336{
7337 if ((res >> 26) == ALC880_HP_EVENT)
7338 alc883_medion_md2_automute(codec);
7339}
7340
ccc656ce
KY
7341/* toggle speaker-output according to the hp-jack state */
7342static void alc883_tagra_automute(struct hda_codec *codec)
7343{
7344 unsigned int present;
f12ab1e0 7345 unsigned char bits;
ccc656ce
KY
7346
7347 present = snd_hda_codec_read(codec, 0x14, 0,
7348 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7349 bits = present ? HDA_AMP_MUTE : 0;
7350 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7351 HDA_AMP_MUTE, bits);
82beb8fd
TI
7352 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7353 present ? 1 : 3);
ccc656ce
KY
7354}
7355
7356static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7357{
7358 if ((res >> 26) == ALC880_HP_EVENT)
7359 alc883_tagra_automute(codec);
7360}
7361
189609ae
KY
7362static void alc883_haier_w66_automute(struct hda_codec *codec)
7363{
7364 unsigned int present;
7365 unsigned char bits;
7366
7367 present = snd_hda_codec_read(codec, 0x1b, 0,
7368 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7369 bits = present ? 0x80 : 0;
7370 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7371 0x80, bits);
7372}
7373
7374static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7375 unsigned int res)
7376{
7377 if ((res >> 26) == ALC880_HP_EVENT)
7378 alc883_haier_w66_automute(codec);
7379}
7380
bc9f98a9
KY
7381static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7382{
7383 unsigned int present;
f12ab1e0 7384 unsigned char bits;
bc9f98a9
KY
7385
7386 present = snd_hda_codec_read(codec, 0x14, 0,
7387 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7388 bits = present ? HDA_AMP_MUTE : 0;
7389 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7390 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7391}
7392
7393static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7394{
7395 unsigned int present;
f12ab1e0 7396 unsigned char bits;
bc9f98a9
KY
7397
7398 present = snd_hda_codec_read(codec, 0x1b, 0,
7399 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7400 bits = present ? HDA_AMP_MUTE : 0;
7401 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7402 HDA_AMP_MUTE, bits);
7403 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7404 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7405}
7406
7407static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7408 unsigned int res)
7409{
7410 if ((res >> 26) == ALC880_HP_EVENT)
7411 alc883_lenovo_101e_all_automute(codec);
7412 if ((res >> 26) == ALC880_FRONT_EVENT)
7413 alc883_lenovo_101e_ispeaker_automute(codec);
7414}
7415
676a9b53
TI
7416/* toggle speaker-output according to the hp-jack state */
7417static void alc883_acer_aspire_automute(struct hda_codec *codec)
7418{
7419 unsigned int present;
7420
7421 present = snd_hda_codec_read(codec, 0x14, 0,
7422 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7423 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7424 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7425 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7426 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7427}
7428
7429static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7430 unsigned int res)
7431{
7432 if ((res >> 26) == ALC880_HP_EVENT)
7433 alc883_acer_aspire_automute(codec);
7434}
7435
d1a991a6
KY
7436static struct hda_verb alc883_acer_eapd_verbs[] = {
7437 /* HP Pin: output 0 (0x0c) */
7438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7439 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7441 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7444 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7445 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7446 /* eanable EAPD on medion laptop */
7447 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7448 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7449 /* enable unsolicited event */
7450 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7451 { }
7452};
7453
5795b9e6
CM
7454static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7455{
7456 unsigned int present;
7457
7458 present = snd_hda_codec_read(codec, 0x1b, 0,
7459 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7460 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7462 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7463 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7464 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7465 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7466 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7467 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7468}
7469
7470static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7471 unsigned int res)
7472{
7473 switch (res >> 26) {
7474 case ALC880_HP_EVENT:
7475 printk("hp_event\n");
7476 alc888_6st_dell_front_automute(codec);
7477 break;
7478 }
7479}
7480
9c7f852e
TI
7481/*
7482 * generic initialization of ADC, input mixers and output mixers
7483 */
7484static struct hda_verb alc883_auto_init_verbs[] = {
7485 /*
7486 * Unmute ADC0-2 and set the default input to mic-in
7487 */
7488 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7489 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7490 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7491 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7492
cb53c626 7493 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7494 * mixer widget
f12ab1e0
TI
7495 * Note: PASD motherboards uses the Line In 2 as the input for
7496 * front panel mic (mic 2)
9c7f852e
TI
7497 */
7498 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7504
7505 /*
7506 * Set up output mixers (0x0c - 0x0f)
7507 */
7508 /* set vol=0 to output mixers */
7509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7510 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7511 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7513 /* set up input amps for analog loopback */
7514 /* Amp Indices: DAC = 0, mixer = 1 */
7515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7523 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7524 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7525
7526 /* FIXME: use matrix-type input source selection */
7527 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7528 /* Input mixer1 */
7529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7530 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7532 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7534 /* Input mixer2 */
7535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7536 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7538 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7540
7541 { }
7542};
7543
7544/* capture mixer elements */
7545static struct snd_kcontrol_new alc883_capture_mixer[] = {
7546 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7547 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7548 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7550 {
7551 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7552 /* The multiple "Capture Source" controls confuse alsamixer
7553 * So call somewhat different..
9c7f852e
TI
7554 */
7555 /* .name = "Capture Source", */
7556 .name = "Input Source",
7557 .count = 2,
7558 .info = alc882_mux_enum_info,
7559 .get = alc882_mux_enum_get,
7560 .put = alc882_mux_enum_put,
7561 },
7562 { } /* end */
7563};
7564
cb53c626
TI
7565#ifdef CONFIG_SND_HDA_POWER_SAVE
7566#define alc883_loopbacks alc880_loopbacks
7567#endif
7568
9c7f852e
TI
7569/* pcm configuration: identiacal with ALC880 */
7570#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7571#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 7572#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
7573#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7574#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7575
7576/*
7577 * configuration and preset
7578 */
f5fcc13c
TI
7579static const char *alc883_models[ALC883_MODEL_LAST] = {
7580 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7581 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7582 [ALC883_3ST_6ch] = "3stack-6ch",
7583 [ALC883_6ST_DIG] = "6stack-dig",
7584 [ALC883_TARGA_DIG] = "targa-dig",
7585 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7586 [ALC883_ACER] = "acer",
2880a867 7587 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7588 [ALC883_MEDION] = "medion",
272a527c 7589 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7590 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7591 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7592 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7593 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7594 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7595 [ALC888_6ST_HP] = "6stack-hp",
7596 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 7597 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 7598 [ALC883_MITAC] = "mitac",
f5fcc13c
TI
7599 [ALC883_AUTO] = "auto",
7600};
7601
7602static struct snd_pci_quirk alc883_cfg_tbl[] = {
7603 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7604 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7605 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7606 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7607 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 7608 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 7609 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7610 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7611 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7612 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7613 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7614 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7615 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7616 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7617 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7618 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7619 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7620 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7621 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7622 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
f5fcc13c 7623 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7624 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7625 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7626 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7627 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7628 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7629 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7630 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7631 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7632 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7633 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7634 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7635 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7636 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7637 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741
TI
7638 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7639 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7640 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7641 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7642 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7643 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7644 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7645 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7646 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 7647 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 7648 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7649 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7650 {}
7651};
7652
7653static struct alc_config_preset alc883_presets[] = {
7654 [ALC883_3ST_2ch_DIG] = {
7655 .mixers = { alc883_3ST_2ch_mixer },
7656 .init_verbs = { alc883_init_verbs },
7657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7658 .dac_nids = alc883_dac_nids,
7659 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7660 .dig_in_nid = ALC883_DIGIN_NID,
7661 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7662 .channel_mode = alc883_3ST_2ch_modes,
7663 .input_mux = &alc883_capture_source,
7664 },
7665 [ALC883_3ST_6ch_DIG] = {
7666 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7667 .init_verbs = { alc883_init_verbs },
7668 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7669 .dac_nids = alc883_dac_nids,
7670 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7671 .dig_in_nid = ALC883_DIGIN_NID,
7672 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7673 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7674 .need_dac_fix = 1,
9c7f852e 7675 .input_mux = &alc883_capture_source,
f12ab1e0 7676 },
9c7f852e
TI
7677 [ALC883_3ST_6ch] = {
7678 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7679 .init_verbs = { alc883_init_verbs },
7680 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7681 .dac_nids = alc883_dac_nids,
9c7f852e
TI
7682 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7683 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7684 .need_dac_fix = 1,
9c7f852e 7685 .input_mux = &alc883_capture_source,
f12ab1e0 7686 },
9c7f852e
TI
7687 [ALC883_6ST_DIG] = {
7688 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7689 .init_verbs = { alc883_init_verbs },
7690 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7691 .dac_nids = alc883_dac_nids,
7692 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7693 .dig_in_nid = ALC883_DIGIN_NID,
7694 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7695 .channel_mode = alc883_sixstack_modes,
7696 .input_mux = &alc883_capture_source,
7697 },
ccc656ce
KY
7698 [ALC883_TARGA_DIG] = {
7699 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7700 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7701 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7702 .dac_nids = alc883_dac_nids,
7703 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7704 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7705 .channel_mode = alc883_3ST_6ch_modes,
7706 .need_dac_fix = 1,
7707 .input_mux = &alc883_capture_source,
7708 .unsol_event = alc883_tagra_unsol_event,
7709 .init_hook = alc883_tagra_automute,
7710 },
7711 [ALC883_TARGA_2ch_DIG] = {
7712 .mixers = { alc883_tagra_2ch_mixer},
7713 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7714 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7715 .dac_nids = alc883_dac_nids,
7716 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7718 .channel_mode = alc883_3ST_2ch_modes,
7719 .input_mux = &alc883_capture_source,
7720 .unsol_event = alc883_tagra_unsol_event,
7721 .init_hook = alc883_tagra_automute,
7722 },
bab282b9 7723 [ALC883_ACER] = {
676a9b53 7724 .mixers = { alc883_base_mixer },
bab282b9
VA
7725 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7726 * and the headphone jack. Turn this on and rely on the
7727 * standard mute methods whenever the user wants to turn
7728 * these outputs off.
7729 */
7730 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7731 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7732 .dac_nids = alc883_dac_nids,
bab282b9
VA
7733 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7734 .channel_mode = alc883_3ST_2ch_modes,
7735 .input_mux = &alc883_capture_source,
7736 },
2880a867 7737 [ALC883_ACER_ASPIRE] = {
676a9b53 7738 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7739 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7740 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7741 .dac_nids = alc883_dac_nids,
7742 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
7743 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7744 .channel_mode = alc883_3ST_2ch_modes,
7745 .input_mux = &alc883_capture_source,
676a9b53
TI
7746 .unsol_event = alc883_acer_aspire_unsol_event,
7747 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7748 },
c07584c8
TD
7749 [ALC883_MEDION] = {
7750 .mixers = { alc883_fivestack_mixer,
7751 alc883_chmode_mixer },
7752 .init_verbs = { alc883_init_verbs,
b373bdeb 7753 alc883_medion_eapd_verbs },
c07584c8
TD
7754 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7755 .dac_nids = alc883_dac_nids,
c07584c8
TD
7756 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7757 .channel_mode = alc883_sixstack_modes,
7758 .input_mux = &alc883_capture_source,
b373bdeb 7759 },
272a527c
KY
7760 [ALC883_MEDION_MD2] = {
7761 .mixers = { alc883_medion_md2_mixer},
7762 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7764 .dac_nids = alc883_dac_nids,
7765 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7767 .channel_mode = alc883_3ST_2ch_modes,
7768 .input_mux = &alc883_capture_source,
7769 .unsol_event = alc883_medion_md2_unsol_event,
7770 .init_hook = alc883_medion_md2_automute,
7771 },
b373bdeb 7772 [ALC883_LAPTOP_EAPD] = {
676a9b53 7773 .mixers = { alc883_base_mixer },
b373bdeb
AN
7774 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7775 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7776 .dac_nids = alc883_dac_nids,
b373bdeb
AN
7777 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7778 .channel_mode = alc883_3ST_2ch_modes,
7779 .input_mux = &alc883_capture_source,
7780 },
bc9f98a9
KY
7781 [ALC883_LENOVO_101E_2ch] = {
7782 .mixers = { alc883_lenovo_101e_2ch_mixer},
7783 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7784 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7785 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
7786 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7787 .channel_mode = alc883_3ST_2ch_modes,
7788 .input_mux = &alc883_lenovo_101e_capture_source,
7789 .unsol_event = alc883_lenovo_101e_unsol_event,
7790 .init_hook = alc883_lenovo_101e_all_automute,
7791 },
272a527c
KY
7792 [ALC883_LENOVO_NB0763] = {
7793 .mixers = { alc883_lenovo_nb0763_mixer },
7794 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7795 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7796 .dac_nids = alc883_dac_nids,
272a527c
KY
7797 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7798 .channel_mode = alc883_3ST_2ch_modes,
7799 .need_dac_fix = 1,
7800 .input_mux = &alc883_lenovo_nb0763_capture_source,
7801 .unsol_event = alc883_medion_md2_unsol_event,
7802 .init_hook = alc883_medion_md2_automute,
7803 },
7804 [ALC888_LENOVO_MS7195_DIG] = {
7805 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7806 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7807 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7808 .dac_nids = alc883_dac_nids,
7809 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7810 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7811 .channel_mode = alc883_3ST_6ch_modes,
7812 .need_dac_fix = 1,
7813 .input_mux = &alc883_capture_source,
7814 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7815 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7816 },
7817 [ALC883_HAIER_W66] = {
7818 .mixers = { alc883_tagra_2ch_mixer},
7819 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7820 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7821 .dac_nids = alc883_dac_nids,
7822 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
7823 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7824 .channel_mode = alc883_3ST_2ch_modes,
7825 .input_mux = &alc883_capture_source,
7826 .unsol_event = alc883_haier_w66_unsol_event,
7827 .init_hook = alc883_haier_w66_automute,
272a527c 7828 },
4723c022
CM
7829 [ALC888_6ST_HP] = {
7830 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7831 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7832 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7833 .dac_nids = alc883_dac_nids,
7834 .dig_out_nid = ALC883_DIGOUT_NID,
cd1e3b40
CM
7835 .dig_in_nid = ALC883_DIGIN_NID,
7836 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7837 .channel_mode = alc883_sixstack_modes,
7838 .input_mux = &alc883_capture_source,
7839 },
4723c022
CM
7840 [ALC888_3ST_HP] = {
7841 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7842 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7843 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7844 .dac_nids = alc883_dac_nids,
4723c022
CM
7845 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7846 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7847 .need_dac_fix = 1,
7848 .input_mux = &alc883_capture_source,
7849 },
5795b9e6
CM
7850 [ALC888_6ST_DELL] = {
7851 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7852 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7853 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7854 .dac_nids = alc883_dac_nids,
7855 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
7856 .dig_in_nid = ALC883_DIGIN_NID,
7857 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7858 .channel_mode = alc883_sixstack_modes,
7859 .input_mux = &alc883_capture_source,
7860 .unsol_event = alc888_6st_dell_unsol_event,
7861 .init_hook = alc888_6st_dell_front_automute,
7862 },
a8848bd6
AS
7863 [ALC883_MITAC] = {
7864 .mixers = { alc883_mitac_mixer },
7865 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7866 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7867 .dac_nids = alc883_dac_nids,
a8848bd6
AS
7868 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7869 .channel_mode = alc883_3ST_2ch_modes,
7870 .input_mux = &alc883_capture_source,
7871 .unsol_event = alc883_mitac_unsol_event,
7872 .init_hook = alc883_mitac_automute,
7873 },
9c7f852e
TI
7874};
7875
7876
7877/*
7878 * BIOS auto configuration
7879 */
7880static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7881 hda_nid_t nid, int pin_type,
7882 int dac_idx)
7883{
7884 /* set as output */
7885 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7886 int idx;
7887
f6c7e546 7888 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
7889 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7890 idx = 4;
7891 else
7892 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
7893 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7894
7895}
7896
7897static void alc883_auto_init_multi_out(struct hda_codec *codec)
7898{
7899 struct alc_spec *spec = codec->spec;
7900 int i;
7901
bc9f98a9 7902 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7903 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7904 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7905 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7906 if (nid)
baba8ee9 7907 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7908 i);
9c7f852e
TI
7909 }
7910}
7911
7912static void alc883_auto_init_hp_out(struct hda_codec *codec)
7913{
7914 struct alc_spec *spec = codec->spec;
7915 hda_nid_t pin;
7916
eb06ed8f 7917 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7918 if (pin) /* connect to front */
7919 /* use dac 0 */
7920 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7921 pin = spec->autocfg.speaker_pins[0];
7922 if (pin)
7923 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
7924}
7925
7926#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7927#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7928
7929static void alc883_auto_init_analog_input(struct hda_codec *codec)
7930{
7931 struct alc_spec *spec = codec->spec;
7932 int i;
7933
7934 for (i = 0; i < AUTO_PIN_LAST; i++) {
7935 hda_nid_t nid = spec->autocfg.input_pins[i];
7936 if (alc883_is_input_pin(nid)) {
7937 snd_hda_codec_write(codec, nid, 0,
7938 AC_VERB_SET_PIN_WIDGET_CONTROL,
7939 (i <= AUTO_PIN_FRONT_MIC ?
7940 PIN_VREF80 : PIN_IN));
7941 if (nid != ALC883_PIN_CD_NID)
7942 snd_hda_codec_write(codec, nid, 0,
7943 AC_VERB_SET_AMP_GAIN_MUTE,
7944 AMP_OUT_MUTE);
7945 }
7946 }
7947}
7948
7949/* almost identical with ALC880 parser... */
7950static int alc883_parse_auto_config(struct hda_codec *codec)
7951{
7952 struct alc_spec *spec = codec->spec;
7953 int err = alc880_parse_auto_config(codec);
7954
7955 if (err < 0)
7956 return err;
776e184e
TI
7957 else if (!err)
7958 return 0; /* no config found */
7959
7960 err = alc_auto_add_mic_boost(codec);
7961 if (err < 0)
7962 return err;
7963
7964 /* hack - override the init verbs */
7965 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
7966 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7967 spec->num_mixers++;
776e184e
TI
7968
7969 return 1; /* config found */
9c7f852e
TI
7970}
7971
7972/* additional initialization for auto-configuration model */
7973static void alc883_auto_init(struct hda_codec *codec)
7974{
f6c7e546 7975 struct alc_spec *spec = codec->spec;
9c7f852e
TI
7976 alc883_auto_init_multi_out(codec);
7977 alc883_auto_init_hp_out(codec);
7978 alc883_auto_init_analog_input(codec);
f6c7e546
TI
7979 if (spec->unsol_event)
7980 alc_sku_automute(codec);
9c7f852e
TI
7981}
7982
7983static int patch_alc883(struct hda_codec *codec)
7984{
7985 struct alc_spec *spec;
7986 int err, board_config;
7987
7988 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7989 if (spec == NULL)
7990 return -ENOMEM;
7991
7992 codec->spec = spec;
7993
f5fcc13c
TI
7994 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7995 alc883_models,
7996 alc883_cfg_tbl);
7997 if (board_config < 0) {
9c7f852e
TI
7998 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7999 "trying auto-probe from BIOS...\n");
8000 board_config = ALC883_AUTO;
8001 }
8002
8003 if (board_config == ALC883_AUTO) {
8004 /* automatic parse from the BIOS config */
8005 err = alc883_parse_auto_config(codec);
8006 if (err < 0) {
8007 alc_free(codec);
8008 return err;
f12ab1e0 8009 } else if (!err) {
9c7f852e
TI
8010 printk(KERN_INFO
8011 "hda_codec: Cannot set up configuration "
8012 "from BIOS. Using base mode...\n");
8013 board_config = ALC883_3ST_2ch_DIG;
8014 }
8015 }
8016
8017 if (board_config != ALC883_AUTO)
8018 setup_preset(spec, &alc883_presets[board_config]);
8019
8020 spec->stream_name_analog = "ALC883 Analog";
8021 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8022 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8023 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e
TI
8024
8025 spec->stream_name_digital = "ALC883 Digital";
8026 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8027 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8028
e1406348
TI
8029 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8030 spec->adc_nids = alc883_adc_nids;
8031 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8032
2134ea4f
TI
8033 spec->vmaster_nid = 0x0c;
8034
9c7f852e
TI
8035 codec->patch_ops = alc_patch_ops;
8036 if (board_config == ALC883_AUTO)
8037 spec->init_hook = alc883_auto_init;
cb53c626
TI
8038#ifdef CONFIG_SND_HDA_POWER_SAVE
8039 if (!spec->loopback.amplist)
8040 spec->loopback.amplist = alc883_loopbacks;
8041#endif
9c7f852e
TI
8042
8043 return 0;
8044}
8045
8046/*
8047 * ALC262 support
8048 */
8049
8050#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8051#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8052
8053#define alc262_dac_nids alc260_dac_nids
8054#define alc262_adc_nids alc882_adc_nids
8055#define alc262_adc_nids_alt alc882_adc_nids_alt
8056
8057#define alc262_modes alc260_modes
8058#define alc262_capture_source alc882_capture_source
8059
8060static struct snd_kcontrol_new alc262_base_mixer[] = {
8061 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8062 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8063 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8064 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8069 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8070 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8071 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8072 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8073 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8074 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8075 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8077 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8078 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8079 { } /* end */
8080};
8081
ccc656ce
KY
8082static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8083 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8084 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8085 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8086 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8087 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8088 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8091 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8092 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8093 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8094 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8095 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8096 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8097 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8099 { } /* end */
8100};
8101
ce875f07
TI
8102/* update HP, line and mono-out pins according to the master switch */
8103static void alc262_hp_master_update(struct hda_codec *codec)
8104{
8105 struct alc_spec *spec = codec->spec;
8106 int val = spec->master_sw;
8107
8108 /* HP & line-out */
8109 snd_hda_codec_write_cache(codec, 0x1b, 0,
8110 AC_VERB_SET_PIN_WIDGET_CONTROL,
8111 val ? PIN_HP : 0);
8112 snd_hda_codec_write_cache(codec, 0x15, 0,
8113 AC_VERB_SET_PIN_WIDGET_CONTROL,
8114 val ? PIN_HP : 0);
8115 /* mono (speaker) depending on the HP jack sense */
8116 val = val && !spec->jack_present;
8117 snd_hda_codec_write_cache(codec, 0x16, 0,
8118 AC_VERB_SET_PIN_WIDGET_CONTROL,
8119 val ? PIN_OUT : 0);
8120}
8121
8122static void alc262_hp_bpc_automute(struct hda_codec *codec)
8123{
8124 struct alc_spec *spec = codec->spec;
8125 unsigned int presence;
8126 presence = snd_hda_codec_read(codec, 0x1b, 0,
8127 AC_VERB_GET_PIN_SENSE, 0);
8128 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8129 alc262_hp_master_update(codec);
8130}
8131
8132static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8133{
8134 if ((res >> 26) != ALC880_HP_EVENT)
8135 return;
8136 alc262_hp_bpc_automute(codec);
8137}
8138
8139static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8140{
8141 struct alc_spec *spec = codec->spec;
8142 unsigned int presence;
8143 presence = snd_hda_codec_read(codec, 0x15, 0,
8144 AC_VERB_GET_PIN_SENSE, 0);
8145 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8146 alc262_hp_master_update(codec);
8147}
8148
8149static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8150 unsigned int res)
8151{
8152 if ((res >> 26) != ALC880_HP_EVENT)
8153 return;
8154 alc262_hp_wildwest_automute(codec);
8155}
8156
8157static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8158 struct snd_ctl_elem_value *ucontrol)
8159{
8160 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8161 struct alc_spec *spec = codec->spec;
8162 *ucontrol->value.integer.value = spec->master_sw;
8163 return 0;
8164}
8165
8166static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8167 struct snd_ctl_elem_value *ucontrol)
8168{
8169 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8170 struct alc_spec *spec = codec->spec;
8171 int val = !!*ucontrol->value.integer.value;
8172
8173 if (val == spec->master_sw)
8174 return 0;
8175 spec->master_sw = val;
8176 alc262_hp_master_update(codec);
8177 return 1;
8178}
8179
9c7f852e 8180static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8181 {
8182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8183 .name = "Master Playback Switch",
8184 .info = snd_ctl_boolean_mono_info,
8185 .get = alc262_hp_master_sw_get,
8186 .put = alc262_hp_master_sw_put,
8187 },
9c7f852e
TI
8188 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8189 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8190 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8191 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8192 HDA_OUTPUT),
8193 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8194 HDA_OUTPUT),
9c7f852e
TI
8195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8197 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8200 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
8201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8203 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8204 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8205 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8206 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8207 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8208 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8209 { } /* end */
8210};
8211
cd7509a4 8212static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
8213 {
8214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8215 .name = "Master Playback Switch",
8216 .info = snd_ctl_boolean_mono_info,
8217 .get = alc262_hp_master_sw_get,
8218 .put = alc262_hp_master_sw_put,
8219 },
cd7509a4
KY
8220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8221 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8223 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
8224 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8225 HDA_OUTPUT),
8226 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8227 HDA_OUTPUT),
cd7509a4
KY
8228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 8230 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
8231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8233 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8234 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8235 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8236 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8237 { } /* end */
8238};
8239
8240static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8241 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8242 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8243 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
8244 { } /* end */
8245};
8246
66d2a9d6
KY
8247/* mute/unmute internal speaker according to the hp jack and mute state */
8248static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8249{
8250 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
8251
8252 if (force || !spec->sense_updated) {
8253 unsigned int present;
8254 present = snd_hda_codec_read(codec, 0x15, 0,
8255 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 8256 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
8257 spec->sense_updated = 1;
8258 }
4bb26130
TI
8259 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8260 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
8261}
8262
8263static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8264 unsigned int res)
8265{
8266 if ((res >> 26) != ALC880_HP_EVENT)
8267 return;
8268 alc262_hp_t5735_automute(codec, 1);
8269}
8270
8271static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8272{
8273 alc262_hp_t5735_automute(codec, 1);
8274}
8275
8276static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
8277 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8278 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
8279 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8280 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8283 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8284 { } /* end */
8285};
8286
8287static struct hda_verb alc262_hp_t5735_verbs[] = {
8288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8290
8291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8292 { }
8293};
8294
8c427226 8295static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
8296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
8298 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8299 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
8300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8302 { } /* end */
8303};
8304
8305static struct hda_verb alc262_hp_rp5700_verbs[] = {
8306 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8308 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8310 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8311 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8316 {}
8317};
8318
8319static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8320 .num_items = 1,
8321 .items = {
8322 { "Line", 0x1 },
8323 },
8324};
8325
0724ea2a
TI
8326/* bind hp and internal speaker mute (with plug check) */
8327static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8328 struct snd_ctl_elem_value *ucontrol)
8329{
8330 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8331 long *valp = ucontrol->value.integer.value;
8332 int change;
8333
8334 /* change hp mute */
8335 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8336 HDA_AMP_MUTE,
8337 valp[0] ? 0 : HDA_AMP_MUTE);
8338 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8339 HDA_AMP_MUTE,
8340 valp[1] ? 0 : HDA_AMP_MUTE);
8341 if (change) {
8342 /* change speaker according to HP jack state */
8343 struct alc_spec *spec = codec->spec;
8344 unsigned int mute;
8345 if (spec->jack_present)
8346 mute = HDA_AMP_MUTE;
8347 else
8348 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8349 HDA_OUTPUT, 0);
8350 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8351 HDA_AMP_MUTE, mute);
8352 }
8353 return change;
8354}
5b31954e 8355
272a527c 8356static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
8357 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8358 {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Master Playback Switch",
8361 .info = snd_hda_mixer_amp_switch_info,
8362 .get = snd_hda_mixer_amp_switch_get,
8363 .put = alc262_sony_master_sw_put,
8364 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8365 },
272a527c
KY
8366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8368 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8369 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8370 { } /* end */
8371};
8372
83c34218
KY
8373static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8374 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8375 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8379 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8380 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8381 { } /* end */
8382};
272a527c 8383
9c7f852e
TI
8384#define alc262_capture_mixer alc882_capture_mixer
8385#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8386
8387/*
8388 * generic initialization of ADC, input mixers and output mixers
8389 */
8390static struct hda_verb alc262_init_verbs[] = {
8391 /*
8392 * Unmute ADC0-2 and set the default input to mic-in
8393 */
8394 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8396 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8397 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8398 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8400
cb53c626 8401 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8402 * mixer widget
f12ab1e0
TI
8403 * Note: PASD motherboards uses the Line In 2 as the input for
8404 * front panel mic (mic 2)
9c7f852e
TI
8405 */
8406 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8412
8413 /*
df694daa
KY
8414 * Set up output mixers (0x0c - 0x0e)
8415 */
8416 /* set vol=0 to output mixers */
8417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8420 /* set up input amps for analog loopback */
8421 /* Amp Indices: DAC = 0, mixer = 1 */
8422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8428
8429 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8433 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8434 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8435
8436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8437 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8441
8442 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8444
8445 /* FIXME: use matrix-type input source selection */
8446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8447 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8452 /* Input mixer2 */
8453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8456 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8457 /* Input mixer3 */
8458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8462
8463 { }
8464};
1da177e4 8465
ccc656ce
KY
8466static struct hda_verb alc262_hippo_unsol_verbs[] = {
8467 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8469 {}
8470};
8471
8472static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8473 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8474 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8475 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8476
8477 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8479 {}
8480};
8481
272a527c
KY
8482static struct hda_verb alc262_sony_unsol_verbs[] = {
8483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8484 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8486
8487 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8489};
8490
ccc656ce 8491/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8492static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8493{
8494 struct alc_spec *spec = codec->spec;
8495 unsigned int mute;
5b31954e 8496 unsigned int present;
ccc656ce 8497
5b31954e
TI
8498 /* need to execute and sync at first */
8499 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8500 present = snd_hda_codec_read(codec, 0x15, 0,
8501 AC_VERB_GET_PIN_SENSE, 0);
8502 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8503 if (spec->jack_present) {
8504 /* mute internal speaker */
47fd830a
TI
8505 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8506 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8507 } else {
8508 /* unmute internal speaker if necessary */
8509 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8510 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8511 HDA_AMP_MUTE, mute);
ccc656ce
KY
8512 }
8513}
8514
8515/* unsolicited event for HP jack sensing */
8516static void alc262_hippo_unsol_event(struct hda_codec *codec,
8517 unsigned int res)
8518{
8519 if ((res >> 26) != ALC880_HP_EVENT)
8520 return;
5b31954e 8521 alc262_hippo_automute(codec);
ccc656ce
KY
8522}
8523
5b31954e 8524static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8525{
ccc656ce 8526 unsigned int mute;
5b31954e 8527 unsigned int present;
ccc656ce 8528
5b31954e
TI
8529 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8530 present = snd_hda_codec_read(codec, 0x1b, 0,
8531 AC_VERB_GET_PIN_SENSE, 0);
8532 present = (present & 0x80000000) != 0;
8533 if (present) {
ccc656ce 8534 /* mute internal speaker */
47fd830a
TI
8535 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8536 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8537 } else {
8538 /* unmute internal speaker if necessary */
8539 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8540 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8541 HDA_AMP_MUTE, mute);
ccc656ce
KY
8542 }
8543}
8544
8545/* unsolicited event for HP jack sensing */
8546static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8547 unsigned int res)
8548{
8549 if ((res >> 26) != ALC880_HP_EVENT)
8550 return;
5b31954e 8551 alc262_hippo1_automute(codec);
ccc656ce
KY
8552}
8553
834be88d
TI
8554/*
8555 * fujitsu model
8556 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8557 */
8558
8559#define ALC_HP_EVENT 0x37
8560
8561static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8562 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8564 {}
8565};
8566
8567static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8568 .num_items = 3,
834be88d
TI
8569 .items = {
8570 { "Mic", 0x0 },
39d3ed38 8571 { "Int Mic", 0x1 },
834be88d
TI
8572 { "CD", 0x4 },
8573 },
8574};
8575
9c7f852e
TI
8576static struct hda_input_mux alc262_HP_capture_source = {
8577 .num_items = 5,
8578 .items = {
8579 { "Mic", 0x0 },
accbe498 8580 { "Front Mic", 0x1 },
9c7f852e
TI
8581 { "Line", 0x2 },
8582 { "CD", 0x4 },
8583 { "AUX IN", 0x6 },
8584 },
8585};
8586
accbe498 8587static struct hda_input_mux alc262_HP_D7000_capture_source = {
8588 .num_items = 4,
8589 .items = {
8590 { "Mic", 0x0 },
8591 { "Front Mic", 0x2 },
8592 { "Line", 0x1 },
8593 { "CD", 0x4 },
8594 },
8595};
8596
834be88d
TI
8597/* mute/unmute internal speaker according to the hp jack and mute state */
8598static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8599{
8600 struct alc_spec *spec = codec->spec;
8601 unsigned int mute;
8602
f12ab1e0 8603 if (force || !spec->sense_updated) {
834be88d
TI
8604 unsigned int present;
8605 /* need to execute and sync at first */
8606 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8607 present = snd_hda_codec_read(codec, 0x14, 0,
8608 AC_VERB_GET_PIN_SENSE, 0);
8609 spec->jack_present = (present & 0x80000000) != 0;
8610 spec->sense_updated = 1;
8611 }
8612 if (spec->jack_present) {
8613 /* mute internal speaker */
47fd830a
TI
8614 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8615 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8616 } else {
8617 /* unmute internal speaker if necessary */
8618 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8619 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8620 HDA_AMP_MUTE, mute);
834be88d
TI
8621 }
8622}
8623
8624/* unsolicited event for HP jack sensing */
8625static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8626 unsigned int res)
8627{
8628 if ((res >> 26) != ALC_HP_EVENT)
8629 return;
8630 alc262_fujitsu_automute(codec, 1);
8631}
8632
8633/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8634static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8635 .ops = &snd_hda_bind_vol,
8636 .values = {
8637 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8638 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8639 0
8640 },
8641};
834be88d
TI
8642
8643/* bind hp and internal speaker mute (with plug check) */
8644static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8645 struct snd_ctl_elem_value *ucontrol)
8646{
8647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8648 long *valp = ucontrol->value.integer.value;
8649 int change;
8650
8651 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8652 HDA_AMP_MUTE,
8653 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8654 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8655 HDA_AMP_MUTE,
8656 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8657 if (change)
8658 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8659 return change;
8660}
8661
8662static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8663 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8664 {
8665 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8666 .name = "Master Playback Switch",
8667 .info = snd_hda_mixer_amp_switch_info,
8668 .get = snd_hda_mixer_amp_switch_get,
8669 .put = alc262_fujitsu_master_sw_put,
8670 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8671 },
8672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8674 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8676 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8677 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8678 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8679 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8680 { } /* end */
8681};
8682
304dcaac
TI
8683/* additional init verbs for Benq laptops */
8684static struct hda_verb alc262_EAPD_verbs[] = {
8685 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8686 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8687 {}
8688};
8689
83c34218
KY
8690static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8691 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8692 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8693
8694 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8695 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8696 {}
8697};
8698
f651b50b
TD
8699/* Samsung Q1 Ultra Vista model setup */
8700static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8701 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8702 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8706 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8707 { } /* end */
8708};
8709
8710static struct hda_verb alc262_ultra_verbs[] = {
8711 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8713 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8714 /* Mic is on Node 0x19 */
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8716 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8717 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8718 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8720 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8721 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8722 {}
8723};
8724
8725static struct hda_input_mux alc262_ultra_capture_source = {
8726 .num_items = 1,
8727 .items = {
8728 { "Mic", 0x1 },
8729 },
8730};
8731
8732/* mute/unmute internal speaker according to the hp jack and mute state */
8733static void alc262_ultra_automute(struct hda_codec *codec)
8734{
8735 struct alc_spec *spec = codec->spec;
8736 unsigned int mute;
8737 unsigned int present;
8738
8739 /* need to execute and sync at first */
8740 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8741 present = snd_hda_codec_read(codec, 0x15, 0,
8742 AC_VERB_GET_PIN_SENSE, 0);
8743 spec->jack_present = (present & 0x80000000) != 0;
8744 if (spec->jack_present) {
8745 /* mute internal speaker */
8746 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8747 HDA_AMP_MUTE, HDA_AMP_MUTE);
8748 } else {
8749 /* unmute internal speaker if necessary */
8750 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8751 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8752 HDA_AMP_MUTE, mute);
8753 }
8754}
8755
8756/* unsolicited event for HP jack sensing */
8757static void alc262_ultra_unsol_event(struct hda_codec *codec,
8758 unsigned int res)
8759{
8760 if ((res >> 26) != ALC880_HP_EVENT)
8761 return;
8762 alc262_ultra_automute(codec);
8763}
8764
df694daa 8765/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8766static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8767 const struct auto_pin_cfg *cfg)
df694daa
KY
8768{
8769 hda_nid_t nid;
8770 int err;
8771
8772 spec->multiout.num_dacs = 1; /* only use one dac */
8773 spec->multiout.dac_nids = spec->private_dac_nids;
8774 spec->multiout.dac_nids[0] = 2;
8775
8776 nid = cfg->line_out_pins[0];
8777 if (nid) {
f12ab1e0
TI
8778 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8779 "Front Playback Volume",
8780 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8781 if (err < 0)
df694daa 8782 return err;
f12ab1e0
TI
8783 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8784 "Front Playback Switch",
8785 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8786 if (err < 0)
df694daa
KY
8787 return err;
8788 }
8789
82bc955f 8790 nid = cfg->speaker_pins[0];
df694daa
KY
8791 if (nid) {
8792 if (nid == 0x16) {
f12ab1e0
TI
8793 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8794 "Speaker Playback Volume",
8795 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8796 HDA_OUTPUT));
8797 if (err < 0)
df694daa 8798 return err;
f12ab1e0
TI
8799 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8800 "Speaker Playback Switch",
8801 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8802 HDA_OUTPUT));
8803 if (err < 0)
df694daa
KY
8804 return err;
8805 } else {
f12ab1e0
TI
8806 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8807 "Speaker Playback Switch",
8808 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8809 HDA_OUTPUT));
8810 if (err < 0)
df694daa
KY
8811 return err;
8812 }
8813 }
eb06ed8f 8814 nid = cfg->hp_pins[0];
df694daa
KY
8815 if (nid) {
8816 /* spec->multiout.hp_nid = 2; */
8817 if (nid == 0x16) {
f12ab1e0
TI
8818 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8819 "Headphone Playback Volume",
8820 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8821 HDA_OUTPUT));
8822 if (err < 0)
df694daa 8823 return err;
f12ab1e0
TI
8824 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8825 "Headphone Playback Switch",
8826 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8827 HDA_OUTPUT));
8828 if (err < 0)
df694daa
KY
8829 return err;
8830 } else {
f12ab1e0
TI
8831 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8832 "Headphone Playback Switch",
8833 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8834 HDA_OUTPUT));
8835 if (err < 0)
df694daa
KY
8836 return err;
8837 }
8838 }
f12ab1e0 8839 return 0;
df694daa
KY
8840}
8841
8842/* identical with ALC880 */
f12ab1e0
TI
8843#define alc262_auto_create_analog_input_ctls \
8844 alc880_auto_create_analog_input_ctls
df694daa
KY
8845
8846/*
8847 * generic initialization of ADC, input mixers and output mixers
8848 */
8849static struct hda_verb alc262_volume_init_verbs[] = {
8850 /*
8851 * Unmute ADC0-2 and set the default input to mic-in
8852 */
8853 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8855 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8856 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8857 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8859
cb53c626 8860 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8861 * mixer widget
f12ab1e0
TI
8862 * Note: PASD motherboards uses the Line In 2 as the input for
8863 * front panel mic (mic 2)
df694daa
KY
8864 */
8865 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8866 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8867 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8868 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8869 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8871
8872 /*
8873 * Set up output mixers (0x0c - 0x0f)
8874 */
8875 /* set vol=0 to output mixers */
8876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8877 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8878 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8879
8880 /* set up input amps for analog loopback */
8881 /* Amp Indices: DAC = 0, mixer = 1 */
8882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8884 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8885 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8886 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8888
8889 /* FIXME: use matrix-type input source selection */
8890 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8891 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8896 /* Input mixer2 */
8897 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8898 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8899 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8901 /* Input mixer3 */
8902 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8903 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8904 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8905 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8906
8907 { }
8908};
8909
9c7f852e
TI
8910static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8911 /*
8912 * Unmute ADC0-2 and set the default input to mic-in
8913 */
8914 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8916 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8918 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920
cb53c626 8921 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8922 * mixer widget
f12ab1e0
TI
8923 * Note: PASD motherboards uses the Line In 2 as the input for
8924 * front panel mic (mic 2)
9c7f852e
TI
8925 */
8926 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
8934
8935 /*
8936 * Set up output mixers (0x0c - 0x0e)
8937 */
8938 /* set vol=0 to output mixers */
8939 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8940 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8941 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8942
8943 /* set up input amps for analog loopback */
8944 /* Amp Indices: DAC = 0, mixer = 1 */
8945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8946 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8948 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8950 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8951
ce875f07 8952 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
8953 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8954 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8955
8956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8958
8959 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8960 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8961
8962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8963 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8964 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8966 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8967
8968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8969 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8970 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8971 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8972 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8973 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8974
8975
8976 /* FIXME: use matrix-type input source selection */
8977 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8978 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8979 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8980 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8981 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8982 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8983 /* Input mixer2 */
8984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8985 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8986 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8987 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8988 /* Input mixer3 */
8989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8991 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8993
ce875f07
TI
8994 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8995
9c7f852e
TI
8996 { }
8997};
8998
cd7509a4
KY
8999static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9000 /*
9001 * Unmute ADC0-2 and set the default input to mic-in
9002 */
9003 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9004 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9005 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9007 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9008 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9009
cb53c626 9010 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
9011 * mixer widget
9012 * Note: PASD motherboards uses the Line In 2 as the input for front
9013 * panel mic (mic 2)
9014 */
9015 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9016 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9017 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9018 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9019 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
9024 /*
9025 * Set up output mixers (0x0c - 0x0e)
9026 */
9027 /* set vol=0 to output mixers */
9028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9031
9032 /* set up input amps for analog loopback */
9033 /* Amp Indices: DAC = 0, mixer = 1 */
9034 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9036 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9037 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9038 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9040
9041
9042 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9043 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9044 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9046 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9048 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9049
9050 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9051 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9052
9053 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9054 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9055
9056 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9057 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9058 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9060 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9061 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9062
9063 /* FIXME: use matrix-type input source selection */
9064 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9065 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9071 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9073 /* Input mixer2 */
9074 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9079 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9081 /* Input mixer3 */
9082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9087 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9089
ce875f07
TI
9090 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9091
cd7509a4
KY
9092 { }
9093};
9094
cb53c626
TI
9095#ifdef CONFIG_SND_HDA_POWER_SAVE
9096#define alc262_loopbacks alc880_loopbacks
9097#endif
9098
df694daa
KY
9099/* pcm configuration: identiacal with ALC880 */
9100#define alc262_pcm_analog_playback alc880_pcm_analog_playback
9101#define alc262_pcm_analog_capture alc880_pcm_analog_capture
9102#define alc262_pcm_digital_playback alc880_pcm_digital_playback
9103#define alc262_pcm_digital_capture alc880_pcm_digital_capture
9104
9105/*
9106 * BIOS auto configuration
9107 */
9108static int alc262_parse_auto_config(struct hda_codec *codec)
9109{
9110 struct alc_spec *spec = codec->spec;
9111 int err;
9112 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9113
f12ab1e0
TI
9114 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9115 alc262_ignore);
9116 if (err < 0)
df694daa 9117 return err;
f12ab1e0 9118 if (!spec->autocfg.line_outs)
df694daa 9119 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
9120 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9121 if (err < 0)
9122 return err;
9123 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9124 if (err < 0)
df694daa
KY
9125 return err;
9126
9127 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9128
9129 if (spec->autocfg.dig_out_pin)
9130 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9131 if (spec->autocfg.dig_in_pin)
9132 spec->dig_in_nid = ALC262_DIGIN_NID;
9133
9134 if (spec->kctl_alloc)
9135 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9136
9137 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 9138 spec->num_mux_defs = 1;
df694daa
KY
9139 spec->input_mux = &spec->private_imux;
9140
776e184e
TI
9141 err = alc_auto_add_mic_boost(codec);
9142 if (err < 0)
9143 return err;
9144
df694daa
KY
9145 return 1;
9146}
9147
9148#define alc262_auto_init_multi_out alc882_auto_init_multi_out
9149#define alc262_auto_init_hp_out alc882_auto_init_hp_out
9150#define alc262_auto_init_analog_input alc882_auto_init_analog_input
9151
9152
9153/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 9154static void alc262_auto_init(struct hda_codec *codec)
df694daa 9155{
f6c7e546 9156 struct alc_spec *spec = codec->spec;
df694daa
KY
9157 alc262_auto_init_multi_out(codec);
9158 alc262_auto_init_hp_out(codec);
9159 alc262_auto_init_analog_input(codec);
f6c7e546
TI
9160 if (spec->unsol_event)
9161 alc_sku_automute(codec);
df694daa
KY
9162}
9163
9164/*
9165 * configuration and preset
9166 */
f5fcc13c
TI
9167static const char *alc262_models[ALC262_MODEL_LAST] = {
9168 [ALC262_BASIC] = "basic",
9169 [ALC262_HIPPO] = "hippo",
9170 [ALC262_HIPPO_1] = "hippo_1",
9171 [ALC262_FUJITSU] = "fujitsu",
9172 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 9173 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 9174 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 9175 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 9176 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
9177 [ALC262_BENQ_T31] = "benq-t31",
9178 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 9179 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
9180 [ALC262_AUTO] = "auto",
9181};
9182
9183static struct snd_pci_quirk alc262_cfg_tbl[] = {
9184 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9185 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 9186 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
9187 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9188 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 9189 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 9190 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 9191 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 9192 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 9193 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9194 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9195 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9196 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9197 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9198 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9199 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9200 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
9201 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9202 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9203 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
9204 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9205 ALC262_HP_TC_T5735),
8c427226 9206 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 9207 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 9208 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 9209 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 9210 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
9211 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9212 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 9213 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 9214 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
9215 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9216 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9217 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
9218 {}
9219};
9220
9221static struct alc_config_preset alc262_presets[] = {
9222 [ALC262_BASIC] = {
9223 .mixers = { alc262_base_mixer },
9224 .init_verbs = { alc262_init_verbs },
9225 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9226 .dac_nids = alc262_dac_nids,
9227 .hp_nid = 0x03,
9228 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9229 .channel_mode = alc262_modes,
a3bcba38 9230 .input_mux = &alc262_capture_source,
df694daa 9231 },
ccc656ce
KY
9232 [ALC262_HIPPO] = {
9233 .mixers = { alc262_base_mixer },
9234 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9235 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9236 .dac_nids = alc262_dac_nids,
9237 .hp_nid = 0x03,
9238 .dig_out_nid = ALC262_DIGOUT_NID,
9239 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9240 .channel_mode = alc262_modes,
9241 .input_mux = &alc262_capture_source,
9242 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9243 .init_hook = alc262_hippo_automute,
ccc656ce
KY
9244 },
9245 [ALC262_HIPPO_1] = {
9246 .mixers = { alc262_hippo1_mixer },
9247 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9248 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9249 .dac_nids = alc262_dac_nids,
9250 .hp_nid = 0x02,
9251 .dig_out_nid = ALC262_DIGOUT_NID,
9252 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9253 .channel_mode = alc262_modes,
9254 .input_mux = &alc262_capture_source,
9255 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 9256 .init_hook = alc262_hippo1_automute,
ccc656ce 9257 },
834be88d
TI
9258 [ALC262_FUJITSU] = {
9259 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
9260 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9261 alc262_fujitsu_unsol_verbs },
834be88d
TI
9262 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9263 .dac_nids = alc262_dac_nids,
9264 .hp_nid = 0x03,
9265 .dig_out_nid = ALC262_DIGOUT_NID,
9266 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9267 .channel_mode = alc262_modes,
9268 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 9269 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 9270 },
9c7f852e
TI
9271 [ALC262_HP_BPC] = {
9272 .mixers = { alc262_HP_BPC_mixer },
9273 .init_verbs = { alc262_HP_BPC_init_verbs },
9274 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9275 .dac_nids = alc262_dac_nids,
9276 .hp_nid = 0x03,
9277 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9278 .channel_mode = alc262_modes,
9279 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
9280 .unsol_event = alc262_hp_bpc_unsol_event,
9281 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 9282 },
cd7509a4
KY
9283 [ALC262_HP_BPC_D7000_WF] = {
9284 .mixers = { alc262_HP_BPC_WildWest_mixer },
9285 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9286 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9287 .dac_nids = alc262_dac_nids,
9288 .hp_nid = 0x03,
9289 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9290 .channel_mode = alc262_modes,
accbe498 9291 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9292 .unsol_event = alc262_hp_wildwest_unsol_event,
9293 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9294 },
cd7509a4
KY
9295 [ALC262_HP_BPC_D7000_WL] = {
9296 .mixers = { alc262_HP_BPC_WildWest_mixer,
9297 alc262_HP_BPC_WildWest_option_mixer },
9298 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9299 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9300 .dac_nids = alc262_dac_nids,
9301 .hp_nid = 0x03,
9302 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9303 .channel_mode = alc262_modes,
accbe498 9304 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9305 .unsol_event = alc262_hp_wildwest_unsol_event,
9306 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9307 },
66d2a9d6
KY
9308 [ALC262_HP_TC_T5735] = {
9309 .mixers = { alc262_hp_t5735_mixer },
9310 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9311 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9312 .dac_nids = alc262_dac_nids,
9313 .hp_nid = 0x03,
9314 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9315 .channel_mode = alc262_modes,
9316 .input_mux = &alc262_capture_source,
9317 .unsol_event = alc262_hp_t5735_unsol_event,
9318 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
9319 },
9320 [ALC262_HP_RP5700] = {
9321 .mixers = { alc262_hp_rp5700_mixer },
9322 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9323 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9324 .dac_nids = alc262_dac_nids,
9325 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9326 .channel_mode = alc262_modes,
9327 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 9328 },
304dcaac
TI
9329 [ALC262_BENQ_ED8] = {
9330 .mixers = { alc262_base_mixer },
9331 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9332 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9333 .dac_nids = alc262_dac_nids,
9334 .hp_nid = 0x03,
9335 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9336 .channel_mode = alc262_modes,
9337 .input_mux = &alc262_capture_source,
f12ab1e0 9338 },
272a527c
KY
9339 [ALC262_SONY_ASSAMD] = {
9340 .mixers = { alc262_sony_mixer },
9341 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9342 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9343 .dac_nids = alc262_dac_nids,
9344 .hp_nid = 0x02,
9345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9346 .channel_mode = alc262_modes,
9347 .input_mux = &alc262_capture_source,
9348 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9349 .init_hook = alc262_hippo_automute,
83c34218
KY
9350 },
9351 [ALC262_BENQ_T31] = {
9352 .mixers = { alc262_benq_t31_mixer },
9353 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9354 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9355 .dac_nids = alc262_dac_nids,
9356 .hp_nid = 0x03,
9357 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9358 .channel_mode = alc262_modes,
9359 .input_mux = &alc262_capture_source,
9360 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9361 .init_hook = alc262_hippo_automute,
272a527c 9362 },
f651b50b
TD
9363 [ALC262_ULTRA] = {
9364 .mixers = { alc262_ultra_mixer },
9365 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9366 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9367 .dac_nids = alc262_dac_nids,
9368 .hp_nid = 0x03,
9369 .dig_out_nid = ALC262_DIGOUT_NID,
9370 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9371 .channel_mode = alc262_modes,
9372 .input_mux = &alc262_ultra_capture_source,
9373 .unsol_event = alc262_ultra_unsol_event,
9374 .init_hook = alc262_ultra_automute,
9375 },
df694daa
KY
9376};
9377
9378static int patch_alc262(struct hda_codec *codec)
9379{
9380 struct alc_spec *spec;
9381 int board_config;
9382 int err;
9383
dc041e0b 9384 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
9385 if (spec == NULL)
9386 return -ENOMEM;
9387
9388 codec->spec = spec;
9389#if 0
f12ab1e0
TI
9390 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9391 * under-run
9392 */
df694daa
KY
9393 {
9394 int tmp;
9395 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9396 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9397 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9398 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9399 }
9400#endif
9401
f5fcc13c
TI
9402 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9403 alc262_models,
9404 alc262_cfg_tbl);
cd7509a4 9405
f5fcc13c 9406 if (board_config < 0) {
9c7f852e
TI
9407 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9408 "trying auto-probe from BIOS...\n");
df694daa
KY
9409 board_config = ALC262_AUTO;
9410 }
9411
9412 if (board_config == ALC262_AUTO) {
9413 /* automatic parse from the BIOS config */
9414 err = alc262_parse_auto_config(codec);
9415 if (err < 0) {
9416 alc_free(codec);
9417 return err;
f12ab1e0 9418 } else if (!err) {
9c7f852e
TI
9419 printk(KERN_INFO
9420 "hda_codec: Cannot set up configuration "
9421 "from BIOS. Using base mode...\n");
df694daa
KY
9422 board_config = ALC262_BASIC;
9423 }
9424 }
9425
9426 if (board_config != ALC262_AUTO)
9427 setup_preset(spec, &alc262_presets[board_config]);
9428
9429 spec->stream_name_analog = "ALC262 Analog";
9430 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9431 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9432
9433 spec->stream_name_digital = "ALC262 Digital";
9434 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9435 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9436
f12ab1e0 9437 if (!spec->adc_nids && spec->input_mux) {
df694daa 9438 /* check whether NID 0x07 is valid */
4a471b7d
TI
9439 unsigned int wcap = get_wcaps(codec, 0x07);
9440
f12ab1e0
TI
9441 /* get type */
9442 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9443 if (wcap != AC_WID_AUD_IN) {
9444 spec->adc_nids = alc262_adc_nids_alt;
9445 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
f12ab1e0
TI
9446 spec->mixers[spec->num_mixers] =
9447 alc262_capture_alt_mixer;
df694daa
KY
9448 spec->num_mixers++;
9449 } else {
9450 spec->adc_nids = alc262_adc_nids;
9451 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9452 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9453 spec->num_mixers++;
9454 }
9455 }
9456
2134ea4f
TI
9457 spec->vmaster_nid = 0x0c;
9458
df694daa
KY
9459 codec->patch_ops = alc_patch_ops;
9460 if (board_config == ALC262_AUTO)
ae6b813a 9461 spec->init_hook = alc262_auto_init;
cb53c626
TI
9462#ifdef CONFIG_SND_HDA_POWER_SAVE
9463 if (!spec->loopback.amplist)
9464 spec->loopback.amplist = alc262_loopbacks;
9465#endif
834be88d 9466
df694daa
KY
9467 return 0;
9468}
9469
a361d84b
KY
9470/*
9471 * ALC268 channel source setting (2 channel)
9472 */
9473#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9474#define alc268_modes alc260_modes
9475
9476static hda_nid_t alc268_dac_nids[2] = {
9477 /* front, hp */
9478 0x02, 0x03
9479};
9480
9481static hda_nid_t alc268_adc_nids[2] = {
9482 /* ADC0-1 */
9483 0x08, 0x07
9484};
9485
9486static hda_nid_t alc268_adc_nids_alt[1] = {
9487 /* ADC0 */
9488 0x08
9489};
9490
e1406348
TI
9491static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9492
a361d84b
KY
9493static struct snd_kcontrol_new alc268_base_mixer[] = {
9494 /* output mixer control */
9495 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9496 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9497 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9498 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9499 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9500 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9501 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9502 { }
9503};
9504
d1a991a6
KY
9505static struct hda_verb alc268_eapd_verbs[] = {
9506 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9507 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9508 { }
9509};
9510
d273809e
TI
9511/* Toshiba specific */
9512#define alc268_toshiba_automute alc262_hippo_automute
9513
9514static struct hda_verb alc268_toshiba_verbs[] = {
9515 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9516 { } /* end */
9517};
9518
9519/* Acer specific */
889c4395 9520/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9521static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9522 .ops = &snd_hda_bind_vol,
9523 .values = {
9524 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9525 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9526 0
9527 },
9528};
9529
889c4395
TI
9530/* mute/unmute internal speaker according to the hp jack and mute state */
9531static void alc268_acer_automute(struct hda_codec *codec, int force)
9532{
9533 struct alc_spec *spec = codec->spec;
9534 unsigned int mute;
9535
9536 if (force || !spec->sense_updated) {
9537 unsigned int present;
9538 present = snd_hda_codec_read(codec, 0x14, 0,
9539 AC_VERB_GET_PIN_SENSE, 0);
9540 spec->jack_present = (present & 0x80000000) != 0;
9541 spec->sense_updated = 1;
9542 }
9543 if (spec->jack_present)
9544 mute = HDA_AMP_MUTE; /* mute internal speaker */
9545 else /* unmute internal speaker if necessary */
9546 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9547 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9548 HDA_AMP_MUTE, mute);
9549}
9550
9551
9552/* bind hp and internal speaker mute (with plug check) */
9553static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9554 struct snd_ctl_elem_value *ucontrol)
9555{
9556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9557 long *valp = ucontrol->value.integer.value;
9558 int change;
9559
9560 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9561 HDA_AMP_MUTE,
9562 valp[0] ? 0 : HDA_AMP_MUTE);
9563 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9564 HDA_AMP_MUTE,
9565 valp[1] ? 0 : HDA_AMP_MUTE);
9566 if (change)
9567 alc268_acer_automute(codec, 0);
9568 return change;
9569}
d273809e
TI
9570
9571static struct snd_kcontrol_new alc268_acer_mixer[] = {
9572 /* output mixer control */
9573 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9574 {
9575 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9576 .name = "Master Playback Switch",
9577 .info = snd_hda_mixer_amp_switch_info,
9578 .get = snd_hda_mixer_amp_switch_get,
9579 .put = alc268_acer_master_sw_put,
9580 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9581 },
33bf17ab
TI
9582 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9583 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9584 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9585 { }
9586};
9587
9588static struct hda_verb alc268_acer_verbs[] = {
9589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9591
9592 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9593 { }
9594};
9595
9596/* unsolicited event for HP jack sensing */
9597static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9598 unsigned int res)
9599{
889c4395 9600 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9601 return;
9602 alc268_toshiba_automute(codec);
9603}
9604
9605static void alc268_acer_unsol_event(struct hda_codec *codec,
9606 unsigned int res)
9607{
889c4395 9608 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9609 return;
9610 alc268_acer_automute(codec, 1);
9611}
9612
889c4395
TI
9613static void alc268_acer_init_hook(struct hda_codec *codec)
9614{
9615 alc268_acer_automute(codec, 1);
9616}
9617
3866f0b0
TI
9618static struct snd_kcontrol_new alc268_dell_mixer[] = {
9619 /* output mixer control */
9620 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9621 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9622 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9623 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9625 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9626 { }
9627};
9628
9629static struct hda_verb alc268_dell_verbs[] = {
9630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9631 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9633 { }
9634};
9635
9636/* mute/unmute internal speaker according to the hp jack and mute state */
9637static void alc268_dell_automute(struct hda_codec *codec)
9638{
9639 unsigned int present;
9640 unsigned int mute;
9641
9642 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9643 if (present & 0x80000000)
9644 mute = HDA_AMP_MUTE;
9645 else
9646 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9647 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9648 HDA_AMP_MUTE, mute);
9649}
9650
9651static void alc268_dell_unsol_event(struct hda_codec *codec,
9652 unsigned int res)
9653{
9654 if ((res >> 26) != ALC880_HP_EVENT)
9655 return;
9656 alc268_dell_automute(codec);
9657}
9658
9659#define alc268_dell_init_hook alc268_dell_automute
9660
a361d84b
KY
9661/*
9662 * generic initialization of ADC, input mixers and output mixers
9663 */
9664static struct hda_verb alc268_base_init_verbs[] = {
9665 /* Unmute DAC0-1 and set vol = 0 */
9666 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9667 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9670 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9671 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9672
9673 /*
9674 * Set up output mixers (0x0c - 0x0e)
9675 */
9676 /* set vol=0 to output mixers */
9677 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9678 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9679 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9680 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9681
9682 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684
9685 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9686 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9687 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9688 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9689 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9690 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9691 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9692 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9693
9694 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9700 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9701 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9702
a9b3aa8a
JZ
9703 /* Unmute Selector 23h,24h and set the default input to mic-in */
9704
9705 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9707 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9709
a361d84b
KY
9710 { }
9711};
9712
9713/*
9714 * generic initialization of ADC, input mixers and output mixers
9715 */
9716static struct hda_verb alc268_volume_init_verbs[] = {
9717 /* set output DAC */
9718 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9719 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9720 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9721 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9722
9723 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9724 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9725 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9726 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9727 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9728
9729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9731 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9732 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9733 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9734
9735 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9736 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9738 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9739
9740 /* set PCBEEP vol = 0 */
9741 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9742
9743 { }
9744};
9745
9746#define alc268_mux_enum_info alc_mux_enum_info
9747#define alc268_mux_enum_get alc_mux_enum_get
e1406348 9748#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
9749
9750static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9751 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9752 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9753 {
9754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9755 /* The multiple "Capture Source" controls confuse alsamixer
9756 * So call somewhat different..
a361d84b
KY
9757 */
9758 /* .name = "Capture Source", */
9759 .name = "Input Source",
9760 .count = 1,
9761 .info = alc268_mux_enum_info,
9762 .get = alc268_mux_enum_get,
9763 .put = alc268_mux_enum_put,
9764 },
9765 { } /* end */
9766};
9767
9768static struct snd_kcontrol_new alc268_capture_mixer[] = {
9769 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9770 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9771 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9772 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9773 {
9774 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9775 /* The multiple "Capture Source" controls confuse alsamixer
9776 * So call somewhat different..
a361d84b
KY
9777 */
9778 /* .name = "Capture Source", */
9779 .name = "Input Source",
9780 .count = 2,
9781 .info = alc268_mux_enum_info,
9782 .get = alc268_mux_enum_get,
9783 .put = alc268_mux_enum_put,
9784 },
9785 { } /* end */
9786};
9787
9788static struct hda_input_mux alc268_capture_source = {
9789 .num_items = 4,
9790 .items = {
9791 { "Mic", 0x0 },
9792 { "Front Mic", 0x1 },
9793 { "Line", 0x2 },
9794 { "CD", 0x3 },
9795 },
9796};
9797
86c53bd2
JW
9798#ifdef CONFIG_SND_DEBUG
9799static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
9800 /* Volume widgets */
9801 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9802 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9803 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9804 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9805 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9806 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9807 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9808 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9809 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9810 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9811 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9812 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9813 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
9814 /* The below appears problematic on some hardwares */
9815 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
9816 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9817 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9818 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9819 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9820
9821 /* Modes for retasking pin widgets */
9822 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9823 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9824 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9825 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9826
9827 /* Controls for GPIO pins, assuming they are configured as outputs */
9828 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9829 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9830 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9831 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9832
9833 /* Switches to allow the digital SPDIF output pin to be enabled.
9834 * The ALC268 does not have an SPDIF input.
9835 */
9836 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9837
9838 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9839 * this output to turn on an external amplifier.
9840 */
9841 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9842 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9843
9844 { } /* end */
9845};
9846#endif
9847
a361d84b
KY
9848/* create input playback/capture controls for the given pin */
9849static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9850 const char *ctlname, int idx)
9851{
9852 char name[32];
9853 int err;
9854
9855 sprintf(name, "%s Playback Volume", ctlname);
9856 if (nid == 0x14) {
9857 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9858 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9859 HDA_OUTPUT));
9860 if (err < 0)
9861 return err;
9862 } else if (nid == 0x15) {
9863 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9864 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9865 HDA_OUTPUT));
9866 if (err < 0)
9867 return err;
9868 } else
9869 return -1;
9870 sprintf(name, "%s Playback Switch", ctlname);
9871 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9872 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9873 if (err < 0)
9874 return err;
9875 return 0;
9876}
9877
9878/* add playback controls from the parsed DAC table */
9879static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9880 const struct auto_pin_cfg *cfg)
9881{
9882 hda_nid_t nid;
9883 int err;
9884
9885 spec->multiout.num_dacs = 2; /* only use one dac */
9886 spec->multiout.dac_nids = spec->private_dac_nids;
9887 spec->multiout.dac_nids[0] = 2;
9888 spec->multiout.dac_nids[1] = 3;
9889
9890 nid = cfg->line_out_pins[0];
9891 if (nid)
9892 alc268_new_analog_output(spec, nid, "Front", 0);
9893
9894 nid = cfg->speaker_pins[0];
9895 if (nid == 0x1d) {
9896 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9897 "Speaker Playback Volume",
9898 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9899 if (err < 0)
9900 return err;
9901 }
9902 nid = cfg->hp_pins[0];
9903 if (nid)
9904 alc268_new_analog_output(spec, nid, "Headphone", 0);
9905
9906 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9907 if (nid == 0x16) {
9908 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9909 "Mono Playback Switch",
9910 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9911 if (err < 0)
9912 return err;
9913 }
9914 return 0;
9915}
9916
9917/* create playback/capture controls for input pins */
9918static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9919 const struct auto_pin_cfg *cfg)
9920{
9921 struct hda_input_mux *imux = &spec->private_imux;
9922 int i, idx1;
9923
9924 for (i = 0; i < AUTO_PIN_LAST; i++) {
9925 switch(cfg->input_pins[i]) {
9926 case 0x18:
9927 idx1 = 0; /* Mic 1 */
9928 break;
9929 case 0x19:
9930 idx1 = 1; /* Mic 2 */
9931 break;
9932 case 0x1a:
9933 idx1 = 2; /* Line In */
9934 break;
9935 case 0x1c:
9936 idx1 = 3; /* CD */
9937 break;
9938 default:
9939 continue;
9940 }
9941 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9942 imux->items[imux->num_items].index = idx1;
9943 imux->num_items++;
9944 }
9945 return 0;
9946}
9947
9948static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9949{
9950 struct alc_spec *spec = codec->spec;
9951 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9952 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9953 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9954 unsigned int dac_vol1, dac_vol2;
9955
9956 if (speaker_nid) {
9957 snd_hda_codec_write(codec, speaker_nid, 0,
9958 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9959 snd_hda_codec_write(codec, 0x0f, 0,
9960 AC_VERB_SET_AMP_GAIN_MUTE,
9961 AMP_IN_UNMUTE(1));
9962 snd_hda_codec_write(codec, 0x10, 0,
9963 AC_VERB_SET_AMP_GAIN_MUTE,
9964 AMP_IN_UNMUTE(1));
9965 } else {
9966 snd_hda_codec_write(codec, 0x0f, 0,
9967 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9968 snd_hda_codec_write(codec, 0x10, 0,
9969 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9970 }
9971
9972 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
9973 if (line_nid == 0x14)
9974 dac_vol2 = AMP_OUT_ZERO;
9975 else if (line_nid == 0x15)
9976 dac_vol1 = AMP_OUT_ZERO;
9977 if (hp_nid == 0x14)
9978 dac_vol2 = AMP_OUT_ZERO;
9979 else if (hp_nid == 0x15)
9980 dac_vol1 = AMP_OUT_ZERO;
9981 if (line_nid != 0x16 || hp_nid != 0x16 ||
9982 spec->autocfg.line_out_pins[1] != 0x16 ||
9983 spec->autocfg.line_out_pins[2] != 0x16)
9984 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9985
9986 snd_hda_codec_write(codec, 0x02, 0,
9987 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9988 snd_hda_codec_write(codec, 0x03, 0,
9989 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9990}
9991
9992/* pcm configuration: identiacal with ALC880 */
9993#define alc268_pcm_analog_playback alc880_pcm_analog_playback
9994#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 9995#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
9996#define alc268_pcm_digital_playback alc880_pcm_digital_playback
9997
9998/*
9999 * BIOS auto configuration
10000 */
10001static int alc268_parse_auto_config(struct hda_codec *codec)
10002{
10003 struct alc_spec *spec = codec->spec;
10004 int err;
10005 static hda_nid_t alc268_ignore[] = { 0 };
10006
10007 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10008 alc268_ignore);
10009 if (err < 0)
10010 return err;
10011 if (!spec->autocfg.line_outs)
10012 return 0; /* can't find valid BIOS pin config */
10013
10014 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10015 if (err < 0)
10016 return err;
10017 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10018 if (err < 0)
10019 return err;
10020
10021 spec->multiout.max_channels = 2;
10022
10023 /* digital only support output */
10024 if (spec->autocfg.dig_out_pin)
10025 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10026
10027 if (spec->kctl_alloc)
10028 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10029
10030 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10031 spec->num_mux_defs = 1;
10032 spec->input_mux = &spec->private_imux;
10033
776e184e
TI
10034 err = alc_auto_add_mic_boost(codec);
10035 if (err < 0)
10036 return err;
10037
a361d84b
KY
10038 return 1;
10039}
10040
10041#define alc268_auto_init_multi_out alc882_auto_init_multi_out
10042#define alc268_auto_init_hp_out alc882_auto_init_hp_out
10043#define alc268_auto_init_analog_input alc882_auto_init_analog_input
10044
10045/* init callback for auto-configuration model -- overriding the default init */
10046static void alc268_auto_init(struct hda_codec *codec)
10047{
f6c7e546 10048 struct alc_spec *spec = codec->spec;
a361d84b
KY
10049 alc268_auto_init_multi_out(codec);
10050 alc268_auto_init_hp_out(codec);
10051 alc268_auto_init_mono_speaker_out(codec);
10052 alc268_auto_init_analog_input(codec);
f6c7e546
TI
10053 if (spec->unsol_event)
10054 alc_sku_automute(codec);
a361d84b
KY
10055}
10056
10057/*
10058 * configuration and preset
10059 */
10060static const char *alc268_models[ALC268_MODEL_LAST] = {
10061 [ALC268_3ST] = "3stack",
983f8ae4 10062 [ALC268_TOSHIBA] = "toshiba",
d273809e 10063 [ALC268_ACER] = "acer",
3866f0b0 10064 [ALC268_DELL] = "dell",
f12462c5 10065 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
10066#ifdef CONFIG_SND_DEBUG
10067 [ALC268_TEST] = "test",
10068#endif
a361d84b
KY
10069 [ALC268_AUTO] = "auto",
10070};
10071
10072static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741 10073 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 10074 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 10075 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 10076 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
3866f0b0 10077 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 10078 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 10079 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 10080 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 10081 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 10082 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
f12462c5 10083 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
10084 {}
10085};
10086
10087static struct alc_config_preset alc268_presets[] = {
10088 [ALC268_3ST] = {
10089 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10090 .init_verbs = { alc268_base_init_verbs },
10091 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10092 .dac_nids = alc268_dac_nids,
10093 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10094 .adc_nids = alc268_adc_nids_alt,
e1406348 10095 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
10096 .hp_nid = 0x03,
10097 .dig_out_nid = ALC268_DIGOUT_NID,
10098 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10099 .channel_mode = alc268_modes,
10100 .input_mux = &alc268_capture_source,
10101 },
d1a991a6
KY
10102 [ALC268_TOSHIBA] = {
10103 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
d273809e
TI
10104 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10105 alc268_toshiba_verbs },
d1a991a6
KY
10106 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10107 .dac_nids = alc268_dac_nids,
10108 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10109 .adc_nids = alc268_adc_nids_alt,
e1406348 10110 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
10111 .hp_nid = 0x03,
10112 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10113 .channel_mode = alc268_modes,
10114 .input_mux = &alc268_capture_source,
d273809e
TI
10115 .unsol_event = alc268_toshiba_unsol_event,
10116 .init_hook = alc268_toshiba_automute,
10117 },
10118 [ALC268_ACER] = {
10119 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
10120 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10121 alc268_acer_verbs },
10122 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10123 .dac_nids = alc268_dac_nids,
10124 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10125 .adc_nids = alc268_adc_nids_alt,
e1406348 10126 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
10127 .hp_nid = 0x02,
10128 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10129 .channel_mode = alc268_modes,
10130 .input_mux = &alc268_capture_source,
10131 .unsol_event = alc268_acer_unsol_event,
889c4395 10132 .init_hook = alc268_acer_init_hook,
d1a991a6 10133 },
3866f0b0
TI
10134 [ALC268_DELL] = {
10135 .mixers = { alc268_dell_mixer },
10136 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10137 alc268_dell_verbs },
10138 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10139 .dac_nids = alc268_dac_nids,
10140 .hp_nid = 0x02,
10141 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10142 .channel_mode = alc268_modes,
10143 .unsol_event = alc268_dell_unsol_event,
10144 .init_hook = alc268_dell_init_hook,
10145 .input_mux = &alc268_capture_source,
10146 },
f12462c5
MT
10147 [ALC268_ZEPTO] = {
10148 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10149 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10150 alc268_toshiba_verbs },
10151 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10152 .dac_nids = alc268_dac_nids,
10153 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10154 .adc_nids = alc268_adc_nids_alt,
e1406348 10155 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
10156 .hp_nid = 0x03,
10157 .dig_out_nid = ALC268_DIGOUT_NID,
10158 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10159 .channel_mode = alc268_modes,
10160 .input_mux = &alc268_capture_source,
10161 .unsol_event = alc268_toshiba_unsol_event,
10162 .init_hook = alc268_toshiba_automute
10163 },
86c53bd2
JW
10164#ifdef CONFIG_SND_DEBUG
10165 [ALC268_TEST] = {
10166 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10167 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10168 alc268_volume_init_verbs },
10169 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10170 .dac_nids = alc268_dac_nids,
10171 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10172 .adc_nids = alc268_adc_nids_alt,
e1406348 10173 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
10174 .hp_nid = 0x03,
10175 .dig_out_nid = ALC268_DIGOUT_NID,
10176 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10177 .channel_mode = alc268_modes,
10178 .input_mux = &alc268_capture_source,
10179 },
10180#endif
a361d84b
KY
10181};
10182
10183static int patch_alc268(struct hda_codec *codec)
10184{
10185 struct alc_spec *spec;
10186 int board_config;
10187 int err;
10188
10189 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10190 if (spec == NULL)
10191 return -ENOMEM;
10192
10193 codec->spec = spec;
10194
10195 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10196 alc268_models,
10197 alc268_cfg_tbl);
10198
10199 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10200 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10201 "trying auto-probe from BIOS...\n");
10202 board_config = ALC268_AUTO;
10203 }
10204
10205 if (board_config == ALC268_AUTO) {
10206 /* automatic parse from the BIOS config */
10207 err = alc268_parse_auto_config(codec);
10208 if (err < 0) {
10209 alc_free(codec);
10210 return err;
10211 } else if (!err) {
10212 printk(KERN_INFO
10213 "hda_codec: Cannot set up configuration "
10214 "from BIOS. Using base mode...\n");
10215 board_config = ALC268_3ST;
10216 }
10217 }
10218
10219 if (board_config != ALC268_AUTO)
10220 setup_preset(spec, &alc268_presets[board_config]);
10221
10222 spec->stream_name_analog = "ALC268 Analog";
10223 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10224 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 10225 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b
KY
10226
10227 spec->stream_name_digital = "ALC268 Digital";
10228 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10229
3866f0b0
TI
10230 if (!spec->adc_nids && spec->input_mux) {
10231 /* check whether NID 0x07 is valid */
10232 unsigned int wcap = get_wcaps(codec, 0x07);
10233
10234 /* get type */
10235 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10236 if (wcap != AC_WID_AUD_IN) {
10237 spec->adc_nids = alc268_adc_nids_alt;
10238 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10239 spec->mixers[spec->num_mixers] =
a361d84b 10240 alc268_capture_alt_mixer;
3866f0b0
TI
10241 spec->num_mixers++;
10242 } else {
10243 spec->adc_nids = alc268_adc_nids;
10244 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10245 spec->mixers[spec->num_mixers] =
10246 alc268_capture_mixer;
10247 spec->num_mixers++;
a361d84b 10248 }
e1406348 10249 spec->capsrc_nids = alc268_capsrc_nids;
a361d84b 10250 }
2134ea4f
TI
10251
10252 spec->vmaster_nid = 0x02;
10253
a361d84b
KY
10254 codec->patch_ops = alc_patch_ops;
10255 if (board_config == ALC268_AUTO)
10256 spec->init_hook = alc268_auto_init;
10257
10258 return 0;
10259}
10260
f6a92248
KY
10261/*
10262 * ALC269 channel source setting (2 channel)
10263 */
10264#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10265
10266#define alc269_dac_nids alc260_dac_nids
10267
10268static hda_nid_t alc269_adc_nids[1] = {
10269 /* ADC1 */
10270 0x07,
10271};
10272
10273#define alc269_modes alc260_modes
10274#define alc269_capture_source alc880_lg_lw_capture_source
10275
10276static struct snd_kcontrol_new alc269_base_mixer[] = {
10277 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10278 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10280 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10283 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10284 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10286 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10287 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10288 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10289 { } /* end */
10290};
10291
10292/* capture mixer elements */
10293static struct snd_kcontrol_new alc269_capture_mixer[] = {
10294 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10295 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10296 {
10297 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10298 /* The multiple "Capture Source" controls confuse alsamixer
10299 * So call somewhat different..
f6a92248
KY
10300 */
10301 /* .name = "Capture Source", */
10302 .name = "Input Source",
10303 .count = 1,
10304 .info = alc_mux_enum_info,
10305 .get = alc_mux_enum_get,
10306 .put = alc_mux_enum_put,
10307 },
10308 { } /* end */
10309};
10310
10311/*
10312 * generic initialization of ADC, input mixers and output mixers
10313 */
10314static struct hda_verb alc269_init_verbs[] = {
10315 /*
10316 * Unmute ADC0 and set the default input to mic-in
10317 */
10318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10319
10320 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10321 * analog-loopback mixer widget
10322 * Note: PASD motherboards uses the Line In 2 as the input for
10323 * front panel mic (mic 2)
10324 */
10325 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10327 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10329 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10330 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10331
10332 /*
10333 * Set up output mixers (0x0c - 0x0e)
10334 */
10335 /* set vol=0 to output mixers */
10336 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10337 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10338
10339 /* set up input amps for analog loopback */
10340 /* Amp Indices: DAC = 0, mixer = 1 */
10341 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10343 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10344 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10345 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10346 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10347
10348 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10349 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10350 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10352 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10353 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10354 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10355
10356 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10357 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10358 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10359 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10361 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10362 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10363
10364 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10366
10367 /* FIXME: use matrix-type input source selection */
10368 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10369 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10372 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10373 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10374
10375 /* set EAPD */
10376 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10377 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10378 { }
10379};
10380
10381/* add playback controls from the parsed DAC table */
10382static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10383 const struct auto_pin_cfg *cfg)
10384{
10385 hda_nid_t nid;
10386 int err;
10387
10388 spec->multiout.num_dacs = 1; /* only use one dac */
10389 spec->multiout.dac_nids = spec->private_dac_nids;
10390 spec->multiout.dac_nids[0] = 2;
10391
10392 nid = cfg->line_out_pins[0];
10393 if (nid) {
10394 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10395 "Front Playback Volume",
10396 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10397 if (err < 0)
10398 return err;
10399 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10400 "Front Playback Switch",
10401 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10402 if (err < 0)
10403 return err;
10404 }
10405
10406 nid = cfg->speaker_pins[0];
10407 if (nid) {
10408 if (!cfg->line_out_pins[0]) {
10409 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10410 "Speaker Playback Volume",
10411 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10412 HDA_OUTPUT));
10413 if (err < 0)
10414 return err;
10415 }
10416 if (nid == 0x16) {
10417 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10418 "Speaker Playback Switch",
10419 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10420 HDA_OUTPUT));
10421 if (err < 0)
10422 return err;
10423 } else {
10424 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10425 "Speaker Playback Switch",
10426 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10427 HDA_OUTPUT));
10428 if (err < 0)
10429 return err;
10430 }
10431 }
10432 nid = cfg->hp_pins[0];
10433 if (nid) {
10434 /* spec->multiout.hp_nid = 2; */
10435 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10436 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10437 "Headphone Playback Volume",
10438 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10439 HDA_OUTPUT));
10440 if (err < 0)
10441 return err;
10442 }
10443 if (nid == 0x16) {
10444 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10445 "Headphone Playback Switch",
10446 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10447 HDA_OUTPUT));
10448 if (err < 0)
10449 return err;
10450 } else {
10451 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10452 "Headphone Playback Switch",
10453 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10454 HDA_OUTPUT));
10455 if (err < 0)
10456 return err;
10457 }
10458 }
10459 return 0;
10460}
10461
10462#define alc269_auto_create_analog_input_ctls \
10463 alc880_auto_create_analog_input_ctls
10464
10465#ifdef CONFIG_SND_HDA_POWER_SAVE
10466#define alc269_loopbacks alc880_loopbacks
10467#endif
10468
10469/* pcm configuration: identiacal with ALC880 */
10470#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10471#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10472#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10473#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10474
10475/*
10476 * BIOS auto configuration
10477 */
10478static int alc269_parse_auto_config(struct hda_codec *codec)
10479{
10480 struct alc_spec *spec = codec->spec;
10481 int err;
10482 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10483
10484 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10485 alc269_ignore);
10486 if (err < 0)
10487 return err;
10488
10489 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10490 if (err < 0)
10491 return err;
10492 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10493 if (err < 0)
10494 return err;
10495
10496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10497
10498 if (spec->autocfg.dig_out_pin)
10499 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10500
10501 if (spec->kctl_alloc)
10502 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10503
10504 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10505 spec->num_mux_defs = 1;
10506 spec->input_mux = &spec->private_imux;
10507
10508 err = alc_auto_add_mic_boost(codec);
10509 if (err < 0)
10510 return err;
10511
10512 return 1;
10513}
10514
10515#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10516#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10517#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10518
10519
10520/* init callback for auto-configuration model -- overriding the default init */
10521static void alc269_auto_init(struct hda_codec *codec)
10522{
f6c7e546 10523 struct alc_spec *spec = codec->spec;
f6a92248
KY
10524 alc269_auto_init_multi_out(codec);
10525 alc269_auto_init_hp_out(codec);
10526 alc269_auto_init_analog_input(codec);
f6c7e546
TI
10527 if (spec->unsol_event)
10528 alc_sku_automute(codec);
f6a92248
KY
10529}
10530
10531/*
10532 * configuration and preset
10533 */
10534static const char *alc269_models[ALC269_MODEL_LAST] = {
10535 [ALC269_BASIC] = "basic",
10536};
10537
10538static struct snd_pci_quirk alc269_cfg_tbl[] = {
10539 {}
10540};
10541
10542static struct alc_config_preset alc269_presets[] = {
10543 [ALC269_BASIC] = {
10544 .mixers = { alc269_base_mixer },
10545 .init_verbs = { alc269_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10547 .dac_nids = alc269_dac_nids,
10548 .hp_nid = 0x03,
10549 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10550 .channel_mode = alc269_modes,
10551 .input_mux = &alc269_capture_source,
10552 },
10553};
10554
10555static int patch_alc269(struct hda_codec *codec)
10556{
10557 struct alc_spec *spec;
10558 int board_config;
10559 int err;
10560
10561 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10562 if (spec == NULL)
10563 return -ENOMEM;
10564
10565 codec->spec = spec;
10566
10567 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10568 alc269_models,
10569 alc269_cfg_tbl);
10570
10571 if (board_config < 0) {
10572 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10573 "trying auto-probe from BIOS...\n");
10574 board_config = ALC269_AUTO;
10575 }
10576
10577 if (board_config == ALC269_AUTO) {
10578 /* automatic parse from the BIOS config */
10579 err = alc269_parse_auto_config(codec);
10580 if (err < 0) {
10581 alc_free(codec);
10582 return err;
10583 } else if (!err) {
10584 printk(KERN_INFO
10585 "hda_codec: Cannot set up configuration "
10586 "from BIOS. Using base mode...\n");
10587 board_config = ALC269_BASIC;
10588 }
10589 }
10590
10591 if (board_config != ALC269_AUTO)
10592 setup_preset(spec, &alc269_presets[board_config]);
10593
10594 spec->stream_name_analog = "ALC269 Analog";
10595 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10596 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10597
10598 spec->stream_name_digital = "ALC269 Digital";
10599 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10600 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10601
10602 spec->adc_nids = alc269_adc_nids;
10603 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10604 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10605 spec->num_mixers++;
10606
10607 codec->patch_ops = alc_patch_ops;
10608 if (board_config == ALC269_AUTO)
10609 spec->init_hook = alc269_auto_init;
10610#ifdef CONFIG_SND_HDA_POWER_SAVE
10611 if (!spec->loopback.amplist)
10612 spec->loopback.amplist = alc269_loopbacks;
10613#endif
10614
10615 return 0;
10616}
10617
df694daa
KY
10618/*
10619 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10620 */
10621
10622/*
10623 * set the path ways for 2 channel output
10624 * need to set the codec line out and mic 1 pin widgets to inputs
10625 */
10626static struct hda_verb alc861_threestack_ch2_init[] = {
10627 /* set pin widget 1Ah (line in) for input */
10628 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10629 /* set pin widget 18h (mic1/2) for input, for mic also enable
10630 * the vref
10631 */
df694daa
KY
10632 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10633
9c7f852e
TI
10634 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10635#if 0
10636 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10637 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10638#endif
df694daa
KY
10639 { } /* end */
10640};
10641/*
10642 * 6ch mode
10643 * need to set the codec line out and mic 1 pin widgets to outputs
10644 */
10645static struct hda_verb alc861_threestack_ch6_init[] = {
10646 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10647 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10648 /* set pin widget 18h (mic1) for output (CLFE)*/
10649 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10650
10651 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10652 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10653
9c7f852e
TI
10654 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10655#if 0
10656 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10657 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10658#endif
df694daa
KY
10659 { } /* end */
10660};
10661
10662static struct hda_channel_mode alc861_threestack_modes[2] = {
10663 { 2, alc861_threestack_ch2_init },
10664 { 6, alc861_threestack_ch6_init },
10665};
22309c3e
TI
10666/* Set mic1 as input and unmute the mixer */
10667static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10668 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10669 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10670 { } /* end */
10671};
10672/* Set mic1 as output and mute mixer */
10673static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10674 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10675 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10676 { } /* end */
10677};
10678
10679static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10680 { 2, alc861_uniwill_m31_ch2_init },
10681 { 4, alc861_uniwill_m31_ch4_init },
10682};
df694daa 10683
7cdbff94
MD
10684/* Set mic1 and line-in as input and unmute the mixer */
10685static struct hda_verb alc861_asus_ch2_init[] = {
10686 /* set pin widget 1Ah (line in) for input */
10687 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10688 /* set pin widget 18h (mic1/2) for input, for mic also enable
10689 * the vref
10690 */
7cdbff94
MD
10691 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10692
10693 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10694#if 0
10695 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10696 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10697#endif
10698 { } /* end */
10699};
10700/* Set mic1 nad line-in as output and mute mixer */
10701static struct hda_verb alc861_asus_ch6_init[] = {
10702 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10703 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10704 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10705 /* set pin widget 18h (mic1) for output (CLFE)*/
10706 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10707 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10708 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10709 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10710
10711 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10712#if 0
10713 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10714 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10715#endif
10716 { } /* end */
10717};
10718
10719static struct hda_channel_mode alc861_asus_modes[2] = {
10720 { 2, alc861_asus_ch2_init },
10721 { 6, alc861_asus_ch6_init },
10722};
10723
df694daa
KY
10724/* patch-ALC861 */
10725
10726static struct snd_kcontrol_new alc861_base_mixer[] = {
10727 /* output mixer control */
10728 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10729 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10730 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10731 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10732 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10733
10734 /*Input mixer control */
10735 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10736 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10737 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10738 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10739 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10740 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10742 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10743 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10744 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10745
df694daa
KY
10746 /* Capture mixer control */
10747 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10748 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10749 {
10750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10751 .name = "Capture Source",
10752 .count = 1,
10753 .info = alc_mux_enum_info,
10754 .get = alc_mux_enum_get,
10755 .put = alc_mux_enum_put,
10756 },
10757 { } /* end */
10758};
10759
10760static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10761 /* output mixer control */
10762 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10763 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10764 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10765 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10766 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10767
10768 /* Input mixer control */
10769 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10770 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10771 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10772 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10773 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10774 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10776 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10777 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10779
df694daa
KY
10780 /* Capture mixer control */
10781 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10782 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10783 {
10784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10785 .name = "Capture Source",
10786 .count = 1,
10787 .info = alc_mux_enum_info,
10788 .get = alc_mux_enum_get,
10789 .put = alc_mux_enum_put,
10790 },
10791 {
10792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10793 .name = "Channel Mode",
10794 .info = alc_ch_mode_info,
10795 .get = alc_ch_mode_get,
10796 .put = alc_ch_mode_put,
10797 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10798 },
10799 { } /* end */
a53d1aec
TD
10800};
10801
d1d985f0 10802static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10803 /* output mixer control */
10804 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10805 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10806 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10807
10808 /*Capture mixer control */
10809 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10810 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10811 {
10812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10813 .name = "Capture Source",
10814 .count = 1,
10815 .info = alc_mux_enum_info,
10816 .get = alc_mux_enum_get,
10817 .put = alc_mux_enum_put,
10818 },
10819
10820 { } /* end */
f12ab1e0 10821};
a53d1aec 10822
22309c3e
TI
10823static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10824 /* output mixer control */
10825 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10826 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10827 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10828 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10829 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10830
10831 /* Input mixer control */
10832 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10833 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10834 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10835 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10836 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10837 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10838 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10839 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10840 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10842
22309c3e
TI
10843 /* Capture mixer control */
10844 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10845 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10846 {
10847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10848 .name = "Capture Source",
10849 .count = 1,
10850 .info = alc_mux_enum_info,
10851 .get = alc_mux_enum_get,
10852 .put = alc_mux_enum_put,
10853 },
10854 {
10855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10856 .name = "Channel Mode",
10857 .info = alc_ch_mode_info,
10858 .get = alc_ch_mode_get,
10859 .put = alc_ch_mode_put,
10860 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10861 },
10862 { } /* end */
f12ab1e0 10863};
7cdbff94
MD
10864
10865static struct snd_kcontrol_new alc861_asus_mixer[] = {
10866 /* output mixer control */
10867 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10868 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10869 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10870 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10871 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10872
10873 /* Input mixer control */
10874 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10875 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10876 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10877 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10878 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10879 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10881 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
10883 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10884
7cdbff94
MD
10885 /* Capture mixer control */
10886 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10887 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10888 {
10889 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10890 .name = "Capture Source",
10891 .count = 1,
10892 .info = alc_mux_enum_info,
10893 .get = alc_mux_enum_get,
10894 .put = alc_mux_enum_put,
10895 },
10896 {
10897 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10898 .name = "Channel Mode",
10899 .info = alc_ch_mode_info,
10900 .get = alc_ch_mode_get,
10901 .put = alc_ch_mode_put,
10902 .private_value = ARRAY_SIZE(alc861_asus_modes),
10903 },
10904 { }
56bb0cab
TI
10905};
10906
10907/* additional mixer */
d1d985f0 10908static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
10909 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10910 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10911 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10912 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10913 { }
10914};
7cdbff94 10915
df694daa
KY
10916/*
10917 * generic initialization of ADC, input mixers and output mixers
10918 */
10919static struct hda_verb alc861_base_init_verbs[] = {
10920 /*
10921 * Unmute ADC0 and set the default input to mic-in
10922 */
10923 /* port-A for surround (rear panel) */
10924 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10925 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10926 /* port-B for mic-in (rear panel) with vref */
10927 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10928 /* port-C for line-in (rear panel) */
10929 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10930 /* port-D for Front */
10931 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10932 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10933 /* port-E for HP out (front panel) */
10934 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10935 /* route front PCM to HP */
9dece1d7 10936 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10937 /* port-F for mic-in (front panel) with vref */
10938 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10939 /* port-G for CLFE (rear panel) */
10940 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10941 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10942 /* port-H for side (rear panel) */
10943 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10944 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10945 /* CD-in */
10946 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10947 /* route front mic to ADC1*/
10948 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10949 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10950
10951 /* Unmute DAC0~3 & spdif out*/
10952 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10953 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10954 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10955 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10956 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10957
10958 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10959 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10960 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10961 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10962 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10963
10964 /* Unmute Stereo Mixer 15 */
10965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 10968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
10969
10970 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10971 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10972 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10974 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10975 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10976 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10977 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
10978 /* hp used DAC 3 (Front) */
10979 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
10980 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10981
10982 { }
10983};
10984
10985static struct hda_verb alc861_threestack_init_verbs[] = {
10986 /*
10987 * Unmute ADC0 and set the default input to mic-in
10988 */
10989 /* port-A for surround (rear panel) */
10990 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10991 /* port-B for mic-in (rear panel) with vref */
10992 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10993 /* port-C for line-in (rear panel) */
10994 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10995 /* port-D for Front */
10996 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10997 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10998 /* port-E for HP out (front panel) */
10999 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11000 /* route front PCM to HP */
9dece1d7 11001 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11002 /* port-F for mic-in (front panel) with vref */
11003 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11004 /* port-G for CLFE (rear panel) */
11005 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11006 /* port-H for side (rear panel) */
11007 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11008 /* CD-in */
11009 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11010 /* route front mic to ADC1*/
11011 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11013 /* Unmute DAC0~3 & spdif out*/
11014 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11016 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11017 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11019
11020 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11021 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11022 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11023 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11024 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11025
11026 /* Unmute Stereo Mixer 15 */
11027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11028 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11029 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11031
11032 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11033 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11034 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11035 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11036 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11038 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11039 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11040 /* hp used DAC 3 (Front) */
11041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11042 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11043 { }
11044};
22309c3e
TI
11045
11046static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11047 /*
11048 * Unmute ADC0 and set the default input to mic-in
11049 */
11050 /* port-A for surround (rear panel) */
11051 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11052 /* port-B for mic-in (rear panel) with vref */
11053 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11054 /* port-C for line-in (rear panel) */
11055 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11056 /* port-D for Front */
11057 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11058 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11059 /* port-E for HP out (front panel) */
f12ab1e0
TI
11060 /* this has to be set to VREF80 */
11061 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 11062 /* route front PCM to HP */
9dece1d7 11063 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
11064 /* port-F for mic-in (front panel) with vref */
11065 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11066 /* port-G for CLFE (rear panel) */
11067 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11068 /* port-H for side (rear panel) */
11069 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11070 /* CD-in */
11071 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11072 /* route front mic to ADC1*/
11073 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11075 /* Unmute DAC0~3 & spdif out*/
11076 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11077 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11078 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11079 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11081
11082 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11083 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11085 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11086 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11087
11088 /* Unmute Stereo Mixer 15 */
11089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
11093
11094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11095 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11096 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11097 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11100 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11101 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11102 /* hp used DAC 3 (Front) */
11103 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
11104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11105 { }
11106};
11107
7cdbff94
MD
11108static struct hda_verb alc861_asus_init_verbs[] = {
11109 /*
11110 * Unmute ADC0 and set the default input to mic-in
11111 */
f12ab1e0
TI
11112 /* port-A for surround (rear panel)
11113 * according to codec#0 this is the HP jack
11114 */
7cdbff94
MD
11115 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11116 /* route front PCM to HP */
11117 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11118 /* port-B for mic-in (rear panel) with vref */
11119 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11120 /* port-C for line-in (rear panel) */
11121 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11122 /* port-D for Front */
11123 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11124 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11125 /* port-E for HP out (front panel) */
f12ab1e0
TI
11126 /* this has to be set to VREF80 */
11127 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 11128 /* route front PCM to HP */
9dece1d7 11129 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
11130 /* port-F for mic-in (front panel) with vref */
11131 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11132 /* port-G for CLFE (rear panel) */
11133 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11134 /* port-H for side (rear panel) */
11135 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11136 /* CD-in */
11137 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11138 /* route front mic to ADC1*/
11139 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11140 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11141 /* Unmute DAC0~3 & spdif out*/
11142 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11143 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11144 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11145 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11146 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11147 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11148 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11149 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11150 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11151 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11152
11153 /* Unmute Stereo Mixer 15 */
11154 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11157 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
11158
11159 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11161 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11162 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11163 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11164 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11165 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11166 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11167 /* hp used DAC 3 (Front) */
11168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
11169 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11170 { }
11171};
11172
56bb0cab
TI
11173/* additional init verbs for ASUS laptops */
11174static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11175 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11176 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11177 { }
11178};
7cdbff94 11179
df694daa
KY
11180/*
11181 * generic initialization of ADC, input mixers and output mixers
11182 */
11183static struct hda_verb alc861_auto_init_verbs[] = {
11184 /*
11185 * Unmute ADC0 and set the default input to mic-in
11186 */
f12ab1e0 11187 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
11188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11189
11190 /* Unmute DAC0~3 & spdif out*/
11191 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11192 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11193 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11194 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11196
11197 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11198 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11199 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11200 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11202
11203 /* Unmute Stereo Mixer 15 */
11204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11208
11209 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11210 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11212 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11214 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11215 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11217
11218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11220 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11221 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11223 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11224 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11225 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 11226
f12ab1e0 11227 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
11228
11229 { }
11230};
11231
a53d1aec
TD
11232static struct hda_verb alc861_toshiba_init_verbs[] = {
11233 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 11234
a53d1aec
TD
11235 { }
11236};
11237
11238/* toggle speaker-output according to the hp-jack state */
11239static void alc861_toshiba_automute(struct hda_codec *codec)
11240{
11241 unsigned int present;
11242
11243 present = snd_hda_codec_read(codec, 0x0f, 0,
11244 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11245 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11246 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11247 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11248 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
11249}
11250
11251static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11252 unsigned int res)
11253{
a53d1aec
TD
11254 if ((res >> 26) == ALC880_HP_EVENT)
11255 alc861_toshiba_automute(codec);
11256}
11257
df694daa
KY
11258/* pcm configuration: identiacal with ALC880 */
11259#define alc861_pcm_analog_playback alc880_pcm_analog_playback
11260#define alc861_pcm_analog_capture alc880_pcm_analog_capture
11261#define alc861_pcm_digital_playback alc880_pcm_digital_playback
11262#define alc861_pcm_digital_capture alc880_pcm_digital_capture
11263
11264
11265#define ALC861_DIGOUT_NID 0x07
11266
11267static struct hda_channel_mode alc861_8ch_modes[1] = {
11268 { 8, NULL }
11269};
11270
11271static hda_nid_t alc861_dac_nids[4] = {
11272 /* front, surround, clfe, side */
11273 0x03, 0x06, 0x05, 0x04
11274};
11275
9c7f852e
TI
11276static hda_nid_t alc660_dac_nids[3] = {
11277 /* front, clfe, surround */
11278 0x03, 0x05, 0x06
11279};
11280
df694daa
KY
11281static hda_nid_t alc861_adc_nids[1] = {
11282 /* ADC0-2 */
11283 0x08,
11284};
11285
11286static struct hda_input_mux alc861_capture_source = {
11287 .num_items = 5,
11288 .items = {
11289 { "Mic", 0x0 },
11290 { "Front Mic", 0x3 },
11291 { "Line", 0x1 },
11292 { "CD", 0x4 },
11293 { "Mixer", 0x5 },
11294 },
11295};
11296
11297/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
11298static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11299 const struct auto_pin_cfg *cfg)
df694daa
KY
11300{
11301 int i;
11302 hda_nid_t nid;
11303
11304 spec->multiout.dac_nids = spec->private_dac_nids;
11305 for (i = 0; i < cfg->line_outs; i++) {
11306 nid = cfg->line_out_pins[i];
11307 if (nid) {
11308 if (i >= ARRAY_SIZE(alc861_dac_nids))
11309 continue;
11310 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11311 }
11312 }
11313 spec->multiout.num_dacs = cfg->line_outs;
11314 return 0;
11315}
11316
11317/* add playback controls from the parsed DAC table */
11318static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11319 const struct auto_pin_cfg *cfg)
11320{
11321 char name[32];
f12ab1e0
TI
11322 static const char *chname[4] = {
11323 "Front", "Surround", NULL /*CLFE*/, "Side"
11324 };
df694daa
KY
11325 hda_nid_t nid;
11326 int i, idx, err;
11327
11328 for (i = 0; i < cfg->line_outs; i++) {
11329 nid = spec->multiout.dac_nids[i];
f12ab1e0 11330 if (!nid)
df694daa
KY
11331 continue;
11332 if (nid == 0x05) {
11333 /* Center/LFE */
f12ab1e0
TI
11334 err = add_control(spec, ALC_CTL_BIND_MUTE,
11335 "Center Playback Switch",
11336 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11337 HDA_OUTPUT));
11338 if (err < 0)
df694daa 11339 return err;
f12ab1e0
TI
11340 err = add_control(spec, ALC_CTL_BIND_MUTE,
11341 "LFE Playback Switch",
11342 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11343 HDA_OUTPUT));
11344 if (err < 0)
df694daa
KY
11345 return err;
11346 } else {
f12ab1e0
TI
11347 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11348 idx++)
df694daa
KY
11349 if (nid == alc861_dac_nids[idx])
11350 break;
11351 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
11352 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11353 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11354 HDA_OUTPUT));
11355 if (err < 0)
df694daa
KY
11356 return err;
11357 }
11358 }
11359 return 0;
11360}
11361
11362static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11363{
11364 int err;
11365 hda_nid_t nid;
11366
f12ab1e0 11367 if (!pin)
df694daa
KY
11368 return 0;
11369
11370 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11371 nid = 0x03;
f12ab1e0
TI
11372 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11373 "Headphone Playback Switch",
11374 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11375 if (err < 0)
df694daa
KY
11376 return err;
11377 spec->multiout.hp_nid = nid;
11378 }
11379 return 0;
11380}
11381
11382/* create playback/capture controls for input pins */
f12ab1e0
TI
11383static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11384 const struct auto_pin_cfg *cfg)
df694daa 11385{
df694daa
KY
11386 struct hda_input_mux *imux = &spec->private_imux;
11387 int i, err, idx, idx1;
11388
11389 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 11390 switch (cfg->input_pins[i]) {
df694daa
KY
11391 case 0x0c:
11392 idx1 = 1;
f12ab1e0 11393 idx = 2; /* Line In */
df694daa
KY
11394 break;
11395 case 0x0f:
11396 idx1 = 2;
f12ab1e0 11397 idx = 2; /* Line In */
df694daa
KY
11398 break;
11399 case 0x0d:
11400 idx1 = 0;
f12ab1e0 11401 idx = 1; /* Mic In */
df694daa 11402 break;
f12ab1e0 11403 case 0x10:
df694daa 11404 idx1 = 3;
f12ab1e0 11405 idx = 1; /* Mic In */
df694daa
KY
11406 break;
11407 case 0x11:
11408 idx1 = 4;
f12ab1e0 11409 idx = 0; /* CD */
df694daa
KY
11410 break;
11411 default:
11412 continue;
11413 }
11414
4a471b7d
TI
11415 err = new_analog_input(spec, cfg->input_pins[i],
11416 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
11417 if (err < 0)
11418 return err;
11419
4a471b7d 11420 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 11421 imux->items[imux->num_items].index = idx1;
f12ab1e0 11422 imux->num_items++;
df694daa
KY
11423 }
11424 return 0;
11425}
11426
11427static struct snd_kcontrol_new alc861_capture_mixer[] = {
11428 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11429 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11430
11431 {
11432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11433 /* The multiple "Capture Source" controls confuse alsamixer
11434 * So call somewhat different..
df694daa
KY
11435 */
11436 /* .name = "Capture Source", */
11437 .name = "Input Source",
11438 .count = 1,
11439 .info = alc_mux_enum_info,
11440 .get = alc_mux_enum_get,
11441 .put = alc_mux_enum_put,
11442 },
11443 { } /* end */
11444};
11445
f12ab1e0
TI
11446static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11447 hda_nid_t nid,
df694daa
KY
11448 int pin_type, int dac_idx)
11449{
f6c7e546 11450 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
11451}
11452
11453static void alc861_auto_init_multi_out(struct hda_codec *codec)
11454{
11455 struct alc_spec *spec = codec->spec;
11456 int i;
11457
bc9f98a9 11458 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
11459 for (i = 0; i < spec->autocfg.line_outs; i++) {
11460 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11461 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 11462 if (nid)
baba8ee9 11463 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11464 spec->multiout.dac_nids[i]);
df694daa
KY
11465 }
11466}
11467
11468static void alc861_auto_init_hp_out(struct hda_codec *codec)
11469{
11470 struct alc_spec *spec = codec->spec;
11471 hda_nid_t pin;
11472
eb06ed8f 11473 pin = spec->autocfg.hp_pins[0];
df694daa 11474 if (pin) /* connect to front */
f12ab1e0
TI
11475 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11476 spec->multiout.dac_nids[0]);
f6c7e546
TI
11477 pin = spec->autocfg.speaker_pins[0];
11478 if (pin)
11479 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
11480}
11481
11482static void alc861_auto_init_analog_input(struct hda_codec *codec)
11483{
11484 struct alc_spec *spec = codec->spec;
11485 int i;
11486
11487 for (i = 0; i < AUTO_PIN_LAST; i++) {
11488 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11489 if (nid >= 0x0c && nid <= 0x11) {
11490 snd_hda_codec_write(codec, nid, 0,
11491 AC_VERB_SET_PIN_WIDGET_CONTROL,
11492 i <= AUTO_PIN_FRONT_MIC ?
11493 PIN_VREF80 : PIN_IN);
df694daa
KY
11494 }
11495 }
11496}
11497
11498/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11499/* return 1 if successful, 0 if the proper config is not found,
11500 * or a negative error code
11501 */
df694daa
KY
11502static int alc861_parse_auto_config(struct hda_codec *codec)
11503{
11504 struct alc_spec *spec = codec->spec;
11505 int err;
11506 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11507
f12ab1e0
TI
11508 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11509 alc861_ignore);
11510 if (err < 0)
df694daa 11511 return err;
f12ab1e0 11512 if (!spec->autocfg.line_outs)
df694daa
KY
11513 return 0; /* can't find valid BIOS pin config */
11514
f12ab1e0
TI
11515 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11516 if (err < 0)
11517 return err;
11518 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11519 if (err < 0)
11520 return err;
11521 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11522 if (err < 0)
11523 return err;
11524 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11525 if (err < 0)
df694daa
KY
11526 return err;
11527
11528 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11529
11530 if (spec->autocfg.dig_out_pin)
11531 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11532
11533 if (spec->kctl_alloc)
11534 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11535
11536 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11537
a1e8d2da 11538 spec->num_mux_defs = 1;
df694daa
KY
11539 spec->input_mux = &spec->private_imux;
11540
11541 spec->adc_nids = alc861_adc_nids;
11542 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11543 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11544 spec->num_mixers++;
11545
11546 return 1;
11547}
11548
ae6b813a
TI
11549/* additional initialization for auto-configuration model */
11550static void alc861_auto_init(struct hda_codec *codec)
df694daa 11551{
f6c7e546 11552 struct alc_spec *spec = codec->spec;
df694daa
KY
11553 alc861_auto_init_multi_out(codec);
11554 alc861_auto_init_hp_out(codec);
11555 alc861_auto_init_analog_input(codec);
f6c7e546
TI
11556 if (spec->unsol_event)
11557 alc_sku_automute(codec);
df694daa
KY
11558}
11559
cb53c626
TI
11560#ifdef CONFIG_SND_HDA_POWER_SAVE
11561static struct hda_amp_list alc861_loopbacks[] = {
11562 { 0x15, HDA_INPUT, 0 },
11563 { 0x15, HDA_INPUT, 1 },
11564 { 0x15, HDA_INPUT, 2 },
11565 { 0x15, HDA_INPUT, 3 },
11566 { } /* end */
11567};
11568#endif
11569
df694daa
KY
11570
11571/*
11572 * configuration and preset
11573 */
f5fcc13c
TI
11574static const char *alc861_models[ALC861_MODEL_LAST] = {
11575 [ALC861_3ST] = "3stack",
11576 [ALC660_3ST] = "3stack-660",
11577 [ALC861_3ST_DIG] = "3stack-dig",
11578 [ALC861_6ST_DIG] = "6stack-dig",
11579 [ALC861_UNIWILL_M31] = "uniwill-m31",
11580 [ALC861_TOSHIBA] = "toshiba",
11581 [ALC861_ASUS] = "asus",
11582 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11583 [ALC861_AUTO] = "auto",
11584};
11585
11586static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11587 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11588 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11589 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11590 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11591 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11592 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11593 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11594 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11595 * Any other models that need this preset?
11596 */
11597 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11598 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11599 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11600 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11601 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11602 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11603 /* FIXME: the below seems conflict */
11604 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11605 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11606 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11607 {}
11608};
11609
11610static struct alc_config_preset alc861_presets[] = {
11611 [ALC861_3ST] = {
11612 .mixers = { alc861_3ST_mixer },
11613 .init_verbs = { alc861_threestack_init_verbs },
11614 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11615 .dac_nids = alc861_dac_nids,
11616 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11617 .channel_mode = alc861_threestack_modes,
4e195a7b 11618 .need_dac_fix = 1,
df694daa
KY
11619 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11620 .adc_nids = alc861_adc_nids,
11621 .input_mux = &alc861_capture_source,
11622 },
11623 [ALC861_3ST_DIG] = {
11624 .mixers = { alc861_base_mixer },
11625 .init_verbs = { alc861_threestack_init_verbs },
11626 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11627 .dac_nids = alc861_dac_nids,
11628 .dig_out_nid = ALC861_DIGOUT_NID,
11629 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11630 .channel_mode = alc861_threestack_modes,
4e195a7b 11631 .need_dac_fix = 1,
df694daa
KY
11632 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11633 .adc_nids = alc861_adc_nids,
11634 .input_mux = &alc861_capture_source,
11635 },
11636 [ALC861_6ST_DIG] = {
11637 .mixers = { alc861_base_mixer },
11638 .init_verbs = { alc861_base_init_verbs },
11639 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11640 .dac_nids = alc861_dac_nids,
11641 .dig_out_nid = ALC861_DIGOUT_NID,
11642 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11643 .channel_mode = alc861_8ch_modes,
11644 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11645 .adc_nids = alc861_adc_nids,
11646 .input_mux = &alc861_capture_source,
11647 },
9c7f852e
TI
11648 [ALC660_3ST] = {
11649 .mixers = { alc861_3ST_mixer },
11650 .init_verbs = { alc861_threestack_init_verbs },
11651 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11652 .dac_nids = alc660_dac_nids,
11653 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11654 .channel_mode = alc861_threestack_modes,
4e195a7b 11655 .need_dac_fix = 1,
9c7f852e
TI
11656 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11657 .adc_nids = alc861_adc_nids,
11658 .input_mux = &alc861_capture_source,
11659 },
22309c3e
TI
11660 [ALC861_UNIWILL_M31] = {
11661 .mixers = { alc861_uniwill_m31_mixer },
11662 .init_verbs = { alc861_uniwill_m31_init_verbs },
11663 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11664 .dac_nids = alc861_dac_nids,
11665 .dig_out_nid = ALC861_DIGOUT_NID,
11666 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11667 .channel_mode = alc861_uniwill_m31_modes,
11668 .need_dac_fix = 1,
11669 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11670 .adc_nids = alc861_adc_nids,
11671 .input_mux = &alc861_capture_source,
11672 },
a53d1aec
TD
11673 [ALC861_TOSHIBA] = {
11674 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11675 .init_verbs = { alc861_base_init_verbs,
11676 alc861_toshiba_init_verbs },
a53d1aec
TD
11677 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11678 .dac_nids = alc861_dac_nids,
11679 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11680 .channel_mode = alc883_3ST_2ch_modes,
11681 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11682 .adc_nids = alc861_adc_nids,
11683 .input_mux = &alc861_capture_source,
11684 .unsol_event = alc861_toshiba_unsol_event,
11685 .init_hook = alc861_toshiba_automute,
11686 },
7cdbff94
MD
11687 [ALC861_ASUS] = {
11688 .mixers = { alc861_asus_mixer },
11689 .init_verbs = { alc861_asus_init_verbs },
11690 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11691 .dac_nids = alc861_dac_nids,
11692 .dig_out_nid = ALC861_DIGOUT_NID,
11693 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11694 .channel_mode = alc861_asus_modes,
11695 .need_dac_fix = 1,
11696 .hp_nid = 0x06,
11697 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11698 .adc_nids = alc861_adc_nids,
11699 .input_mux = &alc861_capture_source,
11700 },
56bb0cab
TI
11701 [ALC861_ASUS_LAPTOP] = {
11702 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11703 .init_verbs = { alc861_asus_init_verbs,
11704 alc861_asus_laptop_init_verbs },
11705 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11706 .dac_nids = alc861_dac_nids,
11707 .dig_out_nid = ALC861_DIGOUT_NID,
11708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11709 .channel_mode = alc883_3ST_2ch_modes,
11710 .need_dac_fix = 1,
11711 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11712 .adc_nids = alc861_adc_nids,
11713 .input_mux = &alc861_capture_source,
11714 },
11715};
df694daa
KY
11716
11717
11718static int patch_alc861(struct hda_codec *codec)
11719{
11720 struct alc_spec *spec;
11721 int board_config;
11722 int err;
11723
dc041e0b 11724 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11725 if (spec == NULL)
11726 return -ENOMEM;
11727
f12ab1e0 11728 codec->spec = spec;
df694daa 11729
f5fcc13c
TI
11730 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11731 alc861_models,
11732 alc861_cfg_tbl);
9c7f852e 11733
f5fcc13c 11734 if (board_config < 0) {
9c7f852e
TI
11735 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11736 "trying auto-probe from BIOS...\n");
df694daa
KY
11737 board_config = ALC861_AUTO;
11738 }
11739
11740 if (board_config == ALC861_AUTO) {
11741 /* automatic parse from the BIOS config */
11742 err = alc861_parse_auto_config(codec);
11743 if (err < 0) {
11744 alc_free(codec);
11745 return err;
f12ab1e0 11746 } else if (!err) {
9c7f852e
TI
11747 printk(KERN_INFO
11748 "hda_codec: Cannot set up configuration "
11749 "from BIOS. Using base mode...\n");
df694daa
KY
11750 board_config = ALC861_3ST_DIG;
11751 }
11752 }
11753
11754 if (board_config != ALC861_AUTO)
11755 setup_preset(spec, &alc861_presets[board_config]);
11756
11757 spec->stream_name_analog = "ALC861 Analog";
11758 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11759 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11760
11761 spec->stream_name_digital = "ALC861 Digital";
11762 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11763 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11764
2134ea4f
TI
11765 spec->vmaster_nid = 0x03;
11766
df694daa
KY
11767 codec->patch_ops = alc_patch_ops;
11768 if (board_config == ALC861_AUTO)
ae6b813a 11769 spec->init_hook = alc861_auto_init;
cb53c626
TI
11770#ifdef CONFIG_SND_HDA_POWER_SAVE
11771 if (!spec->loopback.amplist)
11772 spec->loopback.amplist = alc861_loopbacks;
11773#endif
df694daa 11774
1da177e4
LT
11775 return 0;
11776}
11777
f32610ed
JS
11778/*
11779 * ALC861-VD support
11780 *
11781 * Based on ALC882
11782 *
11783 * In addition, an independent DAC
11784 */
11785#define ALC861VD_DIGOUT_NID 0x06
11786
11787static hda_nid_t alc861vd_dac_nids[4] = {
11788 /* front, surr, clfe, side surr */
11789 0x02, 0x03, 0x04, 0x05
11790};
11791
11792/* dac_nids for ALC660vd are in a different order - according to
11793 * Realtek's driver.
11794 * This should probably tesult in a different mixer for 6stack models
11795 * of ALC660vd codecs, but for now there is only 3stack mixer
11796 * - and it is the same as in 861vd.
11797 * adc_nids in ALC660vd are (is) the same as in 861vd
11798 */
11799static hda_nid_t alc660vd_dac_nids[3] = {
11800 /* front, rear, clfe, rear_surr */
11801 0x02, 0x04, 0x03
11802};
11803
11804static hda_nid_t alc861vd_adc_nids[1] = {
11805 /* ADC0 */
11806 0x09,
11807};
11808
e1406348
TI
11809static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
11810
f32610ed
JS
11811/* input MUX */
11812/* FIXME: should be a matrix-type input source selection */
11813static struct hda_input_mux alc861vd_capture_source = {
11814 .num_items = 4,
11815 .items = {
11816 { "Mic", 0x0 },
11817 { "Front Mic", 0x1 },
11818 { "Line", 0x2 },
11819 { "CD", 0x4 },
11820 },
11821};
11822
272a527c
KY
11823static struct hda_input_mux alc861vd_dallas_capture_source = {
11824 .num_items = 3,
11825 .items = {
11826 { "Front Mic", 0x0 },
11827 { "ATAPI Mic", 0x1 },
11828 { "Line In", 0x5 },
11829 },
11830};
11831
d1a991a6
KY
11832static struct hda_input_mux alc861vd_hp_capture_source = {
11833 .num_items = 2,
11834 .items = {
11835 { "Front Mic", 0x0 },
11836 { "ATAPI Mic", 0x1 },
11837 },
11838};
11839
f32610ed
JS
11840#define alc861vd_mux_enum_info alc_mux_enum_info
11841#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
11842/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
11843#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
11844
11845/*
11846 * 2ch mode
11847 */
11848static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11849 { 2, NULL }
11850};
11851
11852/*
11853 * 6ch mode
11854 */
11855static struct hda_verb alc861vd_6stack_ch6_init[] = {
11856 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11857 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11858 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11859 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11860 { } /* end */
11861};
11862
11863/*
11864 * 8ch mode
11865 */
11866static struct hda_verb alc861vd_6stack_ch8_init[] = {
11867 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11868 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11869 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11870 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11871 { } /* end */
11872};
11873
11874static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11875 { 6, alc861vd_6stack_ch6_init },
11876 { 8, alc861vd_6stack_ch8_init },
11877};
11878
11879static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11880 {
11881 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11882 .name = "Channel Mode",
11883 .info = alc_ch_mode_info,
11884 .get = alc_ch_mode_get,
11885 .put = alc_ch_mode_put,
11886 },
11887 { } /* end */
11888};
11889
11890static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11891 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11892 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11893
11894 {
11895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11896 /* The multiple "Capture Source" controls confuse alsamixer
11897 * So call somewhat different..
f32610ed
JS
11898 */
11899 /* .name = "Capture Source", */
11900 .name = "Input Source",
11901 .count = 1,
11902 .info = alc861vd_mux_enum_info,
11903 .get = alc861vd_mux_enum_get,
11904 .put = alc861vd_mux_enum_put,
11905 },
11906 { } /* end */
11907};
11908
11909/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11910 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11911 */
11912static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11913 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11914 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11915
11916 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11917 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11918
11919 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11920 HDA_OUTPUT),
11921 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11922 HDA_OUTPUT),
11923 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11924 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11925
11926 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11927 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11928
11929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11930
11931 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11934
11935 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11937 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11938
11939 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11940 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11941
11942 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11943 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11944
11945 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11946 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11947
11948 { } /* end */
11949};
11950
11951static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
11952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11953 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11954
11955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11956
11957 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11959 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11960
11961 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11962 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11964
11965 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11966 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11967
11968 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11969 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11970
11971 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11972 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11973
11974 { } /* end */
11975};
11976
bdd148a3
KY
11977static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
11978 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11979 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
11980 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11981
11982 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11983
11984 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11987
11988 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11989 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11990 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11991
11992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11994
11995 { } /* end */
11996};
11997
272a527c
KY
11998/* Pin assignment: Front=0x14, HP = 0x15,
11999 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
12000 */
12001static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12002 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12003 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12005 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12006 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12007 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12008 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12009 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
12012 { } /* end */
12013};
12014
d1a991a6
KY
12015/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12016 * Front Mic=0x18, ATAPI Mic = 0x19,
12017 */
12018static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12019 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12020 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12021 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12022 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12023 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12025 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12026 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12027
12028 { } /* end */
12029};
12030
f32610ed
JS
12031/*
12032 * generic initialization of ADC, input mixers and output mixers
12033 */
12034static struct hda_verb alc861vd_volume_init_verbs[] = {
12035 /*
12036 * Unmute ADC0 and set the default input to mic-in
12037 */
12038 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12039 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12040
12041 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12042 * the analog-loopback mixer widget
12043 */
12044 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12047 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12048 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12049 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
12050
12051 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
12052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 12055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
12056
12057 /*
12058 * Set up output mixers (0x02 - 0x05)
12059 */
12060 /* set vol=0 to output mixers */
12061 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12062 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12063 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12064 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12065
12066 /* set up input amps for analog loopback */
12067 /* Amp Indices: DAC = 0, mixer = 1 */
12068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12071 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12073 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12074 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12075 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12076
12077 { }
12078};
12079
12080/*
12081 * 3-stack pin configuration:
12082 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12083 */
12084static struct hda_verb alc861vd_3stack_init_verbs[] = {
12085 /*
12086 * Set pin mode and muting
12087 */
12088 /* set front pin widgets 0x14 for output */
12089 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12090 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12091 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12092
12093 /* Mic (rear) pin: input vref at 80% */
12094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12096 /* Front Mic pin: input vref at 80% */
12097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12099 /* Line In pin: input */
12100 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12101 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12102 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12103 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12105 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12106 /* CD pin widget for input */
12107 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12108
12109 { }
12110};
12111
12112/*
12113 * 6-stack pin configuration:
12114 */
12115static struct hda_verb alc861vd_6stack_init_verbs[] = {
12116 /*
12117 * Set pin mode and muting
12118 */
12119 /* set front pin widgets 0x14 for output */
12120 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12121 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12122 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12123
12124 /* Rear Pin: output 1 (0x0d) */
12125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12127 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12128 /* CLFE Pin: output 2 (0x0e) */
12129 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12131 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12132 /* Side Pin: output 3 (0x0f) */
12133 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12134 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12135 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12136
12137 /* Mic (rear) pin: input vref at 80% */
12138 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12139 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12140 /* Front Mic pin: input vref at 80% */
12141 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12142 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12143 /* Line In pin: input */
12144 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12145 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12146 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12147 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12148 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12149 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12150 /* CD pin widget for input */
12151 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12152
12153 { }
12154};
12155
bdd148a3
KY
12156static struct hda_verb alc861vd_eapd_verbs[] = {
12157 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12158 { }
12159};
12160
12161static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12162 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12164 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12165 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12166 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12167 {}
12168};
12169
12170/* toggle speaker-output according to the hp-jack state */
12171static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12172{
12173 unsigned int present;
12174 unsigned char bits;
12175
12176 present = snd_hda_codec_read(codec, 0x1b, 0,
12177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12178 bits = present ? HDA_AMP_MUTE : 0;
12179 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12180 HDA_AMP_MUTE, bits);
bdd148a3
KY
12181}
12182
12183static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12184{
12185 unsigned int present;
12186 unsigned char bits;
12187
12188 present = snd_hda_codec_read(codec, 0x18, 0,
12189 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12190 bits = present ? HDA_AMP_MUTE : 0;
12191 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12192 HDA_AMP_MUTE, bits);
bdd148a3
KY
12193}
12194
12195static void alc861vd_lenovo_automute(struct hda_codec *codec)
12196{
12197 alc861vd_lenovo_hp_automute(codec);
12198 alc861vd_lenovo_mic_automute(codec);
12199}
12200
12201static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12202 unsigned int res)
12203{
12204 switch (res >> 26) {
12205 case ALC880_HP_EVENT:
12206 alc861vd_lenovo_hp_automute(codec);
12207 break;
12208 case ALC880_MIC_EVENT:
12209 alc861vd_lenovo_mic_automute(codec);
12210 break;
12211 }
12212}
12213
272a527c
KY
12214static struct hda_verb alc861vd_dallas_verbs[] = {
12215 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12216 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12217 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12218 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12219
12220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12228
12229 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12230 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12232 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12233 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12234 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12235 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12236 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12237
12238 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12239 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12240 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12241 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12243 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12244 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12245 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12246
12247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12251
12252 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12253 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12254 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12255
12256 { } /* end */
12257};
12258
12259/* toggle speaker-output according to the hp-jack state */
12260static void alc861vd_dallas_automute(struct hda_codec *codec)
12261{
12262 unsigned int present;
12263
12264 present = snd_hda_codec_read(codec, 0x15, 0,
12265 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12266 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12267 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
12268}
12269
12270static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12271{
12272 if ((res >> 26) == ALC880_HP_EVENT)
12273 alc861vd_dallas_automute(codec);
12274}
12275
cb53c626
TI
12276#ifdef CONFIG_SND_HDA_POWER_SAVE
12277#define alc861vd_loopbacks alc880_loopbacks
12278#endif
12279
f32610ed
JS
12280/* pcm configuration: identiacal with ALC880 */
12281#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12282#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12283#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12284#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12285
12286/*
12287 * configuration and preset
12288 */
12289static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12290 [ALC660VD_3ST] = "3stack-660",
983f8ae4 12291 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
12292 [ALC861VD_3ST] = "3stack",
12293 [ALC861VD_3ST_DIG] = "3stack-digout",
12294 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 12295 [ALC861VD_LENOVO] = "lenovo",
272a527c 12296 [ALC861VD_DALLAS] = "dallas",
983f8ae4 12297 [ALC861VD_HP] = "hp",
f32610ed
JS
12298 [ALC861VD_AUTO] = "auto",
12299};
12300
12301static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
12302 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12303 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 12304 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 12305 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 12306 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 12307 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 12308 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 12309 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 12310 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 12311 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 12312 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
12313 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12314 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 12315 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
12316 {}
12317};
12318
12319static struct alc_config_preset alc861vd_presets[] = {
12320 [ALC660VD_3ST] = {
12321 .mixers = { alc861vd_3st_mixer },
12322 .init_verbs = { alc861vd_volume_init_verbs,
12323 alc861vd_3stack_init_verbs },
12324 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12325 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
12326 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12327 .channel_mode = alc861vd_3stack_2ch_modes,
12328 .input_mux = &alc861vd_capture_source,
12329 },
6963f84c
MC
12330 [ALC660VD_3ST_DIG] = {
12331 .mixers = { alc861vd_3st_mixer },
12332 .init_verbs = { alc861vd_volume_init_verbs,
12333 alc861vd_3stack_init_verbs },
12334 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12335 .dac_nids = alc660vd_dac_nids,
12336 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
12337 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12338 .channel_mode = alc861vd_3stack_2ch_modes,
12339 .input_mux = &alc861vd_capture_source,
12340 },
f32610ed
JS
12341 [ALC861VD_3ST] = {
12342 .mixers = { alc861vd_3st_mixer },
12343 .init_verbs = { alc861vd_volume_init_verbs,
12344 alc861vd_3stack_init_verbs },
12345 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12346 .dac_nids = alc861vd_dac_nids,
12347 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12348 .channel_mode = alc861vd_3stack_2ch_modes,
12349 .input_mux = &alc861vd_capture_source,
12350 },
12351 [ALC861VD_3ST_DIG] = {
12352 .mixers = { alc861vd_3st_mixer },
12353 .init_verbs = { alc861vd_volume_init_verbs,
12354 alc861vd_3stack_init_verbs },
12355 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12356 .dac_nids = alc861vd_dac_nids,
12357 .dig_out_nid = ALC861VD_DIGOUT_NID,
12358 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12359 .channel_mode = alc861vd_3stack_2ch_modes,
12360 .input_mux = &alc861vd_capture_source,
12361 },
12362 [ALC861VD_6ST_DIG] = {
12363 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12364 .init_verbs = { alc861vd_volume_init_verbs,
12365 alc861vd_6stack_init_verbs },
12366 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12367 .dac_nids = alc861vd_dac_nids,
12368 .dig_out_nid = ALC861VD_DIGOUT_NID,
12369 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12370 .channel_mode = alc861vd_6stack_modes,
12371 .input_mux = &alc861vd_capture_source,
12372 },
bdd148a3
KY
12373 [ALC861VD_LENOVO] = {
12374 .mixers = { alc861vd_lenovo_mixer },
12375 .init_verbs = { alc861vd_volume_init_verbs,
12376 alc861vd_3stack_init_verbs,
12377 alc861vd_eapd_verbs,
12378 alc861vd_lenovo_unsol_verbs },
12379 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12380 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
12381 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12382 .channel_mode = alc861vd_3stack_2ch_modes,
12383 .input_mux = &alc861vd_capture_source,
12384 .unsol_event = alc861vd_lenovo_unsol_event,
12385 .init_hook = alc861vd_lenovo_automute,
12386 },
272a527c
KY
12387 [ALC861VD_DALLAS] = {
12388 .mixers = { alc861vd_dallas_mixer },
12389 .init_verbs = { alc861vd_dallas_verbs },
12390 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12391 .dac_nids = alc861vd_dac_nids,
272a527c
KY
12392 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12393 .channel_mode = alc861vd_3stack_2ch_modes,
12394 .input_mux = &alc861vd_dallas_capture_source,
12395 .unsol_event = alc861vd_dallas_unsol_event,
12396 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
12397 },
12398 [ALC861VD_HP] = {
12399 .mixers = { alc861vd_hp_mixer },
12400 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12401 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12402 .dac_nids = alc861vd_dac_nids,
d1a991a6 12403 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
12404 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12405 .channel_mode = alc861vd_3stack_2ch_modes,
12406 .input_mux = &alc861vd_hp_capture_source,
12407 .unsol_event = alc861vd_dallas_unsol_event,
12408 .init_hook = alc861vd_dallas_automute,
12409 },
f32610ed
JS
12410};
12411
12412/*
12413 * BIOS auto configuration
12414 */
12415static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12416 hda_nid_t nid, int pin_type, int dac_idx)
12417{
f6c7e546 12418 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
12419}
12420
12421static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12422{
12423 struct alc_spec *spec = codec->spec;
12424 int i;
12425
bc9f98a9 12426 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
12427 for (i = 0; i <= HDA_SIDE; i++) {
12428 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12429 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
12430 if (nid)
12431 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 12432 pin_type, i);
f32610ed
JS
12433 }
12434}
12435
12436
12437static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12438{
12439 struct alc_spec *spec = codec->spec;
12440 hda_nid_t pin;
12441
12442 pin = spec->autocfg.hp_pins[0];
12443 if (pin) /* connect to front and use dac 0 */
12444 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
12445 pin = spec->autocfg.speaker_pins[0];
12446 if (pin)
12447 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
12448}
12449
12450#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12451#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12452
12453static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12454{
12455 struct alc_spec *spec = codec->spec;
12456 int i;
12457
12458 for (i = 0; i < AUTO_PIN_LAST; i++) {
12459 hda_nid_t nid = spec->autocfg.input_pins[i];
12460 if (alc861vd_is_input_pin(nid)) {
12461 snd_hda_codec_write(codec, nid, 0,
12462 AC_VERB_SET_PIN_WIDGET_CONTROL,
12463 i <= AUTO_PIN_FRONT_MIC ?
12464 PIN_VREF80 : PIN_IN);
12465 if (nid != ALC861VD_PIN_CD_NID)
12466 snd_hda_codec_write(codec, nid, 0,
12467 AC_VERB_SET_AMP_GAIN_MUTE,
12468 AMP_OUT_MUTE);
12469 }
12470 }
12471}
12472
12473#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12474#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12475
12476/* add playback controls from the parsed DAC table */
12477/* Based on ALC880 version. But ALC861VD has separate,
12478 * different NIDs for mute/unmute switch and volume control */
12479static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12480 const struct auto_pin_cfg *cfg)
12481{
12482 char name[32];
12483 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12484 hda_nid_t nid_v, nid_s;
12485 int i, err;
12486
12487 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12488 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12489 continue;
12490 nid_v = alc861vd_idx_to_mixer_vol(
12491 alc880_dac_to_idx(
12492 spec->multiout.dac_nids[i]));
12493 nid_s = alc861vd_idx_to_mixer_switch(
12494 alc880_dac_to_idx(
12495 spec->multiout.dac_nids[i]));
12496
12497 if (i == 2) {
12498 /* Center/LFE */
f12ab1e0
TI
12499 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12500 "Center Playback Volume",
12501 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12502 HDA_OUTPUT));
12503 if (err < 0)
f32610ed 12504 return err;
f12ab1e0
TI
12505 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12506 "LFE Playback Volume",
12507 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12508 HDA_OUTPUT));
12509 if (err < 0)
f32610ed 12510 return err;
f12ab1e0
TI
12511 err = add_control(spec, ALC_CTL_BIND_MUTE,
12512 "Center Playback Switch",
12513 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12514 HDA_INPUT));
12515 if (err < 0)
f32610ed 12516 return err;
f12ab1e0
TI
12517 err = add_control(spec, ALC_CTL_BIND_MUTE,
12518 "LFE Playback Switch",
12519 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12520 HDA_INPUT));
12521 if (err < 0)
f32610ed
JS
12522 return err;
12523 } else {
12524 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12525 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12526 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12527 HDA_OUTPUT));
12528 if (err < 0)
f32610ed
JS
12529 return err;
12530 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12531 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12532 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12533 HDA_INPUT));
12534 if (err < 0)
f32610ed
JS
12535 return err;
12536 }
12537 }
12538 return 0;
12539}
12540
12541/* add playback controls for speaker and HP outputs */
12542/* Based on ALC880 version. But ALC861VD has separate,
12543 * different NIDs for mute/unmute switch and volume control */
12544static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12545 hda_nid_t pin, const char *pfx)
12546{
12547 hda_nid_t nid_v, nid_s;
12548 int err;
12549 char name[32];
12550
f12ab1e0 12551 if (!pin)
f32610ed
JS
12552 return 0;
12553
12554 if (alc880_is_fixed_pin(pin)) {
12555 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12556 /* specify the DAC as the extra output */
f12ab1e0 12557 if (!spec->multiout.hp_nid)
f32610ed
JS
12558 spec->multiout.hp_nid = nid_v;
12559 else
12560 spec->multiout.extra_out_nid[0] = nid_v;
12561 /* control HP volume/switch on the output mixer amp */
12562 nid_v = alc861vd_idx_to_mixer_vol(
12563 alc880_fixed_pin_idx(pin));
12564 nid_s = alc861vd_idx_to_mixer_switch(
12565 alc880_fixed_pin_idx(pin));
12566
12567 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12568 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12569 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12570 if (err < 0)
f32610ed
JS
12571 return err;
12572 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12573 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12574 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12575 if (err < 0)
f32610ed
JS
12576 return err;
12577 } else if (alc880_is_multi_pin(pin)) {
12578 /* set manual connection */
12579 /* we have only a switch on HP-out PIN */
12580 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12581 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12582 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12583 if (err < 0)
f32610ed
JS
12584 return err;
12585 }
12586 return 0;
12587}
12588
12589/* parse the BIOS configuration and set up the alc_spec
12590 * return 1 if successful, 0 if the proper config is not found,
12591 * or a negative error code
12592 * Based on ALC880 version - had to change it to override
12593 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12594static int alc861vd_parse_auto_config(struct hda_codec *codec)
12595{
12596 struct alc_spec *spec = codec->spec;
12597 int err;
12598 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12599
f12ab1e0
TI
12600 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12601 alc861vd_ignore);
12602 if (err < 0)
f32610ed 12603 return err;
f12ab1e0 12604 if (!spec->autocfg.line_outs)
f32610ed
JS
12605 return 0; /* can't find valid BIOS pin config */
12606
f12ab1e0
TI
12607 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12608 if (err < 0)
12609 return err;
12610 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12611 if (err < 0)
12612 return err;
12613 err = alc861vd_auto_create_extra_out(spec,
12614 spec->autocfg.speaker_pins[0],
12615 "Speaker");
12616 if (err < 0)
12617 return err;
12618 err = alc861vd_auto_create_extra_out(spec,
12619 spec->autocfg.hp_pins[0],
12620 "Headphone");
12621 if (err < 0)
12622 return err;
12623 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12624 if (err < 0)
f32610ed
JS
12625 return err;
12626
12627 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12628
12629 if (spec->autocfg.dig_out_pin)
12630 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12631
12632 if (spec->kctl_alloc)
12633 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12634
12635 spec->init_verbs[spec->num_init_verbs++]
12636 = alc861vd_volume_init_verbs;
12637
12638 spec->num_mux_defs = 1;
12639 spec->input_mux = &spec->private_imux;
12640
776e184e
TI
12641 err = alc_auto_add_mic_boost(codec);
12642 if (err < 0)
12643 return err;
12644
f32610ed
JS
12645 return 1;
12646}
12647
12648/* additional initialization for auto-configuration model */
12649static void alc861vd_auto_init(struct hda_codec *codec)
12650{
f6c7e546 12651 struct alc_spec *spec = codec->spec;
f32610ed
JS
12652 alc861vd_auto_init_multi_out(codec);
12653 alc861vd_auto_init_hp_out(codec);
12654 alc861vd_auto_init_analog_input(codec);
f6c7e546
TI
12655 if (spec->unsol_event)
12656 alc_sku_automute(codec);
f32610ed
JS
12657}
12658
12659static int patch_alc861vd(struct hda_codec *codec)
12660{
12661 struct alc_spec *spec;
12662 int err, board_config;
12663
12664 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12665 if (spec == NULL)
12666 return -ENOMEM;
12667
12668 codec->spec = spec;
12669
12670 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12671 alc861vd_models,
12672 alc861vd_cfg_tbl);
12673
12674 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12675 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12676 "ALC861VD, trying auto-probe from BIOS...\n");
12677 board_config = ALC861VD_AUTO;
12678 }
12679
12680 if (board_config == ALC861VD_AUTO) {
12681 /* automatic parse from the BIOS config */
12682 err = alc861vd_parse_auto_config(codec);
12683 if (err < 0) {
12684 alc_free(codec);
12685 return err;
f12ab1e0 12686 } else if (!err) {
f32610ed
JS
12687 printk(KERN_INFO
12688 "hda_codec: Cannot set up configuration "
12689 "from BIOS. Using base mode...\n");
12690 board_config = ALC861VD_3ST;
12691 }
12692 }
12693
12694 if (board_config != ALC861VD_AUTO)
12695 setup_preset(spec, &alc861vd_presets[board_config]);
12696
12697 spec->stream_name_analog = "ALC861VD Analog";
12698 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12699 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12700
12701 spec->stream_name_digital = "ALC861VD Digital";
12702 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12703 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12704
12705 spec->adc_nids = alc861vd_adc_nids;
12706 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 12707 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
12708
12709 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12710 spec->num_mixers++;
12711
2134ea4f
TI
12712 spec->vmaster_nid = 0x02;
12713
f32610ed
JS
12714 codec->patch_ops = alc_patch_ops;
12715
12716 if (board_config == ALC861VD_AUTO)
12717 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12718#ifdef CONFIG_SND_HDA_POWER_SAVE
12719 if (!spec->loopback.amplist)
12720 spec->loopback.amplist = alc861vd_loopbacks;
12721#endif
f32610ed
JS
12722
12723 return 0;
12724}
12725
bc9f98a9
KY
12726/*
12727 * ALC662 support
12728 *
12729 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12730 * configuration. Each pin widget can choose any input DACs and a mixer.
12731 * Each ADC is connected from a mixer of all inputs. This makes possible
12732 * 6-channel independent captures.
12733 *
12734 * In addition, an independent DAC for the multi-playback (not used in this
12735 * driver yet).
12736 */
12737#define ALC662_DIGOUT_NID 0x06
12738#define ALC662_DIGIN_NID 0x0a
12739
12740static hda_nid_t alc662_dac_nids[4] = {
12741 /* front, rear, clfe, rear_surr */
12742 0x02, 0x03, 0x04
12743};
12744
12745static hda_nid_t alc662_adc_nids[1] = {
12746 /* ADC1-2 */
12747 0x09,
12748};
e1406348
TI
12749
12750static hda_nid_t alc662_capsrc_nids[1] = { 0x23 };
12751
bc9f98a9
KY
12752/* input MUX */
12753/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
12754static struct hda_input_mux alc662_capture_source = {
12755 .num_items = 4,
12756 .items = {
12757 { "Mic", 0x0 },
12758 { "Front Mic", 0x1 },
12759 { "Line", 0x2 },
12760 { "CD", 0x4 },
12761 },
12762};
12763
12764static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12765 .num_items = 2,
12766 .items = {
12767 { "Mic", 0x1 },
12768 { "Line", 0x2 },
12769 },
12770};
291702f0
KY
12771
12772static struct hda_input_mux alc662_eeepc_capture_source = {
12773 .num_items = 2,
12774 .items = {
12775 { "i-Mic", 0x1 },
12776 { "e-Mic", 0x0 },
12777 },
12778};
12779
bc9f98a9
KY
12780#define alc662_mux_enum_info alc_mux_enum_info
12781#define alc662_mux_enum_get alc_mux_enum_get
e1406348 12782#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 12783
bc9f98a9
KY
12784/*
12785 * 2ch mode
12786 */
12787static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12788 { 2, NULL }
12789};
12790
12791/*
12792 * 2ch mode
12793 */
12794static struct hda_verb alc662_3ST_ch2_init[] = {
12795 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12796 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12797 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12798 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12799 { } /* end */
12800};
12801
12802/*
12803 * 6ch mode
12804 */
12805static struct hda_verb alc662_3ST_ch6_init[] = {
12806 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12807 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12808 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12809 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12810 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12811 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12812 { } /* end */
12813};
12814
12815static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12816 { 2, alc662_3ST_ch2_init },
12817 { 6, alc662_3ST_ch6_init },
12818};
12819
12820/*
12821 * 2ch mode
12822 */
12823static struct hda_verb alc662_sixstack_ch6_init[] = {
12824 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12825 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12826 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12827 { } /* end */
12828};
12829
12830/*
12831 * 6ch mode
12832 */
12833static struct hda_verb alc662_sixstack_ch8_init[] = {
12834 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12835 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12836 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12837 { } /* end */
12838};
12839
12840static struct hda_channel_mode alc662_5stack_modes[2] = {
12841 { 2, alc662_sixstack_ch6_init },
12842 { 6, alc662_sixstack_ch8_init },
12843};
12844
12845/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12846 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12847 */
12848
12849static struct snd_kcontrol_new alc662_base_mixer[] = {
12850 /* output mixer control */
12851 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12852 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12853 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12854 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12855 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12856 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12857 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12858 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12860
12861 /*Input mixer control */
12862 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12863 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12864 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12865 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12866 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12867 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12868 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12869 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12870 { } /* end */
12871};
12872
12873static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12874 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12875 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12877 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12878 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12879 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12880 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12882 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12883 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12884 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12885 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12886 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12887 { } /* end */
12888};
12889
12890static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12891 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12892 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12893 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12894 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12895 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12896 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12897 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12898 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12908 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12909 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12910 { } /* end */
12911};
12912
12913static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12914 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12915 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
12916 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12917 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
12918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
12923 { } /* end */
12924};
12925
291702f0 12926static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 12927 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 12928
b4818494
HRK
12929 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12930 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
12931
12932 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12933 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12934 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12935
12936 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12937 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12938 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12939 { } /* end */
12940};
12941
8c427226 12942static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
12943 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
12945 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12946 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12947 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12948 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12949 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12950 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 12951 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
12952 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
12953 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12954 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12957 { } /* end */
12958};
12959
bc9f98a9
KY
12960static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12961 {
12962 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12963 .name = "Channel Mode",
12964 .info = alc_ch_mode_info,
12965 .get = alc_ch_mode_get,
12966 .put = alc_ch_mode_put,
12967 },
12968 { } /* end */
12969};
12970
12971static struct hda_verb alc662_init_verbs[] = {
12972 /* ADC: mute amp left and right */
12973 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12975 /* Front mixer: unmute input/output amp left and right (volume = 0) */
12976
cb53c626
TI
12977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12979 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12980 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12981 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 12982
b60dd394
KY
12983 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12984 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12985 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12986 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12988 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
12989
12990 /* Front Pin: output 0 (0x0c) */
12991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12992 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12993
12994 /* Rear Pin: output 1 (0x0d) */
12995 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12996 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12997
12998 /* CLFE Pin: output 2 (0x0e) */
12999 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13001
13002 /* Mic (rear) pin: input vref at 80% */
13003 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13004 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13005 /* Front Mic pin: input vref at 80% */
13006 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13007 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13008 /* Line In pin: input */
13009 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13010 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13011 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13014 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13015 /* CD pin widget for input */
13016 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13017
13018 /* FIXME: use matrix-type input source selection */
13019 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13020 /* Input mixer */
13021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
13025
13026 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13027 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13029 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
13030 { }
13031};
13032
13033static struct hda_verb alc662_sue_init_verbs[] = {
13034 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
13036 {}
13037};
13038
13039static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13040 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13041 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13042 {}
bc9f98a9
KY
13043};
13044
8c427226
KY
13045/* Set Unsolicited Event*/
13046static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13047 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13048 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13049 {}
13050};
13051
bc9f98a9
KY
13052/*
13053 * generic initialization of ADC, input mixers and output mixers
13054 */
13055static struct hda_verb alc662_auto_init_verbs[] = {
13056 /*
13057 * Unmute ADC and set the default input to mic-in
13058 */
13059 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13060 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13061
13062 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13063 * mixer widget
13064 * Note: PASD motherboards uses the Line In 2 as the input for front
13065 * panel mic (mic 2)
13066 */
13067 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13072 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
13073
13074 /*
13075 * Set up output mixers (0x0c - 0x0f)
13076 */
13077 /* set vol=0 to output mixers */
13078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13080 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13081
13082 /* set up input amps for analog loopback */
13083 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
13084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13085 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13086 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13087 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13090
13091
13092 /* FIXME: use matrix-type input source selection */
13093 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13094 /* Input mixer */
13095 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 13096 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
13097 { }
13098};
13099
13100/* capture mixer elements */
13101static struct snd_kcontrol_new alc662_capture_mixer[] = {
13102 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13103 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13104 {
13105 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13106 /* The multiple "Capture Source" controls confuse alsamixer
13107 * So call somewhat different..
bc9f98a9
KY
13108 */
13109 /* .name = "Capture Source", */
13110 .name = "Input Source",
13111 .count = 1,
6e7939bb
HRK
13112 .info = alc662_mux_enum_info,
13113 .get = alc662_mux_enum_get,
13114 .put = alc662_mux_enum_put,
bc9f98a9
KY
13115 },
13116 { } /* end */
13117};
13118
13119static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13120{
13121 unsigned int present;
f12ab1e0 13122 unsigned char bits;
bc9f98a9
KY
13123
13124 present = snd_hda_codec_read(codec, 0x14, 0,
13125 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13126 bits = present ? HDA_AMP_MUTE : 0;
13127 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13128 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13129}
13130
13131static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13132{
13133 unsigned int present;
f12ab1e0 13134 unsigned char bits;
bc9f98a9
KY
13135
13136 present = snd_hda_codec_read(codec, 0x1b, 0,
13137 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13138 bits = present ? HDA_AMP_MUTE : 0;
13139 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13140 HDA_AMP_MUTE, bits);
13141 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13142 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13143}
13144
13145static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13146 unsigned int res)
13147{
13148 if ((res >> 26) == ALC880_HP_EVENT)
13149 alc662_lenovo_101e_all_automute(codec);
13150 if ((res >> 26) == ALC880_FRONT_EVENT)
13151 alc662_lenovo_101e_ispeaker_automute(codec);
13152}
13153
291702f0
KY
13154static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13155{
13156 unsigned int present;
13157
13158 present = snd_hda_codec_read(codec, 0x18, 0,
13159 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13160 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13161 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13162 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13163 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13164 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13165 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13166 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13167 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13168}
13169
13170/* unsolicited event for HP jack sensing */
13171static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13172 unsigned int res)
13173{
13174 if ((res >> 26) == ALC880_HP_EVENT)
13175 alc262_hippo1_automute( codec );
13176
13177 if ((res >> 26) == ALC880_MIC_EVENT)
13178 alc662_eeepc_mic_automute(codec);
13179}
13180
13181static void alc662_eeepc_inithook(struct hda_codec *codec)
13182{
13183 alc262_hippo1_automute( codec );
13184 alc662_eeepc_mic_automute(codec);
13185}
13186
8c427226
KY
13187static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13188{
13189 unsigned int mute;
13190 unsigned int present;
13191
13192 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13193 present = snd_hda_codec_read(codec, 0x14, 0,
13194 AC_VERB_GET_PIN_SENSE, 0);
13195 present = (present & 0x80000000) != 0;
13196 if (present) {
13197 /* mute internal speaker */
13198 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13199 HDA_AMP_MUTE, HDA_AMP_MUTE);
13200 } else {
13201 /* unmute internal speaker if necessary */
13202 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13203 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13204 HDA_AMP_MUTE, mute);
13205 }
13206}
13207
13208/* unsolicited event for HP jack sensing */
13209static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13210 unsigned int res)
13211{
13212 if ((res >> 26) == ALC880_HP_EVENT)
13213 alc662_eeepc_ep20_automute(codec);
13214}
13215
13216static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13217{
13218 alc662_eeepc_ep20_automute(codec);
13219}
13220
cb53c626
TI
13221#ifdef CONFIG_SND_HDA_POWER_SAVE
13222#define alc662_loopbacks alc880_loopbacks
13223#endif
13224
bc9f98a9
KY
13225
13226/* pcm configuration: identiacal with ALC880 */
13227#define alc662_pcm_analog_playback alc880_pcm_analog_playback
13228#define alc662_pcm_analog_capture alc880_pcm_analog_capture
13229#define alc662_pcm_digital_playback alc880_pcm_digital_playback
13230#define alc662_pcm_digital_capture alc880_pcm_digital_capture
13231
13232/*
13233 * configuration and preset
13234 */
13235static const char *alc662_models[ALC662_MODEL_LAST] = {
13236 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13237 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13238 [ALC662_3ST_6ch] = "3stack-6ch",
13239 [ALC662_5ST_DIG] = "6stack-dig",
13240 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 13241 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 13242 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
bc9f98a9
KY
13243 [ALC662_AUTO] = "auto",
13244};
13245
13246static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 13247 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 13248 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
ac3e3741 13249 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
13250 {}
13251};
13252
13253static struct alc_config_preset alc662_presets[] = {
13254 [ALC662_3ST_2ch_DIG] = {
291702f0 13255 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
13256 .init_verbs = { alc662_init_verbs },
13257 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13258 .dac_nids = alc662_dac_nids,
13259 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13260 .dig_in_nid = ALC662_DIGIN_NID,
13261 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13262 .channel_mode = alc662_3ST_2ch_modes,
13263 .input_mux = &alc662_capture_source,
13264 },
13265 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
13266 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13267 alc662_capture_mixer },
bc9f98a9
KY
13268 .init_verbs = { alc662_init_verbs },
13269 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13270 .dac_nids = alc662_dac_nids,
13271 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13272 .dig_in_nid = ALC662_DIGIN_NID,
13273 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13274 .channel_mode = alc662_3ST_6ch_modes,
13275 .need_dac_fix = 1,
13276 .input_mux = &alc662_capture_source,
f12ab1e0 13277 },
bc9f98a9 13278 [ALC662_3ST_6ch] = {
291702f0
KY
13279 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13280 alc662_capture_mixer },
bc9f98a9
KY
13281 .init_verbs = { alc662_init_verbs },
13282 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13283 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13284 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13285 .channel_mode = alc662_3ST_6ch_modes,
13286 .need_dac_fix = 1,
13287 .input_mux = &alc662_capture_source,
f12ab1e0 13288 },
bc9f98a9 13289 [ALC662_5ST_DIG] = {
291702f0
KY
13290 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13291 alc662_capture_mixer },
bc9f98a9
KY
13292 .init_verbs = { alc662_init_verbs },
13293 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13294 .dac_nids = alc662_dac_nids,
13295 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13296 .dig_in_nid = ALC662_DIGIN_NID,
13297 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13298 .channel_mode = alc662_5stack_modes,
13299 .input_mux = &alc662_capture_source,
13300 },
13301 [ALC662_LENOVO_101E] = {
291702f0 13302 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
13303 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13304 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13305 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13306 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13307 .channel_mode = alc662_3ST_2ch_modes,
13308 .input_mux = &alc662_lenovo_101e_capture_source,
13309 .unsol_event = alc662_lenovo_101e_unsol_event,
13310 .init_hook = alc662_lenovo_101e_all_automute,
13311 },
291702f0
KY
13312 [ALC662_ASUS_EEEPC_P701] = {
13313 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13314 .init_verbs = { alc662_init_verbs,
13315 alc662_eeepc_sue_init_verbs },
13316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13317 .dac_nids = alc662_dac_nids,
291702f0
KY
13318 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13319 .channel_mode = alc662_3ST_2ch_modes,
13320 .input_mux = &alc662_eeepc_capture_source,
13321 .unsol_event = alc662_eeepc_unsol_event,
13322 .init_hook = alc662_eeepc_inithook,
13323 },
8c427226
KY
13324 [ALC662_ASUS_EEEPC_EP20] = {
13325 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13326 alc662_chmode_mixer },
13327 .init_verbs = { alc662_init_verbs,
13328 alc662_eeepc_ep20_sue_init_verbs },
13329 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13330 .dac_nids = alc662_dac_nids,
8c427226
KY
13331 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13332 .channel_mode = alc662_3ST_6ch_modes,
13333 .input_mux = &alc662_lenovo_101e_capture_source,
13334 .unsol_event = alc662_eeepc_ep20_unsol_event,
13335 .init_hook = alc662_eeepc_ep20_inithook,
13336 },
bc9f98a9
KY
13337
13338};
13339
13340
13341/*
13342 * BIOS auto configuration
13343 */
13344
13345/* add playback controls from the parsed DAC table */
13346static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13347 const struct auto_pin_cfg *cfg)
13348{
13349 char name[32];
13350 static const char *chname[4] = {
13351 "Front", "Surround", NULL /*CLFE*/, "Side"
13352 };
13353 hda_nid_t nid;
13354 int i, err;
13355
13356 for (i = 0; i < cfg->line_outs; i++) {
13357 if (!spec->multiout.dac_nids[i])
13358 continue;
b60dd394 13359 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
13360 if (i == 2) {
13361 /* Center/LFE */
13362 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13363 "Center Playback Volume",
f12ab1e0
TI
13364 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13365 HDA_OUTPUT));
bc9f98a9
KY
13366 if (err < 0)
13367 return err;
13368 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13369 "LFE Playback Volume",
f12ab1e0
TI
13370 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13371 HDA_OUTPUT));
bc9f98a9
KY
13372 if (err < 0)
13373 return err;
13374 err = add_control(spec, ALC_CTL_BIND_MUTE,
13375 "Center Playback Switch",
f12ab1e0
TI
13376 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13377 HDA_INPUT));
bc9f98a9
KY
13378 if (err < 0)
13379 return err;
13380 err = add_control(spec, ALC_CTL_BIND_MUTE,
13381 "LFE Playback Switch",
f12ab1e0
TI
13382 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13383 HDA_INPUT));
bc9f98a9
KY
13384 if (err < 0)
13385 return err;
13386 } else {
13387 sprintf(name, "%s Playback Volume", chname[i]);
13388 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
13389 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13390 HDA_OUTPUT));
bc9f98a9
KY
13391 if (err < 0)
13392 return err;
13393 sprintf(name, "%s Playback Switch", chname[i]);
13394 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
13395 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13396 HDA_INPUT));
bc9f98a9
KY
13397 if (err < 0)
13398 return err;
13399 }
13400 }
13401 return 0;
13402}
13403
13404/* add playback controls for speaker and HP outputs */
13405static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13406 const char *pfx)
13407{
13408 hda_nid_t nid;
13409 int err;
13410 char name[32];
13411
13412 if (!pin)
13413 return 0;
13414
13415 if (alc880_is_fixed_pin(pin)) {
13416 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13417 /* printk("DAC nid=%x\n",nid); */
13418 /* specify the DAC as the extra output */
13419 if (!spec->multiout.hp_nid)
13420 spec->multiout.hp_nid = nid;
13421 else
13422 spec->multiout.extra_out_nid[0] = nid;
13423 /* control HP volume/switch on the output mixer amp */
13424 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13425 sprintf(name, "%s Playback Volume", pfx);
13426 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13427 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13428 if (err < 0)
13429 return err;
13430 sprintf(name, "%s Playback Switch", pfx);
13431 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13432 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13433 if (err < 0)
13434 return err;
13435 } else if (alc880_is_multi_pin(pin)) {
13436 /* set manual connection */
13437 /* we have only a switch on HP-out PIN */
13438 sprintf(name, "%s Playback Switch", pfx);
13439 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13440 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13441 if (err < 0)
13442 return err;
13443 }
13444 return 0;
13445}
13446
13447/* create playback/capture controls for input pins */
13448static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13449 const struct auto_pin_cfg *cfg)
13450{
13451 struct hda_input_mux *imux = &spec->private_imux;
13452 int i, err, idx;
13453
13454 for (i = 0; i < AUTO_PIN_LAST; i++) {
13455 if (alc880_is_input_pin(cfg->input_pins[i])) {
13456 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13457 err = new_analog_input(spec, cfg->input_pins[i],
13458 auto_pin_cfg_labels[i],
13459 idx, 0x0b);
13460 if (err < 0)
13461 return err;
13462 imux->items[imux->num_items].label =
13463 auto_pin_cfg_labels[i];
13464 imux->items[imux->num_items].index =
13465 alc880_input_pin_idx(cfg->input_pins[i]);
13466 imux->num_items++;
13467 }
13468 }
13469 return 0;
13470}
13471
13472static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13473 hda_nid_t nid, int pin_type,
13474 int dac_idx)
13475{
f6c7e546 13476 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
13477 /* need the manual connection? */
13478 if (alc880_is_multi_pin(nid)) {
13479 struct alc_spec *spec = codec->spec;
13480 int idx = alc880_multi_pin_idx(nid);
13481 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13482 AC_VERB_SET_CONNECT_SEL,
13483 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13484 }
13485}
13486
13487static void alc662_auto_init_multi_out(struct hda_codec *codec)
13488{
13489 struct alc_spec *spec = codec->spec;
13490 int i;
13491
8c427226 13492 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
13493 for (i = 0; i <= HDA_SIDE; i++) {
13494 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13495 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 13496 if (nid)
baba8ee9 13497 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
13498 i);
13499 }
13500}
13501
13502static void alc662_auto_init_hp_out(struct hda_codec *codec)
13503{
13504 struct alc_spec *spec = codec->spec;
13505 hda_nid_t pin;
13506
13507 pin = spec->autocfg.hp_pins[0];
13508 if (pin) /* connect to front */
13509 /* use dac 0 */
13510 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
13511 pin = spec->autocfg.speaker_pins[0];
13512 if (pin)
13513 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
13514}
13515
13516#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13517#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13518
13519static void alc662_auto_init_analog_input(struct hda_codec *codec)
13520{
13521 struct alc_spec *spec = codec->spec;
13522 int i;
13523
13524 for (i = 0; i < AUTO_PIN_LAST; i++) {
13525 hda_nid_t nid = spec->autocfg.input_pins[i];
13526 if (alc662_is_input_pin(nid)) {
13527 snd_hda_codec_write(codec, nid, 0,
13528 AC_VERB_SET_PIN_WIDGET_CONTROL,
13529 (i <= AUTO_PIN_FRONT_MIC ?
13530 PIN_VREF80 : PIN_IN));
13531 if (nid != ALC662_PIN_CD_NID)
13532 snd_hda_codec_write(codec, nid, 0,
13533 AC_VERB_SET_AMP_GAIN_MUTE,
13534 AMP_OUT_MUTE);
13535 }
13536 }
13537}
13538
13539static int alc662_parse_auto_config(struct hda_codec *codec)
13540{
13541 struct alc_spec *spec = codec->spec;
13542 int err;
13543 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13544
13545 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13546 alc662_ignore);
13547 if (err < 0)
13548 return err;
13549 if (!spec->autocfg.line_outs)
13550 return 0; /* can't find valid BIOS pin config */
13551
f12ab1e0
TI
13552 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13553 if (err < 0)
13554 return err;
13555 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13556 if (err < 0)
13557 return err;
13558 err = alc662_auto_create_extra_out(spec,
13559 spec->autocfg.speaker_pins[0],
13560 "Speaker");
13561 if (err < 0)
13562 return err;
13563 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13564 "Headphone");
13565 if (err < 0)
13566 return err;
13567 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13568 if (err < 0)
bc9f98a9
KY
13569 return err;
13570
13571 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13572
13573 if (spec->autocfg.dig_out_pin)
13574 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13575
13576 if (spec->kctl_alloc)
13577 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13578
13579 spec->num_mux_defs = 1;
13580 spec->input_mux = &spec->private_imux;
13581
8c87286f 13582 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13583 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13584 spec->num_mixers++;
8c87286f 13585 return 1;
bc9f98a9
KY
13586}
13587
13588/* additional initialization for auto-configuration model */
13589static void alc662_auto_init(struct hda_codec *codec)
13590{
f6c7e546 13591 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
13592 alc662_auto_init_multi_out(codec);
13593 alc662_auto_init_hp_out(codec);
13594 alc662_auto_init_analog_input(codec);
f6c7e546
TI
13595 if (spec->unsol_event)
13596 alc_sku_automute(codec);
bc9f98a9
KY
13597}
13598
13599static int patch_alc662(struct hda_codec *codec)
13600{
13601 struct alc_spec *spec;
13602 int err, board_config;
13603
13604 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13605 if (!spec)
13606 return -ENOMEM;
13607
13608 codec->spec = spec;
13609
13610 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13611 alc662_models,
13612 alc662_cfg_tbl);
13613 if (board_config < 0) {
13614 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13615 "trying auto-probe from BIOS...\n");
13616 board_config = ALC662_AUTO;
13617 }
13618
13619 if (board_config == ALC662_AUTO) {
13620 /* automatic parse from the BIOS config */
13621 err = alc662_parse_auto_config(codec);
13622 if (err < 0) {
13623 alc_free(codec);
13624 return err;
8c87286f 13625 } else if (!err) {
bc9f98a9
KY
13626 printk(KERN_INFO
13627 "hda_codec: Cannot set up configuration "
13628 "from BIOS. Using base mode...\n");
13629 board_config = ALC662_3ST_2ch_DIG;
13630 }
13631 }
13632
13633 if (board_config != ALC662_AUTO)
13634 setup_preset(spec, &alc662_presets[board_config]);
13635
13636 spec->stream_name_analog = "ALC662 Analog";
13637 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13638 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13639
13640 spec->stream_name_digital = "ALC662 Digital";
13641 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13642 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13643
e1406348
TI
13644 spec->adc_nids = alc662_adc_nids;
13645 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13646 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 13647
2134ea4f
TI
13648 spec->vmaster_nid = 0x02;
13649
bc9f98a9
KY
13650 codec->patch_ops = alc_patch_ops;
13651 if (board_config == ALC662_AUTO)
13652 spec->init_hook = alc662_auto_init;
cb53c626
TI
13653#ifdef CONFIG_SND_HDA_POWER_SAVE
13654 if (!spec->loopback.amplist)
13655 spec->loopback.amplist = alc662_loopbacks;
13656#endif
bc9f98a9
KY
13657
13658 return 0;
13659}
13660
1da177e4
LT
13661/*
13662 * patch entries
13663 */
13664struct hda_codec_preset snd_hda_preset_realtek[] = {
13665 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13666 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13667 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13668 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13669 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13670 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13671 .patch = patch_alc861 },
f32610ed
JS
13672 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13673 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13674 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13675 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13676 .patch = patch_alc883 },
13677 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13678 .patch = patch_alc662 },
f32610ed 13679 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13680 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13681 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13682 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13683 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13684 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13685 {} /* terminator */
13686};