]> bbs.cooldavid.org Git - net-next-2.6.git/blame - sound/pci/hda/patch_realtek.c
[ALSA] aw2 - Remove endian dependency
[net-next-2.6.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"
3c9a3203 33#include "hda_patch.h"
1da177e4 34
ccc656ce
KY
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
1da177e4
LT
39
40/* ALC880 board config type */
41enum {
1da177e4
LT
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
dfc0ff62 47 ALC880_Z71V,
b6482d48 48 ALC880_6ST,
16ded525
TI
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
df694daa 54 ALC880_ASUS_DIG2,
2cf9f0fc 55 ALC880_FUJITSU,
16ded525 56 ALC880_UNIWILL_DIG,
ccc656ce
KY
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
df694daa
KY
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
ae6b813a 61 ALC880_LG,
d681518a 62 ALC880_LG_LW,
e9edcee0
TI
63#ifdef CONFIG_SND_DEBUG
64 ALC880_TEST,
65#endif
df694daa 66 ALC880_AUTO,
16ded525
TI
67 ALC880_MODEL_LAST /* last tag */
68};
69
70/* ALC260 models */
71enum {
72 ALC260_BASIC,
73 ALC260_HP,
df694daa
KY
74 ALC260_HP_3013,
75 ALC260_FUJITSU_S702X,
0bfc90e9 76 ALC260_ACER,
bc9f98a9
KY
77 ALC260_WILL,
78 ALC260_REPLACER_672V,
7cf51e48
JW
79#ifdef CONFIG_SND_DEBUG
80 ALC260_TEST,
81#endif
df694daa 82 ALC260_AUTO,
16ded525 83 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
84};
85
df694daa
KY
86/* ALC262 models */
87enum {
88 ALC262_BASIC,
ccc656ce
KY
89 ALC262_HIPPO,
90 ALC262_HIPPO_1,
834be88d 91 ALC262_FUJITSU,
9c7f852e 92 ALC262_HP_BPC,
cd7509a4
KY
93 ALC262_HP_BPC_D7000_WL,
94 ALC262_HP_BPC_D7000_WF,
66d2a9d6 95 ALC262_HP_TC_T5735,
8c427226 96 ALC262_HP_RP5700,
304dcaac 97 ALC262_BENQ_ED8,
272a527c 98 ALC262_SONY_ASSAMD,
83c34218 99 ALC262_BENQ_T31,
f651b50b 100 ALC262_ULTRA,
df694daa
KY
101 ALC262_AUTO,
102 ALC262_MODEL_LAST /* last tag */
103};
104
a361d84b
KY
105/* ALC268 models */
106enum {
107 ALC268_3ST,
d1a991a6 108 ALC268_TOSHIBA,
d273809e 109 ALC268_ACER,
3866f0b0 110 ALC268_DELL,
f12462c5 111 ALC268_ZEPTO,
86c53bd2
JW
112#ifdef CONFIG_SND_DEBUG
113 ALC268_TEST,
114#endif
a361d84b
KY
115 ALC268_AUTO,
116 ALC268_MODEL_LAST /* last tag */
117};
118
f6a92248
KY
119/* ALC269 models */
120enum {
121 ALC269_BASIC,
122 ALC269_AUTO,
123 ALC269_MODEL_LAST /* last tag */
124};
125
df694daa
KY
126/* ALC861 models */
127enum {
128 ALC861_3ST,
9c7f852e 129 ALC660_3ST,
df694daa
KY
130 ALC861_3ST_DIG,
131 ALC861_6ST_DIG,
22309c3e 132 ALC861_UNIWILL_M31,
a53d1aec 133 ALC861_TOSHIBA,
7cdbff94 134 ALC861_ASUS,
56bb0cab 135 ALC861_ASUS_LAPTOP,
df694daa
KY
136 ALC861_AUTO,
137 ALC861_MODEL_LAST,
138};
139
f32610ed
JS
140/* ALC861-VD models */
141enum {
142 ALC660VD_3ST,
6963f84c 143 ALC660VD_3ST_DIG,
f32610ed
JS
144 ALC861VD_3ST,
145 ALC861VD_3ST_DIG,
146 ALC861VD_6ST_DIG,
bdd148a3 147 ALC861VD_LENOVO,
272a527c 148 ALC861VD_DALLAS,
d1a991a6 149 ALC861VD_HP,
f32610ed
JS
150 ALC861VD_AUTO,
151 ALC861VD_MODEL_LAST,
152};
153
bc9f98a9
KY
154/* ALC662 models */
155enum {
156 ALC662_3ST_2ch_DIG,
157 ALC662_3ST_6ch_DIG,
158 ALC662_3ST_6ch,
159 ALC662_5ST_DIG,
160 ALC662_LENOVO_101E,
291702f0 161 ALC662_ASUS_EEEPC_P701,
8c427226 162 ALC662_ASUS_EEEPC_EP20,
bc9f98a9
KY
163 ALC662_AUTO,
164 ALC662_MODEL_LAST,
165};
166
df694daa
KY
167/* ALC882 models */
168enum {
169 ALC882_3ST_DIG,
170 ALC882_6ST_DIG,
4b146cb0 171 ALC882_ARIMA,
bdd148a3 172 ALC882_W2JC,
272a527c
KY
173 ALC882_TARGA,
174 ALC882_ASUS_A7J,
914759b7 175 ALC882_ASUS_A7M,
9102cd1c 176 ALC885_MACPRO,
87350ad0 177 ALC885_MBP3,
c54728d8 178 ALC885_IMAC24,
272a527c 179 ALC882_AUTO,
df694daa
KY
180 ALC882_MODEL_LAST,
181};
182
9c7f852e
TI
183/* ALC883 models */
184enum {
185 ALC883_3ST_2ch_DIG,
186 ALC883_3ST_6ch_DIG,
187 ALC883_3ST_6ch,
188 ALC883_6ST_DIG,
ccc656ce
KY
189 ALC883_TARGA_DIG,
190 ALC883_TARGA_2ch_DIG,
bab282b9 191 ALC883_ACER,
2880a867 192 ALC883_ACER_ASPIRE,
c07584c8 193 ALC883_MEDION,
272a527c 194 ALC883_MEDION_MD2,
b373bdeb 195 ALC883_LAPTOP_EAPD,
bc9f98a9 196 ALC883_LENOVO_101E_2ch,
272a527c 197 ALC883_LENOVO_NB0763,
189609ae
KY
198 ALC888_LENOVO_MS7195_DIG,
199 ALC883_HAIER_W66,
4723c022
CM
200 ALC888_6ST_HP,
201 ALC888_3ST_HP,
5795b9e6 202 ALC888_6ST_DELL,
a8848bd6 203 ALC883_MITAC,
9c7f852e
TI
204 ALC883_AUTO,
205 ALC883_MODEL_LAST,
206};
207
df694daa
KY
208/* for GPIO Poll */
209#define GPIO_MASK 0x03
210
1da177e4
LT
211struct alc_spec {
212 /* codec parameterization */
df694daa 213 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4
LT
214 unsigned int num_mixers;
215
df694daa 216 const struct hda_verb *init_verbs[5]; /* initialization verbs
9c7f852e
TI
217 * don't forget NULL
218 * termination!
e9edcee0
TI
219 */
220 unsigned int num_init_verbs;
1da177e4 221
16ded525 222 char *stream_name_analog; /* analog PCM stream */
1da177e4
LT
223 struct hda_pcm_stream *stream_analog_playback;
224 struct hda_pcm_stream *stream_analog_capture;
6330079f
TI
225 struct hda_pcm_stream *stream_analog_alt_playback;
226 struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 227
f12ab1e0 228 char *stream_name_digital; /* digital PCM stream */
1da177e4
LT
229 struct hda_pcm_stream *stream_digital_playback;
230 struct hda_pcm_stream *stream_digital_capture;
231
232 /* playback */
16ded525
TI
233 struct hda_multi_out multiout; /* playback set-up
234 * max_channels, dacs must be set
235 * dig_out_nid and hp_nid are optional
236 */
6330079f 237 hda_nid_t alt_dac_nid;
1da177e4
LT
238
239 /* capture */
240 unsigned int num_adc_nids;
241 hda_nid_t *adc_nids;
e1406348 242 hda_nid_t *capsrc_nids;
16ded525 243 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4
LT
244
245 /* capture source */
a1e8d2da 246 unsigned int num_mux_defs;
1da177e4
LT
247 const struct hda_input_mux *input_mux;
248 unsigned int cur_mux[3];
249
250 /* channel model */
d2a6d7dc 251 const struct hda_channel_mode *channel_mode;
1da177e4 252 int num_channel_mode;
4e195a7b 253 int need_dac_fix;
1da177e4
LT
254
255 /* PCM information */
4c5186ed 256 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 257
e9edcee0
TI
258 /* dynamic controls, init_verbs and input_mux */
259 struct auto_pin_cfg autocfg;
260 unsigned int num_kctl_alloc, num_kctl_used;
c8b6bf9b 261 struct snd_kcontrol_new *kctl_alloc;
e9edcee0 262 struct hda_input_mux private_imux;
41923e44 263 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
834be88d 264
ae6b813a
TI
265 /* hooks */
266 void (*init_hook)(struct hda_codec *codec);
267 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
268
834be88d
TI
269 /* for pin sensing */
270 unsigned int sense_updated: 1;
271 unsigned int jack_present: 1;
bec15c3a 272 unsigned int master_sw: 1;
cb53c626 273
2134ea4f
TI
274 /* for virtual master */
275 hda_nid_t vmaster_nid;
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")) {
1c82ed1b 1537 unsigned int vmaster_tlv[4];
2134ea4f 1538 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 1539 HDA_OUTPUT, vmaster_tlv);
2134ea4f 1540 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 1541 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
1542 if (err < 0)
1543 return err;
1544 }
1545 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1546 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1547 NULL, alc_slave_sws);
1548 if (err < 0)
1549 return err;
1550 }
1551
1da177e4
LT
1552 return 0;
1553}
1554
e9edcee0 1555
1da177e4
LT
1556/*
1557 * initialize the codec volumes, etc
1558 */
1559
e9edcee0
TI
1560/*
1561 * generic initialization of ADC, input mixers and output mixers
1562 */
1563static struct hda_verb alc880_volume_init_verbs[] = {
1564 /*
1565 * Unmute ADC0-2 and set the default input to mic-in
1566 */
71fe7b82 1567 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1569 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1570 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 1571 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 1572 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 1573
e9edcee0
TI
1574 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1575 * mixer widget
9c7f852e
TI
1576 * Note: PASD motherboards uses the Line In 2 as the input for front
1577 * panel mic (mic 2)
1da177e4 1578 */
e9edcee0 1579 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
1580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 1587
e9edcee0
TI
1588 /*
1589 * Set up output mixers (0x0c - 0x0f)
1da177e4 1590 */
e9edcee0
TI
1591 /* set vol=0 to output mixers */
1592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1593 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1596 /* set up input amps for analog loopback */
1597 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
1598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
1604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1605 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
1606
1607 { }
1608};
1609
e9edcee0
TI
1610/*
1611 * 3-stack pin configuration:
1612 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1613 */
1614static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1615 /*
1616 * preset connection lists of input pins
1617 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1618 */
1619 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1620 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1621 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1622
1623 /*
1624 * Set pin mode and muting
1625 */
1626 /* set front pin widgets 0x14 for output */
05acb863 1627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1628 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1629 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632 /* Mic2 (as headphone out) for HP output */
1633 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1635 /* Line In pin widget for input */
05acb863 1636 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
1637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1638 /* Line2 (as front mic) pin widget for input and vref at 80% */
1639 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1640 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1641 /* CD pin widget for input */
05acb863 1642 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 1643
e9edcee0
TI
1644 { }
1645};
1da177e4 1646
e9edcee0
TI
1647/*
1648 * 5-stack pin configuration:
1649 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1650 * line-in/side = 0x1a, f-mic = 0x1b
1651 */
1652static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1653 /*
1654 * preset connection lists of input pins
1655 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 1656 */
e9edcee0
TI
1657 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1658 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 1659
e9edcee0
TI
1660 /*
1661 * Set pin mode and muting
1da177e4 1662 */
e9edcee0
TI
1663 /* set pin widgets 0x14-0x17 for output */
1664 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1665 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1666 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1667 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1668 /* unmute pins for output (no gain on this amp) */
1669 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1670 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1673
1674 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1677 /* Mic2 (as headphone out) for HP output */
1678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1679 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 /* Line In pin widget for input */
1681 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1682 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683 /* Line2 (as front mic) pin widget for input and vref at 80% */
1684 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1685 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1686 /* CD pin widget for input */
1687 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
1688
1689 { }
1690};
1691
e9edcee0
TI
1692/*
1693 * W810 pin configuration:
1694 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1695 */
1696static struct hda_verb alc880_pin_w810_init_verbs[] = {
1697 /* hphone/speaker input selector: front DAC */
1698 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 1699
05acb863 1700 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1701 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1704 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 1706
e9edcee0 1707 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 1708 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 1709
1da177e4
LT
1710 { }
1711};
1712
e9edcee0
TI
1713/*
1714 * Z71V pin configuration:
1715 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1716 */
1717static struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 1718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1719 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 1720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 1722
16ded525 1723 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 1725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1726 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
1727
1728 { }
1729};
1730
e9edcee0
TI
1731/*
1732 * 6-stack pin configuration:
9c7f852e
TI
1733 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1734 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0
TI
1735 */
1736static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1737 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1738
16ded525 1739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1743 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1745 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1746 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747
16ded525 1748 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1749 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1750 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1751 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 1753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1754 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1757
e9edcee0
TI
1758 { }
1759};
1760
ccc656ce
KY
1761/*
1762 * Uniwill pin configuration:
1763 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1764 * line = 0x1a
1765 */
1766static struct hda_verb alc880_uniwill_init_verbs[] = {
1767 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1768
1769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1771 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1775 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1777 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1778 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1779 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1780 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1781 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1782 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1783
1784 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1786 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1787 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1790 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1791 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1792 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1793
1794 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1795 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1796
1797 { }
1798};
1799
1800/*
1801* Uniwill P53
1802* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1803 */
1804static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1805 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1806
1807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1808 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1811 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1815 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1817 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1818 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1819
1820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1822 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1824 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1826
1827 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1828 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1829
1830 { }
1831};
1832
2cf9f0fc
TD
1833static struct hda_verb alc880_beep_init_verbs[] = {
1834 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1835 { }
1836};
1837
ccc656ce 1838/* toggle speaker-output according to the hp-jack state */
458a4fab 1839static void alc880_uniwill_hp_automute(struct hda_codec *codec)
ccc656ce
KY
1840{
1841 unsigned int present;
f12ab1e0 1842 unsigned char bits;
ccc656ce
KY
1843
1844 present = snd_hda_codec_read(codec, 0x14, 0,
1845 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1846 bits = present ? HDA_AMP_MUTE : 0;
1847 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1848 HDA_AMP_MUTE, bits);
1849 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1850 HDA_AMP_MUTE, bits);
458a4fab
TI
1851}
1852
1853/* auto-toggle front mic */
1854static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1855{
1856 unsigned int present;
1857 unsigned char bits;
ccc656ce
KY
1858
1859 present = snd_hda_codec_read(codec, 0x18, 0,
1860 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1861 bits = present ? HDA_AMP_MUTE : 0;
1862 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
1863}
1864
1865static void alc880_uniwill_automute(struct hda_codec *codec)
1866{
1867 alc880_uniwill_hp_automute(codec);
1868 alc880_uniwill_mic_automute(codec);
ccc656ce
KY
1869}
1870
1871static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1872 unsigned int res)
1873{
1874 /* Looks like the unsol event is incompatible with the standard
1875 * definition. 4bit tag is placed at 28 bit!
1876 */
458a4fab
TI
1877 switch (res >> 28) {
1878 case ALC880_HP_EVENT:
1879 alc880_uniwill_hp_automute(codec);
1880 break;
1881 case ALC880_MIC_EVENT:
1882 alc880_uniwill_mic_automute(codec);
1883 break;
1884 }
ccc656ce
KY
1885}
1886
1887static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1888{
1889 unsigned int present;
f12ab1e0 1890 unsigned char bits;
ccc656ce
KY
1891
1892 present = snd_hda_codec_read(codec, 0x14, 0,
1893 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
1894 bits = present ? HDA_AMP_MUTE : 0;
1895 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
ccc656ce
KY
1896}
1897
1898static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1899{
1900 unsigned int present;
1901
1902 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
1903 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1904 present &= HDA_AMP_VOLMASK;
1905 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1906 HDA_AMP_VOLMASK, present);
1907 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1908 HDA_AMP_VOLMASK, present);
ccc656ce 1909}
47fd830a 1910
ccc656ce
KY
1911static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1912 unsigned int res)
1913{
1914 /* Looks like the unsol event is incompatible with the standard
1915 * definition. 4bit tag is placed at 28 bit!
1916 */
1917 if ((res >> 28) == ALC880_HP_EVENT)
1918 alc880_uniwill_p53_hp_automute(codec);
f12ab1e0 1919 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce
KY
1920 alc880_uniwill_p53_dcvol_automute(codec);
1921}
1922
e9edcee0
TI
1923/*
1924 * F1734 pin configuration:
1925 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1926 */
1927static struct hda_verb alc880_pin_f1734_init_verbs[] = {
16ded525
TI
1928 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1929 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1930 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1931 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1932
e9edcee0 1933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 1934 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 1935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 1936 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1937
e9edcee0
TI
1938 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1940 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 1941 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1942 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1943 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1944 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1945 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1946 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 1947
937b4160
TI
1948 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1949 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1950
dfc0ff62
TI
1951 { }
1952};
1953
e9edcee0
TI
1954/*
1955 * ASUS pin configuration:
1956 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1957 */
1958static struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
1959 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1960 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1961 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1962 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1963
1964 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 1965 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1967 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1969 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 1970 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
1971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1972
1973 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1975 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1977 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 1979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 1980 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525
TI
1981 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1982
e9edcee0
TI
1983 { }
1984};
16ded525 1985
e9edcee0 1986/* Enable GPIO mask and set output */
bc9f98a9
KY
1987#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1988#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
df694daa
KY
1989
1990/* Clevo m520g init */
1991static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1992 /* headphone output */
1993 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1994 /* line-out */
1995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1996 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997 /* Line-in */
1998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1999 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 /* CD */
2001 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2002 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 /* Mic1 (rear panel) */
2004 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2005 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006 /* Mic2 (front panel) */
2007 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2008 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2009 /* headphone */
2010 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2011 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2012 /* change to EAPD mode */
2013 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2014 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2015
2016 { }
16ded525
TI
2017};
2018
df694daa 2019static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
2020 /* change to EAPD mode */
2021 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2022 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2023
df694daa
KY
2024 /* Headphone output */
2025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2026 /* Front output*/
2027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2028 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2029
2030 /* Line In pin widget for input */
2031 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2032 /* CD pin widget for input */
2033 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2034 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2035 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2036
2037 /* change to EAPD mode */
2038 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2039 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2040
2041 { }
2042};
16ded525 2043
e9edcee0 2044/*
ae6b813a
TI
2045 * LG m1 express dual
2046 *
2047 * Pin assignment:
2048 * Rear Line-In/Out (blue): 0x14
2049 * Build-in Mic-In: 0x15
2050 * Speaker-out: 0x17
2051 * HP-Out (green): 0x1b
2052 * Mic-In/Out (red): 0x19
2053 * SPDIF-Out: 0x1e
2054 */
2055
2056/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2057static hda_nid_t alc880_lg_dac_nids[3] = {
2058 0x05, 0x02, 0x03
2059};
2060
2061/* seems analog CD is not working */
2062static struct hda_input_mux alc880_lg_capture_source = {
2063 .num_items = 3,
2064 .items = {
2065 { "Mic", 0x1 },
2066 { "Line", 0x5 },
2067 { "Internal Mic", 0x6 },
2068 },
2069};
2070
2071/* 2,4,6 channel modes */
2072static struct hda_verb alc880_lg_ch2_init[] = {
2073 /* set line-in and mic-in to input */
2074 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2075 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2076 { }
2077};
2078
2079static struct hda_verb alc880_lg_ch4_init[] = {
2080 /* set line-in to out and mic-in to input */
2081 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2082 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2083 { }
2084};
2085
2086static struct hda_verb alc880_lg_ch6_init[] = {
2087 /* set line-in and mic-in to output */
2088 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2090 { }
2091};
2092
2093static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2094 { 2, alc880_lg_ch2_init },
2095 { 4, alc880_lg_ch4_init },
2096 { 6, alc880_lg_ch6_init },
2097};
2098
2099static struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
2100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2101 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
2102 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2103 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2104 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2105 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2106 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2107 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2112 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2113 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2114 {
2115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2116 .name = "Channel Mode",
2117 .info = alc_ch_mode_info,
2118 .get = alc_ch_mode_get,
2119 .put = alc_ch_mode_put,
2120 },
2121 { } /* end */
2122};
2123
2124static struct hda_verb alc880_lg_init_verbs[] = {
2125 /* set capture source to mic-in */
2126 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2127 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2129 /* mute all amp mixer inputs */
2130 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
2131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2132 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
2133 /* line-in to input */
2134 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2135 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2136 /* built-in mic */
2137 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2138 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2139 /* speaker-out */
2140 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2141 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2142 /* mic-in to input */
2143 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2144 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2146 /* HP-out */
2147 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2150 /* jack sense */
2151 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2152 { }
2153};
2154
2155/* toggle speaker-output according to the hp-jack state */
2156static void alc880_lg_automute(struct hda_codec *codec)
2157{
2158 unsigned int present;
f12ab1e0 2159 unsigned char bits;
ae6b813a
TI
2160
2161 present = snd_hda_codec_read(codec, 0x1b, 0,
2162 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2163 bits = present ? HDA_AMP_MUTE : 0;
2164 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2165 HDA_AMP_MUTE, bits);
ae6b813a
TI
2166}
2167
2168static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2169{
2170 /* Looks like the unsol event is incompatible with the standard
2171 * definition. 4bit tag is placed at 28 bit!
2172 */
2173 if ((res >> 28) == 0x01)
2174 alc880_lg_automute(codec);
2175}
2176
d681518a
TI
2177/*
2178 * LG LW20
2179 *
2180 * Pin assignment:
2181 * Speaker-out: 0x14
2182 * Mic-In: 0x18
e4f41da9
CM
2183 * Built-in Mic-In: 0x19
2184 * Line-In: 0x1b
2185 * HP-Out: 0x1a
d681518a
TI
2186 * SPDIF-Out: 0x1e
2187 */
2188
d681518a 2189static struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 2190 .num_items = 3,
d681518a
TI
2191 .items = {
2192 { "Mic", 0x0 },
2193 { "Internal Mic", 0x1 },
e4f41da9 2194 { "Line In", 0x2 },
d681518a
TI
2195 },
2196};
2197
0a8c5da3
CM
2198#define alc880_lg_lw_modes alc880_threestack_modes
2199
d681518a 2200static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
2201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2204 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2205 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2206 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2207 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2208 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
2211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2214 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
2215 {
2216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2217 .name = "Channel Mode",
2218 .info = alc_ch_mode_info,
2219 .get = alc_ch_mode_get,
2220 .put = alc_ch_mode_put,
2221 },
d681518a
TI
2222 { } /* end */
2223};
2224
2225static struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
2226 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2227 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2228 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2229
d681518a
TI
2230 /* set capture source to mic-in */
2231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2232 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2233 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 2234 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
2235 /* speaker-out */
2236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238 /* HP-out */
d681518a
TI
2239 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2241 /* mic-in to input */
2242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2243 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2244 /* built-in mic */
2245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2246 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2247 /* jack sense */
2248 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2249 { }
2250};
2251
2252/* toggle speaker-output according to the hp-jack state */
2253static void alc880_lg_lw_automute(struct hda_codec *codec)
2254{
2255 unsigned int present;
f12ab1e0 2256 unsigned char bits;
d681518a
TI
2257
2258 present = snd_hda_codec_read(codec, 0x1b, 0,
2259 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
2260 bits = present ? HDA_AMP_MUTE : 0;
2261 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2262 HDA_AMP_MUTE, bits);
d681518a
TI
2263}
2264
2265static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2266{
2267 /* Looks like the unsol event is incompatible with the standard
2268 * definition. 4bit tag is placed at 28 bit!
2269 */
2270 if ((res >> 28) == 0x01)
2271 alc880_lg_lw_automute(codec);
2272}
2273
cb53c626
TI
2274#ifdef CONFIG_SND_HDA_POWER_SAVE
2275static struct hda_amp_list alc880_loopbacks[] = {
2276 { 0x0b, HDA_INPUT, 0 },
2277 { 0x0b, HDA_INPUT, 1 },
2278 { 0x0b, HDA_INPUT, 2 },
2279 { 0x0b, HDA_INPUT, 3 },
2280 { 0x0b, HDA_INPUT, 4 },
2281 { } /* end */
2282};
2283
2284static struct hda_amp_list alc880_lg_loopbacks[] = {
2285 { 0x0b, HDA_INPUT, 1 },
2286 { 0x0b, HDA_INPUT, 6 },
2287 { 0x0b, HDA_INPUT, 7 },
2288 { } /* end */
2289};
2290#endif
2291
ae6b813a
TI
2292/*
2293 * Common callbacks
e9edcee0
TI
2294 */
2295
1da177e4
LT
2296static int alc_init(struct hda_codec *codec)
2297{
2298 struct alc_spec *spec = codec->spec;
e9edcee0
TI
2299 unsigned int i;
2300
2301 for (i = 0; i < spec->num_init_verbs; i++)
2302 snd_hda_sequence_write(codec, spec->init_verbs[i]);
ae6b813a
TI
2303
2304 if (spec->init_hook)
2305 spec->init_hook(codec);
2306
1da177e4
LT
2307 return 0;
2308}
2309
ae6b813a
TI
2310static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2311{
2312 struct alc_spec *spec = codec->spec;
2313
2314 if (spec->unsol_event)
2315 spec->unsol_event(codec, res);
2316}
2317
cb53c626
TI
2318#ifdef CONFIG_SND_HDA_POWER_SAVE
2319static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2320{
2321 struct alc_spec *spec = codec->spec;
2322 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2323}
2324#endif
2325
1da177e4
LT
2326/*
2327 * Analog playback callbacks
2328 */
2329static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2330 struct hda_codec *codec,
c8b6bf9b 2331 struct snd_pcm_substream *substream)
1da177e4
LT
2332{
2333 struct alc_spec *spec = codec->spec;
9a08160b
TI
2334 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2335 hinfo);
1da177e4
LT
2336}
2337
2338static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2339 struct hda_codec *codec,
2340 unsigned int stream_tag,
2341 unsigned int format,
c8b6bf9b 2342 struct snd_pcm_substream *substream)
1da177e4
LT
2343{
2344 struct alc_spec *spec = codec->spec;
9c7f852e
TI
2345 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2346 stream_tag, format, substream);
1da177e4
LT
2347}
2348
2349static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2350 struct hda_codec *codec,
c8b6bf9b 2351 struct snd_pcm_substream *substream)
1da177e4
LT
2352{
2353 struct alc_spec *spec = codec->spec;
2354 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2355}
2356
2357/*
2358 * Digital out
2359 */
2360static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2361 struct hda_codec *codec,
c8b6bf9b 2362 struct snd_pcm_substream *substream)
1da177e4
LT
2363{
2364 struct alc_spec *spec = codec->spec;
2365 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2366}
2367
6b97eb45
TI
2368static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2369 struct hda_codec *codec,
2370 unsigned int stream_tag,
2371 unsigned int format,
2372 struct snd_pcm_substream *substream)
2373{
2374 struct alc_spec *spec = codec->spec;
2375 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2376 stream_tag, format, substream);
2377}
2378
1da177e4
LT
2379static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2380 struct hda_codec *codec,
c8b6bf9b 2381 struct snd_pcm_substream *substream)
1da177e4
LT
2382{
2383 struct alc_spec *spec = codec->spec;
2384 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2385}
2386
2387/*
2388 * Analog capture
2389 */
6330079f 2390static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
2391 struct hda_codec *codec,
2392 unsigned int stream_tag,
2393 unsigned int format,
c8b6bf9b 2394 struct snd_pcm_substream *substream)
1da177e4
LT
2395{
2396 struct alc_spec *spec = codec->spec;
2397
6330079f 2398 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
2399 stream_tag, 0, format);
2400 return 0;
2401}
2402
6330079f 2403static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 2404 struct hda_codec *codec,
c8b6bf9b 2405 struct snd_pcm_substream *substream)
1da177e4
LT
2406{
2407 struct alc_spec *spec = codec->spec;
2408
6330079f 2409 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
9c7f852e 2410 0, 0, 0);
1da177e4
LT
2411 return 0;
2412}
2413
2414
2415/*
2416 */
2417static struct hda_pcm_stream alc880_pcm_analog_playback = {
2418 .substreams = 1,
2419 .channels_min = 2,
2420 .channels_max = 8,
e9edcee0 2421 /* NID is set in alc_build_pcms */
1da177e4
LT
2422 .ops = {
2423 .open = alc880_playback_pcm_open,
2424 .prepare = alc880_playback_pcm_prepare,
2425 .cleanup = alc880_playback_pcm_cleanup
2426 },
2427};
2428
2429static struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
2430 .substreams = 1,
2431 .channels_min = 2,
2432 .channels_max = 2,
2433 /* NID is set in alc_build_pcms */
2434};
2435
2436static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2437 .substreams = 1,
2438 .channels_min = 2,
2439 .channels_max = 2,
2440 /* NID is set in alc_build_pcms */
2441};
2442
2443static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2444 .substreams = 2, /* can be overridden */
1da177e4
LT
2445 .channels_min = 2,
2446 .channels_max = 2,
e9edcee0 2447 /* NID is set in alc_build_pcms */
1da177e4 2448 .ops = {
6330079f
TI
2449 .prepare = alc880_alt_capture_pcm_prepare,
2450 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
2451 },
2452};
2453
2454static struct hda_pcm_stream alc880_pcm_digital_playback = {
2455 .substreams = 1,
2456 .channels_min = 2,
2457 .channels_max = 2,
2458 /* NID is set in alc_build_pcms */
2459 .ops = {
2460 .open = alc880_dig_playback_pcm_open,
6b97eb45
TI
2461 .close = alc880_dig_playback_pcm_close,
2462 .prepare = alc880_dig_playback_pcm_prepare
1da177e4
LT
2463 },
2464};
2465
2466static struct hda_pcm_stream alc880_pcm_digital_capture = {
2467 .substreams = 1,
2468 .channels_min = 2,
2469 .channels_max = 2,
2470 /* NID is set in alc_build_pcms */
2471};
2472
4c5186ed 2473/* Used by alc_build_pcms to flag that a PCM has no playback stream */
6330079f 2474static struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
2475 .substreams = 0,
2476 .channels_min = 0,
2477 .channels_max = 0,
2478};
2479
1da177e4
LT
2480static int alc_build_pcms(struct hda_codec *codec)
2481{
2482 struct alc_spec *spec = codec->spec;
2483 struct hda_pcm *info = spec->pcm_rec;
2484 int i;
2485
2486 codec->num_pcms = 1;
2487 codec->pcm_info = info;
2488
2489 info->name = spec->stream_name_analog;
4a471b7d
TI
2490 if (spec->stream_analog_playback) {
2491 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2492 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2493 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2494 }
2495 if (spec->stream_analog_capture) {
2496 snd_assert(spec->adc_nids, return -EINVAL);
2497 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2498 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2499 }
2500
2501 if (spec->channel_mode) {
2502 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2503 for (i = 0; i < spec->num_channel_mode; i++) {
2504 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2505 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2506 }
1da177e4
LT
2507 }
2508 }
2509
e08a007d 2510 /* SPDIF for stream index #1 */
1da177e4 2511 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
e08a007d 2512 codec->num_pcms = 2;
c06134d7 2513 info = spec->pcm_rec + 1;
1da177e4 2514 info->name = spec->stream_name_digital;
7ba72ba1 2515 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
2516 if (spec->multiout.dig_out_nid &&
2517 spec->stream_digital_playback) {
1da177e4
LT
2518 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2519 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2520 }
4a471b7d
TI
2521 if (spec->dig_in_nid &&
2522 spec->stream_digital_capture) {
1da177e4
LT
2523 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2524 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2525 }
2526 }
2527
e08a007d
TI
2528 /* If the use of more than one ADC is requested for the current
2529 * model, configure a second analog capture-only PCM.
2530 */
2531 /* Additional Analaog capture for index #2 */
6330079f
TI
2532 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2533 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 2534 codec->num_pcms = 3;
c06134d7 2535 info = spec->pcm_rec + 2;
e08a007d 2536 info->name = spec->stream_name_analog;
6330079f
TI
2537 if (spec->alt_dac_nid) {
2538 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2539 *spec->stream_analog_alt_playback;
2540 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2541 spec->alt_dac_nid;
2542 } else {
2543 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2544 alc_pcm_null_stream;
2545 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2546 }
2547 if (spec->num_adc_nids > 1) {
2548 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2549 *spec->stream_analog_alt_capture;
2550 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2551 spec->adc_nids[1];
2552 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2553 spec->num_adc_nids - 1;
2554 } else {
2555 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2556 alc_pcm_null_stream;
2557 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
2558 }
2559 }
2560
1da177e4
LT
2561 return 0;
2562}
2563
2564static void alc_free(struct hda_codec *codec)
2565{
e9edcee0
TI
2566 struct alc_spec *spec = codec->spec;
2567 unsigned int i;
2568
f12ab1e0 2569 if (!spec)
e9edcee0
TI
2570 return;
2571
2572 if (spec->kctl_alloc) {
2573 for (i = 0; i < spec->num_kctl_used; i++)
2574 kfree(spec->kctl_alloc[i].name);
2575 kfree(spec->kctl_alloc);
2576 }
2577 kfree(spec);
1da177e4
LT
2578}
2579
2580/*
2581 */
2582static struct hda_codec_ops alc_patch_ops = {
2583 .build_controls = alc_build_controls,
2584 .build_pcms = alc_build_pcms,
2585 .init = alc_init,
2586 .free = alc_free,
ae6b813a 2587 .unsol_event = alc_unsol_event,
cb53c626
TI
2588#ifdef CONFIG_SND_HDA_POWER_SAVE
2589 .check_power_status = alc_check_power_status,
2590#endif
1da177e4
LT
2591};
2592
2fa522be
TI
2593
2594/*
2595 * Test configuration for debugging
2596 *
2597 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2598 * enum controls.
2599 */
2600#ifdef CONFIG_SND_DEBUG
2601static hda_nid_t alc880_test_dac_nids[4] = {
2602 0x02, 0x03, 0x04, 0x05
2603};
2604
2605static struct hda_input_mux alc880_test_capture_source = {
ae6b813a 2606 .num_items = 7,
2fa522be
TI
2607 .items = {
2608 { "In-1", 0x0 },
2609 { "In-2", 0x1 },
2610 { "In-3", 0x2 },
2611 { "In-4", 0x3 },
2612 { "CD", 0x4 },
ae6b813a
TI
2613 { "Front", 0x5 },
2614 { "Surround", 0x6 },
2fa522be
TI
2615 },
2616};
2617
d2a6d7dc 2618static struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 2619 { 2, NULL },
fd2c326d 2620 { 4, NULL },
2fa522be 2621 { 6, NULL },
fd2c326d 2622 { 8, NULL },
2fa522be
TI
2623};
2624
9c7f852e
TI
2625static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2626 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2627{
2628 static char *texts[] = {
2629 "N/A", "Line Out", "HP Out",
2630 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2631 };
2632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2633 uinfo->count = 1;
2634 uinfo->value.enumerated.items = 8;
2635 if (uinfo->value.enumerated.item >= 8)
2636 uinfo->value.enumerated.item = 7;
2637 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2638 return 0;
2639}
2640
9c7f852e
TI
2641static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2642 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2643{
2644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2645 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2646 unsigned int pin_ctl, item = 0;
2647
2648 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2649 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2650 if (pin_ctl & AC_PINCTL_OUT_EN) {
2651 if (pin_ctl & AC_PINCTL_HP_EN)
2652 item = 2;
2653 else
2654 item = 1;
2655 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2656 switch (pin_ctl & AC_PINCTL_VREFEN) {
2657 case AC_PINCTL_VREF_HIZ: item = 3; break;
2658 case AC_PINCTL_VREF_50: item = 4; break;
2659 case AC_PINCTL_VREF_GRD: item = 5; break;
2660 case AC_PINCTL_VREF_80: item = 6; break;
2661 case AC_PINCTL_VREF_100: item = 7; break;
2662 }
2663 }
2664 ucontrol->value.enumerated.item[0] = item;
2665 return 0;
2666}
2667
9c7f852e
TI
2668static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2669 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2670{
2671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2672 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2673 static unsigned int ctls[] = {
2674 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2675 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2676 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2677 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2678 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2679 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2680 };
2681 unsigned int old_ctl, new_ctl;
2682
2683 old_ctl = snd_hda_codec_read(codec, nid, 0,
2684 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2685 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2686 if (old_ctl != new_ctl) {
82beb8fd
TI
2687 int val;
2688 snd_hda_codec_write_cache(codec, nid, 0,
2689 AC_VERB_SET_PIN_WIDGET_CONTROL,
2690 new_ctl);
47fd830a
TI
2691 val = ucontrol->value.enumerated.item[0] >= 3 ?
2692 HDA_AMP_MUTE : 0;
2693 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2694 HDA_AMP_MUTE, val);
2fa522be
TI
2695 return 1;
2696 }
2697 return 0;
2698}
2699
9c7f852e
TI
2700static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2701 struct snd_ctl_elem_info *uinfo)
2fa522be
TI
2702{
2703 static char *texts[] = {
2704 "Front", "Surround", "CLFE", "Side"
2705 };
2706 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2707 uinfo->count = 1;
2708 uinfo->value.enumerated.items = 4;
2709 if (uinfo->value.enumerated.item >= 4)
2710 uinfo->value.enumerated.item = 3;
2711 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2712 return 0;
2713}
2714
9c7f852e
TI
2715static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2716 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2717{
2718 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2719 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2720 unsigned int sel;
2721
2722 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2723 ucontrol->value.enumerated.item[0] = sel & 3;
2724 return 0;
2725}
2726
9c7f852e
TI
2727static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2728 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
2729{
2730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2731 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2732 unsigned int sel;
2733
2734 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2735 if (ucontrol->value.enumerated.item[0] != sel) {
2736 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
2737 snd_hda_codec_write_cache(codec, nid, 0,
2738 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
2739 return 1;
2740 }
2741 return 0;
2742}
2743
2744#define PIN_CTL_TEST(xname,nid) { \
2745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2746 .name = xname, \
2747 .info = alc_test_pin_ctl_info, \
2748 .get = alc_test_pin_ctl_get, \
2749 .put = alc_test_pin_ctl_put, \
2750 .private_value = nid \
2751 }
2752
2753#define PIN_SRC_TEST(xname,nid) { \
2754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2755 .name = xname, \
2756 .info = alc_test_pin_src_info, \
2757 .get = alc_test_pin_src_get, \
2758 .put = alc_test_pin_src_put, \
2759 .private_value = nid \
2760 }
2761
c8b6bf9b 2762static struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
2763 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2764 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2765 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2766 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
2767 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2768 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2769 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2770 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
2771 PIN_CTL_TEST("Front Pin Mode", 0x14),
2772 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2773 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2774 PIN_CTL_TEST("Side Pin Mode", 0x17),
2775 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2776 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2777 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2778 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2779 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2780 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2781 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2782 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2783 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2784 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2785 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2786 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2787 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2788 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2789 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2790 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2791 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2792 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
2793 {
2794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2795 .name = "Channel Mode",
df694daa
KY
2796 .info = alc_ch_mode_info,
2797 .get = alc_ch_mode_get,
2798 .put = alc_ch_mode_put,
2fa522be
TI
2799 },
2800 { } /* end */
2801};
2802
2803static struct hda_verb alc880_test_init_verbs[] = {
2804 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
2805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2810 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 2813 /* Vol output for 0x0c-0x0f */
05acb863
TI
2814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2815 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2816 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2817 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 2818 /* Set output pins 0x14-0x17 */
05acb863
TI
2819 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2820 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2821 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2822 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 2823 /* Unmute output pins 0x14-0x17 */
05acb863
TI
2824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2827 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 2828 /* Set input pins 0x18-0x1c */
16ded525
TI
2829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
2831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2832 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2833 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 2834 /* Mute input pins 0x18-0x1b */
05acb863
TI
2835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 2839 /* ADC set up */
05acb863 2840 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2841 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2842 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2843 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 2844 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 2845 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
2846 /* Analog input/passthru */
2847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
2852 { }
2853};
2854#endif
2855
1da177e4
LT
2856/*
2857 */
2858
f5fcc13c
TI
2859static const char *alc880_models[ALC880_MODEL_LAST] = {
2860 [ALC880_3ST] = "3stack",
2861 [ALC880_TCL_S700] = "tcl",
2862 [ALC880_3ST_DIG] = "3stack-digout",
2863 [ALC880_CLEVO] = "clevo",
2864 [ALC880_5ST] = "5stack",
2865 [ALC880_5ST_DIG] = "5stack-digout",
2866 [ALC880_W810] = "w810",
2867 [ALC880_Z71V] = "z71v",
2868 [ALC880_6ST] = "6stack",
2869 [ALC880_6ST_DIG] = "6stack-digout",
2870 [ALC880_ASUS] = "asus",
2871 [ALC880_ASUS_W1V] = "asus-w1v",
2872 [ALC880_ASUS_DIG] = "asus-dig",
2873 [ALC880_ASUS_DIG2] = "asus-dig2",
2874 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
2875 [ALC880_UNIWILL_P53] = "uniwill-p53",
2876 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
2877 [ALC880_F1734] = "F1734",
2878 [ALC880_LG] = "lg",
2879 [ALC880_LG_LW] = "lg-lw",
2fa522be 2880#ifdef CONFIG_SND_DEBUG
f5fcc13c 2881 [ALC880_TEST] = "test",
2fa522be 2882#endif
f5fcc13c
TI
2883 [ALC880_AUTO] = "auto",
2884};
2885
2886static struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 2887 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
2888 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2889 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2890 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2891 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2892 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2893 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2894 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2895 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
2896 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2897 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
2898 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2899 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2900 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2901 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2902 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2903 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2904 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2905 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2906 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2907 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
0e4ceb75 2908 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
f5fcc13c
TI
2909 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2910 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2911 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
ac3e3741 2912 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 2913 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
2914 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2915 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
2916 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2917 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
2918 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2919 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2920 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2921 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
2922 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2923 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 2924 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 2925 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 2926 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
ac3e3741 2927 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
f5fcc13c
TI
2928 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2929 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741
TI
2930 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2931 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 2932 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 2933 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
ac3e3741 2934 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2cf9f0fc 2935 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 2936 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c
TI
2937 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2938 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 2939 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
2940 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2941 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2942 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2943 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
2944 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2945 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 2946 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 2947 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2948 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2949 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
2950 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2951 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2952 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
2953 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2954 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2955 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
2956 {}
2957};
2958
16ded525 2959/*
df694daa 2960 * ALC880 codec presets
16ded525 2961 */
16ded525
TI
2962static struct alc_config_preset alc880_presets[] = {
2963 [ALC880_3ST] = {
e9edcee0 2964 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2965 .init_verbs = { alc880_volume_init_verbs,
2966 alc880_pin_3stack_init_verbs },
16ded525 2967 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 2968 .dac_nids = alc880_dac_nids,
16ded525
TI
2969 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2970 .channel_mode = alc880_threestack_modes,
4e195a7b 2971 .need_dac_fix = 1,
16ded525
TI
2972 .input_mux = &alc880_capture_source,
2973 },
2974 [ALC880_3ST_DIG] = {
e9edcee0 2975 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
2976 .init_verbs = { alc880_volume_init_verbs,
2977 alc880_pin_3stack_init_verbs },
16ded525 2978 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
2979 .dac_nids = alc880_dac_nids,
2980 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
2981 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2982 .channel_mode = alc880_threestack_modes,
4e195a7b 2983 .need_dac_fix = 1,
16ded525
TI
2984 .input_mux = &alc880_capture_source,
2985 },
df694daa
KY
2986 [ALC880_TCL_S700] = {
2987 .mixers = { alc880_tcl_s700_mixer },
2988 .init_verbs = { alc880_volume_init_verbs,
2989 alc880_pin_tcl_S700_init_verbs,
2990 alc880_gpio2_init_verbs },
2991 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2992 .dac_nids = alc880_dac_nids,
2993 .hp_nid = 0x03,
2994 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2995 .channel_mode = alc880_2_jack_modes,
2996 .input_mux = &alc880_capture_source,
2997 },
16ded525 2998 [ALC880_5ST] = {
f12ab1e0
TI
2999 .mixers = { alc880_three_stack_mixer,
3000 alc880_five_stack_mixer},
3001 .init_verbs = { alc880_volume_init_verbs,
3002 alc880_pin_5stack_init_verbs },
16ded525
TI
3003 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3004 .dac_nids = alc880_dac_nids,
16ded525
TI
3005 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3006 .channel_mode = alc880_fivestack_modes,
3007 .input_mux = &alc880_capture_source,
3008 },
3009 [ALC880_5ST_DIG] = {
f12ab1e0
TI
3010 .mixers = { alc880_three_stack_mixer,
3011 alc880_five_stack_mixer },
3012 .init_verbs = { alc880_volume_init_verbs,
3013 alc880_pin_5stack_init_verbs },
16ded525
TI
3014 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3015 .dac_nids = alc880_dac_nids,
3016 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3017 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3018 .channel_mode = alc880_fivestack_modes,
3019 .input_mux = &alc880_capture_source,
3020 },
b6482d48
TI
3021 [ALC880_6ST] = {
3022 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3023 .init_verbs = { alc880_volume_init_verbs,
3024 alc880_pin_6stack_init_verbs },
b6482d48
TI
3025 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3026 .dac_nids = alc880_6st_dac_nids,
3027 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3028 .channel_mode = alc880_sixstack_modes,
3029 .input_mux = &alc880_6stack_capture_source,
3030 },
16ded525 3031 [ALC880_6ST_DIG] = {
e9edcee0 3032 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
3033 .init_verbs = { alc880_volume_init_verbs,
3034 alc880_pin_6stack_init_verbs },
16ded525
TI
3035 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3036 .dac_nids = alc880_6st_dac_nids,
3037 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3038 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3039 .channel_mode = alc880_sixstack_modes,
3040 .input_mux = &alc880_6stack_capture_source,
3041 },
3042 [ALC880_W810] = {
e9edcee0 3043 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
3044 .init_verbs = { alc880_volume_init_verbs,
3045 alc880_pin_w810_init_verbs,
b0af0de5 3046 alc880_gpio2_init_verbs },
16ded525
TI
3047 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3048 .dac_nids = alc880_w810_dac_nids,
3049 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3050 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3051 .channel_mode = alc880_w810_modes,
3052 .input_mux = &alc880_capture_source,
3053 },
3054 [ALC880_Z71V] = {
e9edcee0 3055 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
3056 .init_verbs = { alc880_volume_init_verbs,
3057 alc880_pin_z71v_init_verbs },
16ded525
TI
3058 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3059 .dac_nids = alc880_z71v_dac_nids,
3060 .dig_out_nid = ALC880_DIGOUT_NID,
3061 .hp_nid = 0x03,
e9edcee0
TI
3062 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3063 .channel_mode = alc880_2_jack_modes,
16ded525
TI
3064 .input_mux = &alc880_capture_source,
3065 },
3066 [ALC880_F1734] = {
e9edcee0 3067 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
3068 .init_verbs = { alc880_volume_init_verbs,
3069 alc880_pin_f1734_init_verbs },
e9edcee0
TI
3070 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3071 .dac_nids = alc880_f1734_dac_nids,
3072 .hp_nid = 0x02,
3073 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3074 .channel_mode = alc880_2_jack_modes,
937b4160
TI
3075 .input_mux = &alc880_f1734_capture_source,
3076 .unsol_event = alc880_uniwill_p53_unsol_event,
3077 .init_hook = alc880_uniwill_p53_hp_automute,
16ded525
TI
3078 },
3079 [ALC880_ASUS] = {
e9edcee0 3080 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3081 .init_verbs = { alc880_volume_init_verbs,
3082 alc880_pin_asus_init_verbs,
e9edcee0
TI
3083 alc880_gpio1_init_verbs },
3084 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3085 .dac_nids = alc880_asus_dac_nids,
3086 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3087 .channel_mode = alc880_asus_modes,
4e195a7b 3088 .need_dac_fix = 1,
16ded525
TI
3089 .input_mux = &alc880_capture_source,
3090 },
3091 [ALC880_ASUS_DIG] = {
e9edcee0 3092 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3093 .init_verbs = { alc880_volume_init_verbs,
3094 alc880_pin_asus_init_verbs,
e9edcee0
TI
3095 alc880_gpio1_init_verbs },
3096 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3097 .dac_nids = alc880_asus_dac_nids,
16ded525 3098 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3099 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3100 .channel_mode = alc880_asus_modes,
4e195a7b 3101 .need_dac_fix = 1,
16ded525
TI
3102 .input_mux = &alc880_capture_source,
3103 },
df694daa
KY
3104 [ALC880_ASUS_DIG2] = {
3105 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
3106 .init_verbs = { alc880_volume_init_verbs,
3107 alc880_pin_asus_init_verbs,
df694daa
KY
3108 alc880_gpio2_init_verbs }, /* use GPIO2 */
3109 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3110 .dac_nids = alc880_asus_dac_nids,
3111 .dig_out_nid = ALC880_DIGOUT_NID,
3112 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3113 .channel_mode = alc880_asus_modes,
4e195a7b 3114 .need_dac_fix = 1,
df694daa
KY
3115 .input_mux = &alc880_capture_source,
3116 },
16ded525 3117 [ALC880_ASUS_W1V] = {
e9edcee0 3118 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
3119 .init_verbs = { alc880_volume_init_verbs,
3120 alc880_pin_asus_init_verbs,
e9edcee0
TI
3121 alc880_gpio1_init_verbs },
3122 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3123 .dac_nids = alc880_asus_dac_nids,
16ded525 3124 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3125 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3126 .channel_mode = alc880_asus_modes,
4e195a7b 3127 .need_dac_fix = 1,
16ded525
TI
3128 .input_mux = &alc880_capture_source,
3129 },
3130 [ALC880_UNIWILL_DIG] = {
3c10a9d9 3131 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
ccc656ce
KY
3132 .init_verbs = { alc880_volume_init_verbs,
3133 alc880_pin_asus_init_verbs },
e9edcee0
TI
3134 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3135 .dac_nids = alc880_asus_dac_nids,
16ded525 3136 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
3137 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3138 .channel_mode = alc880_asus_modes,
4e195a7b 3139 .need_dac_fix = 1,
16ded525
TI
3140 .input_mux = &alc880_capture_source,
3141 },
ccc656ce
KY
3142 [ALC880_UNIWILL] = {
3143 .mixers = { alc880_uniwill_mixer },
3144 .init_verbs = { alc880_volume_init_verbs,
3145 alc880_uniwill_init_verbs },
3146 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3147 .dac_nids = alc880_asus_dac_nids,
3148 .dig_out_nid = ALC880_DIGOUT_NID,
3149 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3150 .channel_mode = alc880_threestack_modes,
3151 .need_dac_fix = 1,
3152 .input_mux = &alc880_capture_source,
3153 .unsol_event = alc880_uniwill_unsol_event,
3154 .init_hook = alc880_uniwill_automute,
3155 },
3156 [ALC880_UNIWILL_P53] = {
3157 .mixers = { alc880_uniwill_p53_mixer },
3158 .init_verbs = { alc880_volume_init_verbs,
3159 alc880_uniwill_p53_init_verbs },
3160 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3161 .dac_nids = alc880_asus_dac_nids,
3162 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
3163 .channel_mode = alc880_threestack_modes,
3164 .input_mux = &alc880_capture_source,
3165 .unsol_event = alc880_uniwill_p53_unsol_event,
3166 .init_hook = alc880_uniwill_p53_hp_automute,
3167 },
3168 [ALC880_FUJITSU] = {
f12ab1e0 3169 .mixers = { alc880_fujitsu_mixer,
2cf9f0fc
TD
3170 alc880_pcbeep_mixer, },
3171 .init_verbs = { alc880_volume_init_verbs,
3172 alc880_uniwill_p53_init_verbs,
3173 alc880_beep_init_verbs },
3174 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3175 .dac_nids = alc880_dac_nids,
d53d7d9e 3176 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
3177 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3178 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
3179 .input_mux = &alc880_capture_source,
3180 .unsol_event = alc880_uniwill_p53_unsol_event,
3181 .init_hook = alc880_uniwill_p53_hp_automute,
3182 },
df694daa
KY
3183 [ALC880_CLEVO] = {
3184 .mixers = { alc880_three_stack_mixer },
3185 .init_verbs = { alc880_volume_init_verbs,
3186 alc880_pin_clevo_init_verbs },
3187 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3188 .dac_nids = alc880_dac_nids,
3189 .hp_nid = 0x03,
3190 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3191 .channel_mode = alc880_threestack_modes,
4e195a7b 3192 .need_dac_fix = 1,
df694daa
KY
3193 .input_mux = &alc880_capture_source,
3194 },
ae6b813a
TI
3195 [ALC880_LG] = {
3196 .mixers = { alc880_lg_mixer },
3197 .init_verbs = { alc880_volume_init_verbs,
3198 alc880_lg_init_verbs },
3199 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3200 .dac_nids = alc880_lg_dac_nids,
3201 .dig_out_nid = ALC880_DIGOUT_NID,
3202 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3203 .channel_mode = alc880_lg_ch_modes,
4e195a7b 3204 .need_dac_fix = 1,
ae6b813a
TI
3205 .input_mux = &alc880_lg_capture_source,
3206 .unsol_event = alc880_lg_unsol_event,
3207 .init_hook = alc880_lg_automute,
cb53c626
TI
3208#ifdef CONFIG_SND_HDA_POWER_SAVE
3209 .loopbacks = alc880_lg_loopbacks,
3210#endif
ae6b813a 3211 },
d681518a
TI
3212 [ALC880_LG_LW] = {
3213 .mixers = { alc880_lg_lw_mixer },
3214 .init_verbs = { alc880_volume_init_verbs,
3215 alc880_lg_lw_init_verbs },
0a8c5da3 3216 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
3217 .dac_nids = alc880_dac_nids,
3218 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
3219 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3220 .channel_mode = alc880_lg_lw_modes,
d681518a
TI
3221 .input_mux = &alc880_lg_lw_capture_source,
3222 .unsol_event = alc880_lg_lw_unsol_event,
3223 .init_hook = alc880_lg_lw_automute,
3224 },
16ded525
TI
3225#ifdef CONFIG_SND_DEBUG
3226 [ALC880_TEST] = {
e9edcee0
TI
3227 .mixers = { alc880_test_mixer },
3228 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
3229 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3230 .dac_nids = alc880_test_dac_nids,
3231 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
3232 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3233 .channel_mode = alc880_test_modes,
3234 .input_mux = &alc880_test_capture_source,
3235 },
3236#endif
3237};
3238
e9edcee0
TI
3239/*
3240 * Automatic parse of I/O pins from the BIOS configuration
3241 */
3242
3243#define NUM_CONTROL_ALLOC 32
3244#define NUM_VERB_ALLOC 32
3245
3246enum {
3247 ALC_CTL_WIDGET_VOL,
3248 ALC_CTL_WIDGET_MUTE,
3249 ALC_CTL_BIND_MUTE,
3250};
c8b6bf9b 3251static struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
3252 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3253 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 3254 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
3255};
3256
3257/* add dynamic controls */
f12ab1e0
TI
3258static int add_control(struct alc_spec *spec, int type, const char *name,
3259 unsigned long val)
e9edcee0 3260{
c8b6bf9b 3261 struct snd_kcontrol_new *knew;
e9edcee0
TI
3262
3263 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3264 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3265
f12ab1e0
TI
3266 /* array + terminator */
3267 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3268 if (!knew)
e9edcee0
TI
3269 return -ENOMEM;
3270 if (spec->kctl_alloc) {
f12ab1e0
TI
3271 memcpy(knew, spec->kctl_alloc,
3272 sizeof(*knew) * spec->num_kctl_alloc);
e9edcee0
TI
3273 kfree(spec->kctl_alloc);
3274 }
3275 spec->kctl_alloc = knew;
3276 spec->num_kctl_alloc = num;
3277 }
3278
3279 knew = &spec->kctl_alloc[spec->num_kctl_used];
3280 *knew = alc880_control_templates[type];
543537bd 3281 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 3282 if (!knew->name)
e9edcee0
TI
3283 return -ENOMEM;
3284 knew->private_value = val;
3285 spec->num_kctl_used++;
3286 return 0;
3287}
3288
3289#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3290#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3291#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3292#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3293#define alc880_is_input_pin(nid) ((nid) >= 0x18)
3294#define alc880_input_pin_idx(nid) ((nid) - 0x18)
3295#define alc880_idx_to_dac(nid) ((nid) + 0x02)
3296#define alc880_dac_to_idx(nid) ((nid) - 0x02)
3297#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3298#define alc880_idx_to_selector(nid) ((nid) + 0x10)
3299#define ALC880_PIN_CD_NID 0x1c
3300
3301/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
3302static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3303 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3304{
3305 hda_nid_t nid;
3306 int assigned[4];
3307 int i, j;
3308
3309 memset(assigned, 0, sizeof(assigned));
b0af0de5 3310 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
3311
3312 /* check the pins hardwired to audio widget */
3313 for (i = 0; i < cfg->line_outs; i++) {
3314 nid = cfg->line_out_pins[i];
3315 if (alc880_is_fixed_pin(nid)) {
3316 int idx = alc880_fixed_pin_idx(nid);
5014f193 3317 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
3318 assigned[idx] = 1;
3319 }
3320 }
3321 /* left pins can be connect to any audio widget */
3322 for (i = 0; i < cfg->line_outs; i++) {
3323 nid = cfg->line_out_pins[i];
3324 if (alc880_is_fixed_pin(nid))
3325 continue;
3326 /* search for an empty channel */
3327 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0
TI
3328 if (!assigned[j]) {
3329 spec->multiout.dac_nids[i] =
3330 alc880_idx_to_dac(j);
e9edcee0
TI
3331 assigned[j] = 1;
3332 break;
3333 }
3334 }
3335 }
3336 spec->multiout.num_dacs = cfg->line_outs;
3337 return 0;
3338}
3339
3340/* add playback controls from the parsed DAC table */
df694daa
KY
3341static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3342 const struct auto_pin_cfg *cfg)
e9edcee0
TI
3343{
3344 char name[32];
f12ab1e0
TI
3345 static const char *chname[4] = {
3346 "Front", "Surround", NULL /*CLFE*/, "Side"
3347 };
e9edcee0
TI
3348 hda_nid_t nid;
3349 int i, err;
3350
3351 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 3352 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
3353 continue;
3354 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3355 if (i == 2) {
3356 /* Center/LFE */
f12ab1e0
TI
3357 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3358 "Center Playback Volume",
3359 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3360 HDA_OUTPUT));
3361 if (err < 0)
e9edcee0 3362 return err;
f12ab1e0
TI
3363 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3364 "LFE Playback Volume",
3365 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3366 HDA_OUTPUT));
3367 if (err < 0)
e9edcee0 3368 return err;
f12ab1e0
TI
3369 err = add_control(spec, ALC_CTL_BIND_MUTE,
3370 "Center Playback Switch",
3371 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3372 HDA_INPUT));
3373 if (err < 0)
e9edcee0 3374 return err;
f12ab1e0
TI
3375 err = add_control(spec, ALC_CTL_BIND_MUTE,
3376 "LFE Playback Switch",
3377 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3378 HDA_INPUT));
3379 if (err < 0)
e9edcee0
TI
3380 return err;
3381 } else {
3382 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
3383 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3384 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3385 HDA_OUTPUT));
3386 if (err < 0)
e9edcee0
TI
3387 return err;
3388 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0
TI
3389 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3390 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3391 HDA_INPUT));
3392 if (err < 0)
e9edcee0
TI
3393 return err;
3394 }
3395 }
e9edcee0
TI
3396 return 0;
3397}
3398
8d88bc3d
TI
3399/* add playback controls for speaker and HP outputs */
3400static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3401 const char *pfx)
e9edcee0
TI
3402{
3403 hda_nid_t nid;
3404 int err;
8d88bc3d 3405 char name[32];
e9edcee0 3406
f12ab1e0 3407 if (!pin)
e9edcee0
TI
3408 return 0;
3409
3410 if (alc880_is_fixed_pin(pin)) {
3411 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 3412 /* specify the DAC as the extra output */
f12ab1e0 3413 if (!spec->multiout.hp_nid)
e9edcee0 3414 spec->multiout.hp_nid = nid;
82bc955f
TI
3415 else
3416 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
3417 /* control HP volume/switch on the output mixer amp */
3418 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
8d88bc3d 3419 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
3420 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3421 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3422 if (err < 0)
e9edcee0 3423 return err;
8d88bc3d 3424 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3425 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3426 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3427 if (err < 0)
e9edcee0
TI
3428 return err;
3429 } else if (alc880_is_multi_pin(pin)) {
3430 /* set manual connection */
e9edcee0 3431 /* we have only a switch on HP-out PIN */
8d88bc3d 3432 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
3433 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3434 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3435 if (err < 0)
e9edcee0
TI
3436 return err;
3437 }
3438 return 0;
3439}
3440
3441/* create input playback/capture controls for the given pin */
f12ab1e0
TI
3442static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3443 const char *ctlname,
df694daa 3444 int idx, hda_nid_t mix_nid)
e9edcee0
TI
3445{
3446 char name[32];
df694daa 3447 int err;
e9edcee0
TI
3448
3449 sprintf(name, "%s Playback Volume", ctlname);
f12ab1e0
TI
3450 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3451 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3452 if (err < 0)
e9edcee0
TI
3453 return err;
3454 sprintf(name, "%s Playback Switch", ctlname);
f12ab1e0
TI
3455 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3456 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3457 if (err < 0)
e9edcee0
TI
3458 return err;
3459 return 0;
3460}
3461
3462/* create playback/capture controls for input pins */
df694daa
KY
3463static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3464 const struct auto_pin_cfg *cfg)
e9edcee0 3465{
e9edcee0 3466 struct hda_input_mux *imux = &spec->private_imux;
df694daa 3467 int i, err, idx;
e9edcee0
TI
3468
3469 for (i = 0; i < AUTO_PIN_LAST; i++) {
3470 if (alc880_is_input_pin(cfg->input_pins[i])) {
df694daa 3471 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4a471b7d
TI
3472 err = new_analog_input(spec, cfg->input_pins[i],
3473 auto_pin_cfg_labels[i],
df694daa 3474 idx, 0x0b);
e9edcee0
TI
3475 if (err < 0)
3476 return err;
f12ab1e0
TI
3477 imux->items[imux->num_items].label =
3478 auto_pin_cfg_labels[i];
3479 imux->items[imux->num_items].index =
3480 alc880_input_pin_idx(cfg->input_pins[i]);
e9edcee0
TI
3481 imux->num_items++;
3482 }
3483 }
3484 return 0;
3485}
3486
f6c7e546
TI
3487static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3488 unsigned int pin_type)
3489{
3490 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3491 pin_type);
3492 /* unmute pin */
d260cdf6
TI
3493 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3494 AMP_OUT_UNMUTE);
f6c7e546
TI
3495}
3496
df694daa
KY
3497static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3498 hda_nid_t nid, int pin_type,
e9edcee0
TI
3499 int dac_idx)
3500{
f6c7e546 3501 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
3502 /* need the manual connection? */
3503 if (alc880_is_multi_pin(nid)) {
3504 struct alc_spec *spec = codec->spec;
3505 int idx = alc880_multi_pin_idx(nid);
3506 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3507 AC_VERB_SET_CONNECT_SEL,
3508 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3509 }
3510}
3511
baba8ee9
TI
3512static int get_pin_type(int line_out_type)
3513{
3514 if (line_out_type == AUTO_PIN_HP_OUT)
3515 return PIN_HP;
3516 else
3517 return PIN_OUT;
3518}
3519
e9edcee0
TI
3520static void alc880_auto_init_multi_out(struct hda_codec *codec)
3521{
3522 struct alc_spec *spec = codec->spec;
3523 int i;
bc9f98a9
KY
3524
3525 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
e9edcee0
TI
3526 for (i = 0; i < spec->autocfg.line_outs; i++) {
3527 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
3528 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3529 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
3530 }
3531}
3532
8d88bc3d 3533static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
3534{
3535 struct alc_spec *spec = codec->spec;
3536 hda_nid_t pin;
3537
82bc955f 3538 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
3539 if (pin) /* connect to front */
3540 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 3541 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
3542 if (pin) /* connect to front */
3543 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3544}
3545
3546static void alc880_auto_init_analog_input(struct hda_codec *codec)
3547{
3548 struct alc_spec *spec = codec->spec;
3549 int i;
3550
3551 for (i = 0; i < AUTO_PIN_LAST; i++) {
3552 hda_nid_t nid = spec->autocfg.input_pins[i];
3553 if (alc880_is_input_pin(nid)) {
f12ab1e0
TI
3554 snd_hda_codec_write(codec, nid, 0,
3555 AC_VERB_SET_PIN_WIDGET_CONTROL,
3556 i <= AUTO_PIN_FRONT_MIC ?
3557 PIN_VREF80 : PIN_IN);
e9edcee0 3558 if (nid != ALC880_PIN_CD_NID)
f12ab1e0
TI
3559 snd_hda_codec_write(codec, nid, 0,
3560 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
3561 AMP_OUT_MUTE);
3562 }
3563 }
3564}
3565
3566/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
3567/* return 1 if successful, 0 if the proper config is not found,
3568 * or a negative error code
3569 */
e9edcee0
TI
3570static int alc880_parse_auto_config(struct hda_codec *codec)
3571{
3572 struct alc_spec *spec = codec->spec;
3573 int err;
df694daa 3574 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 3575
f12ab1e0
TI
3576 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3577 alc880_ignore);
3578 if (err < 0)
e9edcee0 3579 return err;
f12ab1e0 3580 if (!spec->autocfg.line_outs)
e9edcee0 3581 return 0; /* can't find valid BIOS pin config */
df694daa 3582
f12ab1e0
TI
3583 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3584 if (err < 0)
3585 return err;
3586 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3587 if (err < 0)
3588 return err;
3589 err = alc880_auto_create_extra_out(spec,
3590 spec->autocfg.speaker_pins[0],
3591 "Speaker");
3592 if (err < 0)
3593 return err;
3594 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3595 "Headphone");
3596 if (err < 0)
3597 return err;
3598 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3599 if (err < 0)
e9edcee0
TI
3600 return err;
3601
3602 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3603
3604 if (spec->autocfg.dig_out_pin)
3605 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3606 if (spec->autocfg.dig_in_pin)
3607 spec->dig_in_nid = ALC880_DIGIN_NID;
3608
3609 if (spec->kctl_alloc)
3610 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3611
3612 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3613
a1e8d2da 3614 spec->num_mux_defs = 1;
e9edcee0
TI
3615 spec->input_mux = &spec->private_imux;
3616
3617 return 1;
3618}
3619
ae6b813a
TI
3620/* additional initialization for auto-configuration model */
3621static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 3622{
f6c7e546 3623 struct alc_spec *spec = codec->spec;
e9edcee0 3624 alc880_auto_init_multi_out(codec);
8d88bc3d 3625 alc880_auto_init_extra_out(codec);
e9edcee0 3626 alc880_auto_init_analog_input(codec);
f6c7e546
TI
3627 if (spec->unsol_event)
3628 alc_sku_automute(codec);
e9edcee0
TI
3629}
3630
3631/*
3632 * OK, here we have finally the patch for ALC880
3633 */
3634
1da177e4
LT
3635static int patch_alc880(struct hda_codec *codec)
3636{
3637 struct alc_spec *spec;
3638 int board_config;
df694daa 3639 int err;
1da177e4 3640
e560d8d8 3641 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
3642 if (spec == NULL)
3643 return -ENOMEM;
3644
3645 codec->spec = spec;
3646
f5fcc13c
TI
3647 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3648 alc880_models,
3649 alc880_cfg_tbl);
3650 if (board_config < 0) {
9c7f852e
TI
3651 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3652 "trying auto-probe from BIOS...\n");
e9edcee0 3653 board_config = ALC880_AUTO;
1da177e4 3654 }
1da177e4 3655
e9edcee0
TI
3656 if (board_config == ALC880_AUTO) {
3657 /* automatic parse from the BIOS config */
3658 err = alc880_parse_auto_config(codec);
3659 if (err < 0) {
3660 alc_free(codec);
3661 return err;
f12ab1e0 3662 } else if (!err) {
9c7f852e
TI
3663 printk(KERN_INFO
3664 "hda_codec: Cannot set up configuration "
3665 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
3666 board_config = ALC880_3ST;
3667 }
1da177e4
LT
3668 }
3669
df694daa
KY
3670 if (board_config != ALC880_AUTO)
3671 setup_preset(spec, &alc880_presets[board_config]);
1da177e4
LT
3672
3673 spec->stream_name_analog = "ALC880 Analog";
3674 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3675 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 3676 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
3677
3678 spec->stream_name_digital = "ALC880 Digital";
3679 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3680 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3681
f12ab1e0 3682 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 3683 /* check whether NID 0x07 is valid */
54d17403 3684 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0
TI
3685 /* get type */
3686 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
e9edcee0
TI
3687 if (wcap != AC_WID_AUD_IN) {
3688 spec->adc_nids = alc880_adc_nids_alt;
3689 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
f12ab1e0
TI
3690 spec->mixers[spec->num_mixers] =
3691 alc880_capture_alt_mixer;
e9edcee0
TI
3692 spec->num_mixers++;
3693 } else {
3694 spec->adc_nids = alc880_adc_nids;
3695 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3696 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3697 spec->num_mixers++;
3698 }
3699 }
1da177e4 3700
2134ea4f
TI
3701 spec->vmaster_nid = 0x0c;
3702
1da177e4 3703 codec->patch_ops = alc_patch_ops;
e9edcee0 3704 if (board_config == ALC880_AUTO)
ae6b813a 3705 spec->init_hook = alc880_auto_init;
cb53c626
TI
3706#ifdef CONFIG_SND_HDA_POWER_SAVE
3707 if (!spec->loopback.amplist)
3708 spec->loopback.amplist = alc880_loopbacks;
3709#endif
1da177e4
LT
3710
3711 return 0;
3712}
3713
e9edcee0 3714
1da177e4
LT
3715/*
3716 * ALC260 support
3717 */
3718
e9edcee0
TI
3719static hda_nid_t alc260_dac_nids[1] = {
3720 /* front */
3721 0x02,
3722};
3723
3724static hda_nid_t alc260_adc_nids[1] = {
3725 /* ADC0 */
3726 0x04,
3727};
3728
df694daa 3729static hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
3730 /* ADC1 */
3731 0x05,
3732};
3733
df694daa
KY
3734static hda_nid_t alc260_hp_adc_nids[2] = {
3735 /* ADC1, 0 */
3736 0x05, 0x04
3737};
3738
d57fdac0
JW
3739/* NIDs used when simultaneous access to both ADCs makes sense. Note that
3740 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3741 */
3742static hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
3743 /* ADC0, ADC1 */
3744 0x04, 0x05
3745};
3746
e9edcee0
TI
3747#define ALC260_DIGOUT_NID 0x03
3748#define ALC260_DIGIN_NID 0x06
3749
3750static struct hda_input_mux alc260_capture_source = {
3751 .num_items = 4,
3752 .items = {
3753 { "Mic", 0x0 },
3754 { "Front Mic", 0x1 },
3755 { "Line", 0x2 },
3756 { "CD", 0x4 },
3757 },
3758};
3759
17e7aec6 3760/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
3761 * headphone jack and the internal CD lines since these are the only pins at
3762 * which audio can appear. For flexibility, also allow the option of
3763 * recording the mixer output on the second ADC (ADC0 doesn't have a
3764 * connection to the mixer output).
a9430dd8 3765 */
a1e8d2da
JW
3766static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3767 {
3768 .num_items = 3,
3769 .items = {
3770 { "Mic/Line", 0x0 },
3771 { "CD", 0x4 },
3772 { "Headphone", 0x2 },
3773 },
a9430dd8 3774 },
a1e8d2da
JW
3775 {
3776 .num_items = 4,
3777 .items = {
3778 { "Mic/Line", 0x0 },
3779 { "CD", 0x4 },
3780 { "Headphone", 0x2 },
3781 { "Mixer", 0x5 },
3782 },
3783 },
3784
a9430dd8
JW
3785};
3786
a1e8d2da
JW
3787/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3788 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 3789 */
a1e8d2da
JW
3790static struct hda_input_mux alc260_acer_capture_sources[2] = {
3791 {
3792 .num_items = 4,
3793 .items = {
3794 { "Mic", 0x0 },
3795 { "Line", 0x2 },
3796 { "CD", 0x4 },
3797 { "Headphone", 0x5 },
3798 },
3799 },
3800 {
3801 .num_items = 5,
3802 .items = {
3803 { "Mic", 0x0 },
3804 { "Line", 0x2 },
3805 { "CD", 0x4 },
3806 { "Headphone", 0x6 },
3807 { "Mixer", 0x5 },
3808 },
0bfc90e9
JW
3809 },
3810};
1da177e4
LT
3811/*
3812 * This is just place-holder, so there's something for alc_build_pcms to look
3813 * at when it calculates the maximum number of channels. ALC260 has no mixer
3814 * element which allows changing the channel mode, so the verb list is
3815 * never used.
3816 */
d2a6d7dc 3817static struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
3818 { 2, NULL },
3819};
3820
df694daa
KY
3821
3822/* Mixer combinations
3823 *
3824 * basic: base_output + input + pc_beep + capture
3825 * HP: base_output + input + capture_alt
3826 * HP_3013: hp_3013 + input + capture
3827 * fujitsu: fujitsu + capture
0bfc90e9 3828 * acer: acer + capture
df694daa
KY
3829 */
3830
3831static struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 3832 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3833 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 3834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 3835 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 3836 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 3837 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 3838 { } /* end */
f12ab1e0 3839};
1da177e4 3840
df694daa 3841static struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
3842 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3843 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3844 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3845 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3847 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3848 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3849 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
3850 { } /* end */
3851};
3852
3853static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3854 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3855 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3856 { } /* end */
3857};
3858
bec15c3a
TI
3859/* update HP, line and mono out pins according to the master switch */
3860static void alc260_hp_master_update(struct hda_codec *codec,
3861 hda_nid_t hp, hda_nid_t line,
3862 hda_nid_t mono)
3863{
3864 struct alc_spec *spec = codec->spec;
3865 unsigned int val = spec->master_sw ? PIN_HP : 0;
3866 /* change HP and line-out pins */
3867 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3868 val);
3869 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3870 val);
3871 /* mono (speaker) depending on the HP jack sense */
3872 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3873 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3874 val);
3875}
3876
3877static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3878 struct snd_ctl_elem_value *ucontrol)
3879{
3880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3881 struct alc_spec *spec = codec->spec;
3882 *ucontrol->value.integer.value = spec->master_sw;
3883 return 0;
3884}
3885
3886static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3887 struct snd_ctl_elem_value *ucontrol)
3888{
3889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3890 struct alc_spec *spec = codec->spec;
3891 int val = !!*ucontrol->value.integer.value;
3892 hda_nid_t hp, line, mono;
3893
3894 if (val == spec->master_sw)
3895 return 0;
3896 spec->master_sw = val;
3897 hp = (kcontrol->private_value >> 16) & 0xff;
3898 line = (kcontrol->private_value >> 8) & 0xff;
3899 mono = kcontrol->private_value & 0xff;
3900 alc260_hp_master_update(codec, hp, line, mono);
3901 return 1;
3902}
3903
3904static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3905 {
3906 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3907 .name = "Master Playback Switch",
3908 .info = snd_ctl_boolean_mono_info,
3909 .get = alc260_hp_master_sw_get,
3910 .put = alc260_hp_master_sw_put,
3911 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3912 },
3913 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3914 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3915 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3916 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3917 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3918 HDA_OUTPUT),
3919 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3920 { } /* end */
3921};
3922
3923static struct hda_verb alc260_hp_unsol_verbs[] = {
3924 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3925 {},
3926};
3927
3928static void alc260_hp_automute(struct hda_codec *codec)
3929{
3930 struct alc_spec *spec = codec->spec;
3931 unsigned int present;
3932
3933 present = snd_hda_codec_read(codec, 0x10, 0,
3934 AC_VERB_GET_PIN_SENSE, 0);
3935 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3936 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3937}
3938
3939static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3940{
3941 if ((res >> 26) == ALC880_HP_EVENT)
3942 alc260_hp_automute(codec);
3943}
3944
df694daa 3945static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
3946 {
3947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3948 .name = "Master Playback Switch",
3949 .info = snd_ctl_boolean_mono_info,
3950 .get = alc260_hp_master_sw_get,
3951 .put = alc260_hp_master_sw_put,
3952 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3953 },
df694daa
KY
3954 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3955 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3956 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3957 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3959 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
3960 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3961 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
3962 { } /* end */
3963};
3964
bec15c3a
TI
3965static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3966 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3967 {},
3968};
3969
3970static void alc260_hp_3013_automute(struct hda_codec *codec)
3971{
3972 struct alc_spec *spec = codec->spec;
3973 unsigned int present;
3974
3975 present = snd_hda_codec_read(codec, 0x15, 0,
3976 AC_VERB_GET_PIN_SENSE, 0);
3977 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3978 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3979}
3980
3981static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3982 unsigned int res)
3983{
3984 if ((res >> 26) == ALC880_HP_EVENT)
3985 alc260_hp_3013_automute(codec);
3986}
3987
a1e8d2da
JW
3988/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3989 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3990 */
c8b6bf9b 3991static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 3992 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 3993 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 3994 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
3995 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3996 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3997 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3998 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 3999 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
a9430dd8
JW
4000 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4001 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
31bffaa9
TI
4002 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4003 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
4004 { } /* end */
4005};
4006
a1e8d2da
JW
4007/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4008 * versions of the ALC260 don't act on requests to enable mic bias from NID
4009 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4010 * datasheet doesn't mention this restriction. At this stage it's not clear
4011 * whether this behaviour is intentional or is a hardware bug in chip
4012 * revisions available in early 2006. Therefore for now allow the
4013 * "Headphone Jack Mode" control to span all choices, but if it turns out
4014 * that the lack of mic bias for this NID is intentional we could change the
4015 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4016 *
4017 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4018 * don't appear to make the mic bias available from the "line" jack, even
4019 * though the NID used for this jack (0x14) can supply it. The theory is
4020 * that perhaps Acer have included blocking capacitors between the ALC260
4021 * and the output jack. If this turns out to be the case for all such
4022 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4023 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
4024 *
4025 * The C20x Tablet series have a mono internal speaker which is controlled
4026 * via the chip's Mono sum widget and pin complex, so include the necessary
4027 * controls for such models. On models without a "mono speaker" the control
4028 * won't do anything.
a1e8d2da 4029 */
0bfc90e9
JW
4030static struct snd_kcontrol_new alc260_acer_mixer[] = {
4031 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4032 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 4033 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 4034 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 4035 HDA_OUTPUT),
31bffaa9 4036 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 4037 HDA_INPUT),
0bfc90e9
JW
4038 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4039 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4041 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4042 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4043 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4044 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4045 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4046 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4047 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4048 { } /* end */
4049};
4050
bc9f98a9
KY
4051/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4052 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4053 */
4054static struct snd_kcontrol_new alc260_will_mixer[] = {
4055 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4056 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4058 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4059 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4060 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4061 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4062 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4063 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4064 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4065 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4066 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4067 { } /* end */
4068};
4069
4070/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4071 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4072 */
4073static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4074 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4075 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4077 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4078 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4079 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4080 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4081 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4082 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4083 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4084 { } /* end */
4085};
4086
df694daa
KY
4087/* capture mixer elements */
4088static struct snd_kcontrol_new alc260_capture_mixer[] = {
a9430dd8
JW
4089 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4090 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
df694daa
KY
4091 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4092 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
a9430dd8
JW
4093 {
4094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
df694daa
KY
4095 /* The multiple "Capture Source" controls confuse alsamixer
4096 * So call somewhat different..
df694daa
KY
4097 */
4098 /* .name = "Capture Source", */
4099 .name = "Input Source",
4100 .count = 2,
4101 .info = alc_mux_enum_info,
4102 .get = alc_mux_enum_get,
4103 .put = alc_mux_enum_put,
4104 },
4105 { } /* end */
4106};
4107
4108static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4109 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4110 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4111 {
4112 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4113 /* The multiple "Capture Source" controls confuse alsamixer
4114 * So call somewhat different..
df694daa
KY
4115 */
4116 /* .name = "Capture Source", */
4117 .name = "Input Source",
4118 .count = 1,
a9430dd8
JW
4119 .info = alc_mux_enum_info,
4120 .get = alc_mux_enum_get,
4121 .put = alc_mux_enum_put,
4122 },
4123 { } /* end */
4124};
4125
df694daa
KY
4126/*
4127 * initialization verbs
4128 */
1da177e4
LT
4129static struct hda_verb alc260_init_verbs[] = {
4130 /* Line In pin widget for input */
05acb863 4131 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4132 /* CD pin widget for input */
05acb863 4133 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 4134 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 4135 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4136 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 4137 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 4138 /* LINE-2 is used for line-out in rear */
05acb863 4139 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4140 /* select line-out */
fd56f2db 4141 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 4142 /* LINE-OUT pin */
05acb863 4143 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 4144 /* enable HP */
05acb863 4145 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 4146 /* enable Mono */
05acb863
TI
4147 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4148 /* mute capture amp left and right */
16ded525 4149 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
4150 /* set connection select to line in (default select for this ADC) */
4151 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
4152 /* mute capture amp left and right */
4153 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4154 /* set connection select to line in (default select for this ADC) */
4155 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
4156 /* set vol=0 Line-Out mixer amp left and right */
4157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4158 /* unmute pin widget amp left and right (no gain on this amp) */
4159 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4160 /* set vol=0 HP mixer amp left and right */
4161 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4162 /* unmute pin widget amp left and right (no gain on this amp) */
4163 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4164 /* set vol=0 Mono mixer amp left and right */
4165 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4166 /* unmute pin widget amp left and right (no gain on this amp) */
4167 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4168 /* unmute LINE-2 out pin */
4169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
4170 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4171 * Line In 2 = 0x03
4172 */
cb53c626
TI
4173 /* mute analog inputs */
4174 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4175 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4176 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4177 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 4179 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
4180 /* mute Front out path */
4181 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4182 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4183 /* mute Headphone out path */
4184 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4185 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4186 /* mute Mono out path */
4187 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4188 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
4189 { }
4190};
4191
474167d6 4192#if 0 /* should be identical with alc260_init_verbs? */
df694daa
KY
4193static struct hda_verb alc260_hp_init_verbs[] = {
4194 /* Headphone and output */
4195 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4196 /* mono output */
4197 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4198 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4199 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4200 /* Mic2 (front panel) pin widget for input and vref at 80% */
4201 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4202 /* Line In pin widget for input */
4203 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4204 /* Line-2 pin widget for output */
4205 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4206 /* CD pin widget for input */
4207 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4208 /* unmute amp left and right */
4209 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4210 /* set connection select to line in (default select for this ADC) */
4211 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4212 /* unmute Line-Out mixer amp left and right (volume = 0) */
4213 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4214 /* mute pin widget amp left and right (no gain on this amp) */
4215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4216 /* unmute HP mixer amp left and right (volume = 0) */
4217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4218 /* mute pin widget amp left and right (no gain on this amp) */
4219 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4220 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4221 * Line In 2 = 0x03
4222 */
cb53c626
TI
4223 /* mute analog inputs */
4224 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4225 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4226 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4229 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4230 /* Unmute Front out path */
4231 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4232 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4233 /* Unmute Headphone out path */
4234 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4235 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4236 /* Unmute Mono out path */
4237 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4238 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4239 { }
4240};
474167d6 4241#endif
df694daa
KY
4242
4243static struct hda_verb alc260_hp_3013_init_verbs[] = {
4244 /* Line out and output */
4245 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4246 /* mono output */
4247 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4248 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4249 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4250 /* Mic2 (front panel) pin widget for input and vref at 80% */
4251 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4252 /* Line In pin widget for input */
4253 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4254 /* Headphone pin widget for output */
4255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4256 /* CD pin widget for input */
4257 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4258 /* unmute amp left and right */
4259 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4260 /* set connection select to line in (default select for this ADC) */
4261 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4262 /* unmute Line-Out mixer amp left and right (volume = 0) */
4263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4264 /* mute pin widget amp left and right (no gain on this amp) */
4265 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4266 /* unmute HP mixer amp left and right (volume = 0) */
4267 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4268 /* mute pin widget amp left and right (no gain on this amp) */
4269 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
4270 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4271 * Line In 2 = 0x03
4272 */
cb53c626
TI
4273 /* mute analog inputs */
4274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4279 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4280 /* Unmute Front out path */
4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4282 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4283 /* Unmute Headphone out path */
4284 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4285 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4286 /* Unmute Mono out path */
4287 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4288 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4289 { }
4290};
4291
a9430dd8 4292/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
4293 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4294 * audio = 0x16, internal speaker = 0x10.
a9430dd8
JW
4295 */
4296static struct hda_verb alc260_fujitsu_init_verbs[] = {
4297 /* Disable all GPIOs */
4298 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4299 /* Internal speaker is connected to headphone pin */
4300 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4301 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
4303 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4304 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4305 /* Ensure all other unused pins are disabled and muted. */
4306 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4307 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4308 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 4309 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 4310 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
4311 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4313 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4314
4315 /* Disable digital (SPDIF) pins */
4316 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4317 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 4318
f7ace40d
JW
4319 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4320 * when acting as an output.
4321 */
4322 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 4323
f7ace40d 4324 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
4325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4327 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4329 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4330 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4331 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4332 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4333 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 4334
f7ace40d
JW
4335 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4336 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4337 /* Unmute Line1 pin widget output buffer since it starts as an output.
4338 * If the pin mode is changed by the user the pin mode control will
4339 * take care of enabling the pin's input/output buffers as needed.
4340 * Therefore there's no need to enable the input buffer at this
4341 * stage.
cdcd9268 4342 */
f7ace40d 4343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
cdcd9268
JW
4344 /* Unmute input buffer of pin widget used for Line-in (no equiv
4345 * mixer ctrl)
4346 */
f7ace40d
JW
4347 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4348
4349 /* Mute capture amp left and right */
4350 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4351 /* Set ADC connection select to match default mixer setting - line
4352 * in (on mic1 pin)
4353 */
4354 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4355
4356 /* Do the same for the second ADC: mute capture input amp and
4357 * set ADC connection to line in (on mic1 pin)
4358 */
4359 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4360 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4361
4362 /* Mute all inputs to mixer widget (even unconnected ones) */
4363 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4364 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4366 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4370 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
4371
4372 { }
a9430dd8
JW
4373};
4374
0bfc90e9
JW
4375/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4376 * similar laptops (adapted from Fujitsu init verbs).
4377 */
4378static struct hda_verb alc260_acer_init_verbs[] = {
4379 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4380 * the headphone jack. Turn this on and rely on the standard mute
4381 * methods whenever the user wants to turn these outputs off.
4382 */
4383 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4384 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4385 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4386 /* Internal speaker/Headphone jack is connected to Line-out pin */
4387 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4388 /* Internal microphone/Mic jack is connected to Mic1 pin */
4389 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4390 /* Line In jack is connected to Line1 pin */
4391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
4392 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4393 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
4394 /* Ensure all other unused pins are disabled and muted. */
4395 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4396 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
4397 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4398 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4401 /* Disable digital (SPDIF) pins */
4402 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4403 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4404
4405 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4406 * bus when acting as outputs.
4407 */
4408 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4409 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4410
4411 /* Start with output sum widgets muted and their output gains at min */
4412 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4421
f12ab1e0
TI
4422 /* Unmute Line-out pin widget amp left and right
4423 * (no equiv mixer ctrl)
4424 */
0bfc90e9 4425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
4426 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4427 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
4428 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4429 * inputs. If the pin mode is changed by the user the pin mode control
4430 * will take care of enabling the pin's input/output buffers as needed.
4431 * Therefore there's no need to enable the input buffer at this
4432 * stage.
4433 */
4434 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4436
4437 /* Mute capture amp left and right */
4438 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4439 /* Set ADC connection select to match default mixer setting - mic
4440 * (on mic1 pin)
4441 */
4442 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4443
4444 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 4445 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
4446 */
4447 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 4448 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
4449
4450 /* Mute all inputs to mixer widget (even unconnected ones) */
4451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4459
4460 { }
4461};
4462
bc9f98a9
KY
4463static struct hda_verb alc260_will_verbs[] = {
4464 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4465 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4466 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4467 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4468 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4469 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4470 {}
4471};
4472
4473static struct hda_verb alc260_replacer_672v_verbs[] = {
4474 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4475 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4476 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4477
4478 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4479 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4480 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4481
4482 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4483 {}
4484};
4485
4486/* toggle speaker-output according to the hp-jack state */
4487static void alc260_replacer_672v_automute(struct hda_codec *codec)
4488{
4489 unsigned int present;
4490
4491 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4492 present = snd_hda_codec_read(codec, 0x0f, 0,
4493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4494 if (present) {
82beb8fd
TI
4495 snd_hda_codec_write_cache(codec, 0x01, 0,
4496 AC_VERB_SET_GPIO_DATA, 1);
4497 snd_hda_codec_write_cache(codec, 0x0f, 0,
4498 AC_VERB_SET_PIN_WIDGET_CONTROL,
4499 PIN_HP);
bc9f98a9 4500 } else {
82beb8fd
TI
4501 snd_hda_codec_write_cache(codec, 0x01, 0,
4502 AC_VERB_SET_GPIO_DATA, 0);
4503 snd_hda_codec_write_cache(codec, 0x0f, 0,
4504 AC_VERB_SET_PIN_WIDGET_CONTROL,
4505 PIN_OUT);
bc9f98a9
KY
4506 }
4507}
4508
4509static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4510 unsigned int res)
4511{
4512 if ((res >> 26) == ALC880_HP_EVENT)
4513 alc260_replacer_672v_automute(codec);
4514}
4515
7cf51e48
JW
4516/* Test configuration for debugging, modelled after the ALC880 test
4517 * configuration.
4518 */
4519#ifdef CONFIG_SND_DEBUG
4520static hda_nid_t alc260_test_dac_nids[1] = {
4521 0x02,
4522};
4523static hda_nid_t alc260_test_adc_nids[2] = {
4524 0x04, 0x05,
4525};
a1e8d2da
JW
4526/* For testing the ALC260, each input MUX needs its own definition since
4527 * the signal assignments are different. This assumes that the first ADC
4528 * is NID 0x04.
17e7aec6 4529 */
a1e8d2da
JW
4530static struct hda_input_mux alc260_test_capture_sources[2] = {
4531 {
4532 .num_items = 7,
4533 .items = {
4534 { "MIC1 pin", 0x0 },
4535 { "MIC2 pin", 0x1 },
4536 { "LINE1 pin", 0x2 },
4537 { "LINE2 pin", 0x3 },
4538 { "CD pin", 0x4 },
4539 { "LINE-OUT pin", 0x5 },
4540 { "HP-OUT pin", 0x6 },
4541 },
4542 },
4543 {
4544 .num_items = 8,
4545 .items = {
4546 { "MIC1 pin", 0x0 },
4547 { "MIC2 pin", 0x1 },
4548 { "LINE1 pin", 0x2 },
4549 { "LINE2 pin", 0x3 },
4550 { "CD pin", 0x4 },
4551 { "Mixer", 0x5 },
4552 { "LINE-OUT pin", 0x6 },
4553 { "HP-OUT pin", 0x7 },
4554 },
7cf51e48
JW
4555 },
4556};
4557static struct snd_kcontrol_new alc260_test_mixer[] = {
4558 /* Output driver widgets */
4559 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4560 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4561 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4562 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4563 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4564 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4565
a1e8d2da
JW
4566 /* Modes for retasking pin widgets
4567 * Note: the ALC260 doesn't seem to act on requests to enable mic
4568 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4569 * mention this restriction. At this stage it's not clear whether
4570 * this behaviour is intentional or is a hardware bug in chip
4571 * revisions available at least up until early 2006. Therefore for
4572 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4573 * choices, but if it turns out that the lack of mic bias for these
4574 * NIDs is intentional we could change their modes from
4575 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4576 */
7cf51e48
JW
4577 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4578 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4579 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4580 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4581 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4582 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4583
4584 /* Loopback mixer controls */
4585 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4586 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4587 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4588 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4589 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4590 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4591 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4592 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4593 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4594 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4595 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4596 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4597 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4598 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4599 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4600 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
4601
4602 /* Controls for GPIO pins, assuming they are configured as outputs */
4603 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4604 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4605 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4606 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4607
92621f13
JW
4608 /* Switches to allow the digital IO pins to be enabled. The datasheet
4609 * is ambigious as to which NID is which; testing on laptops which
4610 * make this output available should provide clarification.
4611 */
4612 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4613 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4614
f8225f6d
JW
4615 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4616 * this output to turn on an external amplifier.
4617 */
4618 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4619 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4620
7cf51e48
JW
4621 { } /* end */
4622};
4623static struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
4624 /* Enable all GPIOs as outputs with an initial value of 0 */
4625 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4626 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4627 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4628
7cf51e48
JW
4629 /* Enable retasking pins as output, initially without power amp */
4630 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4631 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4634 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4636
92621f13
JW
4637 /* Disable digital (SPDIF) pins initially, but users can enable
4638 * them via a mixer switch. In the case of SPDIF-out, this initverb
4639 * payload also sets the generation to 0, output to be in "consumer"
4640 * PCM format, copyright asserted, no pre-emphasis and no validity
4641 * control.
4642 */
7cf51e48
JW
4643 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4644 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4645
f7ace40d 4646 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
4647 * OUT1 sum bus when acting as an output.
4648 */
4649 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4650 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4651 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4652 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4653
4654 /* Start with output sum widgets muted and their output gains at min */
4655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4657 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4660 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4663 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4664
cdcd9268
JW
4665 /* Unmute retasking pin widget output buffers since the default
4666 * state appears to be output. As the pin mode is changed by the
4667 * user the pin mode control will take care of enabling the pin's
4668 * input/output buffers as needed.
4669 */
7cf51e48
JW
4670 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4673 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4674 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4675 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4676 /* Also unmute the mono-out pin widget */
4677 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4678
7cf51e48
JW
4679 /* Mute capture amp left and right */
4680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
4681 /* Set ADC connection select to match default mixer setting (mic1
4682 * pin)
7cf51e48
JW
4683 */
4684 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4685
4686 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 4687 * set ADC connection to mic1 pin
7cf51e48
JW
4688 */
4689 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4690 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4691
4692 /* Mute all inputs to mixer widget (even unconnected ones) */
4693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4701
4702 { }
4703};
4704#endif
4705
6330079f
TI
4706#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4707#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 4708
a3bcba38
TI
4709#define alc260_pcm_digital_playback alc880_pcm_digital_playback
4710#define alc260_pcm_digital_capture alc880_pcm_digital_capture
4711
df694daa
KY
4712/*
4713 * for BIOS auto-configuration
4714 */
16ded525 4715
df694daa
KY
4716static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4717 const char *pfx)
4718{
4719 hda_nid_t nid_vol;
4720 unsigned long vol_val, sw_val;
4721 char name[32];
4722 int err;
4723
4724 if (nid >= 0x0f && nid < 0x11) {
4725 nid_vol = nid - 0x7;
4726 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4727 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4728 } else if (nid == 0x11) {
4729 nid_vol = nid - 0x7;
4730 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4731 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4732 } else if (nid >= 0x12 && nid <= 0x15) {
4733 nid_vol = 0x08;
4734 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4735 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4736 } else
4737 return 0; /* N/A */
4738
4739 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
f12ab1e0
TI
4740 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4741 if (err < 0)
df694daa
KY
4742 return err;
4743 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
f12ab1e0
TI
4744 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4745 if (err < 0)
df694daa
KY
4746 return err;
4747 return 1;
4748}
4749
4750/* add playback controls from the parsed DAC table */
4751static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4752 const struct auto_pin_cfg *cfg)
4753{
4754 hda_nid_t nid;
4755 int err;
4756
4757 spec->multiout.num_dacs = 1;
4758 spec->multiout.dac_nids = spec->private_dac_nids;
4759 spec->multiout.dac_nids[0] = 0x02;
4760
4761 nid = cfg->line_out_pins[0];
4762 if (nid) {
4763 err = alc260_add_playback_controls(spec, nid, "Front");
4764 if (err < 0)
4765 return err;
4766 }
4767
82bc955f 4768 nid = cfg->speaker_pins[0];
df694daa
KY
4769 if (nid) {
4770 err = alc260_add_playback_controls(spec, nid, "Speaker");
4771 if (err < 0)
4772 return err;
4773 }
4774
eb06ed8f 4775 nid = cfg->hp_pins[0];
df694daa
KY
4776 if (nid) {
4777 err = alc260_add_playback_controls(spec, nid, "Headphone");
4778 if (err < 0)
4779 return err;
4780 }
f12ab1e0 4781 return 0;
df694daa
KY
4782}
4783
4784/* create playback/capture controls for input pins */
4785static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4786 const struct auto_pin_cfg *cfg)
4787{
df694daa
KY
4788 struct hda_input_mux *imux = &spec->private_imux;
4789 int i, err, idx;
4790
4791 for (i = 0; i < AUTO_PIN_LAST; i++) {
4792 if (cfg->input_pins[i] >= 0x12) {
4793 idx = cfg->input_pins[i] - 0x12;
4a471b7d 4794 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4795 auto_pin_cfg_labels[i], idx,
4796 0x07);
df694daa
KY
4797 if (err < 0)
4798 return err;
f12ab1e0
TI
4799 imux->items[imux->num_items].label =
4800 auto_pin_cfg_labels[i];
df694daa
KY
4801 imux->items[imux->num_items].index = idx;
4802 imux->num_items++;
4803 }
f12ab1e0 4804 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
df694daa 4805 idx = cfg->input_pins[i] - 0x09;
4a471b7d 4806 err = new_analog_input(spec, cfg->input_pins[i],
f12ab1e0
TI
4807 auto_pin_cfg_labels[i], idx,
4808 0x07);
df694daa
KY
4809 if (err < 0)
4810 return err;
f12ab1e0
TI
4811 imux->items[imux->num_items].label =
4812 auto_pin_cfg_labels[i];
df694daa
KY
4813 imux->items[imux->num_items].index = idx;
4814 imux->num_items++;
4815 }
4816 }
4817 return 0;
4818}
4819
4820static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4821 hda_nid_t nid, int pin_type,
4822 int sel_idx)
4823{
f6c7e546 4824 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
4825 /* need the manual connection? */
4826 if (nid >= 0x12) {
4827 int idx = nid - 0x12;
4828 snd_hda_codec_write(codec, idx + 0x0b, 0,
4829 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
4830 }
4831}
4832
4833static void alc260_auto_init_multi_out(struct hda_codec *codec)
4834{
4835 struct alc_spec *spec = codec->spec;
4836 hda_nid_t nid;
4837
bc9f98a9 4838 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
f12ab1e0 4839 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
4840 if (nid) {
4841 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4842 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4843 }
df694daa 4844
82bc955f 4845 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
4846 if (nid)
4847 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4848
eb06ed8f 4849 nid = spec->autocfg.hp_pins[0];
df694daa 4850 if (nid)
baba8ee9 4851 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 4852}
df694daa
KY
4853
4854#define ALC260_PIN_CD_NID 0x16
4855static void alc260_auto_init_analog_input(struct hda_codec *codec)
4856{
4857 struct alc_spec *spec = codec->spec;
4858 int i;
4859
4860 for (i = 0; i < AUTO_PIN_LAST; i++) {
4861 hda_nid_t nid = spec->autocfg.input_pins[i];
4862 if (nid >= 0x12) {
f12ab1e0
TI
4863 snd_hda_codec_write(codec, nid, 0,
4864 AC_VERB_SET_PIN_WIDGET_CONTROL,
4865 i <= AUTO_PIN_FRONT_MIC ?
4866 PIN_VREF80 : PIN_IN);
df694daa 4867 if (nid != ALC260_PIN_CD_NID)
f12ab1e0
TI
4868 snd_hda_codec_write(codec, nid, 0,
4869 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
4870 AMP_OUT_MUTE);
4871 }
4872 }
4873}
4874
4875/*
4876 * generic initialization of ADC, input mixers and output mixers
4877 */
4878static struct hda_verb alc260_volume_init_verbs[] = {
4879 /*
4880 * Unmute ADC0-1 and set the default input to mic-in
4881 */
4882 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4884 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4885 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4886
4887 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4888 * mixer widget
f12ab1e0
TI
4889 * Note: PASD motherboards uses the Line In 2 as the input for
4890 * front panel mic (mic 2)
df694daa
KY
4891 */
4892 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
4893 /* mute analog inputs */
4894 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4895 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4897 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4898 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
4899
4900 /*
4901 * Set up output mixers (0x08 - 0x0a)
4902 */
4903 /* set vol=0 to output mixers */
4904 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4905 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4906 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4907 /* set up input amps for analog loopback */
4908 /* Amp Indices: DAC = 0, mixer = 1 */
4909 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4910 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4911 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4912 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4913 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4914 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4915
4916 { }
4917};
4918
4919static int alc260_parse_auto_config(struct hda_codec *codec)
4920{
4921 struct alc_spec *spec = codec->spec;
4922 unsigned int wcap;
4923 int err;
4924 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4925
f12ab1e0
TI
4926 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4927 alc260_ignore);
4928 if (err < 0)
df694daa 4929 return err;
f12ab1e0
TI
4930 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4931 if (err < 0)
4a471b7d 4932 return err;
f12ab1e0 4933 if (!spec->kctl_alloc)
df694daa 4934 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
4935 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4936 if (err < 0)
df694daa
KY
4937 return err;
4938
4939 spec->multiout.max_channels = 2;
4940
4941 if (spec->autocfg.dig_out_pin)
4942 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4943 if (spec->kctl_alloc)
4944 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4945
4946 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4947
a1e8d2da 4948 spec->num_mux_defs = 1;
df694daa
KY
4949 spec->input_mux = &spec->private_imux;
4950
4951 /* check whether NID 0x04 is valid */
4a471b7d 4952 wcap = get_wcaps(codec, 0x04);
df694daa 4953 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
67ebcb03 4954 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
df694daa
KY
4955 spec->adc_nids = alc260_adc_nids_alt;
4956 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4957 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
df694daa
KY
4958 } else {
4959 spec->adc_nids = alc260_adc_nids;
4960 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4961 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
df694daa 4962 }
4a471b7d 4963 spec->num_mixers++;
df694daa
KY
4964
4965 return 1;
4966}
4967
ae6b813a
TI
4968/* additional initialization for auto-configuration model */
4969static void alc260_auto_init(struct hda_codec *codec)
df694daa 4970{
f6c7e546 4971 struct alc_spec *spec = codec->spec;
df694daa
KY
4972 alc260_auto_init_multi_out(codec);
4973 alc260_auto_init_analog_input(codec);
f6c7e546
TI
4974 if (spec->unsol_event)
4975 alc_sku_automute(codec);
df694daa
KY
4976}
4977
cb53c626
TI
4978#ifdef CONFIG_SND_HDA_POWER_SAVE
4979static struct hda_amp_list alc260_loopbacks[] = {
4980 { 0x07, HDA_INPUT, 0 },
4981 { 0x07, HDA_INPUT, 1 },
4982 { 0x07, HDA_INPUT, 2 },
4983 { 0x07, HDA_INPUT, 3 },
4984 { 0x07, HDA_INPUT, 4 },
4985 { } /* end */
4986};
4987#endif
4988
df694daa
KY
4989/*
4990 * ALC260 configurations
4991 */
f5fcc13c
TI
4992static const char *alc260_models[ALC260_MODEL_LAST] = {
4993 [ALC260_BASIC] = "basic",
4994 [ALC260_HP] = "hp",
4995 [ALC260_HP_3013] = "hp-3013",
4996 [ALC260_FUJITSU_S702X] = "fujitsu",
4997 [ALC260_ACER] = "acer",
bc9f98a9
KY
4998 [ALC260_WILL] = "will",
4999 [ALC260_REPLACER_672V] = "replacer",
7cf51e48 5000#ifdef CONFIG_SND_DEBUG
f5fcc13c 5001 [ALC260_TEST] = "test",
7cf51e48 5002#endif
f5fcc13c
TI
5003 [ALC260_AUTO] = "auto",
5004};
5005
5006static struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 5007 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
f5fcc13c 5008 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
9720b718 5009 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
a8a5d067 5010 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
f5fcc13c
TI
5011 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5012 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5013 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5014 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5015 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5016 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5017 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5018 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5019 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5020 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5021 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5022 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 5023 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 5024 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
5025 {}
5026};
5027
5028static struct alc_config_preset alc260_presets[] = {
5029 [ALC260_BASIC] = {
5030 .mixers = { alc260_base_output_mixer,
5031 alc260_input_mixer,
5032 alc260_pc_beep_mixer,
5033 alc260_capture_mixer },
5034 .init_verbs = { alc260_init_verbs },
5035 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5036 .dac_nids = alc260_dac_nids,
5037 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5038 .adc_nids = alc260_adc_nids,
5039 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5040 .channel_mode = alc260_modes,
5041 .input_mux = &alc260_capture_source,
5042 },
5043 [ALC260_HP] = {
bec15c3a 5044 .mixers = { alc260_hp_output_mixer,
df694daa
KY
5045 alc260_input_mixer,
5046 alc260_capture_alt_mixer },
bec15c3a
TI
5047 .init_verbs = { alc260_init_verbs,
5048 alc260_hp_unsol_verbs },
df694daa
KY
5049 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5050 .dac_nids = alc260_dac_nids,
5051 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5052 .adc_nids = alc260_hp_adc_nids,
5053 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5054 .channel_mode = alc260_modes,
5055 .input_mux = &alc260_capture_source,
bec15c3a
TI
5056 .unsol_event = alc260_hp_unsol_event,
5057 .init_hook = alc260_hp_automute,
df694daa
KY
5058 },
5059 [ALC260_HP_3013] = {
5060 .mixers = { alc260_hp_3013_mixer,
5061 alc260_input_mixer,
5062 alc260_capture_alt_mixer },
bec15c3a
TI
5063 .init_verbs = { alc260_hp_3013_init_verbs,
5064 alc260_hp_3013_unsol_verbs },
df694daa
KY
5065 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5066 .dac_nids = alc260_dac_nids,
5067 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5068 .adc_nids = alc260_hp_adc_nids,
5069 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5070 .channel_mode = alc260_modes,
5071 .input_mux = &alc260_capture_source,
bec15c3a
TI
5072 .unsol_event = alc260_hp_3013_unsol_event,
5073 .init_hook = alc260_hp_3013_automute,
df694daa
KY
5074 },
5075 [ALC260_FUJITSU_S702X] = {
5076 .mixers = { alc260_fujitsu_mixer,
5077 alc260_capture_mixer },
5078 .init_verbs = { alc260_fujitsu_init_verbs },
5079 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5080 .dac_nids = alc260_dac_nids,
d57fdac0
JW
5081 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5082 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
5083 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5084 .channel_mode = alc260_modes,
a1e8d2da
JW
5085 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5086 .input_mux = alc260_fujitsu_capture_sources,
df694daa 5087 },
0bfc90e9
JW
5088 [ALC260_ACER] = {
5089 .mixers = { alc260_acer_mixer,
5090 alc260_capture_mixer },
5091 .init_verbs = { alc260_acer_init_verbs },
5092 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5093 .dac_nids = alc260_dac_nids,
5094 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5095 .adc_nids = alc260_dual_adc_nids,
5096 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5097 .channel_mode = alc260_modes,
a1e8d2da
JW
5098 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5099 .input_mux = alc260_acer_capture_sources,
0bfc90e9 5100 },
bc9f98a9
KY
5101 [ALC260_WILL] = {
5102 .mixers = { alc260_will_mixer,
5103 alc260_capture_mixer },
5104 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5105 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5106 .dac_nids = alc260_dac_nids,
5107 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5108 .adc_nids = alc260_adc_nids,
5109 .dig_out_nid = ALC260_DIGOUT_NID,
5110 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5111 .channel_mode = alc260_modes,
5112 .input_mux = &alc260_capture_source,
5113 },
5114 [ALC260_REPLACER_672V] = {
5115 .mixers = { alc260_replacer_672v_mixer,
5116 alc260_capture_mixer },
5117 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5118 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5119 .dac_nids = alc260_dac_nids,
5120 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5121 .adc_nids = alc260_adc_nids,
5122 .dig_out_nid = ALC260_DIGOUT_NID,
5123 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5124 .channel_mode = alc260_modes,
5125 .input_mux = &alc260_capture_source,
5126 .unsol_event = alc260_replacer_672v_unsol_event,
5127 .init_hook = alc260_replacer_672v_automute,
5128 },
7cf51e48
JW
5129#ifdef CONFIG_SND_DEBUG
5130 [ALC260_TEST] = {
5131 .mixers = { alc260_test_mixer,
5132 alc260_capture_mixer },
5133 .init_verbs = { alc260_test_init_verbs },
5134 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5135 .dac_nids = alc260_test_dac_nids,
5136 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5137 .adc_nids = alc260_test_adc_nids,
5138 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5139 .channel_mode = alc260_modes,
a1e8d2da
JW
5140 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5141 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
5142 },
5143#endif
df694daa
KY
5144};
5145
5146static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
5147{
5148 struct alc_spec *spec;
df694daa 5149 int err, board_config;
1da177e4 5150
e560d8d8 5151 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5152 if (spec == NULL)
5153 return -ENOMEM;
5154
5155 codec->spec = spec;
5156
f5fcc13c
TI
5157 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5158 alc260_models,
5159 alc260_cfg_tbl);
5160 if (board_config < 0) {
9c7f852e
TI
5161 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5162 "trying auto-probe from BIOS...\n");
df694daa 5163 board_config = ALC260_AUTO;
16ded525 5164 }
1da177e4 5165
df694daa
KY
5166 if (board_config == ALC260_AUTO) {
5167 /* automatic parse from the BIOS config */
5168 err = alc260_parse_auto_config(codec);
5169 if (err < 0) {
5170 alc_free(codec);
5171 return err;
f12ab1e0 5172 } else if (!err) {
9c7f852e
TI
5173 printk(KERN_INFO
5174 "hda_codec: Cannot set up configuration "
5175 "from BIOS. Using base mode...\n");
df694daa
KY
5176 board_config = ALC260_BASIC;
5177 }
a9430dd8 5178 }
e9edcee0 5179
df694daa
KY
5180 if (board_config != ALC260_AUTO)
5181 setup_preset(spec, &alc260_presets[board_config]);
1da177e4
LT
5182
5183 spec->stream_name_analog = "ALC260 Analog";
5184 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5185 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5186
a3bcba38
TI
5187 spec->stream_name_digital = "ALC260 Digital";
5188 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5189 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5190
2134ea4f
TI
5191 spec->vmaster_nid = 0x08;
5192
1da177e4 5193 codec->patch_ops = alc_patch_ops;
df694daa 5194 if (board_config == ALC260_AUTO)
ae6b813a 5195 spec->init_hook = alc260_auto_init;
cb53c626
TI
5196#ifdef CONFIG_SND_HDA_POWER_SAVE
5197 if (!spec->loopback.amplist)
5198 spec->loopback.amplist = alc260_loopbacks;
5199#endif
1da177e4
LT
5200
5201 return 0;
5202}
5203
e9edcee0 5204
1da177e4
LT
5205/*
5206 * ALC882 support
5207 *
5208 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5209 * configuration. Each pin widget can choose any input DACs and a mixer.
5210 * Each ADC is connected from a mixer of all inputs. This makes possible
5211 * 6-channel independent captures.
5212 *
5213 * In addition, an independent DAC for the multi-playback (not used in this
5214 * driver yet).
5215 */
df694daa
KY
5216#define ALC882_DIGOUT_NID 0x06
5217#define ALC882_DIGIN_NID 0x0a
1da177e4 5218
d2a6d7dc 5219static struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
5220 { 8, NULL }
5221};
5222
5223static hda_nid_t alc882_dac_nids[4] = {
5224 /* front, rear, clfe, rear_surr */
5225 0x02, 0x03, 0x04, 0x05
5226};
5227
df694daa
KY
5228/* identical with ALC880 */
5229#define alc882_adc_nids alc880_adc_nids
5230#define alc882_adc_nids_alt alc880_adc_nids_alt
1da177e4 5231
e1406348
TI
5232static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5233static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5234
1da177e4
LT
5235/* input MUX */
5236/* FIXME: should be a matrix-type input source selection */
5237
5238static struct hda_input_mux alc882_capture_source = {
5239 .num_items = 4,
5240 .items = {
5241 { "Mic", 0x0 },
5242 { "Front Mic", 0x1 },
5243 { "Line", 0x2 },
5244 { "CD", 0x4 },
5245 },
5246};
1da177e4
LT
5247#define alc882_mux_enum_info alc_mux_enum_info
5248#define alc882_mux_enum_get alc_mux_enum_get
5249
f12ab1e0
TI
5250static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5251 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
5252{
5253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5254 struct alc_spec *spec = codec->spec;
5255 const struct hda_input_mux *imux = spec->input_mux;
5256 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
88c71a99
TI
5257 hda_nid_t nid = spec->capsrc_nids ?
5258 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
1da177e4
LT
5259 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5260 unsigned int i, idx;
5261
5262 idx = ucontrol->value.enumerated.item[0];
5263 if (idx >= imux->num_items)
5264 idx = imux->num_items - 1;
82beb8fd 5265 if (*cur_val == idx)
1da177e4
LT
5266 return 0;
5267 for (i = 0; i < imux->num_items; i++) {
47fd830a
TI
5268 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5269 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
82beb8fd 5270 imux->items[i].index,
47fd830a 5271 HDA_AMP_MUTE, v);
1da177e4
LT
5272 }
5273 *cur_val = idx;
5274 return 1;
5275}
5276
272a527c
KY
5277/*
5278 * 2ch mode
5279 */
5280static struct hda_verb alc882_3ST_ch2_init[] = {
5281 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5282 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5285 { } /* end */
5286};
5287
5288/*
5289 * 6ch mode
5290 */
5291static struct hda_verb alc882_3ST_ch6_init[] = {
5292 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5293 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5294 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5295 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5296 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5297 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5298 { } /* end */
5299};
5300
5301static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5302 { 2, alc882_3ST_ch2_init },
5303 { 6, alc882_3ST_ch6_init },
5304};
5305
df694daa
KY
5306/*
5307 * 6ch mode
5308 */
5309static struct hda_verb alc882_sixstack_ch6_init[] = {
5310 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5311 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5312 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5314 { } /* end */
5315};
5316
5317/*
5318 * 8ch mode
5319 */
5320static struct hda_verb alc882_sixstack_ch8_init[] = {
5321 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5322 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5323 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5324 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5325 { } /* end */
5326};
5327
5328static struct hda_channel_mode alc882_sixstack_modes[2] = {
5329 { 6, alc882_sixstack_ch6_init },
5330 { 8, alc882_sixstack_ch8_init },
5331};
5332
87350ad0
TI
5333/*
5334 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5335 */
5336
5337/*
5338 * 2ch mode
5339 */
5340static struct hda_verb alc885_mbp_ch2_init[] = {
5341 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5343 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5344 { } /* end */
5345};
5346
5347/*
5348 * 6ch mode
5349 */
5350static struct hda_verb alc885_mbp_ch6_init[] = {
5351 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5352 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5353 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5355 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5356 { } /* end */
5357};
5358
5359static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5360 { 2, alc885_mbp_ch2_init },
5361 { 6, alc885_mbp_ch6_init },
5362};
5363
5364
1da177e4
LT
5365/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5366 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5367 */
c8b6bf9b 5368static struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 5369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 5370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 5371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 5372 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
5373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
5375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 5377 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 5378 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
5379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5380 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5381 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5383 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 5385 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1da177e4
LT
5386 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5387 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 5388 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
1da177e4
LT
5389 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5390 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5391 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1da177e4
LT
5392 { } /* end */
5393};
5394
87350ad0 5395static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
2134ea4f
TI
5396 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5397 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5398 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5399 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5400 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5401 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
5402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5403 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2134ea4f 5404 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
87350ad0
TI
5405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5406 { } /* end */
5407};
bdd148a3
KY
5408static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5411 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5412 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5416 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5418 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5419 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5420 { } /* end */
5421};
5422
272a527c
KY
5423static struct snd_kcontrol_new alc882_targa_mixer[] = {
5424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5426 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5427 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5428 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5429 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5430 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5433 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
96fe7cc8 5436 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
272a527c
KY
5437 { } /* end */
5438};
5439
5440/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5441 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5442 */
5443static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5444 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5445 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5446 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5447 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5448 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5449 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5450 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5451 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5452 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5453 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
96fe7cc8 5456 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
272a527c
KY
5457 { } /* end */
5458};
5459
914759b7
TI
5460static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5461 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5462 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5463 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5469 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5470 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5471 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5472 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5473 { } /* end */
5474};
5475
df694daa
KY
5476static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5477 {
5478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5479 .name = "Channel Mode",
5480 .info = alc_ch_mode_info,
5481 .get = alc_ch_mode_get,
5482 .put = alc_ch_mode_put,
5483 },
5484 { } /* end */
5485};
5486
1da177e4
LT
5487static struct hda_verb alc882_init_verbs[] = {
5488 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
5489 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5490 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5491 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5492 /* Rear mixer */
05acb863
TI
5493 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5494 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5495 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5496 /* CLFE mixer */
05acb863
TI
5497 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5498 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5500 /* Side mixer */
05acb863
TI
5501 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5502 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5503 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 5504
e9edcee0 5505 /* Front Pin: output 0 (0x0c) */
05acb863 5506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5507 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5508 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 5509 /* Rear Pin: output 1 (0x0d) */
05acb863 5510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 5513 /* CLFE Pin: output 2 (0x0e) */
05acb863 5514 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5515 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5516 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 5517 /* Side Pin: output 3 (0x0f) */
05acb863 5518 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 5519 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 5520 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 5521 /* Mic (rear) pin: input vref at 80% */
16ded525 5522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5524 /* Front Mic pin: input vref at 80% */
16ded525 5525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
5526 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5527 /* Line In pin: input */
05acb863 5528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
5529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5530 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5532 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5533 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 5534 /* CD pin widget for input */
05acb863 5535 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
5536
5537 /* FIXME: use matrix-type input source selection */
5538 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5539 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
05acb863
TI
5540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5544 /* Input mixer2 */
05acb863
TI
5545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5547 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 5549 /* Input mixer3 */
05acb863
TI
5550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5551 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5552 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5553 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5554 /* ADC1: mute amp left and right */
5555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5556 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5557 /* ADC2: mute amp left and right */
5558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5559 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
5560 /* ADC3: mute amp left and right */
5561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 5562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
5563
5564 { }
5565};
5566
4b146cb0
TI
5567static struct hda_verb alc882_eapd_verbs[] = {
5568 /* change to EAPD mode */
5569 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 5570 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 5571 { }
4b146cb0
TI
5572};
5573
9102cd1c
TD
5574/* Mac Pro test */
5575static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5576 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5577 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5578 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5579 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5580 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5581 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5582 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5583 { } /* end */
5584};
5585
5586static struct hda_verb alc882_macpro_init_verbs[] = {
5587 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5591 /* Front Pin: output 0 (0x0c) */
5592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5594 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5595 /* Front Mic pin: input vref at 80% */
5596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5598 /* Speaker: output */
5599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5601 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5602 /* Headphone output (output 0 - 0x0c) */
5603 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5604 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5605 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5606
5607 /* FIXME: use matrix-type input source selection */
5608 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5609 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5612 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5613 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5614 /* Input mixer2 */
5615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5616 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5617 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5618 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5619 /* Input mixer3 */
5620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5621 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5622 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5624 /* ADC1: mute amp left and right */
5625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5626 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5627 /* ADC2: mute amp left and right */
5628 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5629 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5630 /* ADC3: mute amp left and right */
5631 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5632 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5633
5634 { }
5635};
f12ab1e0 5636
87350ad0
TI
5637/* Macbook Pro rev3 */
5638static struct hda_verb alc885_mbp3_init_verbs[] = {
5639 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5642 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5643 /* Rear mixer */
5644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5647 /* Front Pin: output 0 (0x0c) */
5648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5651 /* HP Pin: output 0 (0x0d) */
5652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5655 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5656 /* Mic (rear) pin: input vref at 80% */
5657 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5658 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5659 /* Front Mic pin: input vref at 80% */
5660 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5661 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5662 /* Line In pin: use output 1 when in LineOut mode */
5663 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5664 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5665 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5666
5667 /* FIXME: use matrix-type input source selection */
5668 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5669 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5674 /* Input mixer2 */
5675 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5676 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5677 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5679 /* Input mixer3 */
5680 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5681 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5684 /* ADC1: mute amp left and right */
5685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5686 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5687 /* ADC2: mute amp left and right */
5688 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5689 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5690 /* ADC3: mute amp left and right */
5691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5692 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5693
5694 { }
5695};
5696
c54728d8
NF
5697/* iMac 24 mixer. */
5698static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5699 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5700 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5701 { } /* end */
5702};
5703
5704/* iMac 24 init verbs. */
5705static struct hda_verb alc885_imac24_init_verbs[] = {
5706 /* Internal speakers: output 0 (0x0c) */
5707 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5709 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5710 /* Internal speakers: output 0 (0x0c) */
5711 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5712 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5713 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5714 /* Headphone: output 0 (0x0c) */
5715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5716 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5717 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5718 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5719 /* Front Mic: input vref at 80% */
5720 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5722 { }
5723};
5724
5725/* Toggle speaker-output according to the hp-jack state */
5726static void alc885_imac24_automute(struct hda_codec *codec)
5727{
5728 unsigned int present;
5729
5730 present = snd_hda_codec_read(codec, 0x14, 0,
5731 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5732 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5733 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5734 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5735 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
c54728d8
NF
5736}
5737
5738/* Processes unsolicited events. */
5739static void alc885_imac24_unsol_event(struct hda_codec *codec,
5740 unsigned int res)
5741{
5742 /* Headphone insertion or removal. */
5743 if ((res >> 26) == ALC880_HP_EVENT)
5744 alc885_imac24_automute(codec);
5745}
5746
87350ad0
TI
5747static void alc885_mbp3_automute(struct hda_codec *codec)
5748{
5749 unsigned int present;
5750
5751 present = snd_hda_codec_read(codec, 0x15, 0,
5752 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5753 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5754 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5755 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5756 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5757
5758}
5759static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5760 unsigned int res)
5761{
5762 /* Headphone insertion or removal. */
5763 if ((res >> 26) == ALC880_HP_EVENT)
5764 alc885_mbp3_automute(codec);
5765}
5766
5767
272a527c
KY
5768static struct hda_verb alc882_targa_verbs[] = {
5769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5770 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5771
5772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5774
5775 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5776 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5777 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5778
5779 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5780 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5781 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5782 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5783 { } /* end */
5784};
5785
5786/* toggle speaker-output according to the hp-jack state */
5787static void alc882_targa_automute(struct hda_codec *codec)
5788{
5789 unsigned int present;
5790
5791 present = snd_hda_codec_read(codec, 0x14, 0,
5792 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
5793 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5794 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
82beb8fd
TI
5795 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5796 present ? 1 : 3);
272a527c
KY
5797}
5798
5799static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5800{
5801 /* Looks like the unsol event is incompatible with the standard
5802 * definition. 4bit tag is placed at 26 bit!
5803 */
5804 if (((res >> 26) == ALC880_HP_EVENT)) {
5805 alc882_targa_automute(codec);
5806 }
5807}
5808
5809static struct hda_verb alc882_asus_a7j_verbs[] = {
5810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5812
5813 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5815 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5816
5817 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5818 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5819 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5820
5821 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5822 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5823 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5824 { } /* end */
5825};
5826
914759b7
TI
5827static struct hda_verb alc882_asus_a7m_verbs[] = {
5828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5830
5831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5832 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5833 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5834
5835 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5836 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5838
5839 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5840 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5841 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5842 { } /* end */
5843};
5844
9102cd1c
TD
5845static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5846{
5847 unsigned int gpiostate, gpiomask, gpiodir;
5848
5849 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5850 AC_VERB_GET_GPIO_DATA, 0);
5851
5852 if (!muted)
5853 gpiostate |= (1 << pin);
5854 else
5855 gpiostate &= ~(1 << pin);
5856
5857 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5858 AC_VERB_GET_GPIO_MASK, 0);
5859 gpiomask |= (1 << pin);
5860
5861 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5862 AC_VERB_GET_GPIO_DIRECTION, 0);
5863 gpiodir |= (1 << pin);
5864
5865
5866 snd_hda_codec_write(codec, codec->afg, 0,
5867 AC_VERB_SET_GPIO_MASK, gpiomask);
5868 snd_hda_codec_write(codec, codec->afg, 0,
5869 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5870
5871 msleep(1);
5872
5873 snd_hda_codec_write(codec, codec->afg, 0,
5874 AC_VERB_SET_GPIO_DATA, gpiostate);
5875}
5876
7debbe51
TI
5877/* set up GPIO at initialization */
5878static void alc885_macpro_init_hook(struct hda_codec *codec)
5879{
5880 alc882_gpio_mute(codec, 0, 0);
5881 alc882_gpio_mute(codec, 1, 0);
5882}
5883
5884/* set up GPIO and update auto-muting at initialization */
5885static void alc885_imac24_init_hook(struct hda_codec *codec)
5886{
5887 alc885_macpro_init_hook(codec);
5888 alc885_imac24_automute(codec);
5889}
5890
df694daa
KY
5891/*
5892 * generic initialization of ADC, input mixers and output mixers
5893 */
5894static struct hda_verb alc882_auto_init_verbs[] = {
5895 /*
5896 * Unmute ADC0-2 and set the default input to mic-in
5897 */
5898 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5900 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5901 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5902 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5903 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 5904
cb53c626 5905 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 5906 * mixer widget
f12ab1e0
TI
5907 * Note: PASD motherboards uses the Line In 2 as the input for
5908 * front panel mic (mic 2)
df694daa
KY
5909 */
5910 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
5911 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5913 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5914 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5915 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
e9edcee0 5916
df694daa
KY
5917 /*
5918 * Set up output mixers (0x0c - 0x0f)
5919 */
5920 /* set vol=0 to output mixers */
5921 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5922 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5923 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5924 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5925 /* set up input amps for analog loopback */
5926 /* Amp Indices: DAC = 0, mixer = 1 */
5927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5928 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5929 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5932 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5933 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5934 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5935 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5936 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5937
5938 /* FIXME: use matrix-type input source selection */
5939 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5940 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5941 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5944 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5945 /* Input mixer2 */
5946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5950 /* Input mixer3 */
5951 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5955
5956 { }
5957};
5958
5959/* capture mixer elements */
5960static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5961 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5962 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5963 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5964 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5965 {
5966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5967 /* The multiple "Capture Source" controls confuse alsamixer
5968 * So call somewhat different..
df694daa
KY
5969 */
5970 /* .name = "Capture Source", */
5971 .name = "Input Source",
5972 .count = 2,
5973 .info = alc882_mux_enum_info,
5974 .get = alc882_mux_enum_get,
5975 .put = alc882_mux_enum_put,
5976 },
5977 { } /* end */
5978};
5979
5980static struct snd_kcontrol_new alc882_capture_mixer[] = {
5981 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5982 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5983 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5984 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5985 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5986 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5987 {
5988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5989 /* The multiple "Capture Source" controls confuse alsamixer
5990 * So call somewhat different..
df694daa
KY
5991 */
5992 /* .name = "Capture Source", */
5993 .name = "Input Source",
5994 .count = 3,
5995 .info = alc882_mux_enum_info,
5996 .get = alc882_mux_enum_get,
5997 .put = alc882_mux_enum_put,
5998 },
5999 { } /* end */
6000};
6001
cb53c626
TI
6002#ifdef CONFIG_SND_HDA_POWER_SAVE
6003#define alc882_loopbacks alc880_loopbacks
6004#endif
6005
df694daa
KY
6006/* pcm configuration: identiacal with ALC880 */
6007#define alc882_pcm_analog_playback alc880_pcm_analog_playback
6008#define alc882_pcm_analog_capture alc880_pcm_analog_capture
6009#define alc882_pcm_digital_playback alc880_pcm_digital_playback
6010#define alc882_pcm_digital_capture alc880_pcm_digital_capture
6011
6012/*
6013 * configuration and preset
6014 */
f5fcc13c
TI
6015static const char *alc882_models[ALC882_MODEL_LAST] = {
6016 [ALC882_3ST_DIG] = "3stack-dig",
6017 [ALC882_6ST_DIG] = "6stack-dig",
6018 [ALC882_ARIMA] = "arima",
bdd148a3 6019 [ALC882_W2JC] = "w2jc",
0438a00e
TI
6020 [ALC882_TARGA] = "targa",
6021 [ALC882_ASUS_A7J] = "asus-a7j",
6022 [ALC882_ASUS_A7M] = "asus-a7m",
9102cd1c 6023 [ALC885_MACPRO] = "macpro",
87350ad0 6024 [ALC885_MBP3] = "mbp3",
c54728d8 6025 [ALC885_IMAC24] = "imac24",
f5fcc13c
TI
6026 [ALC882_AUTO] = "auto",
6027};
6028
6029static struct snd_pci_quirk alc882_cfg_tbl[] = {
6030 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
272a527c 6031 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
ac8842a0 6032 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
914759b7 6033 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
ac3e3741 6034 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
c5d9f1cd 6035 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7b9470d8 6036 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 6037 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4444704c 6038 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
ac3e3741
TI
6039 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6040 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6041 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
df694daa
KY
6042 {}
6043};
6044
6045static struct alc_config_preset alc882_presets[] = {
6046 [ALC882_3ST_DIG] = {
6047 .mixers = { alc882_base_mixer },
6048 .init_verbs = { alc882_init_verbs },
6049 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6050 .dac_nids = alc882_dac_nids,
6051 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6052 .dig_in_nid = ALC882_DIGIN_NID,
6053 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6054 .channel_mode = alc882_ch_modes,
4e195a7b 6055 .need_dac_fix = 1,
df694daa
KY
6056 .input_mux = &alc882_capture_source,
6057 },
6058 [ALC882_6ST_DIG] = {
6059 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6060 .init_verbs = { alc882_init_verbs },
6061 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6062 .dac_nids = alc882_dac_nids,
6063 .dig_out_nid = ALC882_DIGOUT_NID,
df694daa
KY
6064 .dig_in_nid = ALC882_DIGIN_NID,
6065 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6066 .channel_mode = alc882_sixstack_modes,
6067 .input_mux = &alc882_capture_source,
6068 },
4b146cb0
TI
6069 [ALC882_ARIMA] = {
6070 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6071 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6073 .dac_nids = alc882_dac_nids,
6074 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6075 .channel_mode = alc882_sixstack_modes,
6076 .input_mux = &alc882_capture_source,
6077 },
bdd148a3
KY
6078 [ALC882_W2JC] = {
6079 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6080 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6081 alc880_gpio1_init_verbs },
6082 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6083 .dac_nids = alc882_dac_nids,
6084 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6085 .channel_mode = alc880_threestack_modes,
6086 .need_dac_fix = 1,
6087 .input_mux = &alc882_capture_source,
6088 .dig_out_nid = ALC882_DIGOUT_NID,
6089 },
87350ad0
TI
6090 [ALC885_MBP3] = {
6091 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6092 .init_verbs = { alc885_mbp3_init_verbs,
6093 alc880_gpio1_init_verbs },
6094 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6095 .dac_nids = alc882_dac_nids,
6096 .channel_mode = alc885_mbp_6ch_modes,
6097 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6098 .input_mux = &alc882_capture_source,
6099 .dig_out_nid = ALC882_DIGOUT_NID,
6100 .dig_in_nid = ALC882_DIGIN_NID,
6101 .unsol_event = alc885_mbp3_unsol_event,
6102 .init_hook = alc885_mbp3_automute,
6103 },
9102cd1c
TD
6104 [ALC885_MACPRO] = {
6105 .mixers = { alc882_macpro_mixer },
6106 .init_verbs = { alc882_macpro_init_verbs },
6107 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6108 .dac_nids = alc882_dac_nids,
6109 .dig_out_nid = ALC882_DIGOUT_NID,
6110 .dig_in_nid = ALC882_DIGIN_NID,
6111 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6112 .channel_mode = alc882_ch_modes,
6113 .input_mux = &alc882_capture_source,
7debbe51 6114 .init_hook = alc885_macpro_init_hook,
9102cd1c 6115 },
c54728d8
NF
6116 [ALC885_IMAC24] = {
6117 .mixers = { alc885_imac24_mixer },
6118 .init_verbs = { alc885_imac24_init_verbs },
6119 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6120 .dac_nids = alc882_dac_nids,
6121 .dig_out_nid = ALC882_DIGOUT_NID,
6122 .dig_in_nid = ALC882_DIGIN_NID,
6123 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6124 .channel_mode = alc882_ch_modes,
6125 .input_mux = &alc882_capture_source,
6126 .unsol_event = alc885_imac24_unsol_event,
7debbe51 6127 .init_hook = alc885_imac24_init_hook,
c54728d8 6128 },
272a527c
KY
6129 [ALC882_TARGA] = {
6130 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6131 alc882_capture_mixer },
6132 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6133 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6134 .dac_nids = alc882_dac_nids,
6135 .dig_out_nid = ALC882_DIGOUT_NID,
6136 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6137 .adc_nids = alc882_adc_nids,
e1406348 6138 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6139 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6140 .channel_mode = alc882_3ST_6ch_modes,
6141 .need_dac_fix = 1,
6142 .input_mux = &alc882_capture_source,
6143 .unsol_event = alc882_targa_unsol_event,
6144 .init_hook = alc882_targa_automute,
6145 },
6146 [ALC882_ASUS_A7J] = {
6147 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6148 alc882_capture_mixer },
6149 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6150 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6151 .dac_nids = alc882_dac_nids,
6152 .dig_out_nid = ALC882_DIGOUT_NID,
6153 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6154 .adc_nids = alc882_adc_nids,
e1406348 6155 .capsrc_nids = alc882_capsrc_nids,
272a527c
KY
6156 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6157 .channel_mode = alc882_3ST_6ch_modes,
6158 .need_dac_fix = 1,
6159 .input_mux = &alc882_capture_source,
6160 },
914759b7
TI
6161 [ALC882_ASUS_A7M] = {
6162 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6163 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6164 alc880_gpio1_init_verbs,
6165 alc882_asus_a7m_verbs },
6166 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6167 .dac_nids = alc882_dac_nids,
6168 .dig_out_nid = ALC882_DIGOUT_NID,
6169 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6170 .channel_mode = alc880_threestack_modes,
6171 .need_dac_fix = 1,
6172 .input_mux = &alc882_capture_source,
6173 },
df694daa
KY
6174};
6175
6176
f95474ec
TI
6177/*
6178 * Pin config fixes
6179 */
6180enum {
6181 PINFIX_ABIT_AW9D_MAX
6182};
6183
6184static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6185 { 0x15, 0x01080104 }, /* side */
6186 { 0x16, 0x01011012 }, /* rear */
6187 { 0x17, 0x01016011 }, /* clfe */
6188 { }
6189};
6190
6191static const struct alc_pincfg *alc882_pin_fixes[] = {
6192 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6193};
6194
6195static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6196 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6197 {}
6198};
6199
df694daa
KY
6200/*
6201 * BIOS auto configuration
6202 */
6203static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6204 hda_nid_t nid, int pin_type,
6205 int dac_idx)
6206{
6207 /* set as output */
6208 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
6209 int idx;
6210
f6c7e546 6211 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
6212 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6213 idx = 4;
6214 else
6215 idx = spec->multiout.dac_nids[dac_idx] - 2;
df694daa
KY
6216 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6217
6218}
6219
6220static void alc882_auto_init_multi_out(struct hda_codec *codec)
6221{
6222 struct alc_spec *spec = codec->spec;
6223 int i;
6224
bc9f98a9 6225 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
df694daa 6226 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 6227 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 6228 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 6229 if (nid)
baba8ee9 6230 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 6231 i);
df694daa
KY
6232 }
6233}
6234
6235static void alc882_auto_init_hp_out(struct hda_codec *codec)
6236{
6237 struct alc_spec *spec = codec->spec;
6238 hda_nid_t pin;
6239
eb06ed8f 6240 pin = spec->autocfg.hp_pins[0];
df694daa 6241 if (pin) /* connect to front */
f12ab1e0
TI
6242 /* use dac 0 */
6243 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
6244 pin = spec->autocfg.speaker_pins[0];
6245 if (pin)
6246 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
6247}
6248
6249#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6250#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6251
6252static void alc882_auto_init_analog_input(struct hda_codec *codec)
6253{
6254 struct alc_spec *spec = codec->spec;
6255 int i;
6256
6257 for (i = 0; i < AUTO_PIN_LAST; i++) {
6258 hda_nid_t nid = spec->autocfg.input_pins[i];
6259 if (alc882_is_input_pin(nid)) {
f12ab1e0
TI
6260 snd_hda_codec_write(codec, nid, 0,
6261 AC_VERB_SET_PIN_WIDGET_CONTROL,
6262 i <= AUTO_PIN_FRONT_MIC ?
6263 PIN_VREF80 : PIN_IN);
df694daa 6264 if (nid != ALC882_PIN_CD_NID)
f12ab1e0
TI
6265 snd_hda_codec_write(codec, nid, 0,
6266 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
6267 AMP_OUT_MUTE);
6268 }
6269 }
6270}
6271
776e184e
TI
6272/* add mic boosts if needed */
6273static int alc_auto_add_mic_boost(struct hda_codec *codec)
6274{
6275 struct alc_spec *spec = codec->spec;
6276 int err;
6277 hda_nid_t nid;
6278
6279 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
ce22e03e 6280 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6281 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6282 "Mic Boost",
6283 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6284 if (err < 0)
6285 return err;
6286 }
6287 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
ce22e03e 6288 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
776e184e
TI
6289 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6290 "Front Mic Boost",
6291 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6292 if (err < 0)
6293 return err;
6294 }
6295 return 0;
6296}
6297
df694daa
KY
6298/* almost identical with ALC880 parser... */
6299static int alc882_parse_auto_config(struct hda_codec *codec)
6300{
6301 struct alc_spec *spec = codec->spec;
6302 int err = alc880_parse_auto_config(codec);
6303
6304 if (err < 0)
6305 return err;
776e184e
TI
6306 else if (!err)
6307 return 0; /* no config found */
6308
6309 err = alc_auto_add_mic_boost(codec);
6310 if (err < 0)
6311 return err;
6312
6313 /* hack - override the init verbs */
6314 spec->init_verbs[0] = alc882_auto_init_verbs;
6315
6316 return 1; /* config found */
df694daa
KY
6317}
6318
ae6b813a
TI
6319/* additional initialization for auto-configuration model */
6320static void alc882_auto_init(struct hda_codec *codec)
df694daa 6321{
f6c7e546 6322 struct alc_spec *spec = codec->spec;
df694daa
KY
6323 alc882_auto_init_multi_out(codec);
6324 alc882_auto_init_hp_out(codec);
6325 alc882_auto_init_analog_input(codec);
f6c7e546
TI
6326 if (spec->unsol_event)
6327 alc_sku_automute(codec);
df694daa
KY
6328}
6329
df694daa
KY
6330static int patch_alc882(struct hda_codec *codec)
6331{
6332 struct alc_spec *spec;
6333 int err, board_config;
6334
6335 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6336 if (spec == NULL)
6337 return -ENOMEM;
6338
6339 codec->spec = spec;
6340
f5fcc13c
TI
6341 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6342 alc882_models,
6343 alc882_cfg_tbl);
df694daa
KY
6344
6345 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
081d17c4
TD
6346 /* Pick up systems that don't supply PCI SSID */
6347 switch (codec->subsystem_id) {
6348 case 0x106b0c00: /* Mac Pro */
6349 board_config = ALC885_MACPRO;
6350 break;
c54728d8
NF
6351 case 0x106b1000: /* iMac 24 */
6352 board_config = ALC885_IMAC24;
6353 break;
3d5fa2e5 6354 case 0x106b00a1: /* Macbook */
87350ad0
TI
6355 case 0x106b2c00: /* Macbook Pro rev3 */
6356 board_config = ALC885_MBP3;
6357 break;
081d17c4
TD
6358 default:
6359 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6360 "trying auto-probe from BIOS...\n");
6361 board_config = ALC882_AUTO;
6362 }
df694daa
KY
6363 }
6364
f95474ec
TI
6365 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6366
df694daa
KY
6367 if (board_config == ALC882_AUTO) {
6368 /* automatic parse from the BIOS config */
6369 err = alc882_parse_auto_config(codec);
6370 if (err < 0) {
6371 alc_free(codec);
6372 return err;
f12ab1e0 6373 } else if (!err) {
9c7f852e
TI
6374 printk(KERN_INFO
6375 "hda_codec: Cannot set up configuration "
6376 "from BIOS. Using base mode...\n");
df694daa
KY
6377 board_config = ALC882_3ST_DIG;
6378 }
6379 }
6380
6381 if (board_config != ALC882_AUTO)
6382 setup_preset(spec, &alc882_presets[board_config]);
1da177e4
LT
6383
6384 spec->stream_name_analog = "ALC882 Analog";
df694daa
KY
6385 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6386 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6330079f
TI
6387 /* FIXME: setup DAC5 */
6388 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6389 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4
LT
6390
6391 spec->stream_name_digital = "ALC882 Digital";
df694daa
KY
6392 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6393 spec->stream_digital_capture = &alc882_pcm_digital_capture;
1da177e4 6394
f12ab1e0 6395 if (!spec->adc_nids && spec->input_mux) {
df694daa 6396 /* check whether NID 0x07 is valid */
4a471b7d 6397 unsigned int wcap = get_wcaps(codec, 0x07);
f12ab1e0
TI
6398 /* get type */
6399 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
6400 if (wcap != AC_WID_AUD_IN) {
6401 spec->adc_nids = alc882_adc_nids_alt;
6402 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
e1406348 6403 spec->capsrc_nids = alc882_capsrc_nids_alt;
f12ab1e0
TI
6404 spec->mixers[spec->num_mixers] =
6405 alc882_capture_alt_mixer;
df694daa
KY
6406 spec->num_mixers++;
6407 } else {
6408 spec->adc_nids = alc882_adc_nids;
6409 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
e1406348 6410 spec->capsrc_nids = alc882_capsrc_nids;
df694daa
KY
6411 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6412 spec->num_mixers++;
6413 }
6414 }
1da177e4 6415
2134ea4f
TI
6416 spec->vmaster_nid = 0x0c;
6417
1da177e4 6418 codec->patch_ops = alc_patch_ops;
df694daa 6419 if (board_config == ALC882_AUTO)
ae6b813a 6420 spec->init_hook = alc882_auto_init;
cb53c626
TI
6421#ifdef CONFIG_SND_HDA_POWER_SAVE
6422 if (!spec->loopback.amplist)
6423 spec->loopback.amplist = alc882_loopbacks;
6424#endif
df694daa
KY
6425
6426 return 0;
6427}
6428
6429/*
9c7f852e
TI
6430 * ALC883 support
6431 *
6432 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6433 * configuration. Each pin widget can choose any input DACs and a mixer.
6434 * Each ADC is connected from a mixer of all inputs. This makes possible
6435 * 6-channel independent captures.
6436 *
6437 * In addition, an independent DAC for the multi-playback (not used in this
6438 * driver yet).
df694daa 6439 */
9c7f852e
TI
6440#define ALC883_DIGOUT_NID 0x06
6441#define ALC883_DIGIN_NID 0x0a
df694daa 6442
9c7f852e
TI
6443static hda_nid_t alc883_dac_nids[4] = {
6444 /* front, rear, clfe, rear_surr */
6445 0x02, 0x04, 0x03, 0x05
6446};
df694daa 6447
9c7f852e
TI
6448static hda_nid_t alc883_adc_nids[2] = {
6449 /* ADC1-2 */
6450 0x08, 0x09,
6451};
f12ab1e0 6452
e1406348
TI
6453static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6454
9c7f852e
TI
6455/* input MUX */
6456/* FIXME: should be a matrix-type input source selection */
df694daa 6457
9c7f852e
TI
6458static struct hda_input_mux alc883_capture_source = {
6459 .num_items = 4,
6460 .items = {
6461 { "Mic", 0x0 },
6462 { "Front Mic", 0x1 },
6463 { "Line", 0x2 },
6464 { "CD", 0x4 },
6465 },
6466};
bc9f98a9
KY
6467
6468static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6469 .num_items = 2,
6470 .items = {
6471 { "Mic", 0x1 },
6472 { "Line", 0x2 },
6473 },
6474};
6475
272a527c
KY
6476static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6477 .num_items = 4,
6478 .items = {
6479 { "Mic", 0x0 },
6480 { "iMic", 0x1 },
6481 { "Line", 0x2 },
6482 { "CD", 0x4 },
6483 },
6484};
6485
9c7f852e
TI
6486#define alc883_mux_enum_info alc_mux_enum_info
6487#define alc883_mux_enum_get alc_mux_enum_get
e1406348
TI
6488/* ALC883 has the ALC882-type input selection */
6489#define alc883_mux_enum_put alc882_mux_enum_put
f12ab1e0 6490
9c7f852e
TI
6491/*
6492 * 2ch mode
6493 */
6494static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6495 { 2, NULL }
6496};
6497
6498/*
6499 * 2ch mode
6500 */
6501static struct hda_verb alc883_3ST_ch2_init[] = {
6502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6504 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6505 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6506 { } /* end */
6507};
6508
b201131c
TD
6509/*
6510 * 4ch mode
6511 */
6512static struct hda_verb alc883_3ST_ch4_init[] = {
6513 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6514 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6515 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6516 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6517 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6518 { } /* end */
6519};
6520
9c7f852e
TI
6521/*
6522 * 6ch mode
6523 */
6524static struct hda_verb alc883_3ST_ch6_init[] = {
6525 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6526 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6527 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6528 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6529 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6530 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6531 { } /* end */
6532};
6533
b201131c 6534static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
9c7f852e 6535 { 2, alc883_3ST_ch2_init },
b201131c 6536 { 4, alc883_3ST_ch4_init },
9c7f852e
TI
6537 { 6, alc883_3ST_ch6_init },
6538};
6539
6540/*
6541 * 6ch mode
6542 */
6543static struct hda_verb alc883_sixstack_ch6_init[] = {
6544 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6545 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6546 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6547 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6548 { } /* end */
6549};
6550
6551/*
6552 * 8ch mode
6553 */
6554static struct hda_verb alc883_sixstack_ch8_init[] = {
6555 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6556 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6557 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6558 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6559 { } /* end */
6560};
6561
6562static struct hda_channel_mode alc883_sixstack_modes[2] = {
6563 { 6, alc883_sixstack_ch6_init },
6564 { 8, alc883_sixstack_ch8_init },
6565};
6566
b373bdeb
AN
6567static struct hda_verb alc883_medion_eapd_verbs[] = {
6568 /* eanable EAPD on medion laptop */
6569 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6570 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6571 { }
6572};
6573
9c7f852e
TI
6574/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6575 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6576 */
6577
6578static struct snd_kcontrol_new alc883_base_mixer[] = {
df694daa 6579 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9c7f852e
TI
6580 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6581 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6582 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6583 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6584 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6585 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6586 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6587 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6588 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
df694daa
KY
6590 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6591 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6592 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6593 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6594 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6595 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
df694daa 6596 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9c7f852e 6597 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6598 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6599 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6600 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6601 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6602 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6603 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6604 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6605 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6606 {
6607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6608 /* .name = "Capture Source", */
6609 .name = "Input Source",
6610 .count = 2,
6611 .info = alc883_mux_enum_info,
6612 .get = alc883_mux_enum_get,
6613 .put = alc883_mux_enum_put,
6614 },
df694daa 6615 { } /* end */
834be88d
TI
6616};
6617
a8848bd6
AS
6618static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6619 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6620 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6621 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6622 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6623 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6624 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6627 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6629 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6630 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6632 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6633 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6634 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6635 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6636 {
6637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6638 /* .name = "Capture Source", */
6639 .name = "Input Source",
6640 .count = 2,
6641 .info = alc883_mux_enum_info,
6642 .get = alc883_mux_enum_get,
6643 .put = alc883_mux_enum_put,
6644 },
6645 { } /* end */
6646};
6647
9c7f852e
TI
6648static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6649 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6650 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6652 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6653 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6657 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6659 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6660 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6662 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6663 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6664 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6665 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6666 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6667 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6668 {
6669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6670 /* .name = "Capture Source", */
6671 .name = "Input Source",
6672 .count = 2,
6673 .info = alc883_mux_enum_info,
6674 .get = alc883_mux_enum_get,
6675 .put = alc883_mux_enum_put,
6676 },
6677 { } /* end */
6678};
df694daa 6679
9c7f852e
TI
6680static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6681 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6682 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6683 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6684 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6685 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6686 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6687 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6688 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6690 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6691 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
6696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6697 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
6699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6700 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6701 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6702 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6703 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6704 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6705 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6706 {
6707 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6708 /* .name = "Capture Source", */
6709 .name = "Input Source",
6710 .count = 2,
6711 .info = alc883_mux_enum_info,
6712 .get = alc883_mux_enum_get,
6713 .put = alc883_mux_enum_put,
6714 },
6715 { } /* end */
6716};
6717
d1d985f0 6718static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8
TD
6719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6721 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6723 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6724 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6725 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6726 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6727 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6728 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6729 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6731 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
c07584c8
TD
6734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6735 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
32360416 6736 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
c07584c8
TD
6737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6738 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6739 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6740 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6741 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6742
6743 {
6744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6745 /* .name = "Capture Source", */
6746 .name = "Input Source",
6747 .count = 1,
6748 .info = alc883_mux_enum_info,
6749 .get = alc883_mux_enum_get,
6750 .put = alc883_mux_enum_put,
6751 },
6752 { } /* end */
6753};
6754
ccc656ce
KY
6755static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6757 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6758 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6772 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6773 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6774 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6775 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6776 {
6777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6778 /* .name = "Capture Source", */
6779 .name = "Input Source",
6780 .count = 2,
6781 .info = alc883_mux_enum_info,
6782 .get = alc883_mux_enum_get,
6783 .put = alc883_mux_enum_put,
6784 },
6785 { } /* end */
f12ab1e0 6786};
ccc656ce
KY
6787
6788static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6789 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6791 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
32360416 6795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
6796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6797 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6798 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6799 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6800 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6801 {
6802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6803 /* .name = "Capture Source", */
6804 .name = "Input Source",
6805 .count = 2,
6806 .info = alc883_mux_enum_info,
6807 .get = alc883_mux_enum_get,
6808 .put = alc883_mux_enum_put,
6809 },
6810 { } /* end */
f12ab1e0 6811};
ccc656ce 6812
bc9f98a9
KY
6813static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6814 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6815 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
6816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6817 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
6818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6820 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6822 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6823 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6824 {
6825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6826 /* .name = "Capture Source", */
6827 .name = "Input Source",
6828 .count = 1,
6829 .info = alc883_mux_enum_info,
6830 .get = alc883_mux_enum_get,
6831 .put = alc883_mux_enum_put,
6832 },
6833 { } /* end */
f12ab1e0 6834};
bc9f98a9 6835
272a527c
KY
6836static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6837 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6838 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6839 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6840 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6841 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6842 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6843 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6844 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6845 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6846 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6847 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6848 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6849 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6850 {
6851 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6852 /* .name = "Capture Source", */
6853 .name = "Input Source",
6854 .count = 2,
6855 .info = alc883_mux_enum_info,
6856 .get = alc883_mux_enum_get,
6857 .put = alc883_mux_enum_put,
6858 },
6859 { } /* end */
6860};
6861
6862static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6865 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6870 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6871 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6872 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6873 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6874 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6875 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6876 {
6877 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6878 /* .name = "Capture Source", */
6879 .name = "Input Source",
6880 .count = 2,
6881 .info = alc883_mux_enum_info,
6882 .get = alc883_mux_enum_get,
6883 .put = alc883_mux_enum_put,
6884 },
6885 { } /* end */
6886};
6887
4723c022 6888static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
cd1e3b40
CM
6889 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6890 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6891 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6892 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6893 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6895 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6896 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6897 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6898 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6899 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6905 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6907 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6908 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6909 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6910 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6911 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6912 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6913 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6914 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6915 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6916 {
6917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6918 /* .name = "Capture Source", */
6919 .name = "Input Source",
6920 .count = 2,
6921 .info = alc883_mux_enum_info,
6922 .get = alc883_mux_enum_get,
6923 .put = alc883_mux_enum_put,
6924 },
6925 { } /* end */
6926};
6927
4723c022 6928static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
8341de60
CM
6929 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6930 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6931 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6932 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6933 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6934 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6935 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6936 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6938 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6939 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6940 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6941 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6942 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6943 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6944 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6945 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6946 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6947 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6948 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6949 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6950 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6951 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6952 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6953 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6954 {
6955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6956 /* .name = "Capture Source", */
6957 .name = "Input Source",
6958 .count = 2,
6959 .info = alc883_mux_enum_info,
6960 .get = alc883_mux_enum_get,
6961 .put = alc883_mux_enum_put,
6962 },
6963 { } /* end */
6964};
6965
5795b9e6
CM
6966static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6968 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6970 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6975 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6976 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6983 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6986 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6987 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6988 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6989 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6990 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6991 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6992 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6993 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6994 {
6995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6996 /* .name = "Capture Source", */
6997 .name = "Input Source",
6998 .count = 2,
6999 .info = alc883_mux_enum_info,
7000 .get = alc883_mux_enum_get,
7001 .put = alc883_mux_enum_put,
7002 },
7003 { } /* end */
7004};
7005
2880a867 7006static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
7007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 7009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
7010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7011 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6
KY
7012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7013 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7014 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867
TD
7015 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7016 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7017 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7018 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7019 {
7020 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7021 /* .name = "Capture Source", */
7022 .name = "Input Source",
7023 .count = 2,
7024 .info = alc883_mux_enum_info,
7025 .get = alc883_mux_enum_get,
7026 .put = alc883_mux_enum_put,
7027 },
7028 { } /* end */
d1a991a6 7029};
2880a867 7030
9c7f852e
TI
7031static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7032 {
7033 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7034 .name = "Channel Mode",
7035 .info = alc_ch_mode_info,
7036 .get = alc_ch_mode_get,
7037 .put = alc_ch_mode_put,
7038 },
7039 { } /* end */
7040};
7041
7042static struct hda_verb alc883_init_verbs[] = {
7043 /* ADC1: mute amp left and right */
7044 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7045 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7046 /* ADC2: mute amp left and right */
7047 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
df694daa 7048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9c7f852e
TI
7049 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7050 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7053 /* Rear mixer */
7054 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7055 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7057 /* CLFE mixer */
7058 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7059 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7060 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7061 /* Side mixer */
7062 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7063 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7064 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa 7065
cb53c626
TI
7066 /* mute analog input loopbacks */
7067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7070 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa 7072
9c7f852e
TI
7073 /* Front Pin: output 0 (0x0c) */
7074 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7075 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7076 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7077 /* Rear Pin: output 1 (0x0d) */
7078 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7079 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7081 /* CLFE Pin: output 2 (0x0e) */
7082 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7083 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7084 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7085 /* Side Pin: output 3 (0x0f) */
7086 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7087 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7088 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7089 /* Mic (rear) pin: input vref at 80% */
7090 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7092 /* Front Mic pin: input vref at 80% */
7093 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7095 /* Line In pin: input */
7096 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7098 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7099 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7100 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7102 /* CD pin widget for input */
7103 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7104
7105 /* FIXME: use matrix-type input source selection */
7106 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7107 /* Input mixer2 */
7108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7109 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7110 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7111 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7112 /* Input mixer3 */
7113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7114 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7115 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7117 { }
7118};
7119
a8848bd6
AS
7120/* toggle speaker-output according to the hp-jack state */
7121static void alc883_mitac_hp_automute(struct hda_codec *codec)
7122{
7123 unsigned int present;
7124
7125 present = snd_hda_codec_read(codec, 0x15, 0,
7126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7127 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7128 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7129 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7130 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7131}
7132
7133/* auto-toggle front mic */
7134/*
7135static void alc883_mitac_mic_automute(struct hda_codec *codec)
7136{
7137 unsigned int present;
7138 unsigned char bits;
7139
7140 present = snd_hda_codec_read(codec, 0x18, 0,
7141 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7142 bits = present ? HDA_AMP_MUTE : 0;
7143 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7144}
7145*/
7146
7147static void alc883_mitac_automute(struct hda_codec *codec)
7148{
7149 alc883_mitac_hp_automute(codec);
7150 /* alc883_mitac_mic_automute(codec); */
7151}
7152
7153static void alc883_mitac_unsol_event(struct hda_codec *codec,
7154 unsigned int res)
7155{
7156 switch (res >> 26) {
7157 case ALC880_HP_EVENT:
7158 alc883_mitac_hp_automute(codec);
7159 break;
7160 case ALC880_MIC_EVENT:
7161 /* alc883_mitac_mic_automute(codec); */
7162 break;
7163 }
7164}
7165
7166static struct hda_verb alc883_mitac_verbs[] = {
7167 /* HP */
7168 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7170 /* Subwoofer */
7171 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7172 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7173
7174 /* enable unsolicited event */
7175 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7176 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7177
7178 { } /* end */
7179};
7180
ccc656ce
KY
7181static struct hda_verb alc883_tagra_verbs[] = {
7182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7184
7185 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7187
7188 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7189 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7190 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7191
7192 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
f12ab1e0
TI
7193 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7194 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7195 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
ccc656ce
KY
7196
7197 { } /* end */
7198};
7199
bc9f98a9
KY
7200static struct hda_verb alc883_lenovo_101e_verbs[] = {
7201 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7202 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7203 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7204 { } /* end */
7205};
7206
272a527c
KY
7207static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7208 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7210 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7211 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7212 { } /* end */
7213};
7214
7215static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7216 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7218 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7219 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7220 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7221 { } /* end */
7222};
7223
189609ae
KY
7224static struct hda_verb alc883_haier_w66_verbs[] = {
7225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7227
7228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7229
7230 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7232 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7233 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7234 { } /* end */
7235};
7236
4723c022 7237static struct hda_verb alc888_6st_hp_verbs[] = {
cd1e3b40
CM
7238 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7239 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7240 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7241 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7242 { }
7243};
7244
4723c022 7245static struct hda_verb alc888_3st_hp_verbs[] = {
8341de60
CM
7246 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7247 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7248 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7249 { }
7250};
7251
5795b9e6
CM
7252static struct hda_verb alc888_6st_dell_verbs[] = {
7253 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7255 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7256 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7257 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7258 { }
7259};
7260
4723c022 7261static struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
7262 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7263 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7264 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7265 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7266 { }
7267};
7268
4723c022 7269static struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
7270 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7271 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7272 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7273 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7274 { }
7275};
7276
4723c022
CM
7277static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7278 { 2, alc888_3st_hp_2ch_init },
7279 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
7280};
7281
272a527c
KY
7282/* toggle front-jack and RCA according to the hp-jack state */
7283static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7284{
7285 unsigned int present;
7286
7287 present = snd_hda_codec_read(codec, 0x1b, 0,
7288 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7289 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7290 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7291 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7292 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7293}
7294
7295/* toggle RCA according to the front-jack state */
7296static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7297{
7298 unsigned int present;
7299
7300 present = snd_hda_codec_read(codec, 0x14, 0,
7301 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7303 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c 7304}
47fd830a 7305
272a527c
KY
7306static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7307 unsigned int res)
7308{
7309 if ((res >> 26) == ALC880_HP_EVENT)
7310 alc888_lenovo_ms7195_front_automute(codec);
7311 if ((res >> 26) == ALC880_FRONT_EVENT)
7312 alc888_lenovo_ms7195_rca_automute(codec);
7313}
7314
7315static struct hda_verb alc883_medion_md2_verbs[] = {
7316 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7317 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7318
7319 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7320
7321 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7322 { } /* end */
7323};
7324
7325/* toggle speaker-output according to the hp-jack state */
7326static void alc883_medion_md2_automute(struct hda_codec *codec)
7327{
7328 unsigned int present;
7329
7330 present = snd_hda_codec_read(codec, 0x14, 0,
7331 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7332 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7333 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
7334}
7335
7336static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7337 unsigned int res)
7338{
7339 if ((res >> 26) == ALC880_HP_EVENT)
7340 alc883_medion_md2_automute(codec);
7341}
7342
ccc656ce
KY
7343/* toggle speaker-output according to the hp-jack state */
7344static void alc883_tagra_automute(struct hda_codec *codec)
7345{
7346 unsigned int present;
f12ab1e0 7347 unsigned char bits;
ccc656ce
KY
7348
7349 present = snd_hda_codec_read(codec, 0x14, 0,
7350 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7351 bits = present ? HDA_AMP_MUTE : 0;
7352 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7353 HDA_AMP_MUTE, bits);
82beb8fd
TI
7354 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7355 present ? 1 : 3);
ccc656ce
KY
7356}
7357
7358static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7359{
7360 if ((res >> 26) == ALC880_HP_EVENT)
7361 alc883_tagra_automute(codec);
7362}
7363
189609ae
KY
7364static void alc883_haier_w66_automute(struct hda_codec *codec)
7365{
7366 unsigned int present;
7367 unsigned char bits;
7368
7369 present = snd_hda_codec_read(codec, 0x1b, 0,
7370 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7371 bits = present ? 0x80 : 0;
7372 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7373 0x80, bits);
7374}
7375
7376static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7377 unsigned int res)
7378{
7379 if ((res >> 26) == ALC880_HP_EVENT)
7380 alc883_haier_w66_automute(codec);
7381}
7382
bc9f98a9
KY
7383static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7384{
7385 unsigned int present;
f12ab1e0 7386 unsigned char bits;
bc9f98a9
KY
7387
7388 present = snd_hda_codec_read(codec, 0x14, 0,
7389 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7390 bits = present ? HDA_AMP_MUTE : 0;
7391 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7392 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7393}
7394
7395static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7396{
7397 unsigned int present;
f12ab1e0 7398 unsigned char bits;
bc9f98a9
KY
7399
7400 present = snd_hda_codec_read(codec, 0x1b, 0,
7401 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
7402 bits = present ? HDA_AMP_MUTE : 0;
7403 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7404 HDA_AMP_MUTE, bits);
7405 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7406 HDA_AMP_MUTE, bits);
bc9f98a9
KY
7407}
7408
7409static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7410 unsigned int res)
7411{
7412 if ((res >> 26) == ALC880_HP_EVENT)
7413 alc883_lenovo_101e_all_automute(codec);
7414 if ((res >> 26) == ALC880_FRONT_EVENT)
7415 alc883_lenovo_101e_ispeaker_automute(codec);
7416}
7417
676a9b53
TI
7418/* toggle speaker-output according to the hp-jack state */
7419static void alc883_acer_aspire_automute(struct hda_codec *codec)
7420{
7421 unsigned int present;
7422
7423 present = snd_hda_codec_read(codec, 0x14, 0,
7424 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7425 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7426 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7427 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7428 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7429}
7430
7431static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7432 unsigned int res)
7433{
7434 if ((res >> 26) == ALC880_HP_EVENT)
7435 alc883_acer_aspire_automute(codec);
7436}
7437
d1a991a6
KY
7438static struct hda_verb alc883_acer_eapd_verbs[] = {
7439 /* HP Pin: output 0 (0x0c) */
7440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7442 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7443 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
7444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 7446 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
7447 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7448 /* eanable EAPD on medion laptop */
7449 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7450 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
7451 /* enable unsolicited event */
7452 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
7453 { }
7454};
7455
5795b9e6
CM
7456static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7457{
7458 unsigned int present;
7459
7460 present = snd_hda_codec_read(codec, 0x1b, 0,
7461 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7462 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7463 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7464 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7465 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7466 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7467 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7468 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7469 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7470}
7471
7472static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7473 unsigned int res)
7474{
7475 switch (res >> 26) {
7476 case ALC880_HP_EVENT:
7477 printk("hp_event\n");
7478 alc888_6st_dell_front_automute(codec);
7479 break;
7480 }
7481}
7482
9c7f852e
TI
7483/*
7484 * generic initialization of ADC, input mixers and output mixers
7485 */
7486static struct hda_verb alc883_auto_init_verbs[] = {
7487 /*
7488 * Unmute ADC0-2 and set the default input to mic-in
7489 */
7490 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7492 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7493 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7494
cb53c626 7495 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 7496 * mixer widget
f12ab1e0
TI
7497 * Note: PASD motherboards uses the Line In 2 as the input for
7498 * front panel mic (mic 2)
9c7f852e
TI
7499 */
7500 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
7506
7507 /*
7508 * Set up output mixers (0x0c - 0x0f)
7509 */
7510 /* set vol=0 to output mixers */
7511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7514 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7515 /* set up input amps for analog loopback */
7516 /* Amp Indices: DAC = 0, mixer = 1 */
7517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7523 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7524 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7525 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7526 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7527
7528 /* FIXME: use matrix-type input source selection */
7529 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7530 /* Input mixer1 */
7531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7532 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7534 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
9c7f852e
TI
7535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7536 /* Input mixer2 */
7537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 7540 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
e3cde64a 7541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
9c7f852e
TI
7542
7543 { }
7544};
7545
7546/* capture mixer elements */
7547static struct snd_kcontrol_new alc883_capture_mixer[] = {
7548 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7551 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7552 {
7553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7554 /* The multiple "Capture Source" controls confuse alsamixer
7555 * So call somewhat different..
9c7f852e
TI
7556 */
7557 /* .name = "Capture Source", */
7558 .name = "Input Source",
7559 .count = 2,
7560 .info = alc882_mux_enum_info,
7561 .get = alc882_mux_enum_get,
7562 .put = alc882_mux_enum_put,
7563 },
7564 { } /* end */
7565};
7566
cb53c626
TI
7567#ifdef CONFIG_SND_HDA_POWER_SAVE
7568#define alc883_loopbacks alc880_loopbacks
7569#endif
7570
9c7f852e
TI
7571/* pcm configuration: identiacal with ALC880 */
7572#define alc883_pcm_analog_playback alc880_pcm_analog_playback
7573#define alc883_pcm_analog_capture alc880_pcm_analog_capture
6330079f 7574#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9c7f852e
TI
7575#define alc883_pcm_digital_playback alc880_pcm_digital_playback
7576#define alc883_pcm_digital_capture alc880_pcm_digital_capture
7577
7578/*
7579 * configuration and preset
7580 */
f5fcc13c
TI
7581static const char *alc883_models[ALC883_MODEL_LAST] = {
7582 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7583 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7584 [ALC883_3ST_6ch] = "3stack-6ch",
7585 [ALC883_6ST_DIG] = "6stack-dig",
7586 [ALC883_TARGA_DIG] = "targa-dig",
7587 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
f5fcc13c 7588 [ALC883_ACER] = "acer",
2880a867 7589 [ALC883_ACER_ASPIRE] = "acer-aspire",
f5fcc13c 7590 [ALC883_MEDION] = "medion",
272a527c 7591 [ALC883_MEDION_MD2] = "medion-md2",
f5fcc13c 7592 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 7593 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
7594 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7595 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
189609ae 7596 [ALC883_HAIER_W66] = "haier-w66",
4723c022
CM
7597 [ALC888_6ST_HP] = "6stack-hp",
7598 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 7599 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 7600 [ALC883_MITAC] = "mitac",
f5fcc13c
TI
7601 [ALC883_AUTO] = "auto",
7602};
7603
7604static struct snd_pci_quirk alc883_cfg_tbl[] = {
7605 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
ac3e3741
TI
7606 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7607 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7608 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7609 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
5795b9e6 7610 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
febe3375 7611 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
ac3e3741
TI
7612 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7613 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7614 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7615 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
f5fcc13c 7616 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
ac3e3741
TI
7617 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7618 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7619 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
57b14f24 7620 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
6f3bf657 7621 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 7622 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7623 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
dd146a60 7624 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
f5fcc13c 7625 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 7626 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7627 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7628 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 7629 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 7630 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
7631 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7632 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7633 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
ac3e3741
TI
7634 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7635 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7636 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7637 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7638 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
f5fcc13c 7639 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741
TI
7640 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7641 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 7642 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
f5fcc13c 7643 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
272a527c 7644 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 7645 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
7646 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7647 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
272a527c 7648 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
0b167bf4 7649 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 7650 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
ac3e3741 7651 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9c7f852e
TI
7652 {}
7653};
7654
7655static struct alc_config_preset alc883_presets[] = {
7656 [ALC883_3ST_2ch_DIG] = {
7657 .mixers = { alc883_3ST_2ch_mixer },
7658 .init_verbs = { alc883_init_verbs },
7659 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7660 .dac_nids = alc883_dac_nids,
7661 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7662 .dig_in_nid = ALC883_DIGIN_NID,
7663 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7664 .channel_mode = alc883_3ST_2ch_modes,
7665 .input_mux = &alc883_capture_source,
7666 },
7667 [ALC883_3ST_6ch_DIG] = {
7668 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7669 .init_verbs = { alc883_init_verbs },
7670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7671 .dac_nids = alc883_dac_nids,
7672 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7673 .dig_in_nid = ALC883_DIGIN_NID,
7674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7675 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7676 .need_dac_fix = 1,
9c7f852e 7677 .input_mux = &alc883_capture_source,
f12ab1e0 7678 },
9c7f852e
TI
7679 [ALC883_3ST_6ch] = {
7680 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7681 .init_verbs = { alc883_init_verbs },
7682 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7683 .dac_nids = alc883_dac_nids,
9c7f852e
TI
7684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7685 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 7686 .need_dac_fix = 1,
9c7f852e 7687 .input_mux = &alc883_capture_source,
f12ab1e0 7688 },
9c7f852e
TI
7689 [ALC883_6ST_DIG] = {
7690 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7691 .init_verbs = { alc883_init_verbs },
7692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7693 .dac_nids = alc883_dac_nids,
7694 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
7695 .dig_in_nid = ALC883_DIGIN_NID,
7696 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7697 .channel_mode = alc883_sixstack_modes,
7698 .input_mux = &alc883_capture_source,
7699 },
ccc656ce
KY
7700 [ALC883_TARGA_DIG] = {
7701 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7702 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7703 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7704 .dac_nids = alc883_dac_nids,
7705 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7707 .channel_mode = alc883_3ST_6ch_modes,
7708 .need_dac_fix = 1,
7709 .input_mux = &alc883_capture_source,
7710 .unsol_event = alc883_tagra_unsol_event,
7711 .init_hook = alc883_tagra_automute,
7712 },
7713 [ALC883_TARGA_2ch_DIG] = {
7714 .mixers = { alc883_tagra_2ch_mixer},
7715 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7716 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7717 .dac_nids = alc883_dac_nids,
7718 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
7719 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7720 .channel_mode = alc883_3ST_2ch_modes,
7721 .input_mux = &alc883_capture_source,
7722 .unsol_event = alc883_tagra_unsol_event,
7723 .init_hook = alc883_tagra_automute,
7724 },
bab282b9 7725 [ALC883_ACER] = {
676a9b53 7726 .mixers = { alc883_base_mixer },
bab282b9
VA
7727 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7728 * and the headphone jack. Turn this on and rely on the
7729 * standard mute methods whenever the user wants to turn
7730 * these outputs off.
7731 */
7732 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7734 .dac_nids = alc883_dac_nids,
bab282b9
VA
7735 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7736 .channel_mode = alc883_3ST_2ch_modes,
7737 .input_mux = &alc883_capture_source,
7738 },
2880a867 7739 [ALC883_ACER_ASPIRE] = {
676a9b53 7740 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 7741 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
7742 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7743 .dac_nids = alc883_dac_nids,
7744 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
7745 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7746 .channel_mode = alc883_3ST_2ch_modes,
7747 .input_mux = &alc883_capture_source,
676a9b53
TI
7748 .unsol_event = alc883_acer_aspire_unsol_event,
7749 .init_hook = alc883_acer_aspire_automute,
d1a991a6 7750 },
c07584c8
TD
7751 [ALC883_MEDION] = {
7752 .mixers = { alc883_fivestack_mixer,
7753 alc883_chmode_mixer },
7754 .init_verbs = { alc883_init_verbs,
b373bdeb 7755 alc883_medion_eapd_verbs },
c07584c8
TD
7756 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7757 .dac_nids = alc883_dac_nids,
c07584c8
TD
7758 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7759 .channel_mode = alc883_sixstack_modes,
7760 .input_mux = &alc883_capture_source,
b373bdeb 7761 },
272a527c
KY
7762 [ALC883_MEDION_MD2] = {
7763 .mixers = { alc883_medion_md2_mixer},
7764 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7765 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7766 .dac_nids = alc883_dac_nids,
7767 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7769 .channel_mode = alc883_3ST_2ch_modes,
7770 .input_mux = &alc883_capture_source,
7771 .unsol_event = alc883_medion_md2_unsol_event,
7772 .init_hook = alc883_medion_md2_automute,
7773 },
b373bdeb 7774 [ALC883_LAPTOP_EAPD] = {
676a9b53 7775 .mixers = { alc883_base_mixer },
b373bdeb
AN
7776 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7778 .dac_nids = alc883_dac_nids,
b373bdeb
AN
7779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7780 .channel_mode = alc883_3ST_2ch_modes,
7781 .input_mux = &alc883_capture_source,
7782 },
bc9f98a9
KY
7783 [ALC883_LENOVO_101E_2ch] = {
7784 .mixers = { alc883_lenovo_101e_2ch_mixer},
7785 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7786 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7787 .dac_nids = alc883_dac_nids,
bc9f98a9
KY
7788 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7789 .channel_mode = alc883_3ST_2ch_modes,
7790 .input_mux = &alc883_lenovo_101e_capture_source,
7791 .unsol_event = alc883_lenovo_101e_unsol_event,
7792 .init_hook = alc883_lenovo_101e_all_automute,
7793 },
272a527c
KY
7794 [ALC883_LENOVO_NB0763] = {
7795 .mixers = { alc883_lenovo_nb0763_mixer },
7796 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7797 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7798 .dac_nids = alc883_dac_nids,
272a527c
KY
7799 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7800 .channel_mode = alc883_3ST_2ch_modes,
7801 .need_dac_fix = 1,
7802 .input_mux = &alc883_lenovo_nb0763_capture_source,
7803 .unsol_event = alc883_medion_md2_unsol_event,
7804 .init_hook = alc883_medion_md2_automute,
7805 },
7806 [ALC888_LENOVO_MS7195_DIG] = {
7807 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7808 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7809 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7810 .dac_nids = alc883_dac_nids,
7811 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
7812 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7813 .channel_mode = alc883_3ST_6ch_modes,
7814 .need_dac_fix = 1,
7815 .input_mux = &alc883_capture_source,
7816 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7817 .init_hook = alc888_lenovo_ms7195_front_automute,
189609ae
KY
7818 },
7819 [ALC883_HAIER_W66] = {
7820 .mixers = { alc883_tagra_2ch_mixer},
7821 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7822 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7823 .dac_nids = alc883_dac_nids,
7824 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
7825 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7826 .channel_mode = alc883_3ST_2ch_modes,
7827 .input_mux = &alc883_capture_source,
7828 .unsol_event = alc883_haier_w66_unsol_event,
7829 .init_hook = alc883_haier_w66_automute,
272a527c 7830 },
4723c022
CM
7831 [ALC888_6ST_HP] = {
7832 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7833 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
cd1e3b40
CM
7834 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7835 .dac_nids = alc883_dac_nids,
7836 .dig_out_nid = ALC883_DIGOUT_NID,
cd1e3b40
CM
7837 .dig_in_nid = ALC883_DIGIN_NID,
7838 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7839 .channel_mode = alc883_sixstack_modes,
7840 .input_mux = &alc883_capture_source,
7841 },
4723c022
CM
7842 [ALC888_3ST_HP] = {
7843 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7844 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
7845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7846 .dac_nids = alc883_dac_nids,
4723c022
CM
7847 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7848 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
7849 .need_dac_fix = 1,
7850 .input_mux = &alc883_capture_source,
7851 },
5795b9e6
CM
7852 [ALC888_6ST_DELL] = {
7853 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7854 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7855 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7856 .dac_nids = alc883_dac_nids,
7857 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
7858 .dig_in_nid = ALC883_DIGIN_NID,
7859 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7860 .channel_mode = alc883_sixstack_modes,
7861 .input_mux = &alc883_capture_source,
7862 .unsol_event = alc888_6st_dell_unsol_event,
7863 .init_hook = alc888_6st_dell_front_automute,
7864 },
a8848bd6
AS
7865 [ALC883_MITAC] = {
7866 .mixers = { alc883_mitac_mixer },
7867 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7868 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7869 .dac_nids = alc883_dac_nids,
a8848bd6
AS
7870 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7871 .channel_mode = alc883_3ST_2ch_modes,
7872 .input_mux = &alc883_capture_source,
7873 .unsol_event = alc883_mitac_unsol_event,
7874 .init_hook = alc883_mitac_automute,
7875 },
9c7f852e
TI
7876};
7877
7878
7879/*
7880 * BIOS auto configuration
7881 */
7882static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7883 hda_nid_t nid, int pin_type,
7884 int dac_idx)
7885{
7886 /* set as output */
7887 struct alc_spec *spec = codec->spec;
f12ab1e0
TI
7888 int idx;
7889
f6c7e546 7890 alc_set_pin_output(codec, nid, pin_type);
9c7f852e
TI
7891 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7892 idx = 4;
7893 else
7894 idx = spec->multiout.dac_nids[dac_idx] - 2;
9c7f852e
TI
7895 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7896
7897}
7898
7899static void alc883_auto_init_multi_out(struct hda_codec *codec)
7900{
7901 struct alc_spec *spec = codec->spec;
7902 int i;
7903
bc9f98a9 7904 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9c7f852e 7905 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 7906 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 7907 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 7908 if (nid)
baba8ee9 7909 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 7910 i);
9c7f852e
TI
7911 }
7912}
7913
7914static void alc883_auto_init_hp_out(struct hda_codec *codec)
7915{
7916 struct alc_spec *spec = codec->spec;
7917 hda_nid_t pin;
7918
eb06ed8f 7919 pin = spec->autocfg.hp_pins[0];
9c7f852e
TI
7920 if (pin) /* connect to front */
7921 /* use dac 0 */
7922 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
7923 pin = spec->autocfg.speaker_pins[0];
7924 if (pin)
7925 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9c7f852e
TI
7926}
7927
7928#define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7929#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7930
7931static void alc883_auto_init_analog_input(struct hda_codec *codec)
7932{
7933 struct alc_spec *spec = codec->spec;
7934 int i;
7935
7936 for (i = 0; i < AUTO_PIN_LAST; i++) {
7937 hda_nid_t nid = spec->autocfg.input_pins[i];
7938 if (alc883_is_input_pin(nid)) {
7939 snd_hda_codec_write(codec, nid, 0,
7940 AC_VERB_SET_PIN_WIDGET_CONTROL,
7941 (i <= AUTO_PIN_FRONT_MIC ?
7942 PIN_VREF80 : PIN_IN));
7943 if (nid != ALC883_PIN_CD_NID)
7944 snd_hda_codec_write(codec, nid, 0,
7945 AC_VERB_SET_AMP_GAIN_MUTE,
7946 AMP_OUT_MUTE);
7947 }
7948 }
7949}
7950
7951/* almost identical with ALC880 parser... */
7952static int alc883_parse_auto_config(struct hda_codec *codec)
7953{
7954 struct alc_spec *spec = codec->spec;
7955 int err = alc880_parse_auto_config(codec);
7956
7957 if (err < 0)
7958 return err;
776e184e
TI
7959 else if (!err)
7960 return 0; /* no config found */
7961
7962 err = alc_auto_add_mic_boost(codec);
7963 if (err < 0)
7964 return err;
7965
7966 /* hack - override the init verbs */
7967 spec->init_verbs[0] = alc883_auto_init_verbs;
bc9f98a9
KY
7968 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7969 spec->num_mixers++;
776e184e
TI
7970
7971 return 1; /* config found */
9c7f852e
TI
7972}
7973
7974/* additional initialization for auto-configuration model */
7975static void alc883_auto_init(struct hda_codec *codec)
7976{
f6c7e546 7977 struct alc_spec *spec = codec->spec;
9c7f852e
TI
7978 alc883_auto_init_multi_out(codec);
7979 alc883_auto_init_hp_out(codec);
7980 alc883_auto_init_analog_input(codec);
f6c7e546
TI
7981 if (spec->unsol_event)
7982 alc_sku_automute(codec);
9c7f852e
TI
7983}
7984
7985static int patch_alc883(struct hda_codec *codec)
7986{
7987 struct alc_spec *spec;
7988 int err, board_config;
7989
7990 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7991 if (spec == NULL)
7992 return -ENOMEM;
7993
7994 codec->spec = spec;
7995
f5fcc13c
TI
7996 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7997 alc883_models,
7998 alc883_cfg_tbl);
7999 if (board_config < 0) {
9c7f852e
TI
8000 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8001 "trying auto-probe from BIOS...\n");
8002 board_config = ALC883_AUTO;
8003 }
8004
8005 if (board_config == ALC883_AUTO) {
8006 /* automatic parse from the BIOS config */
8007 err = alc883_parse_auto_config(codec);
8008 if (err < 0) {
8009 alc_free(codec);
8010 return err;
f12ab1e0 8011 } else if (!err) {
9c7f852e
TI
8012 printk(KERN_INFO
8013 "hda_codec: Cannot set up configuration "
8014 "from BIOS. Using base mode...\n");
8015 board_config = ALC883_3ST_2ch_DIG;
8016 }
8017 }
8018
8019 if (board_config != ALC883_AUTO)
8020 setup_preset(spec, &alc883_presets[board_config]);
8021
8022 spec->stream_name_analog = "ALC883 Analog";
8023 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8024 spec->stream_analog_capture = &alc883_pcm_analog_capture;
6330079f 8025 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9c7f852e
TI
8026
8027 spec->stream_name_digital = "ALC883 Digital";
8028 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8029 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8030
e1406348
TI
8031 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8032 spec->adc_nids = alc883_adc_nids;
8033 spec->capsrc_nids = alc883_capsrc_nids;
9c7f852e 8034
2134ea4f
TI
8035 spec->vmaster_nid = 0x0c;
8036
9c7f852e
TI
8037 codec->patch_ops = alc_patch_ops;
8038 if (board_config == ALC883_AUTO)
8039 spec->init_hook = alc883_auto_init;
cb53c626
TI
8040#ifdef CONFIG_SND_HDA_POWER_SAVE
8041 if (!spec->loopback.amplist)
8042 spec->loopback.amplist = alc883_loopbacks;
8043#endif
9c7f852e
TI
8044
8045 return 0;
8046}
8047
8048/*
8049 * ALC262 support
8050 */
8051
8052#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8053#define ALC262_DIGIN_NID ALC880_DIGIN_NID
8054
8055#define alc262_dac_nids alc260_dac_nids
8056#define alc262_adc_nids alc882_adc_nids
8057#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
8058#define alc262_capsrc_nids alc882_capsrc_nids
8059#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
8060
8061#define alc262_modes alc260_modes
8062#define alc262_capture_source alc882_capture_source
8063
8064static struct snd_kcontrol_new alc262_base_mixer[] = {
8065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8066 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8067 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8068 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8070 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8073 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8074 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8075 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8076 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e 8077 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8078 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9c7f852e
TI
8079 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8081 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8082 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8083 { } /* end */
8084};
8085
ccc656ce
KY
8086static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8087 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8088 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8090 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8095 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
ccc656ce
KY
8096 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8097 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8098 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
ccc656ce 8099 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
31bffaa9 8100 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
ccc656ce
KY
8101 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8103 { } /* end */
8104};
8105
ce875f07
TI
8106/* update HP, line and mono-out pins according to the master switch */
8107static void alc262_hp_master_update(struct hda_codec *codec)
8108{
8109 struct alc_spec *spec = codec->spec;
8110 int val = spec->master_sw;
8111
8112 /* HP & line-out */
8113 snd_hda_codec_write_cache(codec, 0x1b, 0,
8114 AC_VERB_SET_PIN_WIDGET_CONTROL,
8115 val ? PIN_HP : 0);
8116 snd_hda_codec_write_cache(codec, 0x15, 0,
8117 AC_VERB_SET_PIN_WIDGET_CONTROL,
8118 val ? PIN_HP : 0);
8119 /* mono (speaker) depending on the HP jack sense */
8120 val = val && !spec->jack_present;
8121 snd_hda_codec_write_cache(codec, 0x16, 0,
8122 AC_VERB_SET_PIN_WIDGET_CONTROL,
8123 val ? PIN_OUT : 0);
8124}
8125
8126static void alc262_hp_bpc_automute(struct hda_codec *codec)
8127{
8128 struct alc_spec *spec = codec->spec;
8129 unsigned int presence;
8130 presence = snd_hda_codec_read(codec, 0x1b, 0,
8131 AC_VERB_GET_PIN_SENSE, 0);
8132 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8133 alc262_hp_master_update(codec);
8134}
8135
8136static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8137{
8138 if ((res >> 26) != ALC880_HP_EVENT)
8139 return;
8140 alc262_hp_bpc_automute(codec);
8141}
8142
8143static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8144{
8145 struct alc_spec *spec = codec->spec;
8146 unsigned int presence;
8147 presence = snd_hda_codec_read(codec, 0x15, 0,
8148 AC_VERB_GET_PIN_SENSE, 0);
8149 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8150 alc262_hp_master_update(codec);
8151}
8152
8153static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8154 unsigned int res)
8155{
8156 if ((res >> 26) != ALC880_HP_EVENT)
8157 return;
8158 alc262_hp_wildwest_automute(codec);
8159}
8160
8161static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8162 struct snd_ctl_elem_value *ucontrol)
8163{
8164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8165 struct alc_spec *spec = codec->spec;
8166 *ucontrol->value.integer.value = spec->master_sw;
8167 return 0;
8168}
8169
8170static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8171 struct snd_ctl_elem_value *ucontrol)
8172{
8173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8174 struct alc_spec *spec = codec->spec;
8175 int val = !!*ucontrol->value.integer.value;
8176
8177 if (val == spec->master_sw)
8178 return 0;
8179 spec->master_sw = val;
8180 alc262_hp_master_update(codec);
8181 return 1;
8182}
8183
9c7f852e 8184static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
ce875f07
TI
8185 {
8186 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8187 .name = "Master Playback Switch",
8188 .info = snd_ctl_boolean_mono_info,
8189 .get = alc262_hp_master_sw_get,
8190 .put = alc262_hp_master_sw_put,
8191 },
9c7f852e
TI
8192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8193 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
8195 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8196 HDA_OUTPUT),
8197 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8198 HDA_OUTPUT),
9c7f852e
TI
8199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8201 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8202 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8203 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
cc69d12d 8204 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9c7f852e
TI
8205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8209 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8210 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8211 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8212 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8213 { } /* end */
8214};
8215
cd7509a4 8216static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
ce875f07
TI
8217 {
8218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8219 .name = "Master Playback Switch",
8220 .info = snd_ctl_boolean_mono_info,
8221 .get = alc262_hp_master_sw_get,
8222 .put = alc262_hp_master_sw_put,
8223 },
cd7509a4
KY
8224 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8225 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
8228 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8229 HDA_OUTPUT),
8230 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8231 HDA_OUTPUT),
cd7509a4
KY
8232 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8233 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
cc69d12d 8234 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
8235 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8236 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8239 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8240 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8241 { } /* end */
8242};
8243
8244static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8245 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8246 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
cc69d12d 8247 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
cd7509a4
KY
8248 { } /* end */
8249};
8250
66d2a9d6
KY
8251/* mute/unmute internal speaker according to the hp jack and mute state */
8252static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8253{
8254 struct alc_spec *spec = codec->spec;
66d2a9d6
KY
8255
8256 if (force || !spec->sense_updated) {
8257 unsigned int present;
8258 present = snd_hda_codec_read(codec, 0x15, 0,
8259 AC_VERB_GET_PIN_SENSE, 0);
4bb26130 8260 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
66d2a9d6
KY
8261 spec->sense_updated = 1;
8262 }
4bb26130
TI
8263 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8264 spec->jack_present ? HDA_AMP_MUTE : 0);
66d2a9d6
KY
8265}
8266
8267static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8268 unsigned int res)
8269{
8270 if ((res >> 26) != ALC880_HP_EVENT)
8271 return;
8272 alc262_hp_t5735_automute(codec, 1);
8273}
8274
8275static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8276{
8277 alc262_hp_t5735_automute(codec, 1);
8278}
8279
8280static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
8281 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8282 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
8283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8287 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8288 { } /* end */
8289};
8290
8291static struct hda_verb alc262_hp_t5735_verbs[] = {
8292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8294
8295 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8296 { }
8297};
8298
8c427226 8299static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
8300 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
8302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8303 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
8304 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8305 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8306 { } /* end */
8307};
8308
8309static struct hda_verb alc262_hp_rp5700_verbs[] = {
8310 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8311 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8312 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8313 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8314 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8315 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8316 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8320 {}
8321};
8322
8323static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8324 .num_items = 1,
8325 .items = {
8326 { "Line", 0x1 },
8327 },
8328};
8329
0724ea2a
TI
8330/* bind hp and internal speaker mute (with plug check) */
8331static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8332 struct snd_ctl_elem_value *ucontrol)
8333{
8334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8335 long *valp = ucontrol->value.integer.value;
8336 int change;
8337
8338 /* change hp mute */
8339 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8340 HDA_AMP_MUTE,
8341 valp[0] ? 0 : HDA_AMP_MUTE);
8342 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8343 HDA_AMP_MUTE,
8344 valp[1] ? 0 : HDA_AMP_MUTE);
8345 if (change) {
8346 /* change speaker according to HP jack state */
8347 struct alc_spec *spec = codec->spec;
8348 unsigned int mute;
8349 if (spec->jack_present)
8350 mute = HDA_AMP_MUTE;
8351 else
8352 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8353 HDA_OUTPUT, 0);
8354 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8355 HDA_AMP_MUTE, mute);
8356 }
8357 return change;
8358}
5b31954e 8359
272a527c 8360static struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a
TI
8361 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8362 {
8363 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8364 .name = "Master Playback Switch",
8365 .info = snd_hda_mixer_amp_switch_info,
8366 .get = snd_hda_mixer_amp_switch_get,
8367 .put = alc262_sony_master_sw_put,
8368 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8369 },
272a527c
KY
8370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8372 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8373 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8374 { } /* end */
8375};
8376
83c34218
KY
8377static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8378 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8379 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8383 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8384 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8385 { } /* end */
8386};
272a527c 8387
9c7f852e
TI
8388#define alc262_capture_mixer alc882_capture_mixer
8389#define alc262_capture_alt_mixer alc882_capture_alt_mixer
8390
8391/*
8392 * generic initialization of ADC, input mixers and output mixers
8393 */
8394static struct hda_verb alc262_init_verbs[] = {
8395 /*
8396 * Unmute ADC0-2 and set the default input to mic-in
8397 */
8398 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8400 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8401 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8402 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8403 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8404
cb53c626 8405 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8406 * mixer widget
f12ab1e0
TI
8407 * Note: PASD motherboards uses the Line In 2 as the input for
8408 * front panel mic (mic 2)
9c7f852e
TI
8409 */
8410 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8412 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8413 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8414 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8415 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
8416
8417 /*
df694daa
KY
8418 * Set up output mixers (0x0c - 0x0e)
8419 */
8420 /* set vol=0 to output mixers */
8421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 /* set up input amps for analog loopback */
8425 /* Amp Indices: DAC = 0, mixer = 1 */
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8428 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8430 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8432
8433 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8434 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8435 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8436 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8437 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8438 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8439
8440 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8441 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8442 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8444 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8445
8446 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8447 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8448
8449 /* FIXME: use matrix-type input source selection */
8450 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8451 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8456 /* Input mixer2 */
8457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8461 /* Input mixer3 */
8462 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 8465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
8466
8467 { }
8468};
1da177e4 8469
ccc656ce
KY
8470static struct hda_verb alc262_hippo_unsol_verbs[] = {
8471 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8472 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8473 {}
8474};
8475
8476static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8477 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8478 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8480
8481 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8482 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8483 {}
8484};
8485
272a527c
KY
8486static struct hda_verb alc262_sony_unsol_verbs[] = {
8487 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8488 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8489 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8490
8491 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8493};
8494
ccc656ce 8495/* mute/unmute internal speaker according to the hp jack and mute state */
5b31954e 8496static void alc262_hippo_automute(struct hda_codec *codec)
ccc656ce
KY
8497{
8498 struct alc_spec *spec = codec->spec;
8499 unsigned int mute;
5b31954e 8500 unsigned int present;
ccc656ce 8501
5b31954e
TI
8502 /* need to execute and sync at first */
8503 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8504 present = snd_hda_codec_read(codec, 0x15, 0,
8505 AC_VERB_GET_PIN_SENSE, 0);
8506 spec->jack_present = (present & 0x80000000) != 0;
ccc656ce
KY
8507 if (spec->jack_present) {
8508 /* mute internal speaker */
47fd830a
TI
8509 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8510 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8511 } else {
8512 /* unmute internal speaker if necessary */
8513 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
47fd830a
TI
8514 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8515 HDA_AMP_MUTE, mute);
ccc656ce
KY
8516 }
8517}
8518
8519/* unsolicited event for HP jack sensing */
8520static void alc262_hippo_unsol_event(struct hda_codec *codec,
8521 unsigned int res)
8522{
8523 if ((res >> 26) != ALC880_HP_EVENT)
8524 return;
5b31954e 8525 alc262_hippo_automute(codec);
ccc656ce
KY
8526}
8527
5b31954e 8528static void alc262_hippo1_automute(struct hda_codec *codec)
ccc656ce 8529{
ccc656ce 8530 unsigned int mute;
5b31954e 8531 unsigned int present;
ccc656ce 8532
5b31954e
TI
8533 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8534 present = snd_hda_codec_read(codec, 0x1b, 0,
8535 AC_VERB_GET_PIN_SENSE, 0);
8536 present = (present & 0x80000000) != 0;
8537 if (present) {
ccc656ce 8538 /* mute internal speaker */
47fd830a
TI
8539 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8540 HDA_AMP_MUTE, HDA_AMP_MUTE);
ccc656ce
KY
8541 } else {
8542 /* unmute internal speaker if necessary */
8543 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
47fd830a
TI
8544 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8545 HDA_AMP_MUTE, mute);
ccc656ce
KY
8546 }
8547}
8548
8549/* unsolicited event for HP jack sensing */
8550static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8551 unsigned int res)
8552{
8553 if ((res >> 26) != ALC880_HP_EVENT)
8554 return;
5b31954e 8555 alc262_hippo1_automute(codec);
ccc656ce
KY
8556}
8557
834be88d
TI
8558/*
8559 * fujitsu model
8560 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8561 */
8562
8563#define ALC_HP_EVENT 0x37
8564
8565static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8566 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8567 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8568 {}
8569};
8570
8571static struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 8572 .num_items = 3,
834be88d
TI
8573 .items = {
8574 { "Mic", 0x0 },
39d3ed38 8575 { "Int Mic", 0x1 },
834be88d
TI
8576 { "CD", 0x4 },
8577 },
8578};
8579
9c7f852e
TI
8580static struct hda_input_mux alc262_HP_capture_source = {
8581 .num_items = 5,
8582 .items = {
8583 { "Mic", 0x0 },
accbe498 8584 { "Front Mic", 0x1 },
9c7f852e
TI
8585 { "Line", 0x2 },
8586 { "CD", 0x4 },
8587 { "AUX IN", 0x6 },
8588 },
8589};
8590
accbe498 8591static struct hda_input_mux alc262_HP_D7000_capture_source = {
8592 .num_items = 4,
8593 .items = {
8594 { "Mic", 0x0 },
8595 { "Front Mic", 0x2 },
8596 { "Line", 0x1 },
8597 { "CD", 0x4 },
8598 },
8599};
8600
834be88d
TI
8601/* mute/unmute internal speaker according to the hp jack and mute state */
8602static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8603{
8604 struct alc_spec *spec = codec->spec;
8605 unsigned int mute;
8606
f12ab1e0 8607 if (force || !spec->sense_updated) {
834be88d
TI
8608 unsigned int present;
8609 /* need to execute and sync at first */
8610 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8611 present = snd_hda_codec_read(codec, 0x14, 0,
8612 AC_VERB_GET_PIN_SENSE, 0);
8613 spec->jack_present = (present & 0x80000000) != 0;
8614 spec->sense_updated = 1;
8615 }
8616 if (spec->jack_present) {
8617 /* mute internal speaker */
47fd830a
TI
8618 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8619 HDA_AMP_MUTE, HDA_AMP_MUTE);
834be88d
TI
8620 } else {
8621 /* unmute internal speaker if necessary */
8622 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
47fd830a
TI
8623 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8624 HDA_AMP_MUTE, mute);
834be88d
TI
8625 }
8626}
8627
8628/* unsolicited event for HP jack sensing */
8629static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8630 unsigned int res)
8631{
8632 if ((res >> 26) != ALC_HP_EVENT)
8633 return;
8634 alc262_fujitsu_automute(codec, 1);
8635}
8636
8637/* bind volumes of both NID 0x0c and 0x0d */
cca3b371
TI
8638static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8639 .ops = &snd_hda_bind_vol,
8640 .values = {
8641 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8642 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8643 0
8644 },
8645};
834be88d
TI
8646
8647/* bind hp and internal speaker mute (with plug check) */
8648static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8649 struct snd_ctl_elem_value *ucontrol)
8650{
8651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8652 long *valp = ucontrol->value.integer.value;
8653 int change;
8654
8655 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
47fd830a
TI
8656 HDA_AMP_MUTE,
8657 valp[0] ? 0 : HDA_AMP_MUTE);
834be88d 8658 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
47fd830a
TI
8659 HDA_AMP_MUTE,
8660 valp[1] ? 0 : HDA_AMP_MUTE);
82beb8fd
TI
8661 if (change)
8662 alc262_fujitsu_automute(codec, 0);
834be88d
TI
8663 return change;
8664}
8665
8666static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 8667 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
8668 {
8669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8670 .name = "Master Playback Switch",
8671 .info = snd_hda_mixer_amp_switch_info,
8672 .get = snd_hda_mixer_amp_switch_get,
8673 .put = alc262_fujitsu_master_sw_put,
8674 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8675 },
8676 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8677 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8678 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
39d3ed38
TI
8681 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8682 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8683 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
8684 { } /* end */
8685};
8686
304dcaac
TI
8687/* additional init verbs for Benq laptops */
8688static struct hda_verb alc262_EAPD_verbs[] = {
8689 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8690 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8691 {}
8692};
8693
83c34218
KY
8694static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8695 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8696 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8697
8698 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8699 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8700 {}
8701};
8702
f651b50b
TD
8703/* Samsung Q1 Ultra Vista model setup */
8704static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8705 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8706 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8707 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8711 { } /* end */
8712};
8713
8714static struct hda_verb alc262_ultra_verbs[] = {
8715 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8717 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8718 /* Mic is on Node 0x19 */
8719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8720 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8721 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8722 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8724 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8725 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8726 {}
8727};
8728
8729static struct hda_input_mux alc262_ultra_capture_source = {
8730 .num_items = 1,
8731 .items = {
8732 { "Mic", 0x1 },
8733 },
8734};
8735
8736/* mute/unmute internal speaker according to the hp jack and mute state */
8737static void alc262_ultra_automute(struct hda_codec *codec)
8738{
8739 struct alc_spec *spec = codec->spec;
8740 unsigned int mute;
8741 unsigned int present;
8742
8743 /* need to execute and sync at first */
8744 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8745 present = snd_hda_codec_read(codec, 0x15, 0,
8746 AC_VERB_GET_PIN_SENSE, 0);
8747 spec->jack_present = (present & 0x80000000) != 0;
8748 if (spec->jack_present) {
8749 /* mute internal speaker */
8750 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8751 HDA_AMP_MUTE, HDA_AMP_MUTE);
8752 } else {
8753 /* unmute internal speaker if necessary */
8754 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8755 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8756 HDA_AMP_MUTE, mute);
8757 }
8758}
8759
8760/* unsolicited event for HP jack sensing */
8761static void alc262_ultra_unsol_event(struct hda_codec *codec,
8762 unsigned int res)
8763{
8764 if ((res >> 26) != ALC880_HP_EVENT)
8765 return;
8766 alc262_ultra_automute(codec);
8767}
8768
df694daa 8769/* add playback controls from the parsed DAC table */
f12ab1e0
TI
8770static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8771 const struct auto_pin_cfg *cfg)
df694daa
KY
8772{
8773 hda_nid_t nid;
8774 int err;
8775
8776 spec->multiout.num_dacs = 1; /* only use one dac */
8777 spec->multiout.dac_nids = spec->private_dac_nids;
8778 spec->multiout.dac_nids[0] = 2;
8779
8780 nid = cfg->line_out_pins[0];
8781 if (nid) {
f12ab1e0
TI
8782 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8783 "Front Playback Volume",
8784 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8785 if (err < 0)
df694daa 8786 return err;
f12ab1e0
TI
8787 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8788 "Front Playback Switch",
8789 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8790 if (err < 0)
df694daa
KY
8791 return err;
8792 }
8793
82bc955f 8794 nid = cfg->speaker_pins[0];
df694daa
KY
8795 if (nid) {
8796 if (nid == 0x16) {
f12ab1e0
TI
8797 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8798 "Speaker Playback Volume",
8799 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8800 HDA_OUTPUT));
8801 if (err < 0)
df694daa 8802 return err;
f12ab1e0
TI
8803 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8804 "Speaker Playback Switch",
8805 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8806 HDA_OUTPUT));
8807 if (err < 0)
df694daa
KY
8808 return err;
8809 } else {
f12ab1e0
TI
8810 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8811 "Speaker Playback Switch",
8812 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8813 HDA_OUTPUT));
8814 if (err < 0)
df694daa
KY
8815 return err;
8816 }
8817 }
eb06ed8f 8818 nid = cfg->hp_pins[0];
df694daa
KY
8819 if (nid) {
8820 /* spec->multiout.hp_nid = 2; */
8821 if (nid == 0x16) {
f12ab1e0
TI
8822 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8823 "Headphone Playback Volume",
8824 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8825 HDA_OUTPUT));
8826 if (err < 0)
df694daa 8827 return err;
f12ab1e0
TI
8828 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8829 "Headphone Playback Switch",
8830 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8831 HDA_OUTPUT));
8832 if (err < 0)
df694daa
KY
8833 return err;
8834 } else {
f12ab1e0
TI
8835 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8836 "Headphone Playback Switch",
8837 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8838 HDA_OUTPUT));
8839 if (err < 0)
df694daa
KY
8840 return err;
8841 }
8842 }
f12ab1e0 8843 return 0;
df694daa
KY
8844}
8845
8846/* identical with ALC880 */
f12ab1e0
TI
8847#define alc262_auto_create_analog_input_ctls \
8848 alc880_auto_create_analog_input_ctls
df694daa
KY
8849
8850/*
8851 * generic initialization of ADC, input mixers and output mixers
8852 */
8853static struct hda_verb alc262_volume_init_verbs[] = {
8854 /*
8855 * Unmute ADC0-2 and set the default input to mic-in
8856 */
8857 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8859 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8861 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8863
cb53c626 8864 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 8865 * mixer widget
f12ab1e0
TI
8866 * Note: PASD motherboards uses the Line In 2 as the input for
8867 * front panel mic (mic 2)
df694daa
KY
8868 */
8869 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8871 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8872 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8873 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8874 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
8875
8876 /*
8877 * Set up output mixers (0x0c - 0x0f)
8878 */
8879 /* set vol=0 to output mixers */
8880 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8881 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8883
8884 /* set up input amps for analog loopback */
8885 /* Amp Indices: DAC = 0, mixer = 1 */
8886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8892
8893 /* FIXME: use matrix-type input source selection */
8894 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8895 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8899 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8900 /* Input mixer2 */
8901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8905 /* Input mixer3 */
8906 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8907 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8910
8911 { }
8912};
8913
9c7f852e
TI
8914static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8915 /*
8916 * Unmute ADC0-2 and set the default input to mic-in
8917 */
8918 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8921 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8922 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8923 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8924
cb53c626 8925 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 8926 * mixer widget
f12ab1e0
TI
8927 * Note: PASD motherboards uses the Line In 2 as the input for
8928 * front panel mic (mic 2)
9c7f852e
TI
8929 */
8930 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
8931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8933 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8934 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8935 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8936 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8937 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9c7f852e
TI
8938
8939 /*
8940 * Set up output mixers (0x0c - 0x0e)
8941 */
8942 /* set vol=0 to output mixers */
8943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8946
8947 /* set up input amps for analog loopback */
8948 /* Amp Indices: DAC = 0, mixer = 1 */
8949 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8950 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8951 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8952 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8953 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8954 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8955
ce875f07 8956 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
8957 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8958 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8959
8960 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8962
8963 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8964 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8965
8966 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8967 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8969 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8971
8972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8975 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8976 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8977 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8978
8979
8980 /* FIXME: use matrix-type input source selection */
8981 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8982 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8983 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8984 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8985 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8987 /* Input mixer2 */
8988 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8989 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8990 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8991 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8992 /* Input mixer3 */
8993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8996 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8997
ce875f07
TI
8998 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8999
9c7f852e
TI
9000 { }
9001};
9002
cd7509a4
KY
9003static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9004 /*
9005 * Unmute ADC0-2 and set the default input to mic-in
9006 */
9007 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9009 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9011 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9012 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9013
cb53c626 9014 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
9015 * mixer widget
9016 * Note: PASD motherboards uses the Line In 2 as the input for front
9017 * panel mic (mic 2)
9018 */
9019 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
9020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
9028 /*
9029 * Set up output mixers (0x0c - 0x0e)
9030 */
9031 /* set vol=0 to output mixers */
9032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9033 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9035
9036 /* set up input amps for analog loopback */
9037 /* Amp Indices: DAC = 0, mixer = 1 */
9038 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9039 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9042 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044
9045
9046 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9047 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9048 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9049 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9050 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9051 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9052 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9053
9054 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9056
9057 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9058 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9059
9060 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9061 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9062 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9064 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9065 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9066
9067 /* FIXME: use matrix-type input source selection */
9068 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9069 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9071 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9075 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9077 /* Input mixer2 */
9078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9081 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9083 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9085 /* Input mixer3 */
9086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9088 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9089 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9090 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9091 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9092 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9093
ce875f07
TI
9094 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9095
cd7509a4
KY
9096 { }
9097};
9098
cb53c626
TI
9099#ifdef CONFIG_SND_HDA_POWER_SAVE
9100#define alc262_loopbacks alc880_loopbacks
9101#endif
9102
df694daa
KY
9103/* pcm configuration: identiacal with ALC880 */
9104#define alc262_pcm_analog_playback alc880_pcm_analog_playback
9105#define alc262_pcm_analog_capture alc880_pcm_analog_capture
9106#define alc262_pcm_digital_playback alc880_pcm_digital_playback
9107#define alc262_pcm_digital_capture alc880_pcm_digital_capture
9108
9109/*
9110 * BIOS auto configuration
9111 */
9112static int alc262_parse_auto_config(struct hda_codec *codec)
9113{
9114 struct alc_spec *spec = codec->spec;
9115 int err;
9116 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9117
f12ab1e0
TI
9118 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9119 alc262_ignore);
9120 if (err < 0)
df694daa 9121 return err;
f12ab1e0 9122 if (!spec->autocfg.line_outs)
df694daa 9123 return 0; /* can't find valid BIOS pin config */
f12ab1e0
TI
9124 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9125 if (err < 0)
9126 return err;
9127 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9128 if (err < 0)
df694daa
KY
9129 return err;
9130
9131 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9132
9133 if (spec->autocfg.dig_out_pin)
9134 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9135 if (spec->autocfg.dig_in_pin)
9136 spec->dig_in_nid = ALC262_DIGIN_NID;
9137
9138 if (spec->kctl_alloc)
9139 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9140
9141 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
a1e8d2da 9142 spec->num_mux_defs = 1;
df694daa
KY
9143 spec->input_mux = &spec->private_imux;
9144
776e184e
TI
9145 err = alc_auto_add_mic_boost(codec);
9146 if (err < 0)
9147 return err;
9148
df694daa
KY
9149 return 1;
9150}
9151
9152#define alc262_auto_init_multi_out alc882_auto_init_multi_out
9153#define alc262_auto_init_hp_out alc882_auto_init_hp_out
9154#define alc262_auto_init_analog_input alc882_auto_init_analog_input
9155
9156
9157/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 9158static void alc262_auto_init(struct hda_codec *codec)
df694daa 9159{
f6c7e546 9160 struct alc_spec *spec = codec->spec;
df694daa
KY
9161 alc262_auto_init_multi_out(codec);
9162 alc262_auto_init_hp_out(codec);
9163 alc262_auto_init_analog_input(codec);
f6c7e546
TI
9164 if (spec->unsol_event)
9165 alc_sku_automute(codec);
df694daa
KY
9166}
9167
9168/*
9169 * configuration and preset
9170 */
f5fcc13c
TI
9171static const char *alc262_models[ALC262_MODEL_LAST] = {
9172 [ALC262_BASIC] = "basic",
9173 [ALC262_HIPPO] = "hippo",
9174 [ALC262_HIPPO_1] = "hippo_1",
9175 [ALC262_FUJITSU] = "fujitsu",
9176 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 9177 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 9178 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 9179 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 9180 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
9181 [ALC262_BENQ_T31] = "benq-t31",
9182 [ALC262_SONY_ASSAMD] = "sony-assamd",
f651b50b 9183 [ALC262_ULTRA] = "ultra",
f5fcc13c
TI
9184 [ALC262_AUTO] = "auto",
9185};
9186
9187static struct snd_pci_quirk alc262_cfg_tbl[] = {
9188 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9189 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
7d87de2d 9190 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
ac3e3741
TI
9191 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9192 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
7d87de2d 9193 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
b98f9334 9194 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
b98f9334 9195 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
b98f9334 9196 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
cd7509a4 9197 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9198 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9199 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9200 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9201 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9202 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 9203 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 9204 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
9205 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9206 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9207 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
9208 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9209 ALC262_HP_TC_T5735),
8c427226 9210 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 9211 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 9212 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 9213 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
272a527c 9214 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
ac3e3741
TI
9215 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9216 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 9217 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
f651b50b 9218 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
ac3e3741
TI
9219 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9220 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9221 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
9222 {}
9223};
9224
9225static struct alc_config_preset alc262_presets[] = {
9226 [ALC262_BASIC] = {
9227 .mixers = { alc262_base_mixer },
9228 .init_verbs = { alc262_init_verbs },
9229 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9230 .dac_nids = alc262_dac_nids,
9231 .hp_nid = 0x03,
9232 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9233 .channel_mode = alc262_modes,
a3bcba38 9234 .input_mux = &alc262_capture_source,
df694daa 9235 },
ccc656ce
KY
9236 [ALC262_HIPPO] = {
9237 .mixers = { alc262_base_mixer },
9238 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9239 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9240 .dac_nids = alc262_dac_nids,
9241 .hp_nid = 0x03,
9242 .dig_out_nid = ALC262_DIGOUT_NID,
9243 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9244 .channel_mode = alc262_modes,
9245 .input_mux = &alc262_capture_source,
9246 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9247 .init_hook = alc262_hippo_automute,
ccc656ce
KY
9248 },
9249 [ALC262_HIPPO_1] = {
9250 .mixers = { alc262_hippo1_mixer },
9251 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9252 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9253 .dac_nids = alc262_dac_nids,
9254 .hp_nid = 0x02,
9255 .dig_out_nid = ALC262_DIGOUT_NID,
9256 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9257 .channel_mode = alc262_modes,
9258 .input_mux = &alc262_capture_source,
9259 .unsol_event = alc262_hippo1_unsol_event,
5b31954e 9260 .init_hook = alc262_hippo1_automute,
ccc656ce 9261 },
834be88d
TI
9262 [ALC262_FUJITSU] = {
9263 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
9264 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9265 alc262_fujitsu_unsol_verbs },
834be88d
TI
9266 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9267 .dac_nids = alc262_dac_nids,
9268 .hp_nid = 0x03,
9269 .dig_out_nid = ALC262_DIGOUT_NID,
9270 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9271 .channel_mode = alc262_modes,
9272 .input_mux = &alc262_fujitsu_capture_source,
ae6b813a 9273 .unsol_event = alc262_fujitsu_unsol_event,
834be88d 9274 },
9c7f852e
TI
9275 [ALC262_HP_BPC] = {
9276 .mixers = { alc262_HP_BPC_mixer },
9277 .init_verbs = { alc262_HP_BPC_init_verbs },
9278 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9279 .dac_nids = alc262_dac_nids,
9280 .hp_nid = 0x03,
9281 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9282 .channel_mode = alc262_modes,
9283 .input_mux = &alc262_HP_capture_source,
ce875f07
TI
9284 .unsol_event = alc262_hp_bpc_unsol_event,
9285 .init_hook = alc262_hp_bpc_automute,
f12ab1e0 9286 },
cd7509a4
KY
9287 [ALC262_HP_BPC_D7000_WF] = {
9288 .mixers = { alc262_HP_BPC_WildWest_mixer },
9289 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9290 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9291 .dac_nids = alc262_dac_nids,
9292 .hp_nid = 0x03,
9293 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9294 .channel_mode = alc262_modes,
accbe498 9295 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9296 .unsol_event = alc262_hp_wildwest_unsol_event,
9297 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9298 },
cd7509a4
KY
9299 [ALC262_HP_BPC_D7000_WL] = {
9300 .mixers = { alc262_HP_BPC_WildWest_mixer,
9301 alc262_HP_BPC_WildWest_option_mixer },
9302 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9303 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9304 .dac_nids = alc262_dac_nids,
9305 .hp_nid = 0x03,
9306 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9307 .channel_mode = alc262_modes,
accbe498 9308 .input_mux = &alc262_HP_D7000_capture_source,
ce875f07
TI
9309 .unsol_event = alc262_hp_wildwest_unsol_event,
9310 .init_hook = alc262_hp_wildwest_automute,
f12ab1e0 9311 },
66d2a9d6
KY
9312 [ALC262_HP_TC_T5735] = {
9313 .mixers = { alc262_hp_t5735_mixer },
9314 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9315 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9316 .dac_nids = alc262_dac_nids,
9317 .hp_nid = 0x03,
9318 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9319 .channel_mode = alc262_modes,
9320 .input_mux = &alc262_capture_source,
9321 .unsol_event = alc262_hp_t5735_unsol_event,
9322 .init_hook = alc262_hp_t5735_init_hook,
8c427226
KY
9323 },
9324 [ALC262_HP_RP5700] = {
9325 .mixers = { alc262_hp_rp5700_mixer },
9326 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9327 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9328 .dac_nids = alc262_dac_nids,
9329 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9330 .channel_mode = alc262_modes,
9331 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 9332 },
304dcaac
TI
9333 [ALC262_BENQ_ED8] = {
9334 .mixers = { alc262_base_mixer },
9335 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9336 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9337 .dac_nids = alc262_dac_nids,
9338 .hp_nid = 0x03,
9339 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9340 .channel_mode = alc262_modes,
9341 .input_mux = &alc262_capture_source,
f12ab1e0 9342 },
272a527c
KY
9343 [ALC262_SONY_ASSAMD] = {
9344 .mixers = { alc262_sony_mixer },
9345 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9346 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9347 .dac_nids = alc262_dac_nids,
9348 .hp_nid = 0x02,
9349 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9350 .channel_mode = alc262_modes,
9351 .input_mux = &alc262_capture_source,
9352 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9353 .init_hook = alc262_hippo_automute,
83c34218
KY
9354 },
9355 [ALC262_BENQ_T31] = {
9356 .mixers = { alc262_benq_t31_mixer },
9357 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9358 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9359 .dac_nids = alc262_dac_nids,
9360 .hp_nid = 0x03,
9361 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9362 .channel_mode = alc262_modes,
9363 .input_mux = &alc262_capture_source,
9364 .unsol_event = alc262_hippo_unsol_event,
5b31954e 9365 .init_hook = alc262_hippo_automute,
272a527c 9366 },
f651b50b
TD
9367 [ALC262_ULTRA] = {
9368 .mixers = { alc262_ultra_mixer },
9369 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9370 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9371 .dac_nids = alc262_dac_nids,
9372 .hp_nid = 0x03,
9373 .dig_out_nid = ALC262_DIGOUT_NID,
9374 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9375 .channel_mode = alc262_modes,
9376 .input_mux = &alc262_ultra_capture_source,
9377 .unsol_event = alc262_ultra_unsol_event,
9378 .init_hook = alc262_ultra_automute,
9379 },
df694daa
KY
9380};
9381
9382static int patch_alc262(struct hda_codec *codec)
9383{
9384 struct alc_spec *spec;
9385 int board_config;
9386 int err;
9387
dc041e0b 9388 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
9389 if (spec == NULL)
9390 return -ENOMEM;
9391
9392 codec->spec = spec;
9393#if 0
f12ab1e0
TI
9394 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9395 * under-run
9396 */
df694daa
KY
9397 {
9398 int tmp;
9399 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9400 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9401 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9402 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9403 }
9404#endif
9405
f5fcc13c
TI
9406 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9407 alc262_models,
9408 alc262_cfg_tbl);
cd7509a4 9409
f5fcc13c 9410 if (board_config < 0) {
9c7f852e
TI
9411 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9412 "trying auto-probe from BIOS...\n");
df694daa
KY
9413 board_config = ALC262_AUTO;
9414 }
9415
9416 if (board_config == ALC262_AUTO) {
9417 /* automatic parse from the BIOS config */
9418 err = alc262_parse_auto_config(codec);
9419 if (err < 0) {
9420 alc_free(codec);
9421 return err;
f12ab1e0 9422 } else if (!err) {
9c7f852e
TI
9423 printk(KERN_INFO
9424 "hda_codec: Cannot set up configuration "
9425 "from BIOS. Using base mode...\n");
df694daa
KY
9426 board_config = ALC262_BASIC;
9427 }
9428 }
9429
9430 if (board_config != ALC262_AUTO)
9431 setup_preset(spec, &alc262_presets[board_config]);
9432
9433 spec->stream_name_analog = "ALC262 Analog";
9434 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9435 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9436
9437 spec->stream_name_digital = "ALC262 Digital";
9438 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9439 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9440
f12ab1e0 9441 if (!spec->adc_nids && spec->input_mux) {
df694daa 9442 /* check whether NID 0x07 is valid */
4a471b7d
TI
9443 unsigned int wcap = get_wcaps(codec, 0x07);
9444
f12ab1e0
TI
9445 /* get type */
9446 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
df694daa
KY
9447 if (wcap != AC_WID_AUD_IN) {
9448 spec->adc_nids = alc262_adc_nids_alt;
9449 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
88c71a99 9450 spec->capsrc_nids = alc262_capsrc_nids_alt;
f12ab1e0
TI
9451 spec->mixers[spec->num_mixers] =
9452 alc262_capture_alt_mixer;
df694daa
KY
9453 spec->num_mixers++;
9454 } else {
9455 spec->adc_nids = alc262_adc_nids;
9456 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
88c71a99 9457 spec->capsrc_nids = alc262_capsrc_nids;
df694daa
KY
9458 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9459 spec->num_mixers++;
9460 }
9461 }
9462
2134ea4f
TI
9463 spec->vmaster_nid = 0x0c;
9464
df694daa
KY
9465 codec->patch_ops = alc_patch_ops;
9466 if (board_config == ALC262_AUTO)
ae6b813a 9467 spec->init_hook = alc262_auto_init;
cb53c626
TI
9468#ifdef CONFIG_SND_HDA_POWER_SAVE
9469 if (!spec->loopback.amplist)
9470 spec->loopback.amplist = alc262_loopbacks;
9471#endif
834be88d 9472
df694daa
KY
9473 return 0;
9474}
9475
a361d84b
KY
9476/*
9477 * ALC268 channel source setting (2 channel)
9478 */
9479#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9480#define alc268_modes alc260_modes
9481
9482static hda_nid_t alc268_dac_nids[2] = {
9483 /* front, hp */
9484 0x02, 0x03
9485};
9486
9487static hda_nid_t alc268_adc_nids[2] = {
9488 /* ADC0-1 */
9489 0x08, 0x07
9490};
9491
9492static hda_nid_t alc268_adc_nids_alt[1] = {
9493 /* ADC0 */
9494 0x08
9495};
9496
e1406348
TI
9497static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9498
a361d84b
KY
9499static struct snd_kcontrol_new alc268_base_mixer[] = {
9500 /* output mixer control */
9501 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9502 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9503 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9504 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
33bf17ab
TI
9505 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9506 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9507 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
a361d84b
KY
9508 { }
9509};
9510
aef9d318
TI
9511/* bind Beep switches of both NID 0x0f and 0x10 */
9512static struct hda_bind_ctls alc268_bind_beep_sw = {
9513 .ops = &snd_hda_bind_sw,
9514 .values = {
9515 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
9516 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
9517 0
9518 },
9519};
9520
9521static struct snd_kcontrol_new alc268_beep_mixer[] = {
9522 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
9523 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
9524 { }
9525};
9526
d1a991a6
KY
9527static struct hda_verb alc268_eapd_verbs[] = {
9528 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9529 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9530 { }
9531};
9532
d273809e
TI
9533/* Toshiba specific */
9534#define alc268_toshiba_automute alc262_hippo_automute
9535
9536static struct hda_verb alc268_toshiba_verbs[] = {
9537 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9538 { } /* end */
9539};
9540
9541/* Acer specific */
889c4395 9542/* bind volumes of both NID 0x02 and 0x03 */
6bc96857
TI
9543static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9544 .ops = &snd_hda_bind_vol,
9545 .values = {
9546 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9547 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9548 0
9549 },
9550};
9551
889c4395
TI
9552/* mute/unmute internal speaker according to the hp jack and mute state */
9553static void alc268_acer_automute(struct hda_codec *codec, int force)
9554{
9555 struct alc_spec *spec = codec->spec;
9556 unsigned int mute;
9557
9558 if (force || !spec->sense_updated) {
9559 unsigned int present;
9560 present = snd_hda_codec_read(codec, 0x14, 0,
9561 AC_VERB_GET_PIN_SENSE, 0);
9562 spec->jack_present = (present & 0x80000000) != 0;
9563 spec->sense_updated = 1;
9564 }
9565 if (spec->jack_present)
9566 mute = HDA_AMP_MUTE; /* mute internal speaker */
9567 else /* unmute internal speaker if necessary */
9568 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9569 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9570 HDA_AMP_MUTE, mute);
9571}
9572
9573
9574/* bind hp and internal speaker mute (with plug check) */
9575static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9576 struct snd_ctl_elem_value *ucontrol)
9577{
9578 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9579 long *valp = ucontrol->value.integer.value;
9580 int change;
9581
9582 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9583 HDA_AMP_MUTE,
9584 valp[0] ? 0 : HDA_AMP_MUTE);
9585 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9586 HDA_AMP_MUTE,
9587 valp[1] ? 0 : HDA_AMP_MUTE);
9588 if (change)
9589 alc268_acer_automute(codec, 0);
9590 return change;
9591}
d273809e
TI
9592
9593static struct snd_kcontrol_new alc268_acer_mixer[] = {
9594 /* output mixer control */
9595 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9596 {
9597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9598 .name = "Master Playback Switch",
9599 .info = snd_hda_mixer_amp_switch_info,
9600 .get = snd_hda_mixer_amp_switch_get,
9601 .put = alc268_acer_master_sw_put,
9602 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9603 },
33bf17ab
TI
9604 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9605 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9606 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
d273809e
TI
9607 { }
9608};
9609
9610static struct hda_verb alc268_acer_verbs[] = {
9611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9613
9614 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9615 { }
9616};
9617
9618/* unsolicited event for HP jack sensing */
9619static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9620 unsigned int res)
9621{
889c4395 9622 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9623 return;
9624 alc268_toshiba_automute(codec);
9625}
9626
9627static void alc268_acer_unsol_event(struct hda_codec *codec,
9628 unsigned int res)
9629{
889c4395 9630 if ((res >> 26) != ALC880_HP_EVENT)
d273809e
TI
9631 return;
9632 alc268_acer_automute(codec, 1);
9633}
9634
889c4395
TI
9635static void alc268_acer_init_hook(struct hda_codec *codec)
9636{
9637 alc268_acer_automute(codec, 1);
9638}
9639
3866f0b0
TI
9640static struct snd_kcontrol_new alc268_dell_mixer[] = {
9641 /* output mixer control */
9642 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9643 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9644 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9645 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9646 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9647 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9648 { }
9649};
9650
9651static struct hda_verb alc268_dell_verbs[] = {
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9654 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9655 { }
9656};
9657
9658/* mute/unmute internal speaker according to the hp jack and mute state */
9659static void alc268_dell_automute(struct hda_codec *codec)
9660{
9661 unsigned int present;
9662 unsigned int mute;
9663
9664 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9665 if (present & 0x80000000)
9666 mute = HDA_AMP_MUTE;
9667 else
9668 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9669 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9670 HDA_AMP_MUTE, mute);
9671}
9672
9673static void alc268_dell_unsol_event(struct hda_codec *codec,
9674 unsigned int res)
9675{
9676 if ((res >> 26) != ALC880_HP_EVENT)
9677 return;
9678 alc268_dell_automute(codec);
9679}
9680
9681#define alc268_dell_init_hook alc268_dell_automute
9682
a361d84b
KY
9683/*
9684 * generic initialization of ADC, input mixers and output mixers
9685 */
9686static struct hda_verb alc268_base_init_verbs[] = {
9687 /* Unmute DAC0-1 and set vol = 0 */
9688 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9689 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9690 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9691 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9692 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9693 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9694
9695 /*
9696 * Set up output mixers (0x0c - 0x0e)
9697 */
9698 /* set vol=0 to output mixers */
9699 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9701 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9702 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9703
9704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9705 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9706
9707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9709 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9710 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9711 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9712 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9713 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9714 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9715
9716 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9718 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9721 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9722 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
9723
9724 /* set PCBEEP vol = 0, mute connections */
9725 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9726 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9727 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 9728
a9b3aa8a
JZ
9729 /* Unmute Selector 23h,24h and set the default input to mic-in */
9730
9731 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9732 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9733 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 9735
a361d84b
KY
9736 { }
9737};
9738
9739/*
9740 * generic initialization of ADC, input mixers and output mixers
9741 */
9742static struct hda_verb alc268_volume_init_verbs[] = {
9743 /* set output DAC */
9744 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9745 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9746 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9747 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9748
9749 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9750 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9752 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9753 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9754
9755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9759 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9760
9761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9763 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9764 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9765
aef9d318
TI
9766 /* set PCBEEP vol = 0, mute connections */
9767 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9768 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9769 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
9770
9771 { }
9772};
9773
9774#define alc268_mux_enum_info alc_mux_enum_info
9775#define alc268_mux_enum_get alc_mux_enum_get
e1406348 9776#define alc268_mux_enum_put alc_mux_enum_put
a361d84b
KY
9777
9778static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9779 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9780 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9781 {
9782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9783 /* The multiple "Capture Source" controls confuse alsamixer
9784 * So call somewhat different..
a361d84b
KY
9785 */
9786 /* .name = "Capture Source", */
9787 .name = "Input Source",
9788 .count = 1,
9789 .info = alc268_mux_enum_info,
9790 .get = alc268_mux_enum_get,
9791 .put = alc268_mux_enum_put,
9792 },
9793 { } /* end */
9794};
9795
9796static struct snd_kcontrol_new alc268_capture_mixer[] = {
9797 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9798 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9799 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9800 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9801 {
9802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9803 /* The multiple "Capture Source" controls confuse alsamixer
9804 * So call somewhat different..
a361d84b
KY
9805 */
9806 /* .name = "Capture Source", */
9807 .name = "Input Source",
9808 .count = 2,
9809 .info = alc268_mux_enum_info,
9810 .get = alc268_mux_enum_get,
9811 .put = alc268_mux_enum_put,
9812 },
9813 { } /* end */
9814};
9815
9816static struct hda_input_mux alc268_capture_source = {
9817 .num_items = 4,
9818 .items = {
9819 { "Mic", 0x0 },
9820 { "Front Mic", 0x1 },
9821 { "Line", 0x2 },
9822 { "CD", 0x3 },
9823 },
9824};
9825
86c53bd2
JW
9826#ifdef CONFIG_SND_DEBUG
9827static struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
9828 /* Volume widgets */
9829 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9830 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9831 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9832 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9833 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9834 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9835 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9836 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9837 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9838 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9839 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9840 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9841 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
9842 /* The below appears problematic on some hardwares */
9843 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
9844 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9845 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9846 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9847 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9848
9849 /* Modes for retasking pin widgets */
9850 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9851 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9852 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9853 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9854
9855 /* Controls for GPIO pins, assuming they are configured as outputs */
9856 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9857 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9858 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9859 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9860
9861 /* Switches to allow the digital SPDIF output pin to be enabled.
9862 * The ALC268 does not have an SPDIF input.
9863 */
9864 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9865
9866 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9867 * this output to turn on an external amplifier.
9868 */
9869 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9870 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9871
9872 { } /* end */
9873};
9874#endif
9875
a361d84b
KY
9876/* create input playback/capture controls for the given pin */
9877static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9878 const char *ctlname, int idx)
9879{
9880 char name[32];
9881 int err;
9882
9883 sprintf(name, "%s Playback Volume", ctlname);
9884 if (nid == 0x14) {
9885 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9886 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9887 HDA_OUTPUT));
9888 if (err < 0)
9889 return err;
9890 } else if (nid == 0x15) {
9891 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9892 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9893 HDA_OUTPUT));
9894 if (err < 0)
9895 return err;
9896 } else
9897 return -1;
9898 sprintf(name, "%s Playback Switch", ctlname);
9899 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9900 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9901 if (err < 0)
9902 return err;
9903 return 0;
9904}
9905
9906/* add playback controls from the parsed DAC table */
9907static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9908 const struct auto_pin_cfg *cfg)
9909{
9910 hda_nid_t nid;
9911 int err;
9912
9913 spec->multiout.num_dacs = 2; /* only use one dac */
9914 spec->multiout.dac_nids = spec->private_dac_nids;
9915 spec->multiout.dac_nids[0] = 2;
9916 spec->multiout.dac_nids[1] = 3;
9917
9918 nid = cfg->line_out_pins[0];
9919 if (nid)
9920 alc268_new_analog_output(spec, nid, "Front", 0);
9921
9922 nid = cfg->speaker_pins[0];
9923 if (nid == 0x1d) {
9924 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9925 "Speaker Playback Volume",
9926 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9927 if (err < 0)
9928 return err;
9929 }
9930 nid = cfg->hp_pins[0];
9931 if (nid)
9932 alc268_new_analog_output(spec, nid, "Headphone", 0);
9933
9934 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9935 if (nid == 0x16) {
9936 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9937 "Mono Playback Switch",
9938 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9939 if (err < 0)
9940 return err;
9941 }
9942 return 0;
9943}
9944
9945/* create playback/capture controls for input pins */
9946static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9947 const struct auto_pin_cfg *cfg)
9948{
9949 struct hda_input_mux *imux = &spec->private_imux;
9950 int i, idx1;
9951
9952 for (i = 0; i < AUTO_PIN_LAST; i++) {
9953 switch(cfg->input_pins[i]) {
9954 case 0x18:
9955 idx1 = 0; /* Mic 1 */
9956 break;
9957 case 0x19:
9958 idx1 = 1; /* Mic 2 */
9959 break;
9960 case 0x1a:
9961 idx1 = 2; /* Line In */
9962 break;
9963 case 0x1c:
9964 idx1 = 3; /* CD */
9965 break;
9966 default:
9967 continue;
9968 }
9969 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9970 imux->items[imux->num_items].index = idx1;
9971 imux->num_items++;
9972 }
9973 return 0;
9974}
9975
9976static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9977{
9978 struct alc_spec *spec = codec->spec;
9979 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9980 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9981 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9982 unsigned int dac_vol1, dac_vol2;
9983
9984 if (speaker_nid) {
9985 snd_hda_codec_write(codec, speaker_nid, 0,
9986 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9987 snd_hda_codec_write(codec, 0x0f, 0,
9988 AC_VERB_SET_AMP_GAIN_MUTE,
9989 AMP_IN_UNMUTE(1));
9990 snd_hda_codec_write(codec, 0x10, 0,
9991 AC_VERB_SET_AMP_GAIN_MUTE,
9992 AMP_IN_UNMUTE(1));
9993 } else {
9994 snd_hda_codec_write(codec, 0x0f, 0,
9995 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9996 snd_hda_codec_write(codec, 0x10, 0,
9997 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9998 }
9999
10000 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10001 if (line_nid == 0x14)
10002 dac_vol2 = AMP_OUT_ZERO;
10003 else if (line_nid == 0x15)
10004 dac_vol1 = AMP_OUT_ZERO;
10005 if (hp_nid == 0x14)
10006 dac_vol2 = AMP_OUT_ZERO;
10007 else if (hp_nid == 0x15)
10008 dac_vol1 = AMP_OUT_ZERO;
10009 if (line_nid != 0x16 || hp_nid != 0x16 ||
10010 spec->autocfg.line_out_pins[1] != 0x16 ||
10011 spec->autocfg.line_out_pins[2] != 0x16)
10012 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10013
10014 snd_hda_codec_write(codec, 0x02, 0,
10015 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10016 snd_hda_codec_write(codec, 0x03, 0,
10017 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10018}
10019
10020/* pcm configuration: identiacal with ALC880 */
10021#define alc268_pcm_analog_playback alc880_pcm_analog_playback
10022#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 10023#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
10024#define alc268_pcm_digital_playback alc880_pcm_digital_playback
10025
10026/*
10027 * BIOS auto configuration
10028 */
10029static int alc268_parse_auto_config(struct hda_codec *codec)
10030{
10031 struct alc_spec *spec = codec->spec;
10032 int err;
10033 static hda_nid_t alc268_ignore[] = { 0 };
10034
10035 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10036 alc268_ignore);
10037 if (err < 0)
10038 return err;
10039 if (!spec->autocfg.line_outs)
10040 return 0; /* can't find valid BIOS pin config */
10041
10042 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10043 if (err < 0)
10044 return err;
10045 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10046 if (err < 0)
10047 return err;
10048
10049 spec->multiout.max_channels = 2;
10050
10051 /* digital only support output */
10052 if (spec->autocfg.dig_out_pin)
10053 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10054
10055 if (spec->kctl_alloc)
10056 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10057
aef9d318
TI
10058 if (spec->autocfg.speaker_pins[0] != 0x1d)
10059 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10060
a361d84b
KY
10061 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10062 spec->num_mux_defs = 1;
10063 spec->input_mux = &spec->private_imux;
10064
776e184e
TI
10065 err = alc_auto_add_mic_boost(codec);
10066 if (err < 0)
10067 return err;
10068
a361d84b
KY
10069 return 1;
10070}
10071
10072#define alc268_auto_init_multi_out alc882_auto_init_multi_out
10073#define alc268_auto_init_hp_out alc882_auto_init_hp_out
10074#define alc268_auto_init_analog_input alc882_auto_init_analog_input
10075
10076/* init callback for auto-configuration model -- overriding the default init */
10077static void alc268_auto_init(struct hda_codec *codec)
10078{
f6c7e546 10079 struct alc_spec *spec = codec->spec;
a361d84b
KY
10080 alc268_auto_init_multi_out(codec);
10081 alc268_auto_init_hp_out(codec);
10082 alc268_auto_init_mono_speaker_out(codec);
10083 alc268_auto_init_analog_input(codec);
f6c7e546
TI
10084 if (spec->unsol_event)
10085 alc_sku_automute(codec);
a361d84b
KY
10086}
10087
10088/*
10089 * configuration and preset
10090 */
10091static const char *alc268_models[ALC268_MODEL_LAST] = {
10092 [ALC268_3ST] = "3stack",
983f8ae4 10093 [ALC268_TOSHIBA] = "toshiba",
d273809e 10094 [ALC268_ACER] = "acer",
3866f0b0 10095 [ALC268_DELL] = "dell",
f12462c5 10096 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
10097#ifdef CONFIG_SND_DEBUG
10098 [ALC268_TEST] = "test",
10099#endif
a361d84b
KY
10100 [ALC268_AUTO] = "auto",
10101};
10102
10103static struct snd_pci_quirk alc268_cfg_tbl[] = {
ac3e3741 10104 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 10105 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 10106 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 10107 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
3866f0b0 10108 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
ac3e3741 10109 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
a361d84b 10110 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
d1a991a6 10111 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
8e7f00f9 10112 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
b875bf3a 10113 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
f12462c5 10114 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
a361d84b
KY
10115 {}
10116};
10117
10118static struct alc_config_preset alc268_presets[] = {
10119 [ALC268_3ST] = {
aef9d318
TI
10120 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10121 alc268_beep_mixer },
a361d84b
KY
10122 .init_verbs = { alc268_base_init_verbs },
10123 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10124 .dac_nids = alc268_dac_nids,
10125 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10126 .adc_nids = alc268_adc_nids_alt,
e1406348 10127 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
10128 .hp_nid = 0x03,
10129 .dig_out_nid = ALC268_DIGOUT_NID,
10130 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10131 .channel_mode = alc268_modes,
10132 .input_mux = &alc268_capture_source,
10133 },
d1a991a6 10134 [ALC268_TOSHIBA] = {
aef9d318
TI
10135 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10136 alc268_beep_mixer },
d273809e
TI
10137 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10138 alc268_toshiba_verbs },
d1a991a6
KY
10139 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10140 .dac_nids = alc268_dac_nids,
10141 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10142 .adc_nids = alc268_adc_nids_alt,
e1406348 10143 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
10144 .hp_nid = 0x03,
10145 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10146 .channel_mode = alc268_modes,
10147 .input_mux = &alc268_capture_source,
d273809e
TI
10148 .unsol_event = alc268_toshiba_unsol_event,
10149 .init_hook = alc268_toshiba_automute,
10150 },
10151 [ALC268_ACER] = {
aef9d318
TI
10152 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10153 alc268_beep_mixer },
d273809e
TI
10154 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10155 alc268_acer_verbs },
10156 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10157 .dac_nids = alc268_dac_nids,
10158 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10159 .adc_nids = alc268_adc_nids_alt,
e1406348 10160 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
10161 .hp_nid = 0x02,
10162 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10163 .channel_mode = alc268_modes,
10164 .input_mux = &alc268_capture_source,
10165 .unsol_event = alc268_acer_unsol_event,
889c4395 10166 .init_hook = alc268_acer_init_hook,
d1a991a6 10167 },
3866f0b0 10168 [ALC268_DELL] = {
aef9d318 10169 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
3866f0b0
TI
10170 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10171 alc268_dell_verbs },
10172 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10173 .dac_nids = alc268_dac_nids,
10174 .hp_nid = 0x02,
10175 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10176 .channel_mode = alc268_modes,
10177 .unsol_event = alc268_dell_unsol_event,
10178 .init_hook = alc268_dell_init_hook,
10179 .input_mux = &alc268_capture_source,
10180 },
f12462c5 10181 [ALC268_ZEPTO] = {
aef9d318
TI
10182 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10183 alc268_beep_mixer },
f12462c5
MT
10184 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10185 alc268_toshiba_verbs },
10186 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10187 .dac_nids = alc268_dac_nids,
10188 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10189 .adc_nids = alc268_adc_nids_alt,
e1406348 10190 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
10191 .hp_nid = 0x03,
10192 .dig_out_nid = ALC268_DIGOUT_NID,
10193 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10194 .channel_mode = alc268_modes,
10195 .input_mux = &alc268_capture_source,
10196 .unsol_event = alc268_toshiba_unsol_event,
10197 .init_hook = alc268_toshiba_automute
10198 },
86c53bd2
JW
10199#ifdef CONFIG_SND_DEBUG
10200 [ALC268_TEST] = {
10201 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10202 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10203 alc268_volume_init_verbs },
10204 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10205 .dac_nids = alc268_dac_nids,
10206 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10207 .adc_nids = alc268_adc_nids_alt,
e1406348 10208 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
10209 .hp_nid = 0x03,
10210 .dig_out_nid = ALC268_DIGOUT_NID,
10211 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10212 .channel_mode = alc268_modes,
10213 .input_mux = &alc268_capture_source,
10214 },
10215#endif
a361d84b
KY
10216};
10217
10218static int patch_alc268(struct hda_codec *codec)
10219{
10220 struct alc_spec *spec;
10221 int board_config;
10222 int err;
10223
10224 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10225 if (spec == NULL)
10226 return -ENOMEM;
10227
10228 codec->spec = spec;
10229
10230 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10231 alc268_models,
10232 alc268_cfg_tbl);
10233
10234 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10235 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10236 "trying auto-probe from BIOS...\n");
10237 board_config = ALC268_AUTO;
10238 }
10239
10240 if (board_config == ALC268_AUTO) {
10241 /* automatic parse from the BIOS config */
10242 err = alc268_parse_auto_config(codec);
10243 if (err < 0) {
10244 alc_free(codec);
10245 return err;
10246 } else if (!err) {
10247 printk(KERN_INFO
10248 "hda_codec: Cannot set up configuration "
10249 "from BIOS. Using base mode...\n");
10250 board_config = ALC268_3ST;
10251 }
10252 }
10253
10254 if (board_config != ALC268_AUTO)
10255 setup_preset(spec, &alc268_presets[board_config]);
10256
10257 spec->stream_name_analog = "ALC268 Analog";
10258 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10259 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 10260 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b
KY
10261
10262 spec->stream_name_digital = "ALC268 Digital";
10263 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10264
aef9d318
TI
10265 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10266 /* override the amp caps for beep generator */
10267 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10268 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10269 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10270 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10271 (0 << AC_AMPCAP_MUTE_SHIFT));
10272
3866f0b0
TI
10273 if (!spec->adc_nids && spec->input_mux) {
10274 /* check whether NID 0x07 is valid */
10275 unsigned int wcap = get_wcaps(codec, 0x07);
85860c06 10276 int i;
3866f0b0
TI
10277
10278 /* get type */
10279 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
67ebcb03 10280 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
10281 spec->adc_nids = alc268_adc_nids_alt;
10282 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10283 spec->mixers[spec->num_mixers] =
a361d84b 10284 alc268_capture_alt_mixer;
3866f0b0
TI
10285 spec->num_mixers++;
10286 } else {
10287 spec->adc_nids = alc268_adc_nids;
10288 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10289 spec->mixers[spec->num_mixers] =
10290 alc268_capture_mixer;
10291 spec->num_mixers++;
a361d84b 10292 }
e1406348 10293 spec->capsrc_nids = alc268_capsrc_nids;
85860c06
TI
10294 /* set default input source */
10295 for (i = 0; i < spec->num_adc_nids; i++)
10296 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10297 0, AC_VERB_SET_CONNECT_SEL,
10298 spec->input_mux->items[0].index);
a361d84b 10299 }
2134ea4f
TI
10300
10301 spec->vmaster_nid = 0x02;
10302
a361d84b
KY
10303 codec->patch_ops = alc_patch_ops;
10304 if (board_config == ALC268_AUTO)
10305 spec->init_hook = alc268_auto_init;
10306
10307 return 0;
10308}
10309
f6a92248
KY
10310/*
10311 * ALC269 channel source setting (2 channel)
10312 */
10313#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10314
10315#define alc269_dac_nids alc260_dac_nids
10316
10317static hda_nid_t alc269_adc_nids[1] = {
10318 /* ADC1 */
10319 0x07,
10320};
10321
10322#define alc269_modes alc260_modes
10323#define alc269_capture_source alc880_lg_lw_capture_source
10324
10325static struct snd_kcontrol_new alc269_base_mixer[] = {
10326 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10328 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10329 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10330 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10331 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10332 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10333 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10334 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10335 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10336 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10337 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10338 { } /* end */
10339};
10340
10341/* capture mixer elements */
10342static struct snd_kcontrol_new alc269_capture_mixer[] = {
10343 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10344 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10345 {
10346 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10347 /* The multiple "Capture Source" controls confuse alsamixer
10348 * So call somewhat different..
f6a92248
KY
10349 */
10350 /* .name = "Capture Source", */
10351 .name = "Input Source",
10352 .count = 1,
10353 .info = alc_mux_enum_info,
10354 .get = alc_mux_enum_get,
10355 .put = alc_mux_enum_put,
10356 },
10357 { } /* end */
10358};
10359
10360/*
10361 * generic initialization of ADC, input mixers and output mixers
10362 */
10363static struct hda_verb alc269_init_verbs[] = {
10364 /*
10365 * Unmute ADC0 and set the default input to mic-in
10366 */
10367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10368
10369 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10370 * analog-loopback mixer widget
10371 * Note: PASD motherboards uses the Line In 2 as the input for
10372 * front panel mic (mic 2)
10373 */
10374 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10380
10381 /*
10382 * Set up output mixers (0x0c - 0x0e)
10383 */
10384 /* set vol=0 to output mixers */
10385 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10386 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10387
10388 /* set up input amps for analog loopback */
10389 /* Amp Indices: DAC = 0, mixer = 1 */
10390 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10392 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10393 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10394 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10396
10397 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10398 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10399 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10400 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10403 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10404
10405 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10407 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10408 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10409 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10410 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10411 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10412
10413 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10414 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10415
10416 /* FIXME: use matrix-type input source selection */
10417 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10418 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10420 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10421 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10422 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10423
10424 /* set EAPD */
10425 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10426 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10427 { }
10428};
10429
10430/* add playback controls from the parsed DAC table */
10431static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10432 const struct auto_pin_cfg *cfg)
10433{
10434 hda_nid_t nid;
10435 int err;
10436
10437 spec->multiout.num_dacs = 1; /* only use one dac */
10438 spec->multiout.dac_nids = spec->private_dac_nids;
10439 spec->multiout.dac_nids[0] = 2;
10440
10441 nid = cfg->line_out_pins[0];
10442 if (nid) {
10443 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10444 "Front Playback Volume",
10445 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10446 if (err < 0)
10447 return err;
10448 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10449 "Front Playback Switch",
10450 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10451 if (err < 0)
10452 return err;
10453 }
10454
10455 nid = cfg->speaker_pins[0];
10456 if (nid) {
10457 if (!cfg->line_out_pins[0]) {
10458 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10459 "Speaker Playback Volume",
10460 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10461 HDA_OUTPUT));
10462 if (err < 0)
10463 return err;
10464 }
10465 if (nid == 0x16) {
10466 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10467 "Speaker Playback Switch",
10468 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10469 HDA_OUTPUT));
10470 if (err < 0)
10471 return err;
10472 } else {
10473 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10474 "Speaker Playback Switch",
10475 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10476 HDA_OUTPUT));
10477 if (err < 0)
10478 return err;
10479 }
10480 }
10481 nid = cfg->hp_pins[0];
10482 if (nid) {
10483 /* spec->multiout.hp_nid = 2; */
10484 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10485 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10486 "Headphone Playback Volume",
10487 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10488 HDA_OUTPUT));
10489 if (err < 0)
10490 return err;
10491 }
10492 if (nid == 0x16) {
10493 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10494 "Headphone Playback Switch",
10495 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10496 HDA_OUTPUT));
10497 if (err < 0)
10498 return err;
10499 } else {
10500 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10501 "Headphone Playback Switch",
10502 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10503 HDA_OUTPUT));
10504 if (err < 0)
10505 return err;
10506 }
10507 }
10508 return 0;
10509}
10510
10511#define alc269_auto_create_analog_input_ctls \
10512 alc880_auto_create_analog_input_ctls
10513
10514#ifdef CONFIG_SND_HDA_POWER_SAVE
10515#define alc269_loopbacks alc880_loopbacks
10516#endif
10517
10518/* pcm configuration: identiacal with ALC880 */
10519#define alc269_pcm_analog_playback alc880_pcm_analog_playback
10520#define alc269_pcm_analog_capture alc880_pcm_analog_capture
10521#define alc269_pcm_digital_playback alc880_pcm_digital_playback
10522#define alc269_pcm_digital_capture alc880_pcm_digital_capture
10523
10524/*
10525 * BIOS auto configuration
10526 */
10527static int alc269_parse_auto_config(struct hda_codec *codec)
10528{
10529 struct alc_spec *spec = codec->spec;
10530 int err;
10531 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10532
10533 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10534 alc269_ignore);
10535 if (err < 0)
10536 return err;
10537
10538 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10539 if (err < 0)
10540 return err;
10541 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10542 if (err < 0)
10543 return err;
10544
10545 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10546
10547 if (spec->autocfg.dig_out_pin)
10548 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10549
10550 if (spec->kctl_alloc)
10551 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10552
10553 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10554 spec->num_mux_defs = 1;
10555 spec->input_mux = &spec->private_imux;
10556
10557 err = alc_auto_add_mic_boost(codec);
10558 if (err < 0)
10559 return err;
10560
10561 return 1;
10562}
10563
10564#define alc269_auto_init_multi_out alc882_auto_init_multi_out
10565#define alc269_auto_init_hp_out alc882_auto_init_hp_out
10566#define alc269_auto_init_analog_input alc882_auto_init_analog_input
10567
10568
10569/* init callback for auto-configuration model -- overriding the default init */
10570static void alc269_auto_init(struct hda_codec *codec)
10571{
f6c7e546 10572 struct alc_spec *spec = codec->spec;
f6a92248
KY
10573 alc269_auto_init_multi_out(codec);
10574 alc269_auto_init_hp_out(codec);
10575 alc269_auto_init_analog_input(codec);
f6c7e546
TI
10576 if (spec->unsol_event)
10577 alc_sku_automute(codec);
f6a92248
KY
10578}
10579
10580/*
10581 * configuration and preset
10582 */
10583static const char *alc269_models[ALC269_MODEL_LAST] = {
10584 [ALC269_BASIC] = "basic",
10585};
10586
10587static struct snd_pci_quirk alc269_cfg_tbl[] = {
10588 {}
10589};
10590
10591static struct alc_config_preset alc269_presets[] = {
10592 [ALC269_BASIC] = {
10593 .mixers = { alc269_base_mixer },
10594 .init_verbs = { alc269_init_verbs },
10595 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10596 .dac_nids = alc269_dac_nids,
10597 .hp_nid = 0x03,
10598 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10599 .channel_mode = alc269_modes,
10600 .input_mux = &alc269_capture_source,
10601 },
10602};
10603
10604static int patch_alc269(struct hda_codec *codec)
10605{
10606 struct alc_spec *spec;
10607 int board_config;
10608 int err;
10609
10610 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10611 if (spec == NULL)
10612 return -ENOMEM;
10613
10614 codec->spec = spec;
10615
10616 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10617 alc269_models,
10618 alc269_cfg_tbl);
10619
10620 if (board_config < 0) {
10621 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10622 "trying auto-probe from BIOS...\n");
10623 board_config = ALC269_AUTO;
10624 }
10625
10626 if (board_config == ALC269_AUTO) {
10627 /* automatic parse from the BIOS config */
10628 err = alc269_parse_auto_config(codec);
10629 if (err < 0) {
10630 alc_free(codec);
10631 return err;
10632 } else if (!err) {
10633 printk(KERN_INFO
10634 "hda_codec: Cannot set up configuration "
10635 "from BIOS. Using base mode...\n");
10636 board_config = ALC269_BASIC;
10637 }
10638 }
10639
10640 if (board_config != ALC269_AUTO)
10641 setup_preset(spec, &alc269_presets[board_config]);
10642
10643 spec->stream_name_analog = "ALC269 Analog";
10644 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10645 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10646
10647 spec->stream_name_digital = "ALC269 Digital";
10648 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10649 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10650
10651 spec->adc_nids = alc269_adc_nids;
10652 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10653 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10654 spec->num_mixers++;
10655
10656 codec->patch_ops = alc_patch_ops;
10657 if (board_config == ALC269_AUTO)
10658 spec->init_hook = alc269_auto_init;
10659#ifdef CONFIG_SND_HDA_POWER_SAVE
10660 if (!spec->loopback.amplist)
10661 spec->loopback.amplist = alc269_loopbacks;
10662#endif
10663
10664 return 0;
10665}
10666
df694daa
KY
10667/*
10668 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10669 */
10670
10671/*
10672 * set the path ways for 2 channel output
10673 * need to set the codec line out and mic 1 pin widgets to inputs
10674 */
10675static struct hda_verb alc861_threestack_ch2_init[] = {
10676 /* set pin widget 1Ah (line in) for input */
10677 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10678 /* set pin widget 18h (mic1/2) for input, for mic also enable
10679 * the vref
10680 */
df694daa
KY
10681 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10682
9c7f852e
TI
10683 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10684#if 0
10685 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10686 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10687#endif
df694daa
KY
10688 { } /* end */
10689};
10690/*
10691 * 6ch mode
10692 * need to set the codec line out and mic 1 pin widgets to outputs
10693 */
10694static struct hda_verb alc861_threestack_ch6_init[] = {
10695 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10696 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10697 /* set pin widget 18h (mic1) for output (CLFE)*/
10698 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10699
10700 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 10701 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 10702
9c7f852e
TI
10703 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10704#if 0
10705 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10706 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10707#endif
df694daa
KY
10708 { } /* end */
10709};
10710
10711static struct hda_channel_mode alc861_threestack_modes[2] = {
10712 { 2, alc861_threestack_ch2_init },
10713 { 6, alc861_threestack_ch6_init },
10714};
22309c3e
TI
10715/* Set mic1 as input and unmute the mixer */
10716static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10717 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10718 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10719 { } /* end */
10720};
10721/* Set mic1 as output and mute mixer */
10722static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10723 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10724 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10725 { } /* end */
10726};
10727
10728static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10729 { 2, alc861_uniwill_m31_ch2_init },
10730 { 4, alc861_uniwill_m31_ch4_init },
10731};
df694daa 10732
7cdbff94
MD
10733/* Set mic1 and line-in as input and unmute the mixer */
10734static struct hda_verb alc861_asus_ch2_init[] = {
10735 /* set pin widget 1Ah (line in) for input */
10736 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
10737 /* set pin widget 18h (mic1/2) for input, for mic also enable
10738 * the vref
10739 */
7cdbff94
MD
10740 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10741
10742 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10743#if 0
10744 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10745 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10746#endif
10747 { } /* end */
10748};
10749/* Set mic1 nad line-in as output and mute mixer */
10750static struct hda_verb alc861_asus_ch6_init[] = {
10751 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10752 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10753 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10754 /* set pin widget 18h (mic1) for output (CLFE)*/
10755 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10756 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10757 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10758 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10759
10760 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10761#if 0
10762 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10763 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10764#endif
10765 { } /* end */
10766};
10767
10768static struct hda_channel_mode alc861_asus_modes[2] = {
10769 { 2, alc861_asus_ch2_init },
10770 { 6, alc861_asus_ch6_init },
10771};
10772
df694daa
KY
10773/* patch-ALC861 */
10774
10775static struct snd_kcontrol_new alc861_base_mixer[] = {
10776 /* output mixer control */
10777 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10778 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10779 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10780 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10781 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10782
10783 /*Input mixer control */
10784 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10785 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10786 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10787 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10788 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10789 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10791 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10792 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10793 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10794
df694daa
KY
10795 /* Capture mixer control */
10796 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10797 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10798 {
10799 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10800 .name = "Capture Source",
10801 .count = 1,
10802 .info = alc_mux_enum_info,
10803 .get = alc_mux_enum_get,
10804 .put = alc_mux_enum_put,
10805 },
10806 { } /* end */
10807};
10808
10809static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10810 /* output mixer control */
10811 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10812 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10813 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10814 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10815 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10816
10817 /* Input mixer control */
10818 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10819 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10820 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10821 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10822 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10823 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10825 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10826 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10827 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10828
df694daa
KY
10829 /* Capture mixer control */
10830 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10831 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10832 {
10833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10834 .name = "Capture Source",
10835 .count = 1,
10836 .info = alc_mux_enum_info,
10837 .get = alc_mux_enum_get,
10838 .put = alc_mux_enum_put,
10839 },
10840 {
10841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10842 .name = "Channel Mode",
10843 .info = alc_ch_mode_info,
10844 .get = alc_ch_mode_get,
10845 .put = alc_ch_mode_put,
10846 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10847 },
10848 { } /* end */
a53d1aec
TD
10849};
10850
d1d985f0 10851static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
10852 /* output mixer control */
10853 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10855 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10856
10857 /*Capture mixer control */
10858 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10859 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10860 {
10861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10862 .name = "Capture Source",
10863 .count = 1,
10864 .info = alc_mux_enum_info,
10865 .get = alc_mux_enum_get,
10866 .put = alc_mux_enum_put,
10867 },
10868
10869 { } /* end */
f12ab1e0 10870};
a53d1aec 10871
22309c3e
TI
10872static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10873 /* output mixer control */
10874 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10875 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10876 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10877 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10878 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10879
10880 /* Input mixer control */
10881 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10882 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10883 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10884 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10885 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10886 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10887 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10888 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10889 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10890 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 10891
22309c3e
TI
10892 /* Capture mixer control */
10893 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10894 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10895 {
10896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10897 .name = "Capture Source",
10898 .count = 1,
10899 .info = alc_mux_enum_info,
10900 .get = alc_mux_enum_get,
10901 .put = alc_mux_enum_put,
10902 },
10903 {
10904 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10905 .name = "Channel Mode",
10906 .info = alc_ch_mode_info,
10907 .get = alc_ch_mode_get,
10908 .put = alc_ch_mode_put,
10909 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10910 },
10911 { } /* end */
f12ab1e0 10912};
7cdbff94
MD
10913
10914static struct snd_kcontrol_new alc861_asus_mixer[] = {
10915 /* output mixer control */
10916 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10917 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10918 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10919 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10920 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10921
10922 /* Input mixer control */
10923 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10924 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10925 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10926 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10927 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10928 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10929 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10930 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10931 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
10932 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10933
7cdbff94
MD
10934 /* Capture mixer control */
10935 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10936 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10937 {
10938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10939 .name = "Capture Source",
10940 .count = 1,
10941 .info = alc_mux_enum_info,
10942 .get = alc_mux_enum_get,
10943 .put = alc_mux_enum_put,
10944 },
10945 {
10946 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10947 .name = "Channel Mode",
10948 .info = alc_ch_mode_info,
10949 .get = alc_ch_mode_get,
10950 .put = alc_ch_mode_put,
10951 .private_value = ARRAY_SIZE(alc861_asus_modes),
10952 },
10953 { }
56bb0cab
TI
10954};
10955
10956/* additional mixer */
d1d985f0 10957static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
10958 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10959 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10960 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10961 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10962 { }
10963};
7cdbff94 10964
df694daa
KY
10965/*
10966 * generic initialization of ADC, input mixers and output mixers
10967 */
10968static struct hda_verb alc861_base_init_verbs[] = {
10969 /*
10970 * Unmute ADC0 and set the default input to mic-in
10971 */
10972 /* port-A for surround (rear panel) */
10973 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10974 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10975 /* port-B for mic-in (rear panel) with vref */
10976 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10977 /* port-C for line-in (rear panel) */
10978 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10979 /* port-D for Front */
10980 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10981 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10982 /* port-E for HP out (front panel) */
10983 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10984 /* route front PCM to HP */
9dece1d7 10985 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
10986 /* port-F for mic-in (front panel) with vref */
10987 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10988 /* port-G for CLFE (rear panel) */
10989 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10990 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10991 /* port-H for side (rear panel) */
10992 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10993 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10994 /* CD-in */
10995 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10996 /* route front mic to ADC1*/
10997 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10999
11000 /* Unmute DAC0~3 & spdif out*/
11001 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11002 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11003 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11004 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11006
11007 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11008 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11009 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11010 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11011 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11012
11013 /* Unmute Stereo Mixer 15 */
11014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11017 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11018
11019 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11020 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11021 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11022 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11023 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11024 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11026 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11027 /* hp used DAC 3 (Front) */
11028 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11029 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11030
11031 { }
11032};
11033
11034static struct hda_verb alc861_threestack_init_verbs[] = {
11035 /*
11036 * Unmute ADC0 and set the default input to mic-in
11037 */
11038 /* port-A for surround (rear panel) */
11039 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11040 /* port-B for mic-in (rear panel) with vref */
11041 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11042 /* port-C for line-in (rear panel) */
11043 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11044 /* port-D for Front */
11045 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11046 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11047 /* port-E for HP out (front panel) */
11048 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11049 /* route front PCM to HP */
9dece1d7 11050 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
11051 /* port-F for mic-in (front panel) with vref */
11052 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11053 /* port-G for CLFE (rear panel) */
11054 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11055 /* port-H for side (rear panel) */
11056 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11057 /* CD-in */
11058 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11059 /* route front mic to ADC1*/
11060 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11062 /* Unmute DAC0~3 & spdif out*/
11063 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11064 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11065 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11066 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11068
11069 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11070 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11071 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11072 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11073 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11074
11075 /* Unmute Stereo Mixer 15 */
11076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11077 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11078 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11079 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
11080
11081 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11082 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11083 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11084 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11085 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11086 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11087 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11088 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11089 /* hp used DAC 3 (Front) */
11090 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11091 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11092 { }
11093};
22309c3e
TI
11094
11095static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11096 /*
11097 * Unmute ADC0 and set the default input to mic-in
11098 */
11099 /* port-A for surround (rear panel) */
11100 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11101 /* port-B for mic-in (rear panel) with vref */
11102 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11103 /* port-C for line-in (rear panel) */
11104 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11105 /* port-D for Front */
11106 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11107 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11108 /* port-E for HP out (front panel) */
f12ab1e0
TI
11109 /* this has to be set to VREF80 */
11110 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 11111 /* route front PCM to HP */
9dece1d7 11112 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
11113 /* port-F for mic-in (front panel) with vref */
11114 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11115 /* port-G for CLFE (rear panel) */
11116 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11117 /* port-H for side (rear panel) */
11118 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11119 /* CD-in */
11120 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11121 /* route front mic to ADC1*/
11122 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11124 /* Unmute DAC0~3 & spdif out*/
11125 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11126 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11127 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11128 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11130
11131 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11132 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11133 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11134 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11135 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11136
11137 /* Unmute Stereo Mixer 15 */
11138 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11139 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11141 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
11142
11143 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11144 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11145 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11146 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11147 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11149 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11151 /* hp used DAC 3 (Front) */
11152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
11153 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11154 { }
11155};
11156
7cdbff94
MD
11157static struct hda_verb alc861_asus_init_verbs[] = {
11158 /*
11159 * Unmute ADC0 and set the default input to mic-in
11160 */
f12ab1e0
TI
11161 /* port-A for surround (rear panel)
11162 * according to codec#0 this is the HP jack
11163 */
7cdbff94
MD
11164 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11165 /* route front PCM to HP */
11166 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11167 /* port-B for mic-in (rear panel) with vref */
11168 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11169 /* port-C for line-in (rear panel) */
11170 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11171 /* port-D for Front */
11172 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11173 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11174 /* port-E for HP out (front panel) */
f12ab1e0
TI
11175 /* this has to be set to VREF80 */
11176 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 11177 /* route front PCM to HP */
9dece1d7 11178 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
11179 /* port-F for mic-in (front panel) with vref */
11180 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11181 /* port-G for CLFE (rear panel) */
11182 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11183 /* port-H for side (rear panel) */
11184 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11185 /* CD-in */
11186 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11187 /* route front mic to ADC1*/
11188 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11189 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11190 /* Unmute DAC0~3 & spdif out*/
11191 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11192 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11193 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11194 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11196 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11197 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11198 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11199 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11200 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11201
11202 /* Unmute Stereo Mixer 15 */
11203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 11206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
11207
11208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11209 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11212 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11215 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
11216 /* hp used DAC 3 (Front) */
11217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
11218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11219 { }
11220};
11221
56bb0cab
TI
11222/* additional init verbs for ASUS laptops */
11223static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11224 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11225 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11226 { }
11227};
7cdbff94 11228
df694daa
KY
11229/*
11230 * generic initialization of ADC, input mixers and output mixers
11231 */
11232static struct hda_verb alc861_auto_init_verbs[] = {
11233 /*
11234 * Unmute ADC0 and set the default input to mic-in
11235 */
f12ab1e0 11236 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa
KY
11237 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11238
11239 /* Unmute DAC0~3 & spdif out*/
11240 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11241 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11242 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11243 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11244 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11245
11246 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11247 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11248 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11249 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11250 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11251
11252 /* Unmute Stereo Mixer 15 */
11253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11254 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11255 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11256 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11257
11258 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11260 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11262 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11263 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11265 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11266
11267 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11269 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11270 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
11271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11272 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
f12ab1e0
TI
11273 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11274 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa 11275
f12ab1e0 11276 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
11277
11278 { }
11279};
11280
a53d1aec
TD
11281static struct hda_verb alc861_toshiba_init_verbs[] = {
11282 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 11283
a53d1aec
TD
11284 { }
11285};
11286
11287/* toggle speaker-output according to the hp-jack state */
11288static void alc861_toshiba_automute(struct hda_codec *codec)
11289{
11290 unsigned int present;
11291
11292 present = snd_hda_codec_read(codec, 0x0f, 0,
11293 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
11294 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11295 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11296 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11297 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
11298}
11299
11300static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11301 unsigned int res)
11302{
a53d1aec
TD
11303 if ((res >> 26) == ALC880_HP_EVENT)
11304 alc861_toshiba_automute(codec);
11305}
11306
df694daa
KY
11307/* pcm configuration: identiacal with ALC880 */
11308#define alc861_pcm_analog_playback alc880_pcm_analog_playback
11309#define alc861_pcm_analog_capture alc880_pcm_analog_capture
11310#define alc861_pcm_digital_playback alc880_pcm_digital_playback
11311#define alc861_pcm_digital_capture alc880_pcm_digital_capture
11312
11313
11314#define ALC861_DIGOUT_NID 0x07
11315
11316static struct hda_channel_mode alc861_8ch_modes[1] = {
11317 { 8, NULL }
11318};
11319
11320static hda_nid_t alc861_dac_nids[4] = {
11321 /* front, surround, clfe, side */
11322 0x03, 0x06, 0x05, 0x04
11323};
11324
9c7f852e
TI
11325static hda_nid_t alc660_dac_nids[3] = {
11326 /* front, clfe, surround */
11327 0x03, 0x05, 0x06
11328};
11329
df694daa
KY
11330static hda_nid_t alc861_adc_nids[1] = {
11331 /* ADC0-2 */
11332 0x08,
11333};
11334
11335static struct hda_input_mux alc861_capture_source = {
11336 .num_items = 5,
11337 .items = {
11338 { "Mic", 0x0 },
11339 { "Front Mic", 0x3 },
11340 { "Line", 0x1 },
11341 { "CD", 0x4 },
11342 { "Mixer", 0x5 },
11343 },
11344};
11345
11346/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
11347static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11348 const struct auto_pin_cfg *cfg)
df694daa
KY
11349{
11350 int i;
11351 hda_nid_t nid;
11352
11353 spec->multiout.dac_nids = spec->private_dac_nids;
11354 for (i = 0; i < cfg->line_outs; i++) {
11355 nid = cfg->line_out_pins[i];
11356 if (nid) {
11357 if (i >= ARRAY_SIZE(alc861_dac_nids))
11358 continue;
11359 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11360 }
11361 }
11362 spec->multiout.num_dacs = cfg->line_outs;
11363 return 0;
11364}
11365
11366/* add playback controls from the parsed DAC table */
11367static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11368 const struct auto_pin_cfg *cfg)
11369{
11370 char name[32];
f12ab1e0
TI
11371 static const char *chname[4] = {
11372 "Front", "Surround", NULL /*CLFE*/, "Side"
11373 };
df694daa
KY
11374 hda_nid_t nid;
11375 int i, idx, err;
11376
11377 for (i = 0; i < cfg->line_outs; i++) {
11378 nid = spec->multiout.dac_nids[i];
f12ab1e0 11379 if (!nid)
df694daa
KY
11380 continue;
11381 if (nid == 0x05) {
11382 /* Center/LFE */
f12ab1e0
TI
11383 err = add_control(spec, ALC_CTL_BIND_MUTE,
11384 "Center Playback Switch",
11385 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11386 HDA_OUTPUT));
11387 if (err < 0)
df694daa 11388 return err;
f12ab1e0
TI
11389 err = add_control(spec, ALC_CTL_BIND_MUTE,
11390 "LFE Playback Switch",
11391 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11392 HDA_OUTPUT));
11393 if (err < 0)
df694daa
KY
11394 return err;
11395 } else {
f12ab1e0
TI
11396 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11397 idx++)
df694daa
KY
11398 if (nid == alc861_dac_nids[idx])
11399 break;
11400 sprintf(name, "%s Playback Switch", chname[idx]);
f12ab1e0
TI
11401 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11402 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11403 HDA_OUTPUT));
11404 if (err < 0)
df694daa
KY
11405 return err;
11406 }
11407 }
11408 return 0;
11409}
11410
11411static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11412{
11413 int err;
11414 hda_nid_t nid;
11415
f12ab1e0 11416 if (!pin)
df694daa
KY
11417 return 0;
11418
11419 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11420 nid = 0x03;
f12ab1e0
TI
11421 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11422 "Headphone Playback Switch",
11423 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11424 if (err < 0)
df694daa
KY
11425 return err;
11426 spec->multiout.hp_nid = nid;
11427 }
11428 return 0;
11429}
11430
11431/* create playback/capture controls for input pins */
f12ab1e0
TI
11432static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11433 const struct auto_pin_cfg *cfg)
df694daa 11434{
df694daa
KY
11435 struct hda_input_mux *imux = &spec->private_imux;
11436 int i, err, idx, idx1;
11437
11438 for (i = 0; i < AUTO_PIN_LAST; i++) {
f12ab1e0 11439 switch (cfg->input_pins[i]) {
df694daa
KY
11440 case 0x0c:
11441 idx1 = 1;
f12ab1e0 11442 idx = 2; /* Line In */
df694daa
KY
11443 break;
11444 case 0x0f:
11445 idx1 = 2;
f12ab1e0 11446 idx = 2; /* Line In */
df694daa
KY
11447 break;
11448 case 0x0d:
11449 idx1 = 0;
f12ab1e0 11450 idx = 1; /* Mic In */
df694daa 11451 break;
f12ab1e0 11452 case 0x10:
df694daa 11453 idx1 = 3;
f12ab1e0 11454 idx = 1; /* Mic In */
df694daa
KY
11455 break;
11456 case 0x11:
11457 idx1 = 4;
f12ab1e0 11458 idx = 0; /* CD */
df694daa
KY
11459 break;
11460 default:
11461 continue;
11462 }
11463
4a471b7d
TI
11464 err = new_analog_input(spec, cfg->input_pins[i],
11465 auto_pin_cfg_labels[i], idx, 0x15);
df694daa
KY
11466 if (err < 0)
11467 return err;
11468
4a471b7d 11469 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
df694daa 11470 imux->items[imux->num_items].index = idx1;
f12ab1e0 11471 imux->num_items++;
df694daa
KY
11472 }
11473 return 0;
11474}
11475
11476static struct snd_kcontrol_new alc861_capture_mixer[] = {
11477 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11478 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11479
11480 {
11481 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11482 /* The multiple "Capture Source" controls confuse alsamixer
11483 * So call somewhat different..
df694daa
KY
11484 */
11485 /* .name = "Capture Source", */
11486 .name = "Input Source",
11487 .count = 1,
11488 .info = alc_mux_enum_info,
11489 .get = alc_mux_enum_get,
11490 .put = alc_mux_enum_put,
11491 },
11492 { } /* end */
11493};
11494
f12ab1e0
TI
11495static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11496 hda_nid_t nid,
df694daa
KY
11497 int pin_type, int dac_idx)
11498{
f6c7e546 11499 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
11500}
11501
11502static void alc861_auto_init_multi_out(struct hda_codec *codec)
11503{
11504 struct alc_spec *spec = codec->spec;
11505 int i;
11506
bc9f98a9 11507 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
df694daa
KY
11508 for (i = 0; i < spec->autocfg.line_outs; i++) {
11509 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11510 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 11511 if (nid)
baba8ee9 11512 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 11513 spec->multiout.dac_nids[i]);
df694daa
KY
11514 }
11515}
11516
11517static void alc861_auto_init_hp_out(struct hda_codec *codec)
11518{
11519 struct alc_spec *spec = codec->spec;
11520 hda_nid_t pin;
11521
eb06ed8f 11522 pin = spec->autocfg.hp_pins[0];
df694daa 11523 if (pin) /* connect to front */
f12ab1e0
TI
11524 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11525 spec->multiout.dac_nids[0]);
f6c7e546
TI
11526 pin = spec->autocfg.speaker_pins[0];
11527 if (pin)
11528 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
df694daa
KY
11529}
11530
11531static void alc861_auto_init_analog_input(struct hda_codec *codec)
11532{
11533 struct alc_spec *spec = codec->spec;
11534 int i;
11535
11536 for (i = 0; i < AUTO_PIN_LAST; i++) {
11537 hda_nid_t nid = spec->autocfg.input_pins[i];
f12ab1e0
TI
11538 if (nid >= 0x0c && nid <= 0x11) {
11539 snd_hda_codec_write(codec, nid, 0,
11540 AC_VERB_SET_PIN_WIDGET_CONTROL,
11541 i <= AUTO_PIN_FRONT_MIC ?
11542 PIN_VREF80 : PIN_IN);
df694daa
KY
11543 }
11544 }
11545}
11546
11547/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
11548/* return 1 if successful, 0 if the proper config is not found,
11549 * or a negative error code
11550 */
df694daa
KY
11551static int alc861_parse_auto_config(struct hda_codec *codec)
11552{
11553 struct alc_spec *spec = codec->spec;
11554 int err;
11555 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11556
f12ab1e0
TI
11557 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11558 alc861_ignore);
11559 if (err < 0)
df694daa 11560 return err;
f12ab1e0 11561 if (!spec->autocfg.line_outs)
df694daa
KY
11562 return 0; /* can't find valid BIOS pin config */
11563
f12ab1e0
TI
11564 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11565 if (err < 0)
11566 return err;
11567 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11568 if (err < 0)
11569 return err;
11570 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11571 if (err < 0)
11572 return err;
11573 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11574 if (err < 0)
df694daa
KY
11575 return err;
11576
11577 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11578
11579 if (spec->autocfg.dig_out_pin)
11580 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11581
11582 if (spec->kctl_alloc)
11583 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11584
11585 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11586
a1e8d2da 11587 spec->num_mux_defs = 1;
df694daa
KY
11588 spec->input_mux = &spec->private_imux;
11589
11590 spec->adc_nids = alc861_adc_nids;
11591 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11592 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11593 spec->num_mixers++;
11594
11595 return 1;
11596}
11597
ae6b813a
TI
11598/* additional initialization for auto-configuration model */
11599static void alc861_auto_init(struct hda_codec *codec)
df694daa 11600{
f6c7e546 11601 struct alc_spec *spec = codec->spec;
df694daa
KY
11602 alc861_auto_init_multi_out(codec);
11603 alc861_auto_init_hp_out(codec);
11604 alc861_auto_init_analog_input(codec);
f6c7e546
TI
11605 if (spec->unsol_event)
11606 alc_sku_automute(codec);
df694daa
KY
11607}
11608
cb53c626
TI
11609#ifdef CONFIG_SND_HDA_POWER_SAVE
11610static struct hda_amp_list alc861_loopbacks[] = {
11611 { 0x15, HDA_INPUT, 0 },
11612 { 0x15, HDA_INPUT, 1 },
11613 { 0x15, HDA_INPUT, 2 },
11614 { 0x15, HDA_INPUT, 3 },
11615 { } /* end */
11616};
11617#endif
11618
df694daa
KY
11619
11620/*
11621 * configuration and preset
11622 */
f5fcc13c
TI
11623static const char *alc861_models[ALC861_MODEL_LAST] = {
11624 [ALC861_3ST] = "3stack",
11625 [ALC660_3ST] = "3stack-660",
11626 [ALC861_3ST_DIG] = "3stack-dig",
11627 [ALC861_6ST_DIG] = "6stack-dig",
11628 [ALC861_UNIWILL_M31] = "uniwill-m31",
11629 [ALC861_TOSHIBA] = "toshiba",
11630 [ALC861_ASUS] = "asus",
11631 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11632 [ALC861_AUTO] = "auto",
11633};
11634
11635static struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 11636 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
11637 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11638 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11639 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 11640 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 11641 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 11642 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
11643 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11644 * Any other models that need this preset?
11645 */
11646 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
11647 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11648 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 11649 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
11650 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11651 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11652 /* FIXME: the below seems conflict */
11653 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 11654 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 11655 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
11656 {}
11657};
11658
11659static struct alc_config_preset alc861_presets[] = {
11660 [ALC861_3ST] = {
11661 .mixers = { alc861_3ST_mixer },
11662 .init_verbs = { alc861_threestack_init_verbs },
11663 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11664 .dac_nids = alc861_dac_nids,
11665 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11666 .channel_mode = alc861_threestack_modes,
4e195a7b 11667 .need_dac_fix = 1,
df694daa
KY
11668 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11669 .adc_nids = alc861_adc_nids,
11670 .input_mux = &alc861_capture_source,
11671 },
11672 [ALC861_3ST_DIG] = {
11673 .mixers = { alc861_base_mixer },
11674 .init_verbs = { alc861_threestack_init_verbs },
11675 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11676 .dac_nids = alc861_dac_nids,
11677 .dig_out_nid = ALC861_DIGOUT_NID,
11678 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11679 .channel_mode = alc861_threestack_modes,
4e195a7b 11680 .need_dac_fix = 1,
df694daa
KY
11681 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11682 .adc_nids = alc861_adc_nids,
11683 .input_mux = &alc861_capture_source,
11684 },
11685 [ALC861_6ST_DIG] = {
11686 .mixers = { alc861_base_mixer },
11687 .init_verbs = { alc861_base_init_verbs },
11688 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11689 .dac_nids = alc861_dac_nids,
11690 .dig_out_nid = ALC861_DIGOUT_NID,
11691 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11692 .channel_mode = alc861_8ch_modes,
11693 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11694 .adc_nids = alc861_adc_nids,
11695 .input_mux = &alc861_capture_source,
11696 },
9c7f852e
TI
11697 [ALC660_3ST] = {
11698 .mixers = { alc861_3ST_mixer },
11699 .init_verbs = { alc861_threestack_init_verbs },
11700 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11701 .dac_nids = alc660_dac_nids,
11702 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11703 .channel_mode = alc861_threestack_modes,
4e195a7b 11704 .need_dac_fix = 1,
9c7f852e
TI
11705 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11706 .adc_nids = alc861_adc_nids,
11707 .input_mux = &alc861_capture_source,
11708 },
22309c3e
TI
11709 [ALC861_UNIWILL_M31] = {
11710 .mixers = { alc861_uniwill_m31_mixer },
11711 .init_verbs = { alc861_uniwill_m31_init_verbs },
11712 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11713 .dac_nids = alc861_dac_nids,
11714 .dig_out_nid = ALC861_DIGOUT_NID,
11715 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11716 .channel_mode = alc861_uniwill_m31_modes,
11717 .need_dac_fix = 1,
11718 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11719 .adc_nids = alc861_adc_nids,
11720 .input_mux = &alc861_capture_source,
11721 },
a53d1aec
TD
11722 [ALC861_TOSHIBA] = {
11723 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
11724 .init_verbs = { alc861_base_init_verbs,
11725 alc861_toshiba_init_verbs },
a53d1aec
TD
11726 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11727 .dac_nids = alc861_dac_nids,
11728 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11729 .channel_mode = alc883_3ST_2ch_modes,
11730 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11731 .adc_nids = alc861_adc_nids,
11732 .input_mux = &alc861_capture_source,
11733 .unsol_event = alc861_toshiba_unsol_event,
11734 .init_hook = alc861_toshiba_automute,
11735 },
7cdbff94
MD
11736 [ALC861_ASUS] = {
11737 .mixers = { alc861_asus_mixer },
11738 .init_verbs = { alc861_asus_init_verbs },
11739 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11740 .dac_nids = alc861_dac_nids,
11741 .dig_out_nid = ALC861_DIGOUT_NID,
11742 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11743 .channel_mode = alc861_asus_modes,
11744 .need_dac_fix = 1,
11745 .hp_nid = 0x06,
11746 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11747 .adc_nids = alc861_adc_nids,
11748 .input_mux = &alc861_capture_source,
11749 },
56bb0cab
TI
11750 [ALC861_ASUS_LAPTOP] = {
11751 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11752 .init_verbs = { alc861_asus_init_verbs,
11753 alc861_asus_laptop_init_verbs },
11754 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11755 .dac_nids = alc861_dac_nids,
11756 .dig_out_nid = ALC861_DIGOUT_NID,
11757 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11758 .channel_mode = alc883_3ST_2ch_modes,
11759 .need_dac_fix = 1,
11760 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11761 .adc_nids = alc861_adc_nids,
11762 .input_mux = &alc861_capture_source,
11763 },
11764};
df694daa
KY
11765
11766
11767static int patch_alc861(struct hda_codec *codec)
11768{
11769 struct alc_spec *spec;
11770 int board_config;
11771 int err;
11772
dc041e0b 11773 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
11774 if (spec == NULL)
11775 return -ENOMEM;
11776
f12ab1e0 11777 codec->spec = spec;
df694daa 11778
f5fcc13c
TI
11779 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11780 alc861_models,
11781 alc861_cfg_tbl);
9c7f852e 11782
f5fcc13c 11783 if (board_config < 0) {
9c7f852e
TI
11784 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11785 "trying auto-probe from BIOS...\n");
df694daa
KY
11786 board_config = ALC861_AUTO;
11787 }
11788
11789 if (board_config == ALC861_AUTO) {
11790 /* automatic parse from the BIOS config */
11791 err = alc861_parse_auto_config(codec);
11792 if (err < 0) {
11793 alc_free(codec);
11794 return err;
f12ab1e0 11795 } else if (!err) {
9c7f852e
TI
11796 printk(KERN_INFO
11797 "hda_codec: Cannot set up configuration "
11798 "from BIOS. Using base mode...\n");
df694daa
KY
11799 board_config = ALC861_3ST_DIG;
11800 }
11801 }
11802
11803 if (board_config != ALC861_AUTO)
11804 setup_preset(spec, &alc861_presets[board_config]);
11805
11806 spec->stream_name_analog = "ALC861 Analog";
11807 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11808 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11809
11810 spec->stream_name_digital = "ALC861 Digital";
11811 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11812 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11813
2134ea4f
TI
11814 spec->vmaster_nid = 0x03;
11815
df694daa
KY
11816 codec->patch_ops = alc_patch_ops;
11817 if (board_config == ALC861_AUTO)
ae6b813a 11818 spec->init_hook = alc861_auto_init;
cb53c626
TI
11819#ifdef CONFIG_SND_HDA_POWER_SAVE
11820 if (!spec->loopback.amplist)
11821 spec->loopback.amplist = alc861_loopbacks;
11822#endif
df694daa 11823
1da177e4
LT
11824 return 0;
11825}
11826
f32610ed
JS
11827/*
11828 * ALC861-VD support
11829 *
11830 * Based on ALC882
11831 *
11832 * In addition, an independent DAC
11833 */
11834#define ALC861VD_DIGOUT_NID 0x06
11835
11836static hda_nid_t alc861vd_dac_nids[4] = {
11837 /* front, surr, clfe, side surr */
11838 0x02, 0x03, 0x04, 0x05
11839};
11840
11841/* dac_nids for ALC660vd are in a different order - according to
11842 * Realtek's driver.
11843 * This should probably tesult in a different mixer for 6stack models
11844 * of ALC660vd codecs, but for now there is only 3stack mixer
11845 * - and it is the same as in 861vd.
11846 * adc_nids in ALC660vd are (is) the same as in 861vd
11847 */
11848static hda_nid_t alc660vd_dac_nids[3] = {
11849 /* front, rear, clfe, rear_surr */
11850 0x02, 0x04, 0x03
11851};
11852
11853static hda_nid_t alc861vd_adc_nids[1] = {
11854 /* ADC0 */
11855 0x09,
11856};
11857
e1406348
TI
11858static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
11859
f32610ed
JS
11860/* input MUX */
11861/* FIXME: should be a matrix-type input source selection */
11862static struct hda_input_mux alc861vd_capture_source = {
11863 .num_items = 4,
11864 .items = {
11865 { "Mic", 0x0 },
11866 { "Front Mic", 0x1 },
11867 { "Line", 0x2 },
11868 { "CD", 0x4 },
11869 },
11870};
11871
272a527c
KY
11872static struct hda_input_mux alc861vd_dallas_capture_source = {
11873 .num_items = 3,
11874 .items = {
11875 { "Front Mic", 0x0 },
11876 { "ATAPI Mic", 0x1 },
11877 { "Line In", 0x5 },
11878 },
11879};
11880
d1a991a6
KY
11881static struct hda_input_mux alc861vd_hp_capture_source = {
11882 .num_items = 2,
11883 .items = {
11884 { "Front Mic", 0x0 },
11885 { "ATAPI Mic", 0x1 },
11886 },
11887};
11888
f32610ed
JS
11889#define alc861vd_mux_enum_info alc_mux_enum_info
11890#define alc861vd_mux_enum_get alc_mux_enum_get
e1406348
TI
11891/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
11892#define alc861vd_mux_enum_put alc882_mux_enum_put
f32610ed
JS
11893
11894/*
11895 * 2ch mode
11896 */
11897static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11898 { 2, NULL }
11899};
11900
11901/*
11902 * 6ch mode
11903 */
11904static struct hda_verb alc861vd_6stack_ch6_init[] = {
11905 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11906 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11907 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11908 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11909 { } /* end */
11910};
11911
11912/*
11913 * 8ch mode
11914 */
11915static struct hda_verb alc861vd_6stack_ch8_init[] = {
11916 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11917 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11918 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11919 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11920 { } /* end */
11921};
11922
11923static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11924 { 6, alc861vd_6stack_ch6_init },
11925 { 8, alc861vd_6stack_ch8_init },
11926};
11927
11928static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11929 {
11930 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11931 .name = "Channel Mode",
11932 .info = alc_ch_mode_info,
11933 .get = alc_ch_mode_get,
11934 .put = alc_ch_mode_put,
11935 },
11936 { } /* end */
11937};
11938
11939static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11940 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11941 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11942
11943 {
11944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11945 /* The multiple "Capture Source" controls confuse alsamixer
11946 * So call somewhat different..
f32610ed
JS
11947 */
11948 /* .name = "Capture Source", */
11949 .name = "Input Source",
11950 .count = 1,
11951 .info = alc861vd_mux_enum_info,
11952 .get = alc861vd_mux_enum_get,
11953 .put = alc861vd_mux_enum_put,
11954 },
11955 { } /* end */
11956};
11957
11958/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11959 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11960 */
11961static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11962 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11963 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11964
11965 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11966 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11967
11968 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11969 HDA_OUTPUT),
11970 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11971 HDA_OUTPUT),
11972 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11973 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11974
11975 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11976 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11977
11978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11979
11980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11983
11984 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11987
11988 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11989 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11990
11991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11993
11994 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11995 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11996
11997 { } /* end */
11998};
11999
12000static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12001 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12002 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12003
12004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12005
12006 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12007 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12009
12010 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12011 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12012 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12013
12014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12016
12017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12019
12020 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12021 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12022
12023 { } /* end */
12024};
12025
bdd148a3
KY
12026static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12027 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12028 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12029 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12030
12031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12032
12033 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12036
12037 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12040
12041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12043
12044 { } /* end */
12045};
12046
272a527c
KY
12047/* Pin assignment: Front=0x14, HP = 0x15,
12048 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
12049 */
12050static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12051 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12052 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12053 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12054 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12055 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12056 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12057 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12058 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
272a527c
KY
12061 { } /* end */
12062};
12063
d1a991a6
KY
12064/* Pin assignment: Speaker=0x14, Line-out = 0x15,
12065 * Front Mic=0x18, ATAPI Mic = 0x19,
12066 */
12067static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12068 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12072 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12074 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12075 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12076
12077 { } /* end */
12078};
12079
f32610ed
JS
12080/*
12081 * generic initialization of ADC, input mixers and output mixers
12082 */
12083static struct hda_verb alc861vd_volume_init_verbs[] = {
12084 /*
12085 * Unmute ADC0 and set the default input to mic-in
12086 */
12087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12089
12090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12091 * the analog-loopback mixer widget
12092 */
12093 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
12099
12100 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
12101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 12104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
12105
12106 /*
12107 * Set up output mixers (0x02 - 0x05)
12108 */
12109 /* set vol=0 to output mixers */
12110 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12114
12115 /* set up input amps for analog loopback */
12116 /* Amp Indices: DAC = 0, mixer = 1 */
12117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12125
12126 { }
12127};
12128
12129/*
12130 * 3-stack pin configuration:
12131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12132 */
12133static struct hda_verb alc861vd_3stack_init_verbs[] = {
12134 /*
12135 * Set pin mode and muting
12136 */
12137 /* set front pin widgets 0x14 for output */
12138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12141
12142 /* Mic (rear) pin: input vref at 80% */
12143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12145 /* Front Mic pin: input vref at 80% */
12146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12147 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12148 /* Line In pin: input */
12149 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12150 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12151 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12153 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12155 /* CD pin widget for input */
12156 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12157
12158 { }
12159};
12160
12161/*
12162 * 6-stack pin configuration:
12163 */
12164static struct hda_verb alc861vd_6stack_init_verbs[] = {
12165 /*
12166 * Set pin mode and muting
12167 */
12168 /* set front pin widgets 0x14 for output */
12169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12171 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12172
12173 /* Rear Pin: output 1 (0x0d) */
12174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12176 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12177 /* CLFE Pin: output 2 (0x0e) */
12178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12179 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12181 /* Side Pin: output 3 (0x0f) */
12182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12185
12186 /* Mic (rear) pin: input vref at 80% */
12187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12189 /* Front Mic pin: input vref at 80% */
12190 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12191 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12192 /* Line In pin: input */
12193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12195 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12198 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12199 /* CD pin widget for input */
12200 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12201
12202 { }
12203};
12204
bdd148a3
KY
12205static struct hda_verb alc861vd_eapd_verbs[] = {
12206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12207 { }
12208};
12209
12210static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12215 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12216 {}
12217};
12218
12219/* toggle speaker-output according to the hp-jack state */
12220static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12221{
12222 unsigned int present;
12223 unsigned char bits;
12224
12225 present = snd_hda_codec_read(codec, 0x1b, 0,
12226 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12227 bits = present ? HDA_AMP_MUTE : 0;
12228 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12229 HDA_AMP_MUTE, bits);
bdd148a3
KY
12230}
12231
12232static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12233{
12234 unsigned int present;
12235 unsigned char bits;
12236
12237 present = snd_hda_codec_read(codec, 0x18, 0,
12238 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12239 bits = present ? HDA_AMP_MUTE : 0;
12240 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12241 HDA_AMP_MUTE, bits);
bdd148a3
KY
12242}
12243
12244static void alc861vd_lenovo_automute(struct hda_codec *codec)
12245{
12246 alc861vd_lenovo_hp_automute(codec);
12247 alc861vd_lenovo_mic_automute(codec);
12248}
12249
12250static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12251 unsigned int res)
12252{
12253 switch (res >> 26) {
12254 case ALC880_HP_EVENT:
12255 alc861vd_lenovo_hp_automute(codec);
12256 break;
12257 case ALC880_MIC_EVENT:
12258 alc861vd_lenovo_mic_automute(codec);
12259 break;
12260 }
12261}
12262
272a527c
KY
12263static struct hda_verb alc861vd_dallas_verbs[] = {
12264 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12265 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12266 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12267 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12268
12269 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12270 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12271 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12272 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12273 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12274 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12275 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12276 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12277
12278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12280 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12281 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12282 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12283 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12284 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12285 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12286
12287 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12288 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12289 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12290 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12291 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12292 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12293 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12294 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12295
12296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12298 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12299 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12300
12301 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12302 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12303 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12304
12305 { } /* end */
12306};
12307
12308/* toggle speaker-output according to the hp-jack state */
12309static void alc861vd_dallas_automute(struct hda_codec *codec)
12310{
12311 unsigned int present;
12312
12313 present = snd_hda_codec_read(codec, 0x15, 0,
12314 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
12315 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12316 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
272a527c
KY
12317}
12318
12319static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12320{
12321 if ((res >> 26) == ALC880_HP_EVENT)
12322 alc861vd_dallas_automute(codec);
12323}
12324
cb53c626
TI
12325#ifdef CONFIG_SND_HDA_POWER_SAVE
12326#define alc861vd_loopbacks alc880_loopbacks
12327#endif
12328
f32610ed
JS
12329/* pcm configuration: identiacal with ALC880 */
12330#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12331#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12332#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12333#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12334
12335/*
12336 * configuration and preset
12337 */
12338static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12339 [ALC660VD_3ST] = "3stack-660",
983f8ae4 12340 [ALC660VD_3ST_DIG] = "3stack-660-digout",
f32610ed
JS
12341 [ALC861VD_3ST] = "3stack",
12342 [ALC861VD_3ST_DIG] = "3stack-digout",
12343 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 12344 [ALC861VD_LENOVO] = "lenovo",
272a527c 12345 [ALC861VD_DALLAS] = "dallas",
983f8ae4 12346 [ALC861VD_HP] = "hp",
f32610ed
JS
12347 [ALC861VD_AUTO] = "auto",
12348};
12349
12350static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
12351 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12352 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 12353 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f32610ed 12354 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
6963f84c 12355 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 12356 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 12357 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 12358 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
272a527c 12359 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
542d7c66 12360 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
39c5d41f 12361 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
ac3e3741
TI
12362 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12363 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
625dc0bf 12364 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
12365 {}
12366};
12367
12368static struct alc_config_preset alc861vd_presets[] = {
12369 [ALC660VD_3ST] = {
12370 .mixers = { alc861vd_3st_mixer },
12371 .init_verbs = { alc861vd_volume_init_verbs,
12372 alc861vd_3stack_init_verbs },
12373 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12374 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
12375 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12376 .channel_mode = alc861vd_3stack_2ch_modes,
12377 .input_mux = &alc861vd_capture_source,
12378 },
6963f84c
MC
12379 [ALC660VD_3ST_DIG] = {
12380 .mixers = { alc861vd_3st_mixer },
12381 .init_verbs = { alc861vd_volume_init_verbs,
12382 alc861vd_3stack_init_verbs },
12383 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12384 .dac_nids = alc660vd_dac_nids,
12385 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
12386 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12387 .channel_mode = alc861vd_3stack_2ch_modes,
12388 .input_mux = &alc861vd_capture_source,
12389 },
f32610ed
JS
12390 [ALC861VD_3ST] = {
12391 .mixers = { alc861vd_3st_mixer },
12392 .init_verbs = { alc861vd_volume_init_verbs,
12393 alc861vd_3stack_init_verbs },
12394 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12395 .dac_nids = alc861vd_dac_nids,
12396 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12397 .channel_mode = alc861vd_3stack_2ch_modes,
12398 .input_mux = &alc861vd_capture_source,
12399 },
12400 [ALC861VD_3ST_DIG] = {
12401 .mixers = { alc861vd_3st_mixer },
12402 .init_verbs = { alc861vd_volume_init_verbs,
12403 alc861vd_3stack_init_verbs },
12404 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12405 .dac_nids = alc861vd_dac_nids,
12406 .dig_out_nid = ALC861VD_DIGOUT_NID,
12407 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12408 .channel_mode = alc861vd_3stack_2ch_modes,
12409 .input_mux = &alc861vd_capture_source,
12410 },
12411 [ALC861VD_6ST_DIG] = {
12412 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12413 .init_verbs = { alc861vd_volume_init_verbs,
12414 alc861vd_6stack_init_verbs },
12415 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12416 .dac_nids = alc861vd_dac_nids,
12417 .dig_out_nid = ALC861VD_DIGOUT_NID,
12418 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12419 .channel_mode = alc861vd_6stack_modes,
12420 .input_mux = &alc861vd_capture_source,
12421 },
bdd148a3
KY
12422 [ALC861VD_LENOVO] = {
12423 .mixers = { alc861vd_lenovo_mixer },
12424 .init_verbs = { alc861vd_volume_init_verbs,
12425 alc861vd_3stack_init_verbs,
12426 alc861vd_eapd_verbs,
12427 alc861vd_lenovo_unsol_verbs },
12428 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12429 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
12430 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12431 .channel_mode = alc861vd_3stack_2ch_modes,
12432 .input_mux = &alc861vd_capture_source,
12433 .unsol_event = alc861vd_lenovo_unsol_event,
12434 .init_hook = alc861vd_lenovo_automute,
12435 },
272a527c
KY
12436 [ALC861VD_DALLAS] = {
12437 .mixers = { alc861vd_dallas_mixer },
12438 .init_verbs = { alc861vd_dallas_verbs },
12439 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12440 .dac_nids = alc861vd_dac_nids,
272a527c
KY
12441 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12442 .channel_mode = alc861vd_3stack_2ch_modes,
12443 .input_mux = &alc861vd_dallas_capture_source,
12444 .unsol_event = alc861vd_dallas_unsol_event,
12445 .init_hook = alc861vd_dallas_automute,
d1a991a6
KY
12446 },
12447 [ALC861VD_HP] = {
12448 .mixers = { alc861vd_hp_mixer },
12449 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12450 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12451 .dac_nids = alc861vd_dac_nids,
d1a991a6 12452 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
12453 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12454 .channel_mode = alc861vd_3stack_2ch_modes,
12455 .input_mux = &alc861vd_hp_capture_source,
12456 .unsol_event = alc861vd_dallas_unsol_event,
12457 .init_hook = alc861vd_dallas_automute,
12458 },
f32610ed
JS
12459};
12460
12461/*
12462 * BIOS auto configuration
12463 */
12464static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12465 hda_nid_t nid, int pin_type, int dac_idx)
12466{
f6c7e546 12467 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
12468}
12469
12470static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12471{
12472 struct alc_spec *spec = codec->spec;
12473 int i;
12474
bc9f98a9 12475 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
f32610ed
JS
12476 for (i = 0; i <= HDA_SIDE; i++) {
12477 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 12478 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
12479 if (nid)
12480 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 12481 pin_type, i);
f32610ed
JS
12482 }
12483}
12484
12485
12486static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12487{
12488 struct alc_spec *spec = codec->spec;
12489 hda_nid_t pin;
12490
12491 pin = spec->autocfg.hp_pins[0];
12492 if (pin) /* connect to front and use dac 0 */
12493 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
12494 pin = spec->autocfg.speaker_pins[0];
12495 if (pin)
12496 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
12497}
12498
12499#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12500#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12501
12502static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12503{
12504 struct alc_spec *spec = codec->spec;
12505 int i;
12506
12507 for (i = 0; i < AUTO_PIN_LAST; i++) {
12508 hda_nid_t nid = spec->autocfg.input_pins[i];
12509 if (alc861vd_is_input_pin(nid)) {
12510 snd_hda_codec_write(codec, nid, 0,
12511 AC_VERB_SET_PIN_WIDGET_CONTROL,
12512 i <= AUTO_PIN_FRONT_MIC ?
12513 PIN_VREF80 : PIN_IN);
12514 if (nid != ALC861VD_PIN_CD_NID)
12515 snd_hda_codec_write(codec, nid, 0,
12516 AC_VERB_SET_AMP_GAIN_MUTE,
12517 AMP_OUT_MUTE);
12518 }
12519 }
12520}
12521
12522#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12523#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12524
12525/* add playback controls from the parsed DAC table */
12526/* Based on ALC880 version. But ALC861VD has separate,
12527 * different NIDs for mute/unmute switch and volume control */
12528static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12529 const struct auto_pin_cfg *cfg)
12530{
12531 char name[32];
12532 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12533 hda_nid_t nid_v, nid_s;
12534 int i, err;
12535
12536 for (i = 0; i < cfg->line_outs; i++) {
f12ab1e0 12537 if (!spec->multiout.dac_nids[i])
f32610ed
JS
12538 continue;
12539 nid_v = alc861vd_idx_to_mixer_vol(
12540 alc880_dac_to_idx(
12541 spec->multiout.dac_nids[i]));
12542 nid_s = alc861vd_idx_to_mixer_switch(
12543 alc880_dac_to_idx(
12544 spec->multiout.dac_nids[i]));
12545
12546 if (i == 2) {
12547 /* Center/LFE */
f12ab1e0
TI
12548 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12549 "Center Playback Volume",
12550 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12551 HDA_OUTPUT));
12552 if (err < 0)
f32610ed 12553 return err;
f12ab1e0
TI
12554 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12555 "LFE Playback Volume",
12556 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12557 HDA_OUTPUT));
12558 if (err < 0)
f32610ed 12559 return err;
f12ab1e0
TI
12560 err = add_control(spec, ALC_CTL_BIND_MUTE,
12561 "Center Playback Switch",
12562 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12563 HDA_INPUT));
12564 if (err < 0)
f32610ed 12565 return err;
f12ab1e0
TI
12566 err = add_control(spec, ALC_CTL_BIND_MUTE,
12567 "LFE Playback Switch",
12568 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12569 HDA_INPUT));
12570 if (err < 0)
f32610ed
JS
12571 return err;
12572 } else {
12573 sprintf(name, "%s Playback Volume", chname[i]);
f12ab1e0
TI
12574 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12575 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12576 HDA_OUTPUT));
12577 if (err < 0)
f32610ed
JS
12578 return err;
12579 sprintf(name, "%s Playback Switch", chname[i]);
f12ab1e0 12580 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
bdd148a3 12581 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
12582 HDA_INPUT));
12583 if (err < 0)
f32610ed
JS
12584 return err;
12585 }
12586 }
12587 return 0;
12588}
12589
12590/* add playback controls for speaker and HP outputs */
12591/* Based on ALC880 version. But ALC861VD has separate,
12592 * different NIDs for mute/unmute switch and volume control */
12593static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12594 hda_nid_t pin, const char *pfx)
12595{
12596 hda_nid_t nid_v, nid_s;
12597 int err;
12598 char name[32];
12599
f12ab1e0 12600 if (!pin)
f32610ed
JS
12601 return 0;
12602
12603 if (alc880_is_fixed_pin(pin)) {
12604 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12605 /* specify the DAC as the extra output */
f12ab1e0 12606 if (!spec->multiout.hp_nid)
f32610ed
JS
12607 spec->multiout.hp_nid = nid_v;
12608 else
12609 spec->multiout.extra_out_nid[0] = nid_v;
12610 /* control HP volume/switch on the output mixer amp */
12611 nid_v = alc861vd_idx_to_mixer_vol(
12612 alc880_fixed_pin_idx(pin));
12613 nid_s = alc861vd_idx_to_mixer_switch(
12614 alc880_fixed_pin_idx(pin));
12615
12616 sprintf(name, "%s Playback Volume", pfx);
f12ab1e0
TI
12617 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12618 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12619 if (err < 0)
f32610ed
JS
12620 return err;
12621 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12622 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12623 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12624 if (err < 0)
f32610ed
JS
12625 return err;
12626 } else if (alc880_is_multi_pin(pin)) {
12627 /* set manual connection */
12628 /* we have only a switch on HP-out PIN */
12629 sprintf(name, "%s Playback Switch", pfx);
f12ab1e0
TI
12630 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12631 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12632 if (err < 0)
f32610ed
JS
12633 return err;
12634 }
12635 return 0;
12636}
12637
12638/* parse the BIOS configuration and set up the alc_spec
12639 * return 1 if successful, 0 if the proper config is not found,
12640 * or a negative error code
12641 * Based on ALC880 version - had to change it to override
12642 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12643static int alc861vd_parse_auto_config(struct hda_codec *codec)
12644{
12645 struct alc_spec *spec = codec->spec;
12646 int err;
12647 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12648
f12ab1e0
TI
12649 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12650 alc861vd_ignore);
12651 if (err < 0)
f32610ed 12652 return err;
f12ab1e0 12653 if (!spec->autocfg.line_outs)
f32610ed
JS
12654 return 0; /* can't find valid BIOS pin config */
12655
f12ab1e0
TI
12656 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12657 if (err < 0)
12658 return err;
12659 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12660 if (err < 0)
12661 return err;
12662 err = alc861vd_auto_create_extra_out(spec,
12663 spec->autocfg.speaker_pins[0],
12664 "Speaker");
12665 if (err < 0)
12666 return err;
12667 err = alc861vd_auto_create_extra_out(spec,
12668 spec->autocfg.hp_pins[0],
12669 "Headphone");
12670 if (err < 0)
12671 return err;
12672 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12673 if (err < 0)
f32610ed
JS
12674 return err;
12675
12676 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12677
12678 if (spec->autocfg.dig_out_pin)
12679 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12680
12681 if (spec->kctl_alloc)
12682 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12683
12684 spec->init_verbs[spec->num_init_verbs++]
12685 = alc861vd_volume_init_verbs;
12686
12687 spec->num_mux_defs = 1;
12688 spec->input_mux = &spec->private_imux;
12689
776e184e
TI
12690 err = alc_auto_add_mic_boost(codec);
12691 if (err < 0)
12692 return err;
12693
f32610ed
JS
12694 return 1;
12695}
12696
12697/* additional initialization for auto-configuration model */
12698static void alc861vd_auto_init(struct hda_codec *codec)
12699{
f6c7e546 12700 struct alc_spec *spec = codec->spec;
f32610ed
JS
12701 alc861vd_auto_init_multi_out(codec);
12702 alc861vd_auto_init_hp_out(codec);
12703 alc861vd_auto_init_analog_input(codec);
f6c7e546
TI
12704 if (spec->unsol_event)
12705 alc_sku_automute(codec);
f32610ed
JS
12706}
12707
12708static int patch_alc861vd(struct hda_codec *codec)
12709{
12710 struct alc_spec *spec;
12711 int err, board_config;
12712
12713 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12714 if (spec == NULL)
12715 return -ENOMEM;
12716
12717 codec->spec = spec;
12718
12719 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12720 alc861vd_models,
12721 alc861vd_cfg_tbl);
12722
12723 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12724 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12725 "ALC861VD, trying auto-probe from BIOS...\n");
12726 board_config = ALC861VD_AUTO;
12727 }
12728
12729 if (board_config == ALC861VD_AUTO) {
12730 /* automatic parse from the BIOS config */
12731 err = alc861vd_parse_auto_config(codec);
12732 if (err < 0) {
12733 alc_free(codec);
12734 return err;
f12ab1e0 12735 } else if (!err) {
f32610ed
JS
12736 printk(KERN_INFO
12737 "hda_codec: Cannot set up configuration "
12738 "from BIOS. Using base mode...\n");
12739 board_config = ALC861VD_3ST;
12740 }
12741 }
12742
12743 if (board_config != ALC861VD_AUTO)
12744 setup_preset(spec, &alc861vd_presets[board_config]);
12745
12746 spec->stream_name_analog = "ALC861VD Analog";
12747 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12748 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12749
12750 spec->stream_name_digital = "ALC861VD Digital";
12751 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12752 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12753
12754 spec->adc_nids = alc861vd_adc_nids;
12755 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
e1406348 12756 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed
JS
12757
12758 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12759 spec->num_mixers++;
12760
2134ea4f
TI
12761 spec->vmaster_nid = 0x02;
12762
f32610ed
JS
12763 codec->patch_ops = alc_patch_ops;
12764
12765 if (board_config == ALC861VD_AUTO)
12766 spec->init_hook = alc861vd_auto_init;
cb53c626
TI
12767#ifdef CONFIG_SND_HDA_POWER_SAVE
12768 if (!spec->loopback.amplist)
12769 spec->loopback.amplist = alc861vd_loopbacks;
12770#endif
f32610ed
JS
12771
12772 return 0;
12773}
12774
bc9f98a9
KY
12775/*
12776 * ALC662 support
12777 *
12778 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12779 * configuration. Each pin widget can choose any input DACs and a mixer.
12780 * Each ADC is connected from a mixer of all inputs. This makes possible
12781 * 6-channel independent captures.
12782 *
12783 * In addition, an independent DAC for the multi-playback (not used in this
12784 * driver yet).
12785 */
12786#define ALC662_DIGOUT_NID 0x06
12787#define ALC662_DIGIN_NID 0x0a
12788
12789static hda_nid_t alc662_dac_nids[4] = {
12790 /* front, rear, clfe, rear_surr */
12791 0x02, 0x03, 0x04
12792};
12793
12794static hda_nid_t alc662_adc_nids[1] = {
12795 /* ADC1-2 */
12796 0x09,
12797};
e1406348 12798
77a261b7 12799static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
e1406348 12800
bc9f98a9
KY
12801/* input MUX */
12802/* FIXME: should be a matrix-type input source selection */
bc9f98a9
KY
12803static struct hda_input_mux alc662_capture_source = {
12804 .num_items = 4,
12805 .items = {
12806 { "Mic", 0x0 },
12807 { "Front Mic", 0x1 },
12808 { "Line", 0x2 },
12809 { "CD", 0x4 },
12810 },
12811};
12812
12813static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12814 .num_items = 2,
12815 .items = {
12816 { "Mic", 0x1 },
12817 { "Line", 0x2 },
12818 },
12819};
291702f0
KY
12820
12821static struct hda_input_mux alc662_eeepc_capture_source = {
12822 .num_items = 2,
12823 .items = {
12824 { "i-Mic", 0x1 },
12825 { "e-Mic", 0x0 },
12826 },
12827};
12828
bc9f98a9
KY
12829#define alc662_mux_enum_info alc_mux_enum_info
12830#define alc662_mux_enum_get alc_mux_enum_get
e1406348 12831#define alc662_mux_enum_put alc882_mux_enum_put
bc9f98a9 12832
bc9f98a9
KY
12833/*
12834 * 2ch mode
12835 */
12836static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12837 { 2, NULL }
12838};
12839
12840/*
12841 * 2ch mode
12842 */
12843static struct hda_verb alc662_3ST_ch2_init[] = {
12844 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12845 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12846 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12847 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12848 { } /* end */
12849};
12850
12851/*
12852 * 6ch mode
12853 */
12854static struct hda_verb alc662_3ST_ch6_init[] = {
12855 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12856 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12857 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12860 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12861 { } /* end */
12862};
12863
12864static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12865 { 2, alc662_3ST_ch2_init },
12866 { 6, alc662_3ST_ch6_init },
12867};
12868
12869/*
12870 * 2ch mode
12871 */
12872static struct hda_verb alc662_sixstack_ch6_init[] = {
12873 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12874 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12875 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12876 { } /* end */
12877};
12878
12879/*
12880 * 6ch mode
12881 */
12882static struct hda_verb alc662_sixstack_ch8_init[] = {
12883 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12884 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12885 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12886 { } /* end */
12887};
12888
12889static struct hda_channel_mode alc662_5stack_modes[2] = {
12890 { 2, alc662_sixstack_ch6_init },
12891 { 6, alc662_sixstack_ch8_init },
12892};
12893
12894/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12895 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12896 */
12897
12898static struct snd_kcontrol_new alc662_base_mixer[] = {
12899 /* output mixer control */
12900 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12901 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12902 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12903 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12904 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12908 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12909
12910 /*Input mixer control */
12911 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12912 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12913 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12914 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12916 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12917 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12918 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
12919 { } /* end */
12920};
12921
12922static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12923 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12924 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12925 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12926 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12927 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12928 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12929 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12932 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12933 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12934 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12935 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12936 { } /* end */
12937};
12938
12939static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12940 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12941 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12942 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12943 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12944 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12946 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12947 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12948 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12949 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12950 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12955 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12956 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12957 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12958 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
bc9f98a9
KY
12959 { } /* end */
12960};
12961
12962static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
12963 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12964 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
12965 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12966 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
12967 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12968 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12969 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
12972 { } /* end */
12973};
12974
291702f0 12975static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
86cd9298 12976 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
291702f0 12977
b4818494
HRK
12978 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12979 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
291702f0
KY
12980
12981 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
12982 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12983 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12984
12985 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
12986 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12987 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12988 { } /* end */
12989};
12990
8c427226 12991static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
31bffaa9
TI
12992 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12993 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8c427226
KY
12994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12995 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
86cd9298 13000 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8c427226
KY
13001 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13006 { } /* end */
13007};
13008
bc9f98a9
KY
13009static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13010 {
13011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13012 .name = "Channel Mode",
13013 .info = alc_ch_mode_info,
13014 .get = alc_ch_mode_get,
13015 .put = alc_ch_mode_put,
13016 },
13017 { } /* end */
13018};
13019
13020static struct hda_verb alc662_init_verbs[] = {
13021 /* ADC: mute amp left and right */
13022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13023 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13024 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13025
cb53c626
TI
13026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13029 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13030 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9 13031
b60dd394
KY
13032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13034 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13035 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13036 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13037 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13038
13039 /* Front Pin: output 0 (0x0c) */
13040 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13041 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13042
13043 /* Rear Pin: output 1 (0x0d) */
13044 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13046
13047 /* CLFE Pin: output 2 (0x0e) */
13048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13049 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13050
13051 /* Mic (rear) pin: input vref at 80% */
13052 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13053 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13054 /* Front Mic pin: input vref at 80% */
13055 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13056 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13057 /* Line In pin: input */
13058 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13060 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13061 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13063 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13064 /* CD pin widget for input */
13065 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13066
13067 /* FIXME: use matrix-type input source selection */
13068 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13069 /* Input mixer */
13070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
291702f0
KY
13074
13075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
bc9f98a9
KY
13079 { }
13080};
13081
13082static struct hda_verb alc662_sue_init_verbs[] = {
13083 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
13085 {}
13086};
13087
13088static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13090 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13091 {}
bc9f98a9
KY
13092};
13093
8c427226
KY
13094/* Set Unsolicited Event*/
13095static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13097 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13098 {}
13099};
13100
bc9f98a9
KY
13101/*
13102 * generic initialization of ADC, input mixers and output mixers
13103 */
13104static struct hda_verb alc662_auto_init_verbs[] = {
13105 /*
13106 * Unmute ADC and set the default input to mic-in
13107 */
13108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13110
13111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13112 * mixer widget
13113 * Note: PASD motherboards uses the Line In 2 as the input for front
13114 * panel mic (mic 2)
13115 */
13116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
13117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
bc9f98a9
KY
13122
13123 /*
13124 * Set up output mixers (0x0c - 0x0f)
13125 */
13126 /* set vol=0 to output mixers */
13127 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13128 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13130
13131 /* set up input amps for analog loopback */
13132 /* Amp Indices: DAC = 0, mixer = 1 */
b60dd394
KY
13133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13138 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
13139
13140
13141 /* FIXME: use matrix-type input source selection */
13142 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13143 /* Input mixer */
13144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
d1a991a6 13145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
bc9f98a9
KY
13146 { }
13147};
13148
13149/* capture mixer elements */
13150static struct snd_kcontrol_new alc662_capture_mixer[] = {
13151 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13152 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13153 {
13154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13155 /* The multiple "Capture Source" controls confuse alsamixer
13156 * So call somewhat different..
bc9f98a9
KY
13157 */
13158 /* .name = "Capture Source", */
13159 .name = "Input Source",
13160 .count = 1,
6e7939bb
HRK
13161 .info = alc662_mux_enum_info,
13162 .get = alc662_mux_enum_get,
13163 .put = alc662_mux_enum_put,
bc9f98a9
KY
13164 },
13165 { } /* end */
13166};
13167
13168static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13169{
13170 unsigned int present;
f12ab1e0 13171 unsigned char bits;
bc9f98a9
KY
13172
13173 present = snd_hda_codec_read(codec, 0x14, 0,
13174 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13175 bits = present ? HDA_AMP_MUTE : 0;
13176 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13177 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13178}
13179
13180static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13181{
13182 unsigned int present;
f12ab1e0 13183 unsigned char bits;
bc9f98a9
KY
13184
13185 present = snd_hda_codec_read(codec, 0x1b, 0,
13186 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
47fd830a
TI
13187 bits = present ? HDA_AMP_MUTE : 0;
13188 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13189 HDA_AMP_MUTE, bits);
13190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13191 HDA_AMP_MUTE, bits);
bc9f98a9
KY
13192}
13193
13194static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13195 unsigned int res)
13196{
13197 if ((res >> 26) == ALC880_HP_EVENT)
13198 alc662_lenovo_101e_all_automute(codec);
13199 if ((res >> 26) == ALC880_FRONT_EVENT)
13200 alc662_lenovo_101e_ispeaker_automute(codec);
13201}
13202
291702f0
KY
13203static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13204{
13205 unsigned int present;
13206
13207 present = snd_hda_codec_read(codec, 0x18, 0,
13208 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13209 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13210 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13211 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13212 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13213 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13214 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13215 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13216 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13217}
13218
13219/* unsolicited event for HP jack sensing */
13220static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13221 unsigned int res)
13222{
13223 if ((res >> 26) == ALC880_HP_EVENT)
13224 alc262_hippo1_automute( codec );
13225
13226 if ((res >> 26) == ALC880_MIC_EVENT)
13227 alc662_eeepc_mic_automute(codec);
13228}
13229
13230static void alc662_eeepc_inithook(struct hda_codec *codec)
13231{
13232 alc262_hippo1_automute( codec );
13233 alc662_eeepc_mic_automute(codec);
13234}
13235
8c427226
KY
13236static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13237{
13238 unsigned int mute;
13239 unsigned int present;
13240
13241 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13242 present = snd_hda_codec_read(codec, 0x14, 0,
13243 AC_VERB_GET_PIN_SENSE, 0);
13244 present = (present & 0x80000000) != 0;
13245 if (present) {
13246 /* mute internal speaker */
13247 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13248 HDA_AMP_MUTE, HDA_AMP_MUTE);
13249 } else {
13250 /* unmute internal speaker if necessary */
13251 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13252 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13253 HDA_AMP_MUTE, mute);
13254 }
13255}
13256
13257/* unsolicited event for HP jack sensing */
13258static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13259 unsigned int res)
13260{
13261 if ((res >> 26) == ALC880_HP_EVENT)
13262 alc662_eeepc_ep20_automute(codec);
13263}
13264
13265static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13266{
13267 alc662_eeepc_ep20_automute(codec);
13268}
13269
cb53c626
TI
13270#ifdef CONFIG_SND_HDA_POWER_SAVE
13271#define alc662_loopbacks alc880_loopbacks
13272#endif
13273
bc9f98a9
KY
13274
13275/* pcm configuration: identiacal with ALC880 */
13276#define alc662_pcm_analog_playback alc880_pcm_analog_playback
13277#define alc662_pcm_analog_capture alc880_pcm_analog_capture
13278#define alc662_pcm_digital_playback alc880_pcm_digital_playback
13279#define alc662_pcm_digital_capture alc880_pcm_digital_capture
13280
13281/*
13282 * configuration and preset
13283 */
13284static const char *alc662_models[ALC662_MODEL_LAST] = {
13285 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13286 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13287 [ALC662_3ST_6ch] = "3stack-6ch",
13288 [ALC662_5ST_DIG] = "6stack-dig",
13289 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 13290 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 13291 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
bc9f98a9
KY
13292 [ALC662_AUTO] = "auto",
13293};
13294
13295static struct snd_pci_quirk alc662_cfg_tbl[] = {
291702f0 13296 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
8c427226 13297 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
ac3e3741 13298 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
bc9f98a9
KY
13299 {}
13300};
13301
13302static struct alc_config_preset alc662_presets[] = {
13303 [ALC662_3ST_2ch_DIG] = {
291702f0 13304 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
bc9f98a9
KY
13305 .init_verbs = { alc662_init_verbs },
13306 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13307 .dac_nids = alc662_dac_nids,
13308 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13309 .dig_in_nid = ALC662_DIGIN_NID,
13310 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13311 .channel_mode = alc662_3ST_2ch_modes,
13312 .input_mux = &alc662_capture_source,
13313 },
13314 [ALC662_3ST_6ch_DIG] = {
291702f0
KY
13315 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13316 alc662_capture_mixer },
bc9f98a9
KY
13317 .init_verbs = { alc662_init_verbs },
13318 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13319 .dac_nids = alc662_dac_nids,
13320 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13321 .dig_in_nid = ALC662_DIGIN_NID,
13322 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13323 .channel_mode = alc662_3ST_6ch_modes,
13324 .need_dac_fix = 1,
13325 .input_mux = &alc662_capture_source,
f12ab1e0 13326 },
bc9f98a9 13327 [ALC662_3ST_6ch] = {
291702f0
KY
13328 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13329 alc662_capture_mixer },
bc9f98a9
KY
13330 .init_verbs = { alc662_init_verbs },
13331 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13332 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13333 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13334 .channel_mode = alc662_3ST_6ch_modes,
13335 .need_dac_fix = 1,
13336 .input_mux = &alc662_capture_source,
f12ab1e0 13337 },
bc9f98a9 13338 [ALC662_5ST_DIG] = {
291702f0
KY
13339 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13340 alc662_capture_mixer },
bc9f98a9
KY
13341 .init_verbs = { alc662_init_verbs },
13342 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13343 .dac_nids = alc662_dac_nids,
13344 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
13345 .dig_in_nid = ALC662_DIGIN_NID,
13346 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13347 .channel_mode = alc662_5stack_modes,
13348 .input_mux = &alc662_capture_source,
13349 },
13350 [ALC662_LENOVO_101E] = {
291702f0 13351 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
bc9f98a9
KY
13352 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13353 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13354 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
13355 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13356 .channel_mode = alc662_3ST_2ch_modes,
13357 .input_mux = &alc662_lenovo_101e_capture_source,
13358 .unsol_event = alc662_lenovo_101e_unsol_event,
13359 .init_hook = alc662_lenovo_101e_all_automute,
13360 },
291702f0
KY
13361 [ALC662_ASUS_EEEPC_P701] = {
13362 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13363 .init_verbs = { alc662_init_verbs,
13364 alc662_eeepc_sue_init_verbs },
13365 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13366 .dac_nids = alc662_dac_nids,
291702f0
KY
13367 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13368 .channel_mode = alc662_3ST_2ch_modes,
13369 .input_mux = &alc662_eeepc_capture_source,
13370 .unsol_event = alc662_eeepc_unsol_event,
13371 .init_hook = alc662_eeepc_inithook,
13372 },
8c427226
KY
13373 [ALC662_ASUS_EEEPC_EP20] = {
13374 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13375 alc662_chmode_mixer },
13376 .init_verbs = { alc662_init_verbs,
13377 alc662_eeepc_ep20_sue_init_verbs },
13378 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13379 .dac_nids = alc662_dac_nids,
8c427226
KY
13380 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13381 .channel_mode = alc662_3ST_6ch_modes,
13382 .input_mux = &alc662_lenovo_101e_capture_source,
13383 .unsol_event = alc662_eeepc_ep20_unsol_event,
13384 .init_hook = alc662_eeepc_ep20_inithook,
13385 },
bc9f98a9
KY
13386
13387};
13388
13389
13390/*
13391 * BIOS auto configuration
13392 */
13393
13394/* add playback controls from the parsed DAC table */
13395static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13396 const struct auto_pin_cfg *cfg)
13397{
13398 char name[32];
13399 static const char *chname[4] = {
13400 "Front", "Surround", NULL /*CLFE*/, "Side"
13401 };
13402 hda_nid_t nid;
13403 int i, err;
13404
13405 for (i = 0; i < cfg->line_outs; i++) {
13406 if (!spec->multiout.dac_nids[i])
13407 continue;
b60dd394 13408 nid = alc880_idx_to_dac(i);
bc9f98a9
KY
13409 if (i == 2) {
13410 /* Center/LFE */
13411 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13412 "Center Playback Volume",
f12ab1e0
TI
13413 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13414 HDA_OUTPUT));
bc9f98a9
KY
13415 if (err < 0)
13416 return err;
13417 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13418 "LFE Playback Volume",
f12ab1e0
TI
13419 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13420 HDA_OUTPUT));
bc9f98a9
KY
13421 if (err < 0)
13422 return err;
13423 err = add_control(spec, ALC_CTL_BIND_MUTE,
13424 "Center Playback Switch",
f12ab1e0
TI
13425 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13426 HDA_INPUT));
bc9f98a9
KY
13427 if (err < 0)
13428 return err;
13429 err = add_control(spec, ALC_CTL_BIND_MUTE,
13430 "LFE Playback Switch",
f12ab1e0
TI
13431 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13432 HDA_INPUT));
bc9f98a9
KY
13433 if (err < 0)
13434 return err;
13435 } else {
13436 sprintf(name, "%s Playback Volume", chname[i]);
13437 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
f12ab1e0
TI
13438 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13439 HDA_OUTPUT));
bc9f98a9
KY
13440 if (err < 0)
13441 return err;
13442 sprintf(name, "%s Playback Switch", chname[i]);
13443 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
f12ab1e0
TI
13444 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13445 HDA_INPUT));
bc9f98a9
KY
13446 if (err < 0)
13447 return err;
13448 }
13449 }
13450 return 0;
13451}
13452
13453/* add playback controls for speaker and HP outputs */
13454static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13455 const char *pfx)
13456{
13457 hda_nid_t nid;
13458 int err;
13459 char name[32];
13460
13461 if (!pin)
13462 return 0;
13463
13464 if (alc880_is_fixed_pin(pin)) {
13465 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13466 /* printk("DAC nid=%x\n",nid); */
13467 /* specify the DAC as the extra output */
13468 if (!spec->multiout.hp_nid)
13469 spec->multiout.hp_nid = nid;
13470 else
13471 spec->multiout.extra_out_nid[0] = nid;
13472 /* control HP volume/switch on the output mixer amp */
13473 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13474 sprintf(name, "%s Playback Volume", pfx);
13475 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13476 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13477 if (err < 0)
13478 return err;
13479 sprintf(name, "%s Playback Switch", pfx);
13480 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13481 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13482 if (err < 0)
13483 return err;
13484 } else if (alc880_is_multi_pin(pin)) {
13485 /* set manual connection */
13486 /* we have only a switch on HP-out PIN */
13487 sprintf(name, "%s Playback Switch", pfx);
13488 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13489 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13490 if (err < 0)
13491 return err;
13492 }
13493 return 0;
13494}
13495
13496/* create playback/capture controls for input pins */
13497static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13498 const struct auto_pin_cfg *cfg)
13499{
13500 struct hda_input_mux *imux = &spec->private_imux;
13501 int i, err, idx;
13502
13503 for (i = 0; i < AUTO_PIN_LAST; i++) {
13504 if (alc880_is_input_pin(cfg->input_pins[i])) {
13505 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13506 err = new_analog_input(spec, cfg->input_pins[i],
13507 auto_pin_cfg_labels[i],
13508 idx, 0x0b);
13509 if (err < 0)
13510 return err;
13511 imux->items[imux->num_items].label =
13512 auto_pin_cfg_labels[i];
13513 imux->items[imux->num_items].index =
13514 alc880_input_pin_idx(cfg->input_pins[i]);
13515 imux->num_items++;
13516 }
13517 }
13518 return 0;
13519}
13520
13521static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13522 hda_nid_t nid, int pin_type,
13523 int dac_idx)
13524{
f6c7e546 13525 alc_set_pin_output(codec, nid, pin_type);
bc9f98a9
KY
13526 /* need the manual connection? */
13527 if (alc880_is_multi_pin(nid)) {
13528 struct alc_spec *spec = codec->spec;
13529 int idx = alc880_multi_pin_idx(nid);
13530 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13531 AC_VERB_SET_CONNECT_SEL,
13532 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13533 }
13534}
13535
13536static void alc662_auto_init_multi_out(struct hda_codec *codec)
13537{
13538 struct alc_spec *spec = codec->spec;
13539 int i;
13540
8c427226 13541 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
bc9f98a9
KY
13542 for (i = 0; i <= HDA_SIDE; i++) {
13543 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 13544 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9 13545 if (nid)
baba8ee9 13546 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
bc9f98a9
KY
13547 i);
13548 }
13549}
13550
13551static void alc662_auto_init_hp_out(struct hda_codec *codec)
13552{
13553 struct alc_spec *spec = codec->spec;
13554 hda_nid_t pin;
13555
13556 pin = spec->autocfg.hp_pins[0];
13557 if (pin) /* connect to front */
13558 /* use dac 0 */
13559 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
13560 pin = spec->autocfg.speaker_pins[0];
13561 if (pin)
13562 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
bc9f98a9
KY
13563}
13564
13565#define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13566#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13567
13568static void alc662_auto_init_analog_input(struct hda_codec *codec)
13569{
13570 struct alc_spec *spec = codec->spec;
13571 int i;
13572
13573 for (i = 0; i < AUTO_PIN_LAST; i++) {
13574 hda_nid_t nid = spec->autocfg.input_pins[i];
13575 if (alc662_is_input_pin(nid)) {
13576 snd_hda_codec_write(codec, nid, 0,
13577 AC_VERB_SET_PIN_WIDGET_CONTROL,
13578 (i <= AUTO_PIN_FRONT_MIC ?
13579 PIN_VREF80 : PIN_IN));
13580 if (nid != ALC662_PIN_CD_NID)
13581 snd_hda_codec_write(codec, nid, 0,
13582 AC_VERB_SET_AMP_GAIN_MUTE,
13583 AMP_OUT_MUTE);
13584 }
13585 }
13586}
13587
13588static int alc662_parse_auto_config(struct hda_codec *codec)
13589{
13590 struct alc_spec *spec = codec->spec;
13591 int err;
13592 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13593
13594 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13595 alc662_ignore);
13596 if (err < 0)
13597 return err;
13598 if (!spec->autocfg.line_outs)
13599 return 0; /* can't find valid BIOS pin config */
13600
f12ab1e0
TI
13601 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13602 if (err < 0)
13603 return err;
13604 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13605 if (err < 0)
13606 return err;
13607 err = alc662_auto_create_extra_out(spec,
13608 spec->autocfg.speaker_pins[0],
13609 "Speaker");
13610 if (err < 0)
13611 return err;
13612 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13613 "Headphone");
13614 if (err < 0)
13615 return err;
13616 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13617 if (err < 0)
bc9f98a9
KY
13618 return err;
13619
13620 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13621
13622 if (spec->autocfg.dig_out_pin)
13623 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13624
13625 if (spec->kctl_alloc)
13626 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13627
13628 spec->num_mux_defs = 1;
13629 spec->input_mux = &spec->private_imux;
13630
8c87286f 13631 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
bc9f98a9
KY
13632 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13633 spec->num_mixers++;
8c87286f 13634 return 1;
bc9f98a9
KY
13635}
13636
13637/* additional initialization for auto-configuration model */
13638static void alc662_auto_init(struct hda_codec *codec)
13639{
f6c7e546 13640 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
13641 alc662_auto_init_multi_out(codec);
13642 alc662_auto_init_hp_out(codec);
13643 alc662_auto_init_analog_input(codec);
f6c7e546
TI
13644 if (spec->unsol_event)
13645 alc_sku_automute(codec);
bc9f98a9
KY
13646}
13647
13648static int patch_alc662(struct hda_codec *codec)
13649{
13650 struct alc_spec *spec;
13651 int err, board_config;
13652
13653 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13654 if (!spec)
13655 return -ENOMEM;
13656
13657 codec->spec = spec;
13658
13659 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13660 alc662_models,
13661 alc662_cfg_tbl);
13662 if (board_config < 0) {
13663 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13664 "trying auto-probe from BIOS...\n");
13665 board_config = ALC662_AUTO;
13666 }
13667
13668 if (board_config == ALC662_AUTO) {
13669 /* automatic parse from the BIOS config */
13670 err = alc662_parse_auto_config(codec);
13671 if (err < 0) {
13672 alc_free(codec);
13673 return err;
8c87286f 13674 } else if (!err) {
bc9f98a9
KY
13675 printk(KERN_INFO
13676 "hda_codec: Cannot set up configuration "
13677 "from BIOS. Using base mode...\n");
13678 board_config = ALC662_3ST_2ch_DIG;
13679 }
13680 }
13681
13682 if (board_config != ALC662_AUTO)
13683 setup_preset(spec, &alc662_presets[board_config]);
13684
13685 spec->stream_name_analog = "ALC662 Analog";
13686 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13687 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13688
13689 spec->stream_name_digital = "ALC662 Digital";
13690 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13691 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13692
e1406348
TI
13693 spec->adc_nids = alc662_adc_nids;
13694 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13695 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 13696
2134ea4f
TI
13697 spec->vmaster_nid = 0x02;
13698
bc9f98a9
KY
13699 codec->patch_ops = alc_patch_ops;
13700 if (board_config == ALC662_AUTO)
13701 spec->init_hook = alc662_auto_init;
cb53c626
TI
13702#ifdef CONFIG_SND_HDA_POWER_SAVE
13703 if (!spec->loopback.amplist)
13704 spec->loopback.amplist = alc662_loopbacks;
13705#endif
bc9f98a9
KY
13706
13707 return 0;
13708}
13709
1da177e4
LT
13710/*
13711 * patch entries
13712 */
13713struct hda_codec_preset snd_hda_preset_realtek[] = {
13714 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 13715 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 13716 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 13717 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 13718 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
f32610ed 13719 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 13720 .patch = patch_alc861 },
f32610ed
JS
13721 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13722 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13723 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9
KY
13724 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13725 .patch = patch_alc883 },
13726 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13727 .patch = patch_alc662 },
f32610ed 13728 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 13729 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
9c7f852e 13730 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
df694daa 13731 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
9c7f852e 13732 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
f6a92248 13733 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
1da177e4
LT
13734 {} /* terminator */
13735};